MotrixSim MuJoCo 示例分析笔记

Felix Christian Lv3

📁 文件概览

文件名场景描述核心概念
grasp_shaking_test.py机械臂抓取与摇晃测试轨迹控制、夹爪控制、录制
gyroscope.py陀螺仪仿真(有重力)初始速度设置、DOF 控制
gyroscope_zero_gravity.py零重力陀螺仪零重力环境、多轴旋转
newton_cradle.py牛顿摆碰撞模拟、能量传递

1. 机械臂抓取摇晃测试

文件: grasp_shaking_test.py

场景描述

这是一个使用 Franka Emika Panda 机械臂进行抓取测试的仿真场景。机械臂会抓起一个物体(立方体、球或瓶子),然后进行摇晃测试或滑移测试,验证抓取的稳定性。

核心功能

  1. 多物体支持: 支持抓取 3 种不同物体
    • cube - 立方体
    • ball - 球体
    • bottle - 瓶子
  2. 两种测试模式:
    • 摇晃测试 (shake): 抓取后随机摇晃手臂
    • 滑移测试 (slip): 抓取后保持静止,测试物体是否滑落
  3. 录制功能: 可将仿真过程录制为 MP4 视频

代码结构分析

1
2
3
4
# 命令行参数定义
_Obj = flags.DEFINE_string("object", "cube", "...") # 物体选择
_Shake = flags.DEFINE_boolean("shake", True, "...") # 是否摇晃
_Record = flags.DEFINE_boolean("record", True, "...") # 是否录制

仿真流程 (状态机)

stateDiagram-v2
    [*] --> 移动到抬起位置: step 0-500
    移动到抬起位置 --> 移动到抓取位置: step 500-1000
    移动到抓取位置 --> 闭合夹爪: step 1000-1500
    闭合夹爪 --> 抬起物体: step 1500-2000
    抬起物体 --> 摇晃测试: step 2000-10000 (if shake)
    抬起物体 --> 保持静止: step 2000-10000 (if !shake)
    摇晃测试 --> 测试通过: step > 10000
    保持静止 --> 测试通过: step > 10000
    摇晃测试 --> 测试失败: 物体掉落 (z < 0.04)
    保持静止 --> 测试失败: 物体掉落 (z < 0.04)

关键技术点

技术点说明代码位置
Keyframe 使用使用预定义关键帧作为目标位姿model.key("home"), model.key("grasp"), model.key("lift")
线性插值使用 lerp 函数平滑过渡关节位置lerp(a, b, t)
夹爪控制通过 ctrl[7] 控制夹爪开合data.ctrl[7] = lerp(0.04, 0, ...)
随机扰动摇晃时使用高斯噪声扰动np.random.normal(0, 0.025, size=7)
掉落检测监测物体 z 坐标判断是否掉落obj_pos[2] < 0.04
视频录制使用 imageio 保存帧序列imageio.mimwrite(...)

使用示例

1
2
3
4
5
# 抓取立方体并摇晃
python examples/mujoco/grasp_shaking_test.py --object=cube --shake=True

# 抓取瓶子进行滑移测试(不摇晃)
python examples/mujoco/grasp_shaking_test.py --object=bottle --shake=False --record=False

2. 陀螺仪仿真(有重力)

文件: gyroscope.py

场景描述

模拟一个在重力环境下旋转的陀螺仪。陀螺仪被赋予初始角速度后,会在重力作用下产生进动(precession)现象。

物理原理

陀螺进动

当陀螺仪高速旋转时,由于重力产生的力矩不会使其立即倾倒,而是使旋转轴绕垂直方向缓慢旋转,这就是进动现象。

关键代码解析

1
2
3
4
5
6
7
# 获取关节的自由度地址
joint_name = "ball_1"
joint_id = mujoco.mj_name2id(model, mujoco.mjtObj.mjOBJ_JOINT, joint_name)
dof_vel_adr = model.jnt_dofadr[joint_id]

# 设置初始角速度 (绕 Z 轴)
data.qvel[dof_vel_adr + 5] = 50 # 高速自转

DOF 速度地址说明

对于一个 6-DOF 球关节:

  • dof_vel_adr + 0~2: 线速度 (vx, vy, vz)
  • dof_vel_adr + 3~5: 角速度 (wx, wy, wz)

因此 dof_vel_adr + 5 设置的是绕局部 Z 轴的角速度。

仿真特点

  • 相机设置: 将相机距离设为 5,以便观察完整的进动运动
  • 实时同步: 使用 time.sleep 保持仿真与实际时间同步

3. 零重力陀螺仪

文件: gyroscope_zero_gravity.py

场景描述

零重力环境下模拟陀螺仪的自由旋转。由于没有重力,陀螺仪不会产生进动,而是保持角动量守恒的纯旋转运动。

与有重力版本的对比

特性gyroscope.pygyroscope_zero_gravity.py
重力
初始角速度单轴 (Z轴: 50)双轴 (X轴: 10, Z轴: 5)
运动特点进动自由旋转

关键代码解析

1
2
3
# 设置多轴初始角速度
data.qvel[dof_vel_adr + 5] = 5 # Z轴角速度
data.qvel[dof_vel_adr + 3] = 10 # X轴角速度

可视化功能

1
2
3
# 每隔 2 秒切换接触点显示
with viewer.lock():
viewer.opt.flags[mujoco.mjtVisFlag.mjVIS_CONTACTPOINT] = int(data.time % 2)

这个功能展示了如何动态控制 MuJoCo 的可视化选项。


4. 牛顿摆

文件: newton_cradle.py

场景描述

经典的牛顿摆(Newton's Cradle)物理演示。这是一个展示动量守恒能量守恒的经典物理实验装置。

物理原理

牛顿摆原理

当一端的球被拉起释放后,撞击静止的球组,动量和能量通过球组传递,使另一端的球以相同速度弹起。这完美展示了弹性碰撞中的动量守恒和动能守恒。

代码结构

1
2
3
4
5
6
7
8
9
10
11
12
def main():
# 加载模型 (使用 MuJoCo 版本的牛顿摆)
model = mujoco.MjModel.from_xml_path("examples/assets/newton_cradle_mj.xml")
data = mujoco.MjData(model)

with mujoco.viewer.launch_passive(model, data) as viewer:
# 设置相机视角 - 正侧面观察
with viewer.lock():
viewer.cam.lookat = [0, 0, 7] # 观察点
viewer.cam.distance = 20 # 距离
viewer.cam.azimuth = -90 # 方位角 (正侧面)
viewer.cam.elevation = 0 # 仰角 (水平)

相机设置说明

参数说明
lookat[0, 0, 7]相机注视点,位于摆锤悬挂高度
distance20相机与注视点距离
azimuth-90方位角,设为正侧面视角
elevation0仰角,水平观察

资源文件

仓库中有两个牛顿摆模型文件:

  • newton_cradle_mj.xml - MuJoCo 版本
  • newton_cradle_mt.xml - MotrixSim 版本 (可能用于对比)

📊 代码模式总结

通用仿真循环

所有示例都遵循相同的仿真循环模式:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
with mujoco.viewer.launch_passive(model, data) as viewer:
while True:
step_start = time.time()

# 1. 执行物理步进
mujoco.mj_step(model, data)

# 2. 同步渲染
viewer.sync()

# 3. 实时同步
time_until_next_step = model.opt.timestep - (time.time() - step_start)
if time_until_next_step > 0:
time.sleep(time_until_next_step)

关键 API 函数

函数用途
mujoco.MjModel.from_xml_path()从 XML 文件加载模型
mujoco.MjData(model)创建仿真数据结构
mujoco.mj_step(model, data)执行一步物理仿真
mujoco.mj_name2id()通过名称查找对象 ID
mujoco.mj_resetDataKeyframe()重置到关键帧状态
viewer.launch_passive()启动被动模式查看器
viewer.sync()同步渲染状态

🎯 总结

这些 MuJoCo 示例展示了:

  1. 基础仿真: 如何加载模型、创建数据、运行仿真循环
  2. 初始条件设置: 如何设置初始速度和位置
  3. 控制接口: 如何通过 data.ctrl 控制执行器
  4. 轨迹规划: 如何使用插值实现平滑运动
  5. 状态监测: 如何读取和判断仿真状态
  6. 可视化控制: 如何设置相机和切换显示选项
  7. 录制功能: 如何捕获帧并保存为视频

注意

这些示例使用的是原生 MuJoCo Python API,与 MotrixSim 的 API 有所不同。MotrixSim 提供了更高级的抽象和更丰富的功能,参见 examples/ 目录下的其他示例。

  • 标题: MotrixSim MuJoCo 示例分析笔记
  • 作者: Felix Christian
  • 创建于 : 2025-12-29 18:49:00
  • 更新于 : 2025-12-31 15:57:21
  • 链接: https://felixchristian.top/2025/12/29/25-MotrixSim_Mujoco/
  • 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。
评论