ROSP — Robot Open Specification Protocol
The universal protocol for describing, discovering, and streaming data from any robot.
ROSP solves the M x N integration problem in robotics. Instead of every platform building custom connectors for every robot type, each robot implements one ROSP adapter. Any ROSP-compatible platform can then work with any ROSP-described robot.
Before ROSP: M platforms x N robot types = M*N custom integrations
With ROSP: M platforms + N adapters = M+N standardized connections
Install
pip install rosp-sdk
With CLI tools:
pip install rosp-sdk[cli]
Quick Start
from rosp_sdk import RobotCard, validate_robot_card, score_completeness
# Describe your robot
card = RobotCard(
rosp_version="0.1",
id="urn:rosp:robot:robotis:turtlebot3:waffle-001",
identity={"type": "mobile_robot", "manufacturer": "ROBOTIS", "model": "TurtleBot3 Waffle"},
hardware={"weight_kg": 1.8, "max_velocity_mps": 0.26},
sensors=[
{"sensor_id": "lidar", "type": "lidar", "model": "LDS-01"},
{"sensor_id": "imu", "type": "imu", "model": "ICM-20948"},
{"sensor_id": "camera", "type": "camera_rgb", "model": "RealSense R200"},
],
actuators=[
{"actuator_id": "base", "type": "wheel", "max_velocity": 0.26},
],
capabilities=[
{"capability_id": "cap:nav", "name": "Navigation", "type": "navigation"},
],
integration={"supported_protocols": [{"protocol": "ros2", "version": "humble"}]},
)
# Validate against the ROSP schema
errors = validate_robot_card(card)
print(f"Valid: {len(errors) == 0}") # Valid: True
# Score completeness
score = score_completeness(card)
print(f"Completeness: {score.level} ({score.percent}%)") # Completeness: standard (72%)
CLI
# Validate a Robot Card JSON file
rosp validate robot-card.json
# Inspect card details (sensors, actuators, capabilities)
rosp inspect robot-card.json
# Export card in different formats
rosp export-card robot-card.json --format summary
# Check SDK and spec version
rosp version
Build an Adapter
ROSP adapters bridge a specific robot platform to the protocol. Implement 5 methods:
from rosp_sdk import ROSPAdapter, RobotCard, StreamMessage, HealthStatus
class MyRobotAdapter(ROSPAdapter):
async def connect(self) -> None:
"""Connect to the robot."""
async def disconnect(self) -> None:
"""Disconnect from the robot."""
async def describe(self, depth="full") -> RobotCard:
"""Return a Robot Card describing this robot."""
async def stream(self, topics, qos=None) -> AsyncIterator[StreamMessage]:
"""Stream sensor data from the robot."""
async def discover(self) -> DiscoveryInfo:
"""Return discovery information for this robot."""
async def health_check(self) -> HealthStatus:
"""Check adapter and robot health."""
Register in pyproject.toml:
[project.entry-points."rosp.adapters"]
myrobot = "my_adapter:MyRobotAdapter"
See CONTRIBUTING.md and Adapter SDK Guide for the full guide.
Official Adapters
| Adapter | Robots | Install |
|---|---|---|
| ROS2 | Any ROS2 robot (TurtleBot, UR, ABB, etc.) | pip install rosp-adapter-ros2 |
| gRPC | Boston Dynamics Spot, Viam, custom gRPC | pip install rosp-adapter-grpc |
| VDA 5050 | Any VDA 5050 MQTT AGV (MiR, KUKA, Jungheinrich) | pip install rosp-adapter-vda5050 |
How It Works
ROSP defines three core operations:
| Operation | What it does | Think of it as... |
|---|---|---|
| describe | Returns a Robot Card — complete description of what the robot IS and CAN DO | USB device descriptor |
| stream | Streams sensor data in real-time with configurable QoS | ROS2 topics, but protocol-agnostic |
| discover | Announces robot availability on the network | mDNS / SSDP for robots |
Plus two DRAFT operations for future versions:
- command — Send commands to robots (navigate, pick, etc.)
- coordinate — Multi-robot coordination
The Robot Card
The Robot Card is the core data structure — a complete, machine-readable description of a robot:
Robot Card
├── identity (manufacturer, model, type, firmware)
├── hardware (weight, dimensions, DOF, battery)
├── sensors[] (LiDAR, cameras, IMUs — with SOSA/SSN metadata)
├── actuators[] (drives, arms, grippers — with limits)
├── capabilities[] (navigation, manipulation, mapping)
├── integration (how to connect: ROS2, gRPC, MQTT, etc.)
├── safety (e-stop, zones, collision limits)
├── skills[] (DRAFT — high-level abilities)
└── ... (calibration, coordinate frames, simulation, diagnostics)
Progressive enrichment: start with 3 required fields (rosp_version, id, identity.type), add more as needed. The completeness scorer tells you what to add next.
ROSP vs Existing Standards
| ROSP | URDF/SDF | VDA 5050 | ROS2 msg | W3C WoT | |
|---|---|---|---|---|---|
| Scope | Full robot description + streaming | Geometry only | AGV orders only | Message format only | IoT devices |
| Robot types | Any (mobile, arm, sensor, AGV) | Any (geometry) | AGVs only | Any (ROS2) | IoT devices |
| Transport | Any (gRPC, MQTT, WebSocket, Zenoh) | File | MQTT | DDS | HTTP |
| Discovery | Built-in | No | No | DDS | mDNS |
| Streaming | Built-in with QoS | No | State topic | Native | No |
| Progressive | Yes (3 required fields) | No (full model) | No (full spec) | No | Partial |
Integration with RoboTrace
ROSP works standalone, but pairs with RoboTrace for observability:
from rosp_adapter_ros2 import ROS2Adapter
from robotrace import RoboTrace
from robotrace.integrations.rosp import RoboTraceMiddleware
rt = RoboTrace(host="https://your-server.com", public_key="...", secret_key="...")
traced = RoboTraceMiddleware(adapter=ROS2Adapter(config), robotrace=rt)
async with traced:
card = await traced.describe() # Auto-registers device + sensors in RoboTrace
async for msg in traced.stream(["*"]): # Auto-sends telemetry to dashboard
pass
Specification
The full ROSP v0.1 specification is at docs/spec/ROSP-v0.1-spec.md.
JSON Schemas:
Example Robot Cards:
Development
git clone https://github.com/FaultLine-labs/rosp.git
cd rosp
pip install ".[dev,cli]"
pytest # 60 tests
ruff check . # Lint
License
Apache License 2.0 — see LICENSE.
Built by RoboSwarm (FaultLine Labs).
Metadata
Release files for rosp-sdk 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rosp_sdk-0.1.0.tar.gz | 163.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rosp_sdk-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 216.7 kB
Release files / rosp_sdk-0.1.0.tar.gz
| Download URL | rosp_sdk-0.1.0.tar.gz |
|---|---|
| Size | 163.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
8a576ce9e97be0136e11864ba788f3732043a6f0254a64c5947464a304fb6acb
|
|
BLAKE2b-256 checksum How to use checksums |
2e5572dcd102daa2726566fa4475c2befc51cb49e26cadae85797a59f4c53e70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|
Release files / rosp_sdk-0.1.0-py3-none-any.whl
| Download URL | rosp_sdk-0.1.0-py3-none-any.whl |
|---|---|
| Size | 52.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
06a0adb047fcf1440043a0496e4af36aef294fa8385c955dabb1664d0e68f3c1
|
|
BLAKE2b-256 checksum How to use checksums |
517d83547fa1ae2df96bb1ef81f02f308a39df4a6136538d6aec9fb072406455
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.9
|