Planar Joint添加JointActuator报错,求修复或替代方案
球体平面滚动的关节与力控制问题解决方案
问题说明
你尝试用Planar关节实现球体在平面上的滚动,为该关节添加Transmission时触发错误:
SystemExit: Failure at bazel-out/k8-opt/bin/multibody/plant/_virtual_includes/multibody_plant_core/drake/multibody/plant/multibody_plant.h:1135 in AddJointActuator(): condition 'joint.num_velocities() == 1' failed
原因是Planar关节包含3个自由度(x方向平移、y方向平移、绕z轴旋转),而SimpleTransmission要求绑定的关节必须是单自由度类型(如棱形、旋转关节)。
原代码:
ball_joint = """ <joint name="ball_joint" type="planar"> <parent link="world" /> <child link="ball" /> <axis xyz="0 0 1" /> </joint> """ transmission = """ <transmission type="SimpleTransmission" name="ball_force"> <actuator name="force" /> <joint name="ball_joint" /> <mechanicalReduction>1</mechanicalReduction> </transmission> """
修复方案
方案1:拆分关节为单自由度类型
将Planar关节拆分为三个独立的单自由度关节,每个关节对应一个Transmission,分别控制x平移、y平移和z轴旋转:
# 替换原Planar关节为三个单自由度关节 ball_joint_x = """ <joint name="ball_joint_x" type="prismatic"> <parent link="world" /> <child link="ball_x_link" /> <axis xyz="1 0 0" /> </joint> """ ball_joint_y = """ <joint name="ball_joint_y" type="prismatic"> <parent link="ball_x_link" /> <child link="ball_y_link" /> <axis xyz="0 1 0" /> </joint> """ ball_joint_z = """ <joint name="ball_joint_z" type="revolute"> <parent link="ball_y_link" /> <child link="ball" /> <axis xyz="0 0 1" /> </joint> """ # 为每个关节添加对应的Transmission transmission_x = """ <transmission type="SimpleTransmission" name="ball_force_x"> <actuator name="force_x" /> <joint name="ball_joint_x" /> <mechanicalReduction>1</mechanicalReduction> </transmission> """ transmission_y = """ <transmission type="SimpleTransmission" name="ball_force_y"> <actuator name="force_y" /> <joint name="ball_joint_y" /> <mechanicalReduction>1</mechanicalReduction> </transmission> """ transmission_z = """ <transmission type="SimpleTransmission" name="ball_force_z"> <actuator name="force_z" /> <joint name="ball_joint_z" /> <mechanicalReduction>1</mechanicalReduction> </transmission> """
注:需要额外添加中间连杆(ball_x_link、ball_y_link)来串联三个关节,保证运动链的连续性。
方案2:直接使用关节力API(推荐)
跳过Transmission,直接调用Drake的AddJointForce或AddJointTorque接口,直接给Planar关节施加力或力矩,无需受单自由度限制:
# 假设已获取Planar关节对象和MultibodyPlant实例 joint = plant.GetJointByName("ball_joint") # 施加x方向力、y方向力、z轴力矩(示例值) plant.AddJointForce(joint, [10.0, 5.0, 2.0])
这种方式更简洁,无需修改关节结构,直接对多自由度关节进行力控制。
内容的提问来源于stack exchange,提问作者Ben Kang
相关产品推荐
相关产品推荐

