用 Rerun 同步查看 UMI 双腕相机、Head Camera 和腕部 VIO 3D 轨迹。
它直接读取带 VIO pose 的 ROS 2 MCAP,不需要先转换成 LeRobot 数据集。默认布局为:
- 上方:左、右腕两个独立 VIO 3D 视图;
- 下方:Head、Left UMI、Right UMI 三路 RGB;
- 底部:共享的 MCAP header 时间轴,可以播放、暂停和拖动检查。
下面是使用真实 UMI with_pose.mcap 生成的 Rerun 界面
3D 视图中:
- 灰色线是完整 VIO 轨迹;
- 蓝色/红色线是当前位置前一段时间的移动轨迹;
- 彩色点是当前 TCP 位置;
- 红、绿、蓝箭头分别表示 TCP 局部 X、Y、Z 轴。
左右腕 VIO 分别初始化,两个消息虽然都可能写着
frame_id=world,但它们不是天然共享的 robot-base world。因此本工具默认使用两个独立 3D 视图,不把两条轨迹错误地叠加成同一个机器人坐标系。
- Python 3.11+
- 推荐使用 uv
- 输入文件为 ROS 2 MCAP,图像消息支持 H.264/H.265 或普通压缩图像
安装:
git clone git@github.com:MaxLiuyy/VIO_Vis.git
cd VIO_Vis
uv syncuv run python scripts/vio_rerun_viewer.py \
--mcap /path/to/episode_with_pose.mcap脚本会打开本机 Rerun Viewer。展开底部时间轴后即可播放三路画面和两路 VIO 轨迹。
远端服务器通常没有桌面环境,推荐先生成 .rrd:
uv run python scripts/vio_rerun_viewer.py \
--mcap /path/to/episode_with_pose.mcap \
--output-rrd outputs/episode.rrd \
--jpeg-quality 75 \
--trail-seconds 10把 outputs/episode.rrd 下载到本机,然后打开:
uv run rerun outputs/episode.rrd快速检查前 10 秒:
uv run python scripts/vio_rerun_viewer.py \
--mcap /path/to/episode_with_pose.mcap \
--output-rrd outputs/episode_10s.rrd \
--max-duration-s 10 \
--frame-stride 2| 数据 | Topic | 典型频率 |
|---|---|---|
| Head Camera 左目 | /robot/camera/head/left/video_encoded |
30 Hz |
| Left UMI 左目 | /robot/camera/left_wrist/left/video_encoded |
30 Hz |
| Right UMI 左目 | /robot/camera/right_wrist/left/video_encoded |
30 Hz |
| Left wrist VIO pose | /robot/camera/left_wrist/left/pose |
约 7.5 Hz |
| Right wrist VIO pose | /robot/camera/right_wrist/left/pose |
约 7.5 Hz |
Pose 消息类型应为 geometry_msgs/msg/PoseStamped。Head Camera 在当前数据中没有 pose,因此只显示图像。
如果你的 topic 命名不同,可以修改 scripts/vio_rerun_viewer.py 顶部的 CAMERA_TOPICS 和 POSE_TOPICS。
每次运行都会在终端输出 JSON;指定 --output-rrd 时,还会自动生成同名 .summary.json。诊断包括:
- 三路相机和两路 pose 的条数、频率、P95 间隔和最大 gap;
- Head Camera 到两路 UMI 最近 RGB 帧的时间差;
- 腕部 RGB 到同侧最近 VIO pose 的时间差;
- 三相机同步状态和 VIO pose timing 状态;
- pose
frame_id和反序列化错误。
本 README 截图对应的真实 10 秒数据结果:
- 三路 RGB 都约为
30 Hz; - 左、右 VIO pose 都约为
7.5 Hz; - Head 到两路腕相机最近帧的最大时间差约
13.9 ms; - 左右 VIO 在初始化附近各出现一次约
400 ms的 pose gap。
| 参数 | 默认值 | 作用 |
|---|---|---|
--output-rrd |
不设置 | 写入 RRD;不设置时打开本机 Viewer |
--max-duration-s |
完整 episode | 只处理开头 N 秒 |
--frame-stride |
1 |
每 N 帧记录一张 RGB,减小 RRD |
--jpeg-quality |
80 |
RRD 内 JPEG 质量 |
--trail-seconds |
10 |
3D 彩色移动轨迹长度 |
--sync-warn-ms |
50 |
三相机最近帧差的告警阈值 |
完整帮助:
uv run python scripts/vio_rerun_viewer.py --help当前工具展示的是 MCAP 中保存的原始左右 VIO pose:
left_vio_world -> left TCP trajectory
right_vio_world -> right TCP trajectory
它不等于:
robot_base -> left/right TCP
若要把两只手和 Head Camera 放进同一个 3D robot-base 视图,需要额外提供或估计:
base_T_left_vio_worldbase_T_right_vio_world- Head Camera 相对 robot base 的外参
仅靠重力方向或相同的 frame_id=world 不能恢复完整的共同坐标系,因为仍然缺少 yaw 和平移对齐。
工具分两遍读取 MCAP:第一遍索引时间戳和 pose,第二遍逐帧解码并立即写入 Rerun,不会把整段三相机 RGB 同时保存在 Python 内存中。
真实 pilot 使用 JPEG 75、三路 30 Hz,10 秒 RRD 约为 30 MiB。长 episode 可以使用 --frame-stride 2 或 3 降低体积。