修复录制与回放功能,添加新电机控制程序进行测试
This commit is contained in:
parent
9d8d7444b4
commit
4faa9f6b35
@ -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
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