本项目包含 Piper 机械臂的 MuJoCo 仿真场景,以及基于键盘或 ROS2 真机的遥操作 demo 采集流水线。采集数据以 robosuite 兼容的 HDF5 格式保存,包含 states、actions 和多相机 RGB 图像。
MUJOCO/
├── README.md # 本文件
├── piper_scene/ # 仿真场景与采集脚本
│ ├── scene.xml # 主场景(机械臂、桌子、物品、相机)
│ ├── scripts/ # Python 采集脚本
├── piper_description/ # Piper 机械臂 URDF/网格资源
│ └── meshes/ # 机械臂 STL 网格
├── mujoco_scanned_objects/ # 桌面物体 3D 模型
│ └── models/ # 各物品的 model.xml / model_scene.xml
└── demos/ # 采集的 HDF5 demo 输出目录
作用: 仿真场景和遥操作采集逻辑。
| 子项 | 说明 |
|---|---|
scene.xml |
MuJoCo 主场景:地面、桌子、Piper 机械臂、相机、以及通过 include 引入的桌面物品 |
scripts/ |
采集脚本(见下文) |
作用: Piper 机械臂的 3D 网格资源。
| 子项 | 说明 |
|---|---|
meshes/ |
机械臂各 link 的 STL 文件(base_link, link1~8, gripper_base) |
scene.xml 中的 asset 通过 ../piper_description/meshes/xxx.STL 引用这些文件。
作用: 桌面物体的 MuJoCo 模型,源自 kevinzakka/mujoco_scanned_objects。
| 子项 | 说明 |
|---|---|
models/ |
每个物体一个子文件夹,内含 model.xml(原始)、model_scene.xml(场景用,带 freejoint、inertial 等) |
当前场景中的物品:
- ASICS 鞋、泰迪熊、黑森林零食、Target 篮子、Embark 冷藏盒、纸袋 Sporta_di_carta
作用: 采集到的 HDF5 文件存放目录,如 demo_0001.hdf5。
所有脚本位于 piper_scene/scripts/:
| 文件 | 作用 |
|---|---|
| run_teleop.py | 入口脚本。选择键盘 mock 或 ROS2 真机作为关节目标输入,并启动采集 |
| mujoco_sim_loop.py | MuJoCo 主循环:从输入源取关节目标 → 更新 data.ctrl → mj_step → 离屏渲染多相机 → 记录 states/actions/frames |
| joint_state_interface.py | 抽象接口 JointStateSource,统一键盘与 ROS2 两种输入 |
| joint_state_mock.py | 键盘 mock 实现,包装 device_joint |
| joint_state_ros2.py | ROS2 实现,订阅 /joint_states 作为关节目标 |
| device_joint.py | 8 关节键盘控制(q/a |
| config.py | 常量:相机名、分辨率、控制频率、路径等 |
| save_hdf5.py | 将 states、actions、多相机图像保存为 robosuite 兼容 HDF5 |
文件: piper_scene/scripts/config.py
| 变量 | 含义 | 默认值 |
|---|---|---|
CAMERA_NAMES |
使用的相机名(需与 scene.xml 一致) | ["frontview", "topview", "camera_link"] |
CAMERA_SIZE |
离屏渲染分辨率 (宽, 高) | (1920, 1080) |
DISPLAY_SIZE |
显示窗口分辨率 | (1920, 1080) |
CONTROL_FREQ |
控制/采集频率 (Hz) | 20 |
DEMOS_DIR |
HDF5 输出目录 | {项目根}/demos |
JOINT_STATES_TOPIC |
ROS2 关节 topic(真机模式) | "/joint_states" |
文件: piper_scene/scripts/run_teleop.py 第 47 行
source = JointStateMock(model, delta_scale=0.08, use_pynput=False)| 参数 | 含义 | 说明 |
|---|---|---|
delta_scale |
每按一次键的关节增量 | 调大 = 更灵敏,调小 = 更精细 |
use_pynput |
是否用 pynput 监听 | False 配合 OpenCV 窗口,True 可后台监听(与 viewer 冲突) |
文件: piper_scene/scripts/device_joint.py 第 11–29 行
KEY_MAP = {
ord("q"): (0, -1), # joint1 减
ord("a"): (0, 1), # joint1 增
# ...
}
ESC_KEY = 27 # 结束 episode按需修改 KEY_MAP 和 ESC_KEY。
文件: piper_scene/scene.xml
| 位置 | 修改项 |
|---|---|
第 5 行 option |
timestep(仿真步长)、iterations(求解器迭代次数) |
第 8 行 visual/global |
offwidth、offheight(离屏渲染尺寸,需与 config 一致) |
第 11–16 行 include |
增减/替换桌面物品 |
第 40–42 行 camera |
相机位置、朝向 |
第 44–51 行 body table |
桌子位置、尺寸 |
第 53 行 body piper_base |
机械臂底座位置 |
第 107–114 行 actuator |
关节控制限位、kp、力限 |
文件: 各物品的 model_scene.xml,例如:
mujoco_scanned_objects/models/ASICS_.../model_scene.xmlmujoco_scanned_objects/models/Sporta_di_carta/model_scene.xml
| 修改项 | 位置 | 说明 |
|---|---|---|
pos |
<body ... pos="x y z"> |
桌面位置,z 一般为 0.52(桌面高度) |
scale |
<mesh ... scale="sx sy sz"> |
物体缩放 |
mass、diaginertia |
<inertial ...> |
质量与转动惯量 |
文件: piper_scene/scripts/joint_state_ros2.py 第 17–28 行
ROS2JointStateSource(
topic="/joint_states",
model=model,
joint_names=None, # 或 ["joint1", "joint2", ...] 与真机 URDF 对应
)若真机关节名与顺序不同,需设置 joint_names 并保证与 JointState.name 一致。
pip install -r requirements.txt
# ROS2 模式需:pip install rclpy(且在 ROS2 环境中)cd piper_scene/scripts
python run_teleop.py
# 或
python run_teleop.py --source keyboard- 窗口获得焦点后,用 q/a、w/s … i/k 控制关节 1–8
- 按 Esc 结束当前 episode 并保存
- 输出写入
demos/demo_xxxx.hdf5
# 1. 启动机械臂 driver,使其发布 /joint_states
# 2. 运行
python run_teleop.py --source ros2python run_teleop.py --scene /path/to/scene.xml --out-dir /path/to/outputpython -m mujoco.viewer --mjcf=piper_scene/scene.xml每条 demo 的 HDF5 结构(robosuite 兼容):
data/
├── demo_1/
│ ├── states # (T, state_dim) 含 time, qpos, qvel
│ ├── actions # (T, 8) 关节目标
│ ├── obs/
│ │ ├── frontview_image # (T, H, W, 3)
│ │ ├── topview_image
│ │ └── camera_link_image
│ └── model_file # 场景 XML 字符串
- 在
mujoco_scanned_objects/models/下新建文件夹,放入model.obj、model.xml、model_collision_*.obj、texture.png - 复制其他物品的
model_scene.xml,修改资源名前缀、body 名、pos、scale、inertial - 在
piper_scene/scene.xml中加入:<include file="../mujoco_scanned_objects/models/新物品/model_scene.xml"/>
若物品来自 obj 需凸分解,可使用 obj2mjcf:
pip install obj2mjcf
obj2mjcf --obj-dir /path/to/model_dir --decompose --save-mjcf --add-free-joint