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
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.
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:3000Open 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 Rolling):
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/healthVerify 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.
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 startsSee installation docs for details. Feedback welcome on #265.
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 |
On the roadmap: entity lifecycle control, mode management, communication logs.
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.
- OS: Ubuntu 24.04 LTS (Jazzy / Rolling) or Ubuntu 22.04 LTS (Humble)
- ROS 2: Jazzy Jalisco, Humble Hawksbill, or Rolling (experimental)
- Compiler: GCC 11+ (C++17 support)
- Build System: colcon + ament_cmake
- π Full Documentation
- πΊοΈ Roadmap
- π GitHub Milestones
- π¬ Discord - Join our server for discussions, help, and announcements
- π Issues - Report bugs or request features
- π‘ Discussions - GitHub Discussions for Q&A and ideas
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 # everythingCheck out good first issues for places to start.
If you discover a security vulnerability, please follow the responsible disclosure process in SECURITY.md.
Apache License 2.0 - see the LICENSE file for details.
Made with β€οΈ by the selfpatch community
π¬ Join us on Discord
