Write YAML. Run robots.
Describe your robot in YAML. Write tasks as simple verb sequences — go_to, explore, report. The compiler checks that your hardware can actually do what you’re asking, then builds and runs the whole thing in simulation. You spend time on your problem, not the plumbing.
Under the hood: tasks compile to BehaviorTree.CPP XML and execute on Nav2. Every decision is deterministic and traceable.
name: ApartmentCheck
steps:
- verb: go_to
params:
target: $world.pois.kitchen
- verb: report
params:
message: "kitchen_checked"
- verb: go_to
params:
target: $world.pois.living-room
- verb: report
params:
message: "living_room_checked"
- verb: go_to
params:
target: $world.pois.dock This file runs today in simulation.
name: my_robot
version: "0.0.1"
modules:
- name: drive_base
type: motor_controller
capabilities:
- name: navigation
type: differential_drive
parameters:
max_linear_velocity: 0.5
wheel_separation: 0.160
- name: camera_module
type: camera
capabilities:
- name: vision
type: rgb_camera
parameters:
resolution: [640, 480] Describe your robot — motors, sensors, geometry. The platform uses this to configure simulation, validate tasks, and tune navigation.
steps:
- verb: go_to
params:
target: $world.pois.kitchen
- verb: report
params:
message: "kitchen_clear"
- verb: go_to
params:
target: $world.pois.dock Write what the robot should do as a sequence of verbs. The compiler resolves POIs and checks capabilities before anything runs.
name: apartment
pois:
dock: { center: [0.0, 0.0], type: constant }
kitchen: { center: [1.5, 2.0], type: static }
living-room: { center: [3.0, -1.0], type: static } Define where the robot operates. Named points of interest with coordinates — referenced by tasks at compile time.
A verb is a reusable robot behavior. Each verb is a YAML file that declares what hardware it needs. The compiler checks your robot’s capabilities before anything runs — if the hardware can’t do it, you get an error at compile time, not at runtime.
name: go_to
required_capabilities: [differential_drive]
parameters:
target: { type: string, required: true } name: explore
required_capabilities: [differential_drive, lidar_2d]
parameters:
timeout: { type: float, default: 120.0 } name: capture_image
required_capabilities: [rgb_camera]
parameters:
save_path: { type: string, default: "/tmp/capture.jpg" } These are real files from the repository. Browse all verbs on GitHub.
Deterministic by design
When a robot is navigating your warehouse or patrolling a facility, you need to know exactly what it will do and why. Defined Robotics uses behavior trees — not neural networks — to control robot actions. The compiled task is a finite, inspectable tree of decisions. If something goes wrong, you can read the XML and trace every branch.
This doesn’t mean AI has no place here. An LLM can generate task YAML, pick verbs, and compose missions dynamically. A vision model can feed observations into the blackboard. But the execution layer — the thing actually driving motors and making navigation decisions — is deterministic. AI proposes. The behavior tree disposes.
We think this is the right split: let AI handle the parts it’s good at (language, perception, planning at a high level) and keep the safety-critical execution loop predictable, auditable, and boring.
Try it yourself
Clone the starter repo, edit a YAML file, and have a simulated robot patrolling in minutes. No ROS2 install required — everything runs in Docker.
# Install the CLI
uv tool install defined-cli --from git+https://github.com/Defined-Robotics/defined-cli.git
# Clone the starter repo
git clone https://github.com/Defined-Robotics/botcrate.git
cd botcrate
# Make sure Docker is running, then launch
defined --manifest defined.yaml In the TUI, type /run patrol. Requires Python 3.12+, uv, and Docker.
Interested?
Defined Robotics is in active development. If you’re building robots and want to try it, integrate it, or just follow along — get in touch.