mukul-07/missiondebug
GitHub: mukul-07/missiondebug
为 ROS 2 机器人提供故障发生前 60 秒数据的自动捕获与浏览器端回放,帮助工程师在异常事后快速定位根因。
Stars: 5 | Forks: 1
# MissionDebug
[](https://github.com/mukul-07/missiondebug/actions/workflows/test.yml)
[](https://github.com/mukul-07/missiondebug/pkgs/container/missiondebug)
[](https://codecov.io/gh/mukul-07/missiondebug)
[](https://docs.ros.org/)
[](https://www.python.org/)
[](QUALITY_DECLARATION.md)
[](LICENSE)
当机器人出现异常时,你需要的是发生问题*前*的 60 秒数据——它当时看到了什么,下达了什么指令,处于什么状态。MissionDebug 与你的 ROS 2 技术栈并行运行,为你关注的 topic 保留一个滚动缓冲区,并在出现问题时立即写入标准的 MCAP 文件。检测器会自动触发(停滞、路径偏差、低电量、topic 丢失,或任何你用 YAML 编写的规则)。打开 Web UI,点击会话,在时间轴上拖拽查看。为特定时刻添加标注,与队友分享深度链接 URL。
原生标准。本地优先。无需云服务,无需登录,无专有格式。

## MissionDebug 的定位
| | 适用场景 |
|---|---|
| **MissionDebug** | 故障发生*后*。“出故障前 60 秒发生了什么?”基于规则自动触发,在浏览器中重播,添加标注,分享带时间戳的链接。 |
| [`rosbag2 --snapshot-mode`](https://docs.ros.org/en/rolling/Tutorials/Advanced/Recording-A-Bag-From-Your-Own-Node-CPP.html) | MissionDebug 底层调用的录制原语。具有相同的内存滚动缓冲区,但没有自动触发、UI、检测或保留策略。如果你要在其之上构建自己的技术栈,可以使用它。 |
| 实时运维工具 (例如 [ros2_medkit](https://github.com/selfpatch/ros2_medkit)) | 事件发生*期间*。“机器人现在在做什么?”实时内省、故障 API、远程操作。不同的时间维度——是互补关系,而非替代品。 |
| 持续 bag 录制器 | 保存高吞吐量 topic(点云、代价地图)的深度归档。MissionDebug 专门负责提供专注且随时可重播的层面,供工程师在排查事故时回放查看。 |
MissionDebug 是**事后排查层**。它是你在警报触发*后*首先要用到的工具。
## 为什么开发这个工具
大多数 ROS 调试工具都假设你提前知道要进行录制。MissionDebug 会始终将机器人过去 60 秒的状态保存在内存中,并在出现问题时进行快照——你可以手动操作,也可以在检测器触发时自动完成。该代理完全在机器人上本地运行;除非你主动拷贝,否则数据不会离开设备。它适用于国防、医疗、工业等无法使用云优先可观测性方案的环境。


## 免安装体验(60 秒)
无需安装 ROS,无需拉取源码——只需 Docker。参见 [missiondebug-demos](https://github.com/mukul-07/missiondebug-demos):`git clone` → `docker compose up` → 在浏览器中回放 `sample_drive` 示例数据。
## 本地试用(5 分钟)
你需要准备 Ubuntu 22.04(或 24.04)、ROS 2 Humble(或 Jazzy)、Python 3.10+、Node 20+、pnpm 9+ 和 `tmux`。
```
git clone https://github.com/mukul-07/missiondebug.git
cd missiondebug
make install
source /opt/ros/humble/setup.bash
MD_FIXTURES=1 make dev
```
打开 。会话列表中已经包含了一个 `sample_drive` 示例数据——点击它,在时间轴上拖拽查看。
该示例数据时长 30 秒,包含一次人为的停滞(8–14 秒)和 0.8 米的路径偏差(14–22 秒)。你可以看到速度图表下降,橙色圆点停滞,然后偏离绿线。
## 安装到实体机器人
构建三个 `.deb` 包(仅限 Linux):
```
sudo apt install fakeroot dpkg-dev python3-pip python3-venv nodejs
sudo npm install -g pnpm
make package
ls dist/
# missiondebug-agent_1.0.0_.deb — 捕获 sessions
# missiondebug-backend_1.0.0_.deb — API + session 索引 + retention
# missiondebug-web_1.0.0_all.deb — 静态 UI(由 backend 提供服务)
```
在目标机器人上安装:
```
sudo dpkg -i dist/missiondebug-agent_1.0.0_.deb
sudo dpkg -i dist/missiondebug-backend_1.0.0_.deb
sudo dpkg -i dist/missiondebug-web_1.0.0_all.deb
```
完成。这三个服务都会自动启动并在开机时运行:
| 服务 | 端口 | 用途 |
|---|---|---|
| `missiondebug-agent` | `127.0.0.1:7000` | 订阅 ROS topic,在异常时写入 MCAP |
| `missiondebug-backend` | `0.0.0.0:8000` | 索引 MCAP,提供 UI + API 服务 |
| (web — 由后端提供的静态文件) | — | UI 位于 `http://:8000` |
在网络中的任何机器上浏览 `http://:8000`。无需 nginx,无需单独的 Web 服务,无需代理。
## 使用方法
### 1. 为你的机器人配置代理
默认配置会录制 `/cmd_vel`、`/tf`、`/plan` 和一个摄像头。为了匹配你的技术栈,请编辑:
```
sudo nano /etc/missiondebug/config.yaml
sudo systemctl restart missiondebug-agent
journalctl -u missiondebug-agent -n 30 --no-pager
```
你应该能在配置中看到每个 topic 的 `Subscribed to []` 提示,如果你添加了规则,还会看到 `Loaded N config-driven rule(s)`。
有关可直接编辑的示例配置,请参阅 [examples/](./examples/):
- [`ground-vehicle-config.yaml`](./examples/ground-vehicle-config.yaml) — AMR、配送机器人、室内服务机器人
- [`drone-config.yaml`](./examples/drone-config.yaml) — 通过 mavros 控制的无人机
- [`manipulator-config.yaml`](./examples/manipulator-config.yaml) — 机械臂 + MoveIt2
- [`rule-patterns.yaml`](./examples/rule-patterns.yaml) — 检测器规则的复制粘贴参考手册
### 2. 驾驶机器人 — 会话自动出现
每当内置检测器或你的某条规则被触发时,代理会将前 60 秒的数据保存为 MCAP。在浏览器中打开 `http://:8000`,你的会话将显示在列表顶部,并标记触发原因(`anomaly:stall`、`anomaly:my-rule-name`、`anomaly:dropout:/lidar` 等)。
点击一个会话 → 时间轴 + 图表 + 位姿轨迹将进行渲染。拖拽进度条,按空格键播放,使用 ←/→ 进行 100ms 步进,Shift+← / Shift+→ 进行 1s 步进。使用 **+ Add at playhead** 按钮在播放头位置添加备注。通过 **Copy link** 复制带有 `?t=23.4` 的深度链接 URL,与队友分享精确的帧画面。
### 3. 手动保存
当机器人出现异常但未触发规则时,你可以自己捕获前 60 秒的数据:
```
curl -X POST http://:7000/sessions/save -H 'Content-Type: application/json' \
-d '{"label":"weird-behavior-after-corner"}'
```
刷新会话列表——你的快照连同该标签将一起出现在列表中。
### 4. 编写自定义规则
编辑 `/etc/missiondebug/config.yaml`:
```
anomaly:
rules:
- name: my-rule
topic: /my_topic
field: data # dot-path; e.g. "data" or "status.status" or "linear.x"
equals: true # exactly one: equals / not_equals / lt / gt / lte / gte
duration_seconds: 0 # how long the condition must hold (0 = instant)
cooldown_seconds: 30 # min gap between fires
```
使用 `sudo systemctl restart missiondebug-agent` 重启。要验证是否加载成功:
```
journalctl -u missiondebug-agent -n 20 --no-pager | grep "Loaded.*rule"
```
要在测试时手动触发它:
```
ros2 topic pub --once /my_topic std_msgs/Bool '{data: true}'
ls -lh /var/lib/missiondebug/sessions/ # new MCAP appears
```
有关数值阈值、字符串匹配、布尔标志和 actionlib 中止的规则示例,请参阅 [`examples/rule-patterns.yaml`](./examples/rule-patterns.yaml)。
### 5. 管理磁盘使用
当总 MCAP 字节数超过 `MD_MAX_DISK_MB`(默认:2048 MB)时,后端会删除最旧的会话。修改方法:
```
sudo nano /etc/missiondebug/backend.env # set MD_MAX_DISK_MB=
sudo systemctl restart missiondebug-backend
```
检查或强制清理:
```
curl -s http://localhost:8000/api/admin/disk
# {"used_bytes": ..., "used_mb": ..., "cap_mb": 2048, "cap_enabled": true, "session_count": 14}
curl -s -X POST http://localhost:8000/api/admin/sweep
# {"deleted_ids": [...], "bytes_freed": ..., "bytes_after": ..., "cap_bytes": ...}
```
### 6. 常用日常命令
```
# Health
sudo systemctl status missiondebug-agent missiondebug-backend
journalctl -u missiondebug-agent -f # tail capture logs
journalctl -u missiondebug-backend -f # tail backend/UI logs
# 检查 captures
ls -lh /var/lib/missiondebug/sessions/
curl -s http://localhost:8000/api/sessions | jq '.sessions[0:3]'
# 手动触发 stall(发布零 cmd_vel 持续 6 秒)
timeout 6 ros2 topic pub -r 10 /cmd_vel geometry_msgs/Twist '{linear: {x: 0.0}}'
```
### 7. 常见问题
- **代理与你的 shell 处于不同的 ROS graph** — 如果你的 shell 中执行 `ros2 node list` 看不到 `/missiondebug_agent`,说明存在 DDS 隔离问题(systemd 服务和你的 shell 使用了不同的 RMW_IMPLEMENTATION)。将服务切换为 Cyclone DDS:
sudo apt install -y ros-humble-rmw-cyclonedds-cpp
sudo systemctl edit missiondebug-agent
# 添加:
# [Service]
# Environment=RMW_IMPLEMENTATION=rmw_cyclonedds_cpp
echo 'export RMW_IMPLEMENTATION=rmw_cyclonedds_cpp' >> ~/.bashrc
sudo systemctl restart missiondebug-agent
- **没有出现会话** — 检查你配置中的 topic 是否存在(`ros2 topic list`),规则是否已加载(`journalctl -u missiondebug-agent | grep Loaded`),以及触发条件是否确实被满足。请先尝试上述的手动停滞触发。
- **ROS 1 + ROS 2 环境混淆** — 如果你的 shell 在显示 `ROS_DISTRO=humble` 的同时还显示了 `ROS_MASTER_URI`,说明你的 `~/.bashrc` 同时加载了两者。请注释掉 noetic 那一行。
## API
这两个服务都在 `/docs` 提供交互式 Swagger UI,并在 `/openapi.json` 提供 OpenAPI JSON:
```
open http://:7000/docs # agent (capture)
open http://:8000/docs # backend (sessions, files, annotations, admin)
```
只需一个 POST 请求,即可从你现有的监控系统中触发会话保存:
```
curl -X POST http://:7000/sessions/save \
-H 'Content-Type: application/json' \
-d '{"label":"alertmanager:critical-latency"}'
```
完整的端点参考 + curl 示例:[`docs/API.md`](./docs/API.md)。
## 集成
MissionDebug 会在其内置检测器触发时捕获会话数据——但你现有的监控栈已经检测到了许多内置检测器未涵盖的情况。将这些外部警报指向代理的保存端点,即可免费获取根因重播:
- **通用 webhook** — 通过任何监控工具执行 `curl -X POST .../sessions/save -d '{"label":"..."}'`
- **[Prometheus Alertmanager](./docs/INTEGRATIONS.md#2-prometheus-alertmanager-5-minutes)** — webhook 接收器 + 一个将 `alerts[]` 转换为标签的小型适配器
- **[ros2_medkit Triggers](./docs/INTEGRATIONS.md#3-ros2_medkit-triggers-10-minutes)** —桥接脚本,订阅 medkit 的 SSE 事件流并转发触发器
完整的配方及可用脚本:[`docs/INTEGRATIONS.md`](./docs/INTEGRATIONS.md)。
## 构建原理
- **代理 (Agent)** (Python, `agent/`) — rclpy 订阅者 → 内存中按 topic 分配的环形缓冲区(受速率和大小限制)→ MCAP 写入器 → 在 `:7000` 端口提供控制 HTTP API。内置检测器(停滞、路径偏差、battery_low、topic_dropout)加上配置驱动的规则引擎;所有检测器都会自动保存并为生成的会话打上标签。
- **后端 (Backend)** (FastAPI + SQLite, `backend/`) — 每 5 秒自动重新扫描会话目录,索引 MCAP 元数据,并提供支持 HTTP range 的文件服务以便浏览器流式读取。磁盘保留清理程序每 30 秒运行一次。当存在 Web UI 的静态 dist 时,会将其挂载到 `/`。
- **Web** (React + Vite + PixiJS, `web/`) — Web Worker 使用 `@foxglove/rosmsg2-serialization` 解码 MCAP,渲染同步的视频/图表/位姿轨迹。标注存储在服务器端;URL 可通过 `?t=23.4` 实现深度链接。
规格:
- [SPEC.md](./SPEC.md) — v0(录制 + 重播循环,单体机器人,localhost)
- [v1-SPEC.md](./v1-SPEC.md) — v1(路径偏差、标注、分享链接、`.deb` 包、示例数据)
- [v1.5-SPEC.md](./v1.5-SPEC.md) — v1.5(配置驱动的规则、topic 丢失、磁盘保留、完整的 backend/web `.deb` 包)
## 测试
```
make test # 87 tests across agent + backend, ~1s
```
## 许可证
MIT — 详见 [LICENSE](./LICENSE)。
标签:ETW劫持, Foxglove, MCAP, Python, ROS 2, 事件回放, 开源, 异常检测, 故障分析, 数据捕获, 无后门, 日志记录, 时间线, 本地部署, 机器人, 机器人运维, 状态监控, 自动驾驶, 请求拦截, 逆向工具, 遥测数据