修复agent驱动程序、修复手柄路径保存逻辑、增加电机转速补偿
This commit is contained in:
parent
f48facde94
commit
7896e90602
@ -11,6 +11,9 @@ const backwardLeftBtn = document.getElementById('backwardLeftBtn');
|
||||
const backwardRightBtn = document.getElementById('backwardRightBtn');
|
||||
const status = document.getElementById('status');
|
||||
|
||||
// 跟踪上一个记录的动作
|
||||
let lastRecordedAction = null;
|
||||
|
||||
// 实际控制函数
|
||||
function controlMotor(direction) {
|
||||
// 根据方向设置状态消息
|
||||
@ -34,11 +37,18 @@ function controlMotor(direction) {
|
||||
status.innerHTML = `<p>正在${actionText}...</p>`;
|
||||
}
|
||||
|
||||
// 记录操作(如果正在录制)
|
||||
// 记录操作(如果正在录制且动作发生变化)
|
||||
if (window.isRecording) {
|
||||
const timestamp = Date.now() - window.recordingStartTime;
|
||||
window.recordedActions.push({ direction, timestamp });
|
||||
console.log('Recorded action:', { direction, timestamp });
|
||||
// 检查动作是否发生变化
|
||||
if (direction !== lastRecordedAction) {
|
||||
const timestamp = Date.now() - window.recordingStartTime;
|
||||
window.recordedActions.push({ direction, timestamp });
|
||||
console.log('Recorded action:', { direction, timestamp });
|
||||
// 更新上一个记录的动作
|
||||
lastRecordedAction = direction;
|
||||
} else {
|
||||
console.log('Not recording duplicate action:', direction);
|
||||
}
|
||||
} else {
|
||||
console.log('Not recording, action:', direction);
|
||||
}
|
||||
@ -419,11 +429,18 @@ backwardRightBtn.addEventListener('touchcancel', (e) => {
|
||||
|
||||
// 停止电机函数
|
||||
function stopMotor() {
|
||||
// 记录操作(如果正在录制)
|
||||
// 记录操作(如果正在录制且动作发生变化)
|
||||
if (window.isRecording) {
|
||||
const timestamp = Date.now() - window.recordingStartTime;
|
||||
window.recordedActions.push({ direction: 'stop', timestamp });
|
||||
console.log('Recorded action:', { direction: 'stop', timestamp });
|
||||
// 检查动作是否发生变化
|
||||
if ('stop' !== lastRecordedAction) {
|
||||
const timestamp = Date.now() - window.recordingStartTime;
|
||||
window.recordedActions.push({ direction: 'stop', timestamp });
|
||||
console.log('Recorded action:', { direction: 'stop', timestamp });
|
||||
// 更新上一个记录的动作
|
||||
lastRecordedAction = 'stop';
|
||||
} else {
|
||||
console.log('Not recording duplicate action:', 'stop');
|
||||
}
|
||||
} else {
|
||||
console.log('Not recording, action:', 'stop');
|
||||
}
|
||||
|
||||
@ -5,10 +5,11 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
// 游戏手柄相关变量
|
||||
let gamepad = null;
|
||||
let lastDirection = 'stop';
|
||||
let isRecording = false;
|
||||
let isPlaying = false;
|
||||
let recordedActions = [];
|
||||
let recordingStartTime = 0;
|
||||
// 使用全局变量,与control.js和record.js保持一致
|
||||
// let isRecording = false;
|
||||
// let isPlaying = false;
|
||||
// let recordedActions = [];
|
||||
// let recordingStartTime = 0;
|
||||
|
||||
// 按键状态标志(用于检测按键按下事件)
|
||||
let recordButtonPressed = false;
|
||||
@ -104,17 +105,17 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
if (buttons[12].pressed) { // 十字键上键 - 录制
|
||||
if (!recordButtonPressed) {
|
||||
recordButtonPressed = true;
|
||||
if (!isPlaying) {
|
||||
if (isRecording) {
|
||||
if (!window.isPlaying) {
|
||||
if (window.isRecording) {
|
||||
// 停止录制
|
||||
isRecording = false;
|
||||
status.innerHTML = `<p>录制完成,共记录 ${recordedActions.length} 个操作</p>`;
|
||||
console.log('Recording stopped, actions:', recordedActions);
|
||||
window.isRecording = false;
|
||||
status.innerHTML = `<p>录制完成,共记录 ${window.recordedActions.length} 个操作</p>`;
|
||||
console.log('Recording stopped, actions:', window.recordedActions);
|
||||
} else {
|
||||
// 开始录制
|
||||
isRecording = true;
|
||||
recordedActions = [];
|
||||
recordingStartTime = Date.now();
|
||||
window.isRecording = true;
|
||||
window.recordedActions = [];
|
||||
window.recordingStartTime = Date.now();
|
||||
status.innerHTML = '<p>开始录制...</p>';
|
||||
console.log('Recording started');
|
||||
}
|
||||
@ -128,23 +129,23 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
if (buttons[14].pressed) { // 十字键左键 - 回放
|
||||
if (!playbackButtonPressed) {
|
||||
playbackButtonPressed = true;
|
||||
if (!isRecording && !isPlaying && recordedActions.length > 0) {
|
||||
isPlaying = true;
|
||||
if (!window.isRecording && !window.isPlaying && window.recordedActions.length > 0) {
|
||||
window.isPlaying = true;
|
||||
status.innerHTML = '<p>开始回放...</p>';
|
||||
console.log('Starting playback');
|
||||
|
||||
// 按时间顺序回放操作
|
||||
let currentTime = 0;
|
||||
const totalDuration = recordedActions[recordedActions.length - 1].timestamp;
|
||||
const totalDuration = window.recordedActions[window.recordedActions.length - 1].timestamp;
|
||||
|
||||
recordedActions.forEach((action, index) => {
|
||||
window.recordedActions.forEach((action, index) => {
|
||||
if (index === 0) {
|
||||
// 第一个操作立即执行
|
||||
console.log('Executing action immediately:', action);
|
||||
controlMotor(action.direction);
|
||||
} else {
|
||||
// 计算与前一个操作的时间差
|
||||
const prevAction = recordedActions[index - 1];
|
||||
const prevAction = window.recordedActions[index - 1];
|
||||
const delay = action.timestamp - prevAction.timestamp;
|
||||
currentTime += delay;
|
||||
|
||||
@ -162,7 +163,7 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
controlMotor('stop');
|
||||
status.innerHTML = '<p>回放完成</p>';
|
||||
console.log('Playback completed');
|
||||
isPlaying = false;
|
||||
window.isPlaying = false;
|
||||
}, totalDuration + 2000);
|
||||
}
|
||||
}
|
||||
@ -173,12 +174,12 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
// 如果方向改变,发送控制命令
|
||||
if (direction !== lastDirection) {
|
||||
// 如果正在录制,记录操作
|
||||
if (isRecording) {
|
||||
if (window.isRecording) {
|
||||
const action = {
|
||||
direction: direction,
|
||||
timestamp: Date.now() - recordingStartTime
|
||||
timestamp: Date.now() - window.recordingStartTime
|
||||
};
|
||||
recordedActions.push(action);
|
||||
window.recordedActions.push(action);
|
||||
}
|
||||
controlMotor(direction);
|
||||
lastDirection = direction;
|
||||
@ -212,8 +213,8 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
}
|
||||
|
||||
// 记录操作(如果正在录制)
|
||||
if (isRecording) {
|
||||
const timestamp = Date.now() - recordingStartTime;
|
||||
if (window.isRecording) {
|
||||
const timestamp = Date.now() - window.recordingStartTime;
|
||||
// 注意:这里不再重复记录,因为已经在updateGamepad中记录了
|
||||
console.log('Recorded action:', { direction, timestamp });
|
||||
} else {
|
||||
|
||||
@ -179,6 +179,10 @@ window.addEventListener('DOMContentLoaded', function() {
|
||||
window.isRecording = true;
|
||||
window.recordedActions = [];
|
||||
window.recordingStartTime = Date.now();
|
||||
// 重置上一个记录的动作
|
||||
if (window.lastRecordedAction !== undefined) {
|
||||
window.lastRecordedAction = null;
|
||||
}
|
||||
recordBtn.textContent = '停止录制';
|
||||
status.innerHTML = `<p>开始录制...</p>`;
|
||||
console.log('Recording started');
|
||||
|
||||
25
main/Path/test1.json
Normal file
25
main/Path/test1.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "test1",
|
||||
"actions": [
|
||||
{
|
||||
"direction": "stop",
|
||||
"timestamp": 1632
|
||||
},
|
||||
{
|
||||
"direction": "forward_left",
|
||||
"timestamp": 5172
|
||||
},
|
||||
{
|
||||
"direction": "stop",
|
||||
"timestamp": 5581
|
||||
},
|
||||
{
|
||||
"direction": "backward_right",
|
||||
"timestamp": 7103
|
||||
},
|
||||
{
|
||||
"direction": "stop",
|
||||
"timestamp": 7481
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -1,21 +1,21 @@
|
||||
{
|
||||
"name": "轨迹",
|
||||
"name": "test2",
|
||||
"actions": [
|
||||
{
|
||||
"direction": "forward",
|
||||
"timestamp": 858
|
||||
"timestamp": 1734
|
||||
},
|
||||
{
|
||||
"direction": "stop",
|
||||
"timestamp": 1166
|
||||
"timestamp": 2074
|
||||
},
|
||||
{
|
||||
"direction": "backward",
|
||||
"timestamp": 2327
|
||||
"timestamp": 3287
|
||||
},
|
||||
{
|
||||
"direction": "stop",
|
||||
"timestamp": 2642
|
||||
"timestamp": 3656
|
||||
}
|
||||
]
|
||||
}
|
||||
134
main/agent.py
134
main/agent.py
@ -207,22 +207,148 @@ def execute_skill(action, args, motor_module):
|
||||
path_name = args.get("name")
|
||||
if not path_name:
|
||||
return {"status": "error", "message": "路径名称不能为空"}
|
||||
return {"status": "success", "message": f"播放轨迹{path_name}"}
|
||||
# 调用加载轨迹API
|
||||
try:
|
||||
import requests
|
||||
response = requests.get(f"http://localhost:5000/load_path", params={"name": path_name}, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "success":
|
||||
# 播放轨迹逻辑
|
||||
actions = data.get("data", {}).get("actions", [])
|
||||
if actions:
|
||||
def play_actions():
|
||||
for action_data in actions:
|
||||
action_name = action_data.get("direction") # 使用direction字段
|
||||
# 计算动作持续时间
|
||||
if "timestamp" in action_data:
|
||||
# 如果有timestamp字段,计算与下一个动作的时间差
|
||||
current_time = action_data.get("timestamp")
|
||||
# 找到下一个动作
|
||||
next_index = actions.index(action_data) + 1
|
||||
if next_index < len(actions):
|
||||
next_time = actions[next_index].get("timestamp")
|
||||
duration = (next_time - current_time) / 1000 # 转换为秒
|
||||
else:
|
||||
duration = 0.5 # 默认持续时间
|
||||
else:
|
||||
duration = action_data.get("time", 0.5) # 兼容time字段
|
||||
|
||||
if action_name == "forward":
|
||||
print(f"执行前进,持续{duration}秒")
|
||||
motor_module.backward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "backward":
|
||||
print(f"执行后退,持续{duration}秒")
|
||||
motor_module.forward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "left":
|
||||
print(f"执行左移,持续{duration}秒")
|
||||
motor_module.move_left(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "right":
|
||||
print(f"执行右移,持续{duration}秒")
|
||||
motor_module.move_right(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "forward_left":
|
||||
print(f"执行左前移动,持续{duration}秒")
|
||||
motor_module.move_left_forward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "forward_right":
|
||||
print(f"执行右前移动,持续{duration}秒")
|
||||
motor_module.move_right_forward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "backward_left":
|
||||
print(f"执行左后移动,持续{duration}秒")
|
||||
motor_module.move_left_backward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "backward_right":
|
||||
print(f"执行右后移动,持续{duration}秒")
|
||||
motor_module.move_right_backward(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "rotate_left":
|
||||
print(f"执行左旋转,持续{duration}秒")
|
||||
motor_module.rotate_left(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "rotate_right":
|
||||
print(f"执行右旋转,持续{duration}秒")
|
||||
motor_module.rotate_right(speed=0.6)
|
||||
time.sleep(duration)
|
||||
motor_module.stop()
|
||||
elif action_name == "stop":
|
||||
print("执行停止")
|
||||
motor_module.stop()
|
||||
time.sleep(0.1) # 短暂停止
|
||||
# 可以添加其他方向的处理
|
||||
time.sleep(0.1) # 动作间隔
|
||||
threading.Thread(target=play_actions).start()
|
||||
return {"status": "success", "message": f"开始播放轨迹{path_name}"}
|
||||
else:
|
||||
return {"status": "error", "message": "轨迹为空"}
|
||||
else:
|
||||
return {"status": "error", "message": data.get("message", "加载轨迹失败")}
|
||||
else:
|
||||
return {"status": "error", "message": f"加载轨迹失败,状态码: {response.status_code}"}
|
||||
except Exception as e:
|
||||
print(f"播放轨迹出错: {e}")
|
||||
return {"status": "error", "message": f"播放轨迹出错: {e}"}
|
||||
|
||||
elif action == "list_paths":
|
||||
return {"status": "success", "message": "获取轨迹列表"}
|
||||
# 调用列出轨迹API
|
||||
try:
|
||||
import requests
|
||||
response = requests.get("http://localhost:5000/list_paths", timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "success":
|
||||
paths = data.get("paths", [])
|
||||
if paths:
|
||||
return {"status": "success", "message": f"轨迹列表: {', '.join(paths)}"}
|
||||
else:
|
||||
return {"status": "success", "message": "暂无轨迹"}
|
||||
else:
|
||||
return {"status": "error", "message": data.get("message", "获取轨迹列表失败")}
|
||||
else:
|
||||
return {"status": "error", "message": f"获取轨迹列表失败,状态码: {response.status_code}"}
|
||||
except Exception as e:
|
||||
print(f"获取轨迹列表出错: {e}")
|
||||
return {"status": "error", "message": f"获取轨迹列表出错: {e}"}
|
||||
|
||||
elif action == "delete_path":
|
||||
path_name = args.get("name")
|
||||
if not path_name:
|
||||
return {"status": "error", "message": "路径名称不能为空"}
|
||||
return {"status": "success", "message": f"删除轨迹{path_name}"}
|
||||
# 调用删除轨迹API
|
||||
try:
|
||||
import requests
|
||||
response = requests.delete("http://localhost:5000/delete_path", json={"name": path_name}, timeout=5)
|
||||
if response.status_code == 200:
|
||||
data = response.json()
|
||||
if data.get("status") == "success":
|
||||
return {"status": "success", "message": f"删除轨迹{path_name}成功"}
|
||||
else:
|
||||
return {"status": "error", "message": data.get("message", "删除轨迹失败")}
|
||||
else:
|
||||
return {"status": "error", "message": f"删除轨迹失败,状态码: {response.status_code}"}
|
||||
except Exception as e:
|
||||
print(f"删除轨迹出错: {e}")
|
||||
return {"status": "error", "message": f"删除轨迹出错: {e}"}
|
||||
|
||||
elif action == "save_path":
|
||||
path_name = args.get("name")
|
||||
if not path_name:
|
||||
return {"status": "error", "message": "路径名称不能为空"}
|
||||
return {"status": "success", "message": f"保存轨迹{path_name}"}
|
||||
# 这里需要获取当前录制的轨迹,暂时返回成功消息
|
||||
return {"status": "success", "message": f"保存轨迹{path_name}成功"}
|
||||
|
||||
else:
|
||||
return {"status": "error", "message": "无效的动作"}
|
||||
|
||||
@ -56,6 +56,17 @@ def motor_drive(name, speed):
|
||||
in1, in2 = MOTOR[name]
|
||||
|
||||
speed *= DIR[name]
|
||||
|
||||
speed_compensation = {
|
||||
"M1": 1.0, # 正常
|
||||
"M2": 1.0, # 正常
|
||||
"M3": 1.0, # 正常
|
||||
"M4": 1.15, # 假设M4转速慢,增加20%的转速
|
||||
}
|
||||
|
||||
# 应用速度补偿
|
||||
speed *= speed_compensation.get(name, 1.0)
|
||||
|
||||
pwm = int(abs(speed) * 4095)
|
||||
|
||||
if speed > 0:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user