Drake软机器人仿真:自定义曲率滑块如何设置ARBM关节位姿
问题根源
内置JointSliders根本不是通过系统端口连接来设置关节位置的:Drake的MultibodyPlant默认只暴露驱动力矩输入端口,没有直接接收关节位置指令的输入端口,位置属于植物的内部状态,只能通过修改上下文直接设置、或者通过动力学积分更新。你之前尝试直接把自定义系统输出连到"关节位置端口"的思路本身就不成立,JointSliders.Run()的内部逻辑是直接持有模拟器上下文,每次滑块变动时手动写入关节位置,再推进仿真触发可视化更新,完全不走端口连线。
推荐实现方案(和内置JointSliders行为完全一致)
不用修改你已经写好的CurvatureSliders和CC2ARBM类,只需要在Main函数里补全运行循环逻辑,直接在循环里读取计算结果、写入植物上下文、推进仿真即可,实时性最好,没有控制滞后。
修改你Main.py中diagram = builder.Build()之后的代码:
# 构建完diagram后初始化模拟器和上下文 simulator = Simulator(diagram) root_context = simulator.get_mutable_context() plant_context = plant.GetMyMutableContextFromRoot(root_context) cc2arbm_context = cc2arbm.GetMyContextFromRoot(root_context) # 配置模拟器 simulator.set_target_realtime_rate(target_realtime_rate) simulator.Initialize() # 可选:添加停止按钮,和JointSliders行为对齐 meshcat.AddButton("Stop Simulation") # 主运行循环 while meshcat.GetButtonClicks("Stop Simulation") < 1: # 从转换系统读取当前滑块对应的ARBM关节位置 arbm_joint_pos = cc2arbm.get_output_port(0).Eval(cc2arbm_context) # 构造植物完整位置向量,注意核对关节顺序 q = plant.GetPositions(plant_context) # !!!这里必须确认arbm_joint_pos的顺序和plant内关节顺序完全匹配 # 可通过print(plant.GetPositionNames(model))打印所有关节名核对索引 # 示例:如果你的10个ARBM关节对应模型的前10个位置自由度 q[:len(arbm_joint_pos)] = arbm_joint_pos # 直接写入植物上下文 plant.SetPositions(plant_context, q) # 推进一个小时间步,触发可视化更新 current_time = root_context.get_time() simulator.AdvanceTo(current_time + 0.01) time.sleep(0.001) meshcat.DeleteAddedControls()
不推荐的端口连接方案
如果你一定要走系统连线的方式,需要额外搭建位置控制闭环:
- 给每个关节添加PID控制器
- 将你的CC2ARBM输出的期望位置作为PID的设定值输入
- 将Plant输出的关节状态反馈给PID的测量值输入
- 将PID输出的力矩连接到Plant的actuation输入端口
这种方案会引入动力学响应,拖动滑块时会有滞后、超调,完全不适合手动调构型的交互场景,除非你后续要做力矩控制相关的仿真,否则没必要用。
注意事项
- 关节顺序匹配是最容易踩的坑:
MultibodyPlant返回的位置向量顺序是按你加载模型、添加关节的顺序排列的,和你CC2ARBM输出的10个值顺序不一定一致,一定要先打印关节名核对索引,否则会出现机器人构型错乱。 - 你代码中导出的actuation输入端口在这个方案下不需要连接,因为你直接设置位置,绕过了动力学积分环节。
- 如果需要重置功能,可以参考你写的
SetConfiguration方法,加一个重置按钮绑定默认曲率参数即可。
内容的提问来源于stack exchange,提问作者antbre
相关产品推荐
相关产品推荐

