Robot Description Framework (RDF)¶
An RDF file describes a robot in terms of its capabilities — what it can do — rather than low-level hardware details. It is the source of truth the Defined Robotics toolchain uses to validate tasks before compilation and parameterise verb behaviour at runtime.
Think of it as a passport for your robot: the verb compiler reads it before producing any BT XML.
Minimal example¶
name: my_robot
version: "0.0.1"
description: "A simple differential drive robot"
modules:
- name: drive_base
type: motor_controller
capabilities:
- name: navigation
type: differential_drive
version: "1.0"
parameters:
wheel_separation: 0.287
wheel_radius: 0.033
max_linear_velocity: 0.22
max_angular_velocity: 2.84
This declares a robot with one module (drive_base) that provides the differential_drive capability. That capability is what allows the go_to and explore verbs to be used in tasks.
Two-module example¶
The simulation robot used in the starter repo uses two modules:
name: test_robot
version: "0.0.1"
modules:
- name: drive_base
type: motor_controller
capabilities:
- name: differential_drive
type: differential_drive
parameters:
wheel_separation: 0.160
wheel_radius: 0.033
max_linear_velocity: 0.22
max_angular_velocity: 2.84
- name: lidar_module
type: sensor
capabilities:
- name: laser_scanner
type: lidar_2d
parameters:
range_min: 0.120
range_max: 3.500
samples: 360
update_rate: 5.0
topic: /scan
How capabilities gate task compilation¶
When you run:
The compiler checks every verb in the task against the RDF before producing any output:
✓ go_to requires: differential_drive, lidar_2d → present
✓ report requires: (none) → OK
✗ capture_image requires: rgb_camera → MISSING
REJECTED: verb 'capture_image' requires capabilities ['rgb_camera']
not available on robot 'my_robot'
No partial XML is produced. The robot either can run the full task or it cannot.
Known capability types¶
These are the types recognised by the built-in verbs:
| Type | Used by verbs | Typical parameters |
|---|---|---|
differential_drive |
go_to, explore |
wheel_separation, wheel_radius, max_linear_velocity, max_angular_velocity |
lidar_2d |
go_to, explore (via Nav2/SLAM) |
range_min, range_max, samples, update_rate, topic |
rgb_camera |
capture_image |
resolution, fps |
depth_camera |
custom verbs | resolution, fps |
imu |
custom verbs | — |
wheel_encoders |
— | ticks_per_revolution |
Custom types are fully supported — any string is accepted. Declare them in your RDF and reference them in your verb definition's required_capabilities.
Field reference¶
Robot (top-level)¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | yes | — | Robot identifier |
version |
string | no | "0.0.1" |
RDF version |
description |
string | no | — | Human-readable description |
modules |
list[Module] | no | [] |
Hardware modules |
physical |
PhysicalDescription | no | — | Physical/kinematic description for URDF generation |
Module¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Module identifier (e.g. drive_base) |
type |
string | yes | Module type (e.g. motor_controller, sensor, camera) |
capabilities |
list[Capability] | no | Capabilities this module provides |
parameters |
dict | no | Module-level parameters |
Capability¶
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
name |
string | yes | — | Capability identifier |
type |
string | yes | — | Capability type (see known types above) |
version |
string | no | "1.0" |
Version string |
parameters |
dict | no | {} |
Capability-specific parameters passed to verbs |
Physical description (optional)¶
The physical section enables URDF generation for simulation. Task compilation does not require it.
physical:
meshes_package: my_robot_description # ROS package containing mesh files (optional)
links:
- name: base_link
mass: 1.0
visual:
box:
size: [0.2, 0.15, 0.05]
collision:
box:
size: [0.2, 0.15, 0.05]
- name: wheel_left_link
mass: 0.1
visual:
cylinder:
radius: 0.033
length: 0.018
joints:
- name: wheel_left_joint
type: continuous
parent: base_link
child: wheel_left_link
origin:
xyz: [0, 0.08, 0]
rpy: [-1.5708, 0, 0]
axis: [0, 0, 1]
Link fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Link identifier |
mass |
float | no | Mass in kg (default: 0) |
inertia |
Inertia | no | Inertia tensor — ixx, iyy, izz |
origin |
Origin | no | Pose relative to parent — xyz, rpy |
visual |
Geometry | no | Visual geometry |
collision |
Geometry | no | Collision geometry |
Geometry is one of: box (size), cylinder (radius, length), sphere (radius), or mesh (filename).
Joint fields¶
| Field | Type | Required | Description |
|---|---|---|---|
name |
string | yes | Joint identifier |
type |
string | yes | fixed, continuous, revolute, or prismatic |
parent |
string | yes | Parent link name |
child |
string | yes | Child link name |
origin |
Origin | no | Joint origin pose |
axis |
list[float] | no | Rotation/translation axis [x, y, z] |
limit |
dict | no | lower, upper, effort, velocity — for revolute/prismatic |
Python API¶
from defined_rdf.parser import load
from defined_rdf.registry import CapabilityRegistry
robot = load("robot.rdf.yaml")
registry = CapabilityRegistry(robot)
# Check a single capability
registry.has("differential_drive") # True
registry.has("rgb_camera") # False
# Get capability details
cap = registry.get("differential_drive")
print(cap.parameters["wheel_separation"]) # 0.160
# Check a set of requirements (used internally by the verb compiler)
met, missing = registry.check_requirements(["differential_drive", "rgb_camera"])
print(met) # False
print(missing) # ["rgb_camera"]
# List all capability types on this robot
registry.list_types() # ['differential_drive', 'lidar_2d']
JSON Schema generation¶
The package ships with a machine-readable JSON Schema at schema/robot.rdf.schema.json. To regenerate it from the Pydantic models: