Drake仿真MultibodyPlant驱动端口类型与关节速度控制咨询
Drake机械臂速度分解控制器相关问题解答
plant->get_actuation_input_port()的输入属性
- 默认配置下,从URDF导入的
MultibodyPlant的actuation输入端口,固定接收广义力指令:转动关节对应力矩(单位N·m),平动关节对应直线推力(单位N),不是位置也不是速度输入。 - 这个端口的输入类型没法直接修改。URDF里通过
<transmission>标签定义的关节执行器,会一一映射到这个端口的输入通道,所有输入值都会作为外力项参与动力学递推计算。要做位置、速度控制,需要自行在外层实现控制逻辑,把位置/速度指令转换成力矩值,再接到这个端口上。
直接调用set_angular_rate设置关节速度的合理性
你提到的实现代码如下:
const multibody::RevoluteJoint<double>& joint_1 = plant->GetJointByName<multibody::RevoluteJoint>("joint1"); for ( double t = FLAGS_sim_dt ; t < FLAGS_simulation_sec; t += FLAGS_sim_dt) { joint_1.set_angular_rate(&plant_context, v_d); simulator.AdvanceTo(t); }
这个方案能不能用,完全取决于你的仿真目的:
- 如果只是做运动学层面的算法验证,比如检查雅可比矩阵计算是否正确、速度分解得到的关节速度能不能让末端走出预期的任务空间轨迹,不需要考虑动力学、执行器饱和、跟踪误差这些物理特性,这个写法能快速跑通流程,验证算法逻辑正确性。
- 如果要做有物理可信度的动力学仿真,这个写法完全不可行。它本质是每一步仿真前都暴力篡改plant上下文里存储的关节速度状态,直接绕开了动力学积分、关节摩擦、力矩限幅、重力/科氏力计算所有物理环节,相当于给关节装了个能输出无限力矩、瞬间打到目标速度的理想执行器,得到的仿真结果没有实际参考意义。而且这种在Drake的System框架外部手动修改上下文的写法不符合框架的数据流逻辑,后续要加传感器、日志模块或者其他控制节点的时候,很容易出现状态时序不同步的bug。
正规实现思路
要在Drake里实现符合规范的速度分解控制器,按需求选择对应方案即可:
- 做动力学仿真:解出期望关节速度
q_dot_d之后,搭建简单的速度闭环,比如带重力补偿的P控制:tau = kp * (q_dot_d - q_dot_actual) + tau_gravity_compensation,把计算得到的力矩接到actuation输入端口即可。 - 只做纯运动学仿真:将MultibodyPlant切换到运动学模式,通过框架内的状态接口驱动关节,不要在仿真循环外部手动修改上下文。
内容的提问来源于stack exchange,提问作者Haoyun
相关产品推荐
相关产品推荐

