修复录制与回放功能,添加新电机控制程序进行测试
This commit is contained in:
parent
9d8d7444b4
commit
4faa9f6b35
@ -4,6 +4,7 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||||||
|
|
||||||
// 录制相关全局变量
|
// 录制相关全局变量
|
||||||
window.isRecording = false;
|
window.isRecording = false;
|
||||||
|
window.isPlaying = false;
|
||||||
window.recordedActions = [];
|
window.recordedActions = [];
|
||||||
window.recordingStartTime = 0;
|
window.recordingStartTime = 0;
|
||||||
|
|
||||||
@ -21,6 +22,11 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||||||
// 录制按钮点击事件 - 支持鼠标和触摸事件
|
// 录制按钮点击事件 - 支持鼠标和触摸事件
|
||||||
function toggleRecording() {
|
function toggleRecording() {
|
||||||
console.log('toggleRecording called, current isRecording:', window.isRecording);
|
console.log('toggleRecording called, current isRecording:', window.isRecording);
|
||||||
|
if (window.isPlaying) {
|
||||||
|
alert('正在回放,不能录制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (window.isRecording) {
|
if (window.isRecording) {
|
||||||
// 停止录制
|
// 停止录制
|
||||||
window.isRecording = false;
|
window.isRecording = false;
|
||||||
@ -52,6 +58,11 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||||||
// 回放按钮点击事件 - 支持鼠标和触摸事件
|
// 回放按钮点击事件 - 支持鼠标和触摸事件
|
||||||
function startPlayback() {
|
function startPlayback() {
|
||||||
console.log('startPlayback called, recordedActions:', window.recordedActions);
|
console.log('startPlayback called, recordedActions:', window.recordedActions);
|
||||||
|
if (window.isRecording) {
|
||||||
|
alert('请先停止录制');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (window.recordedActions.length === 0) {
|
if (window.recordedActions.length === 0) {
|
||||||
status.innerHTML = `<p>没有可回放的操作</p>`;
|
status.innerHTML = `<p>没有可回放的操作</p>`;
|
||||||
console.log('No actions to playback');
|
console.log('No actions to playback');
|
||||||
@ -61,32 +72,35 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||||||
// 保存当前录制状态并禁用录制
|
// 保存当前录制状态并禁用录制
|
||||||
const originalRecordingState = window.isRecording;
|
const originalRecordingState = window.isRecording;
|
||||||
window.isRecording = false;
|
window.isRecording = false;
|
||||||
|
window.isPlaying = true;
|
||||||
|
|
||||||
status.innerHTML = `<p>开始回放...</p>`;
|
status.innerHTML = `<p>开始回放...</p>`;
|
||||||
console.log('Starting playback');
|
console.log('Starting playback');
|
||||||
|
|
||||||
// 按时间顺序回放操作
|
// 按时间顺序回放操作
|
||||||
let lastTimestamp = 0;
|
let currentTime = 0;
|
||||||
const totalDuration = window.recordedActions[window.recordedActions.length - 1].timestamp;
|
const totalDuration = window.recordedActions[window.recordedActions.length - 1].timestamp;
|
||||||
|
|
||||||
// 确保至少有一个操作
|
// 执行所有操作
|
||||||
if (window.recordedActions.length > 0) {
|
window.recordedActions.forEach((action, index) => {
|
||||||
// 执行第一个操作
|
if (index === 0) {
|
||||||
console.log('Executing first action immediately:', window.recordedActions[0]);
|
// 第一个操作立即执行
|
||||||
controlMotor(window.recordedActions[0].direction);
|
console.log('Executing action immediately:', action);
|
||||||
|
controlMotor(action.direction);
|
||||||
// 执行剩余的操作
|
} else {
|
||||||
for (let i = 1; i < window.recordedActions.length; i++) {
|
// 计算与前一个操作的时间差
|
||||||
const action = window.recordedActions[i];
|
const prevAction = window.recordedActions[index - 1];
|
||||||
const delay = action.timestamp - window.recordedActions[i-1].timestamp;
|
const delay = action.timestamp - prevAction.timestamp;
|
||||||
console.log('Scheduling action:', action, 'at delay:', delay);
|
currentTime += delay;
|
||||||
|
|
||||||
|
console.log('Scheduling action:', action, 'at delay:', currentTime);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
// 调用控制函数执行操作
|
// 调用控制函数执行操作
|
||||||
console.log('Executing action:', action);
|
console.log('Executing action:', action);
|
||||||
controlMotor(action.direction);
|
controlMotor(action.direction);
|
||||||
}, delay);
|
}, currentTime);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
|
|
||||||
// 回放完成后,确保发送停止请求
|
// 回放完成后,确保发送停止请求
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -96,7 +110,8 @@ window.addEventListener('DOMContentLoaded', function() {
|
|||||||
console.log('Playback completed');
|
console.log('Playback completed');
|
||||||
// 恢复原始录制状态
|
// 恢复原始录制状态
|
||||||
window.isRecording = originalRecordingState;
|
window.isRecording = originalRecordingState;
|
||||||
}, totalDuration + 1000);
|
window.isPlaying = false;
|
||||||
|
}, totalDuration + 2000); // 增加延迟,确保所有动作都已执行
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Adding click event listener to playbackBtn');
|
console.log('Adding click event listener to playbackBtn');
|
||||||
|
|||||||
146
main/motor_test.py
Normal file
146
main/motor_test.py
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
from smbus2 import SMBus
|
||||||
|
import time
|
||||||
|
import signal
|
||||||
|
import sys
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# Ctrl+C 安全退出
|
||||||
|
# ======================
|
||||||
|
def signal_handler(sig, frame):
|
||||||
|
print("\n停止电机...")
|
||||||
|
stop()
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
signal.signal(signal.SIGINT, signal_handler)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# PCA9685 初始化
|
||||||
|
# ======================
|
||||||
|
bus = SMBus(1)
|
||||||
|
addr = 0x60
|
||||||
|
|
||||||
|
bus.write_byte_data(addr, 0x00, 0x00)
|
||||||
|
bus.write_byte_data(addr, 0xFE, 60)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# 电机定义
|
||||||
|
# ======================
|
||||||
|
MOTOR = {
|
||||||
|
"M1": (0, 1), # 前左(Y轴)
|
||||||
|
"M2": (2, 3), # 前右(Y轴)
|
||||||
|
"M3": (4, 5), # 后左(X轴)
|
||||||
|
"M4": (6, 7), # 后右(X轴)
|
||||||
|
}
|
||||||
|
|
||||||
|
# ⚠️ 需要你微调方向(如果反了就改 ±1)
|
||||||
|
DIR = {
|
||||||
|
"M1": 1,
|
||||||
|
"M2": 1,
|
||||||
|
"M3": 1,
|
||||||
|
"M4": 1,
|
||||||
|
}
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# PWM输出
|
||||||
|
# ======================
|
||||||
|
def set_pwm(ch, value):
|
||||||
|
value = max(0, min(4095, value))
|
||||||
|
bus.write_byte_data(addr, 0x06 + 4 * ch, 0)
|
||||||
|
bus.write_byte_data(addr, 0x07 + 4 * ch, 0)
|
||||||
|
bus.write_byte_data(addr, 0x08 + 4 * ch, value & 0xFF)
|
||||||
|
bus.write_byte_data(addr, 0x09 + 4 * ch, value >> 8)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# 单电机控制
|
||||||
|
# ======================
|
||||||
|
def motor_drive(name, speed):
|
||||||
|
in1, in2 = MOTOR[name]
|
||||||
|
|
||||||
|
speed *= DIR[name]
|
||||||
|
pwm = int(abs(speed) * 4095)
|
||||||
|
|
||||||
|
if speed > 0:
|
||||||
|
set_pwm(in1, pwm)
|
||||||
|
set_pwm(in2, 0)
|
||||||
|
elif speed < 0:
|
||||||
|
set_pwm(in1, 0)
|
||||||
|
set_pwm(in2, pwm)
|
||||||
|
else:
|
||||||
|
# 刹车
|
||||||
|
set_pwm(in1, 4095)
|
||||||
|
set_pwm(in2, 4095)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# ⭐ 全向轮核心控制(重点)
|
||||||
|
# vx: 左右 (-1~1)
|
||||||
|
# vy: 前后 (-1~1)
|
||||||
|
# w : 旋转 (-1~1)
|
||||||
|
# ======================
|
||||||
|
def move(vx, vy, w):
|
||||||
|
m1 = vy + w
|
||||||
|
m2 = vy - w
|
||||||
|
m3 = vx + w
|
||||||
|
m4 = vx - w
|
||||||
|
|
||||||
|
# 归一化(防止超限)
|
||||||
|
max_val = max(abs(m1), abs(m2), abs(m3), abs(m4), 1)
|
||||||
|
|
||||||
|
motor_drive("M1", m1 / max_val)
|
||||||
|
motor_drive("M2", m2 / max_val)
|
||||||
|
motor_drive("M3", m3 / max_val)
|
||||||
|
motor_drive("M4", m4 / max_val)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# 基础动作(封装)
|
||||||
|
# ======================
|
||||||
|
def forward(speed=0.6):
|
||||||
|
move(0, speed, 0)
|
||||||
|
|
||||||
|
def backward(speed=0.6):
|
||||||
|
move(0, -speed, 0)
|
||||||
|
|
||||||
|
def left(speed=0.6):
|
||||||
|
move(-speed, 0, 0)
|
||||||
|
|
||||||
|
def right(speed=0.6):
|
||||||
|
move(speed, 0, 0)
|
||||||
|
|
||||||
|
def rotate_left(speed=0.6):
|
||||||
|
move(0, 0, speed)
|
||||||
|
|
||||||
|
def rotate_right(speed=0.6):
|
||||||
|
move(0, 0, -speed)
|
||||||
|
|
||||||
|
def stop():
|
||||||
|
motor_drive("M1", 0)
|
||||||
|
motor_drive("M2", 0)
|
||||||
|
motor_drive("M3", 0)
|
||||||
|
motor_drive("M4", 0)
|
||||||
|
|
||||||
|
# ======================
|
||||||
|
# 测试
|
||||||
|
# ======================
|
||||||
|
if __name__ == "__main__":
|
||||||
|
|
||||||
|
print("前进")
|
||||||
|
forward()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("后退")
|
||||||
|
backward()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("左移")
|
||||||
|
left()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("右移")
|
||||||
|
right()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("左旋转")
|
||||||
|
rotate_left()
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
print("停止")
|
||||||
|
stop()
|
||||||
Loading…
x
Reference in New Issue
Block a user