mian.py测试完成的多轨迹运动控制代码

This commit is contained in:
琉璃月光
2025-09-17 16:39:51 +08:00
parent 95c75bd409
commit 02268ca185
14 changed files with 561 additions and 603 deletions

81
main.py
View File

@ -13,7 +13,7 @@ plt.rcParams['font.sans-serif'] = ['SimHei', 'WenQuanYi Zen Hei', 'FangSong']
plt.rcParams['axes.unicode_minus'] = False
# ------------------------ 调试开关 ------------------------
DEBUG_MODE = False # <<< 设为 False 控制真实电机
DEBUG_MODE = True # <<< 设为 False 控制真实电机
# 导入运动学和轨迹函数(确保路径正确)
try:
@ -56,7 +56,7 @@ CAN_SERIAL_PORT = '/dev/ttyACM0'
BAUD_RATE = 921600
KP = 50.0
KD = 1.0
DT = 0.01 # 控制周期 10ms每点延时
DT = 0.01# 控制周期 10ms每点延时
# ------------------------ 全局变量 ------------------------
motor1 = motor2 = motor_control = None
@ -264,7 +264,8 @@ def draw_frame(i):
return line,
# ------------------------ 轨迹动画与执行 + 可视化 + FK 验证 ------------------------
def run_trajectory_with_animation(trajectory_func, **params):
# ------------------------ 轨迹动画预览 ------------------------
def preview_trajectory(trajectory_func, **params):
global x_list, y_list, line
print(f"生成轨迹: {trajectory_func.__name__}")
@ -286,13 +287,18 @@ def run_trajectory_with_animation(trajectory_func, **params):
ani = FuncAnimation(fig, draw_frame, frames=len(x_list),
interval=50, blit=True, repeat=False)
plt.show()
return x_list, y_list
# --- 执行并记录 ---
# ------------------------ 执行轨迹 ------------------------
def execute_trajectory(x_list, y_list, dt=DT):
print("开始执行轨迹(直接发送角度)...")
time_log, theta1_log, theta4_log, x_fk_log, y_fk_log = execute_direct_trajectory(
x_list, y_list, dt=DT # 每个点发送后延时 1ms这个地方控制电机延时
)
return execute_direct_trajectory(x_list, y_list, dt=dt)
# ------------------------ 可视化与误差统计 ------------------------
# ------------------------ 可视化与误差统计 ------------------------
def visualize_results(x_list, y_list, time_log, theta1_log, theta4_log, x_fk_log, y_fk_log):
# --- 绘制关节角度 ---
fig2, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 6), sharex=True)
ax1.plot(time_log, theta1_log, 'b-o', markersize=3, linewidth=1.5, label='θ₁ (电机1)')
@ -332,7 +338,6 @@ def run_trajectory_with_animation(trajectory_func, **params):
print("【警告】FK 数据全为 nan无法计算误差")
return
# 插值对齐长度
t_target = np.linspace(0, 1, len(x_list))
t_fk = np.linspace(0, 1, len(x_fk_valid))
from scipy.interpolate import interp1d
@ -349,11 +354,39 @@ def run_trajectory_with_animation(trajectory_func, **params):
except Exception as e:
print(f"误差计算失败: {e}")
# --- 关节角度范围 ---
# --- 关节角度统计与保存 ---
print("\n=== 关节角度范围统计 ===")
print(f"θ₁ 范围: {min(theta1_log):.2f}° ~ {max(theta1_log):.2f}°")
print(f"θ₄ 范围: {min(theta4_log):.2f}° ~ {max(theta4_log):.2f}°")
# 角度转换为弧度,并组合成配对列表
theta1_rad = np.radians(theta1_log)
theta4_rad = np.radians(theta4_log)
# 构建嵌套列表:[[θ1_0, θ4_0], [θ1_1, θ41], ...]
angles_rad_list = [[t1, t4] for t1, t4 in zip(theta1_rad, theta4_rad)]
# 格式化为字符串保留6位小数用逗号分隔
nested_str = ",\n ".join([f"[{t1:.6f}, {t4:.6f}]" for t1, t4 in angles_rad_list])
nested_str = f"[\n {nested_str}\n]"
# 保存为 txt 文件
filename = 'joint_angles_rad_nested.txt'
with open(filename, 'w') as f:
f.write("angles_rad_list = ")
f.write(nested_str)
f.write("\n")
print(f"\n✅ 嵌套列表格式的弧度数据已保存至: {filename}")
# ------------------------ 主流程 ------------------------
def run_full_trajectory(trajectory_func, **params):
x_list, y_list = preview_trajectory(trajectory_func, **params)
time_log, theta1_log, theta4_log, x_fk_log, y_fk_log = execute_trajectory(x_list, y_list, dt=DT)
visualize_results(x_list, y_list, time_log, theta1_log, theta4_log, x_fk_log, y_fk_log)
# ==================== 获取电机当前位置 =====================
def get_current_motor_position():
"""
@ -448,19 +481,41 @@ if __name__ == "__main__":
# --- 获取当前位置测试 ---
print("\n=== 测试:获取电机当前位置 ===")
theta1, theta4 = get_current_motor_position()
#theta1, theta4 = get_current_motor_position()
# --- MIT 模式回零 ---
print("\n=== MIT 模式回零 ===")
move_motors_to_zero(duration=1.0) # 主函数里执行回零
#move_motors_to_zero(duration=1.0) # 主函数里执行回零
# ---------------- 选择轨迹 ----------------
'''
#直线轨迹:
trajectory_config = {
'func': line_trajectory_fix,
'params': {'start': (25, 300), 'end': (200, 300), 'num_points': 100}
}
run_trajectory_with_animation(trajectory_config['func'], **trajectory_config['params'])
#圆形轨迹
trajectory_config = {
'func': circle_trajectory,
'params': {'center': (100, 300), 'radius': 100}
}
trajectory_config = {
'func': square_trajectory,
'params': {'side':60, 'num_points': 200}
}
#椭圆轨迹
trajectory_config = {
'func': ellipse_trajectory,
'params': {'center': (100, 250), 'rx': 100, 'ry': 60, 'num_points': 200}
}
'''
trajectory_config = {
'func': circle_trajectory,
'params': {'center': (100, 300), 'radius': 100, 'num_points': 100}
}
run_full_trajectory(trajectory_config['func'], **trajectory_config['params'])
except KeyboardInterrupt:
print("\n【用户中断】")