You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Mujoco六自由度机械臂仿真异常:关节不受控自行移动排查求助

6自由度机械臂MuJoCo仿真问题排查

问题描述

  • 所有关节初始位姿(home)设为0,但启动仿真后,upperarm_joint(关节3)和endeffector_joint(关节6)会自发移动(关节3通常从0到0.9,关节6从0到0.3)
  • 除线性关节gantry_joint外,其余旋转关节均无法控制
  • 已尝试将力矩范围放大100倍,仅能实现单次移动,问题未解决

模型XML代码

<mujoco model="robot"
  <compiler angle="degree" meshdir="assets" autolimits="true"/>
  <option integrator="implicitfast"/>
  <default>
    <default class="robot">
      <material specular="0.5" shininess="0.25"/>
      <default class="revolute">
        <joint range="0 180"/>
        <general gaintype="fixed" biastype="affine" ctrlrange="0 180"
                 gainprm="100 0 0" biasprm="0 0 0" forcerange="-1.5 1.5"/>
      </default>
      <default class="linear">
        <joint range="0 540" type="slide"/>
        <general gaintype="fixed" biastype="affine" ctrlrange="0 540"
                 gainprm="500 0 0" biasprm="0 -50 -100" forcerange="-200 200"/>
      </default>
      <default class="visual">
        <geom type="mesh" contype="0" conaffinity="0" group="2"/>
      </default>
      <site size="0.001" rgba="0.5 0.5 0.5 0.3" group="4"/>
    </default>
  </default>
  <asset>
    <material class="robot" name="white" rgba="1 1 1 1"/>
    <material class="robot" name="jointgray" rgba="0.278 0.278 0.278 1"/>
    <material class="robot" name="linkgray" rgba="0.82 0.82 0.82 1"/>
    <material class="robot" name="blue" rgba="0.49 0.678 0.8 1"/>
    <mesh file="base.obj"/>
    <mesh file="gantry.obj"/>
    <mesh file="armbase.obj"/>
    <mesh file="forearm.obj"/>
    <mesh file="shoulder.obj"/>
    <mesh file="upperarm.obj"/>
    <mesh file="wrist.obj"/>
    <mesh file="endeffector.obj"/>
  </asset>
  <worldbody>
    <light name="spotlight" mode="targetbodycom" target="gantry" pos="0 -1 2"/>
    <body name="base" zaxis="1 0 0" childclass="robot">
      <inertial mass="4.0" pos="0 0 0" diaginertia="0.00443333156 0.00443333156 0.0072"/>
      <geom mesh="base" material="white" class="visual"/>
      <body name="gantry" pos="5 190 50 " euler="180 0 90">
        <inertial mass="3.7" pos="0 0 0" diaginertia="0.0102675 0.0102675 0.00666"/>
        <joint name="gantry_joint" class="linear" axis="-1 0 0" pos="0 0 0"/>
        <geom mesh="gantry" material="blue" class="visual"/>
        <geom mesh="armbase" material="white" class="visual" pos="-47 30 8"/>
        <body name="forearm_link" pos="-47 30 8">
          <inertial mass="3.7" pos="0 0 0" diaginertia="0.0102675 0.0102675 0.00666"/>
          <joint name="forearm_joint" class="revolute" axis="0 1 0" pos="0 0 16"/>
          <geom mesh="forearm" material="blue" class="visual"/>
          <body name="shoulder_link" pos="0 0 0">
            <inertial mass="8.393" pos="0 0 0.2125" diaginertia="0.133886 0.133886 0.0151074"/>
            <joint name="shoulder_joint" class="revolute" axis="1 0 0" pos="0 141 -19"/>
            <geom mesh="shoulder" material="linkgray" class="visual"/>
            <body name="upperarm_link" pos="0 0 0">
              <inertial mass="2.275" pos="0 0 0.196" diaginertia="0.0311796 0.0311796 0.004095"/>
              <joint name="upperarm_joint" class="revolute" axis="1 0 0" pos="0 195 -180"/>
              <geom mesh="upperarm" material="blue" class="visual"/>
              <body name="wrist_link" pos="0 0 0.0" zaxis="0 0 1">
                <inertial mass="1.219" pos="0 0.127 0" diaginertia="0.0025599 0.0025599 0.0021942"/>
                <joint name="wrist_joint" class="revolute" axis="0 0.3 -1" pos="0 230 -300"/>
                <geom mesh="wrist" material="white" class="visual"/>
                <body name="endeffector_link" pos="0 0 0">
                  <inertial mass="0.1889" pos="0 0.0771683 0" quat="1 0 0 1"
                    diaginertia="0.000132134 9.90863e-05 9.90863e-05"/>
                  <joint name="endeffector_joint" class="revolute" axis="1 0 0" pos="-125 236.5 -342.7"/>
                  <geom material="linkgray" mesh="endeffector" class="visual"/>
                  <site name="attachment_site" pos="0 0.1 0" quat="-1 1 0 0"/>
                </body>
              </body>
            </body>
          </body>
        </body>
      </body>
    </body>
  </worldbody>
  <actuator>
    <position class="linear" name="gantry_act" joint="gantry_joint"
              kp="500" kv="60" ctrlrange="0 540" forcerange="-200 200"/>
    <position class="revolute" name="forearm_actuator" joint="forearm_joint"
              kp="120" kv="12" ctrlrange="0 180" forcerange="-1.5 1.5"/>
    <position class="revolute" name="shoulder_actuator" joint="shoulder_joint"
              kp="180" kv="18" ctrlrange="0 180" forcerange="-1.5 1.5"/>
    <position class="revolute" name="upperarm_actuator" joint="upperarm_joint"
              kp="140" kv="30" ctrlrange="0 180" forcerange="-1.5 1.5"/>
    <position class="revolute" name="wrist_actuator" joint="wrist_joint"
              kp="100" kv="10" ctrlrange="0 180" forcerange="-1.5 1.5"/>
    <position class="revolute" name="endeffector_actuator" joint="endeffector_joint"
              kp="80" kv="8" ctrlrange="0 180" forcerange="-1.5 1.5"/>
  </actuator>
  <keyframe>
    <key name="home" qpos="0 0 0 0 0 0" ctrl="0 0 0 0 0 0"/>
  </keyframe>
</mujoco>

排查步骤

1. 验证静力学平衡问题

  • 先关闭重力测试:在<option>标签中添加gravity="0 0 0",如果关节不再自发移动,说明是重力导致的非平衡状态。
  • 检查连杆惯性参数:确认upperarm_linkendeffector_linkinertial/pos是否为连杆质心位置。如果质心不在关节旋转轴的正上方/正下方,重力会产生力矩带动关节转动。

2. 修复控制配置冲突

  • 删除<default>块中旋转关节的<general>配置:你同时在<default><actuator>中定义了驱动参数,会导致逻辑冲突,仅保留<actuator>里的<position>驱动定义即可。
  • 提升旋转关节的刚度参数:当前旋转关节的kp(100-180)远低于线性关节的500,对于大惯量连杆,刚度不足会导致无法稳定跟踪目标。先将旋转关节的kp提升至500、kv提升至50测试。

3. 修正关节坐标系与单位问题

  • 检查关节位置单位:MuJoCo默认单位为米,你的关节位置数值(如upperarm_jointpos="0 195 -180")过大,大概率是OBJ文件使用毫米单位导致的偏移,需将关节位置数值除以1000(如改为pos="0 0.195 -0.18")。
  • 确认关节旋转中心:关节pos应是父连杆与子连杆的实际旋转中心,需对照OBJ模型的结构验证位置是否正确。

4. 检查碰撞与约束

  • 在MuJoCo GUI中打开Collision视图,查看是否有红色碰撞提示,排除隐藏碰撞导致的关节锁死。
  • 验证关节range范围:确认初始位姿0是否在旋转关节range="0 180"的有效范围内,避免因边界限制导致无法控制。

5. 基础控制逻辑验证

  • 手动加载home位姿:在仿真代码中明确设置data.qpos = model.keyframe('home').qposdata.ctrl = model.keyframe('home').ctrl,避免依赖XML自动加载的不确定性。
  • 单关节测试:单独启用一个旋转关节的驱动,发送小幅度目标值(如30度),查看data.actuator_force是否有输出,验证控制指令是否正确传递。

内容的提问来源于stack exchange,提问作者EyeQ Tech

火山引擎 最新活动