修复录制与回放功能,添加新电机控制程序进行测试

This commit is contained in:
张梦南 2026-04-13 15:43:48 +08:00
parent 9d8d7444b4
commit 4faa9f6b35
2 changed files with 176 additions and 15 deletions

View File

@ -4,6 +4,7 @@ window.addEventListener('DOMContentLoaded', function() {
// 录制相关全局变量
window.isRecording = false;
window.isPlaying = false;
window.recordedActions = [];
window.recordingStartTime = 0;
@ -21,6 +22,11 @@ window.addEventListener('DOMContentLoaded', function() {
// 录制按钮点击事件 - 支持鼠标和触摸事件
function toggleRecording() {
console.log('toggleRecording called, current isRecording:', window.isRecording);
if (window.isPlaying) {
alert('正在回放,不能录制');
return;
}
if (window.isRecording) {
// 停止录制
window.isRecording = false;
@ -52,6 +58,11 @@ window.addEventListener('DOMContentLoaded', function() {
// 回放按钮点击事件 - 支持鼠标和触摸事件
function startPlayback() {
console.log('startPlayback called, recordedActions:', window.recordedActions);
if (window.isRecording) {
alert('请先停止录制');
return;
}
if (window.recordedActions.length === 0) {
status.innerHTML = `<p>没有可回放的操作</p>`;
console.log('No actions to playback');
@ -61,32 +72,35 @@ window.addEventListener('DOMContentLoaded', function() {
// 保存当前录制状态并禁用录制
const originalRecordingState = window.isRecording;
window.isRecording = false;
window.isPlaying = true;
status.innerHTML = `<p>开始回放...</p>`;
console.log('Starting playback');
// 按时间顺序回放操作
let lastTimestamp = 0;
let currentTime = 0;
const totalDuration = window.recordedActions[window.recordedActions.length - 1].timestamp;
// 确保至少有一个操作
if (window.recordedActions.length > 0) {
// 执行第一个操作
console.log('Executing first action immediately:', window.recordedActions[0]);
controlMotor(window.recordedActions[0].direction);
// 执行剩余的操作
for (let i = 1; i < window.recordedActions.length; i++) {
const action = window.recordedActions[i];
const delay = action.timestamp - window.recordedActions[i-1].timestamp;
console.log('Scheduling action:', action, 'at delay:', delay);
// 执行所有操作
window.recordedActions.forEach((action, index) => {
if (index === 0) {
// 第一个操作立即执行
console.log('Executing action immediately:', action);
controlMotor(action.direction);
} else {
// 计算与前一个操作的时间差
const prevAction = window.recordedActions[index - 1];
const delay = action.timestamp - prevAction.timestamp;
currentTime += delay;
console.log('Scheduling action:', action, 'at delay:', currentTime);
setTimeout(() => {
// 调用控制函数执行操作
console.log('Executing action:', action);
controlMotor(action.direction);
}, delay);
}, currentTime);
}
}
});
// 回放完成后,确保发送停止请求
setTimeout(() => {
@ -96,7 +110,8 @@ window.addEventListener('DOMContentLoaded', function() {
console.log('Playback completed');
// 恢复原始录制状态
window.isRecording = originalRecordingState;
}, totalDuration + 1000);
window.isPlaying = false;
}, totalDuration + 2000); // 增加延迟,确保所有动作都已执行
}
console.log('Adding click event listener to playbackBtn');

146
main/motor_test.py Normal file
View 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()