ros2_medkit
June 7, 2026 · View on GitHub
Structured diagnostics for ROS 2 robots.
When your robot fails, find out why - in minutes, not hours.
Fault management · Live introspection · REST API · AI via MCP
The problem
When a robot breaks in the field, you SSH in, run ros2 node list, grep through logs, and try to reconstruct what happened. It works for one robot on your desk. It does not work for 20 robots at a customer site, at 2 AM, when you cannot reproduce the issue.
ros2_medkit gives your ROS 2 system a diagnostic REST API so you can inspect what is running, what failed, and why, without SSH and without custom tooling.
🚀 Quick Start
Try the full demo (requires Docker with Compose, no ROS 2 needed):
git clone https://github.com/selfpatch/selfpatch_demos.git
cd selfpatch_demos/demos/turtlebot3_integration
./run-demo.sh
# → API: http://localhost:8080/api/v1/ Web UI: http://localhost:3000
Open http://localhost:3000 in your browser. You will see a TurtleBot3 with Nav2, organized into a browsable entity tree with live faults, topic data, and parameter access.
Build from source (ROS 2 Jazzy, Humble, or Lyrical):
source /opt/ros/jazzy/setup.bash # or humble - adjust for your distro
git clone --recurse-submodules https://github.com/selfpatch/ros2_medkit.git
cd ros2_medkit
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install && source install/setup.bash
ros2 launch ros2_medkit_gateway gateway.launch.py
# → http://localhost:8080/api/v1/health
Verify it works: curl http://localhost:8080/api/v1/health should return {"status": "healthy", ...}.
For a guided walkthrough with demo nodes and the full API, see the Getting Started tutorial. For API examples, see our Postman collection.
Experimental: Pixi
Pixi provides a reproducible, lockfile-based environment without requiring a system-wide ROS 2 installation (Linux x86_64 only). This is experimental; the standard ROS 2 toolchain (rosdep + colcon) remains the primary method.
curl -fsSL https://pixi.sh/install.sh | bash
pixi install -e jazzy # or: pixi install -e humble
pixi run -e jazzy build
pixi run -e jazzy test
pixi run -e jazzy smoke # verify gateway starts
See installation docs for details. Feedback welcome on #265.
What you get
Start here: Faults. Your robot has 47 nodes. Something throws an error.
Instead of grepping logs, you query GET /api/v1/faults and get a structured list
with fault codes, timestamps, affected entities, environment snapshots, and history.
Clear faults, subscribe to new ones via SSE, correlate them across components.
Beyond faults, medkit exposes the full ROS 2 graph through REST:
| What it does | |
|---|---|
| Discovery | Automatically finds running nodes, topics, services, and actions |
| Data | Read and write topic data via REST |
| Operations | Call services and actions with execution tracking |
| Configurations | Read, write, and reset node parameters |
| Bulk Data | Upload/download files (calibration, firmware, rosbags) |
| Subscriptions | Stream live data and fault events via SSE |
| Triggers | Condition-based push notifications for resource changes |
| Locking | Resource locking for safe concurrent access |
| Scripts | Upload and execute diagnostic scripts on entities |
| Software Updates | Async prepare/execute lifecycle with pluggable backends |
| Authentication | JWT-based RBAC (viewer, operator, configurator, admin) |
| Logs | Log entries and configuration |
| Docs | OpenAPI 3.1.0 spec and Swagger UI at /api/v1/docs - schemas are generated from typed C++ structs so the spec always matches the wire format |
On the roadmap: entity lifecycle control, mode management, communication logs.
How it organizes your robot
medkit models your system as an entity tree with four levels:
Areas Components Apps (nodes)
───── ────────── ────────────
base ┬─ motor_controller ┬─ left_wheel_driver
│ └─ right_wheel_driver
└─ battery_monitor └─ bms_node
navigation ┬─ lidar_driver └─ rplidar_node
└─ nav_stack ┬─ nav2_controller
├─ nav2_planner
└─ nav2_bt_navigator
A small robot might have a single area. A large robot can use areas to separate physical domains:
areas/
├── base/
│ └── components/
│ ├── motor_controller/ → apps: left_wheel, right_wheel
│ └── battery_monitor/ → apps: bms_node
├── arm/
│ └── components/
│ ├── joint_controller/ → apps: joint_1..joint_6
│ └── gripper/ → apps: gripper_driver
├── navigation/
│ └── components/
│ ├── lidar_driver/ → apps: rplidar_node
│ ├── camera_driver/ → apps: realsense_node
│ └── nav_stack/ → apps: controller, planner, bt_navigator
└── safety/
└── components/
├── emergency_stop/ → apps: estop_monitor
└── collision_detect/ → apps: collision_checker
Functions cut across the tree. A function like localization might depend on apps from both navigation and base, giving you a capability-oriented view alongside the physical hierarchy.
This entity model follows the SOVD (Service-Oriented Vehicle Diagnostics) standard, so the same concepts work across robots, vehicles, and embedded systems.
📋 Requirements
- OS: Ubuntu 26.04 LTS (Resolute, for Lyrical), Ubuntu 24.04 LTS (Noble, for Jazzy), or Ubuntu 22.04 LTS (Jammy, for Humble)
- ROS 2: Jazzy Jalisco, Humble Hawksbill, or Lyrical Luth (LTS, released May 2026)
- Compiler: GCC 11+ (C++17 support)
- Build System: colcon + ament_cmake
📚 Documentation
💬 Community
- 💬 Discord - Join our server for discussions, help, and announcements
- 🐛 Issues - Report bugs or request features
- 💡 Discussions - GitHub Discussions for Q&A and ideas
🤝 Contributing
Contributions are welcome! See CONTRIBUTING.md for build instructions, testing, pre-commit hooks, CI/CD details, and code coverage.
Quick version:
source /opt/ros/jazzy/setup.bash # or humble
pipx install pre-commit && pre-commit install && pre-commit install --hook-type pre-push
colcon build --symlink-install
source install/setup.bash
./scripts/test.sh # unit tests
./scripts/test.sh all # everything
Check out good first issues for places to start.
🔒 Security
If you discover a security vulnerability, please follow the responsible disclosure process in SECURITY.md.
📄 License
Apache License 2.0 - see the LICENSE file for details.
Made with ❤️ by the selfpatch community
💬 Join us on Discord