Skip to content

Tour of the starter repo

This page walks through every file and directory in the starter repo so you understand what each piece does before you start changing things.

The starter repo lives at github.com/Defined-Robotics/botcrate. Clone it and open it alongside this page:

git clone https://github.com/Defined-Robotics/botcrate
cd botcrate

Directory layout

botcrate/
├── defined.yaml          # project manifest — robot, world, sim image
├── robots/
│   ├── burger.rdf.yaml       # TurtleBot3 Burger (nav only)
│   ├── burger_cam.rdf.yaml   # Burger + RGB camera
│   └── minimal.rdf.yaml      # drive + lidar, no extras
├── worlds/
│   ├── open_room.yaml        # 10×10m open room, 3 survey POIs
│   └── maze.yaml             # 10×10m maze, 4 survey POIs
├── tasks/
│   ├── patrol.task.yaml      # visit each POI and report
│   ├── explore.task.yaml     # frontier exploration
│   ├── inspect.task.yaml     # go_to + capture_image at each POI
│   └── security_round.task.yaml
└── verbs/
    ├── go_to.yaml            # thin wrapper — extends defined/go_to
    ├── wait.yaml             # thin wrapper — extends defined/wait
    ├── explore.yaml          # thin wrapper — extends defined/explore
    ├── report.yaml           # thin wrapper — extends defined/report
    └── capture_image.yaml    # thin wrapper — extends defined/capture_image

defined.yaml — the project manifest

defined.yaml
project:
  name: botcrate

robot:
  rdf: robots/burger_cam.rdf.yaml

world:
  file: worlds/open_room.yaml

verbs:
  path: verbs/

sim:
  image: ghcr.io/defined-robotics/sim:0.1.0

This is the first file the defined CLI reads. It tells the compiler:

  • which robot to validate capabilities against
  • which world to load POIs from
  • where to find custom verbs (the verbs/ directory)
  • which Docker image to use for simulation

Change robot.rdf to switch robots, or world.file to change the environment. Everything else updates automatically on the next compile.


robots/ — Robot Definition Files

RDF files describe hardware capabilities. The compiler reads them to check that every verb in a task can be satisfied by the robot.

burger.rdf.yaml

robots/burger.rdf.yaml
name: turtlebot3_burger
version: "0.0.1"
description: >
  TurtleBot3 Burger differential-drive robot with 360-degree LiDAR.
  Supports navigation, exploration, and patrol tasks.

modules:
  - name: drive_base
    type: motor_controller
    capabilities:
      - name: differential_drive
        type: differential_drive
        parameters:
          wheel_separation: 0.160   # meters between wheels
          wheel_radius: 0.033       # meters
          max_linear_velocity: 0.22 # m/s
          max_angular_velocity: 2.84 # rad/s
      - name: wheel_encoders
        type: wheel_encoders
        parameters:
          ticks_per_revolution: 4096

  - name: lidar_module
    type: sensor
    capabilities:
      - name: laser_scanner
        type: lidar_2d
        parameters:
          model: LDS-01
          range_min: 0.120
          range_max: 3.500
          samples: 360
          update_rate: 5.0
          topic: /scan

Each capability has a type that verbs match against. The go_to verb declares required_capabilities: [differential_drive, lidar_2d] — this robot satisfies both.

burger_cam.rdf.yaml

Extends the burger definition with an rgb_camera capability module. Use this robot for tasks that call capture_image.

robots/burger_cam.rdf.yaml
  - name: camera_module
    type: sensor
    capabilities:
      - name: rgb_camera
        type: rgb_camera
        parameters:
          resolution_width: 640
          resolution_height: 480
          fps: 30
          topic: /camera/image_raw

If you try to compile inspect.task.yaml with burger.rdf.yaml (no camera), the compiler will fail with a missing capability error.


tasks/ — task files

Task files list steps as verb + params pairs. POI references use $world.pois.<name> — resolved at compile time against the active world file.

patrol.task.yaml

tasks/patrol.task.yaml
name: Patrol
description: "Visit survey points in sequence, report at each, return to dock"
steps:
  - verb: go_to
    params:
      target: $world.pois.survey-1
  - verb: report
    params:
      message: "arrived_survey_1"
  - verb: wait
    params:
      duration: 2.0
  - verb: go_to
    params:
      target: $world.pois.survey-2
  - verb: report
    params:
      message: "arrived_survey_2"
  - verb: wait
    params:
      duration: 2.0
  - verb: go_to
    params:
      target: $world.pois.survey-3
  - verb: report
    params:
      message: "arrived_survey_3"
  - verb: go_to
    params:
      target: $world.pois.dock
  - verb: report
    params:
      message: "patrol_complete"

explore.task.yaml

tasks/explore.task.yaml
name: Explore
description: "Autonomously explore and map the environment using frontier-based SLAM"
steps:
  - verb: explore
    params:
      timeout: 300.0
  - verb: report
    params:
      message: "exploration_complete"

The explore verb runs frontier-based exploration until timeout seconds elapse. It requires differential_drive and lidar_2d.


worlds/ — world definitions

Worlds define the physical environment and the named POIs within it.

open_room.yaml

worlds/open_room.yaml
name: room_10x10
description: >
  A 10m x 10m open room with perimeter walls only.

pois:
  dock:
    x: 0.0
    y: 0.0
    type: constant
    description: Home/charging station
  survey-1:
    x: 3.0
    y: 3.0
    type: static
    description: Northeast corner survey point
  survey-2:
    x: -3.0
    y: -3.0
    type: static
    description: Southwest corner survey point
  survey-3:
    x: 3.0
    y: -3.0
    type: static
    description: Southeast corner survey point

sim:
  environment: room_10x10
  spawn:
    x: 0.0
    y: 0.0
    yaw: 0.0

The sim block tells the simulation launcher which environment model to load and where to place the robot at startup.

maze.yaml

Same structure as open_room.yaml but uses environment: maze_10x10 — a 10×10m room with internal S-curve walls. The maze POIs are at positions accessible through the wall gaps.


verbs/ — custom verb directory

The verbs in this directory are thin wrappers that delegate to built-in verbs:

verbs/go_to.yaml
# Navigate to a waypoint — inherits everything from the built-in verb.
# Override any field here to customize (e.g. change default timeout).
extends: defined/go_to
verbs/wait.yaml
# Pause execution for a duration — inherits from built-in.
extends: defined/wait

The extends field pulls in the full verb definition from the defined built-in library. You can override individual fields — for example, to lower the default navigation timeout for a fast indoor robot:

verbs/go_to.yaml
extends: defined/go_to
parameters:
  timeout:
    default: 30.0

To write a verb from scratch (no extends), see Create your first custom verb.


Compiling and running

# Validate and compile a single task
defined compile tasks/patrol.task.yaml

# Start the simulator and run a task
defined run tasks/patrol.task.yaml

# Run the TUI monitor without starting a new mission
defined monitor

defined compile produces BT XML in .build/ and validates the full capability chain. It does not require Docker. defined run compiles first, then starts the sim container if it is not already running.


How to extend the starter repo

Add a new POI — edit the world file and add a $world.pois.<name> reference in a task. Re-compile.

Add a new robot — create a .rdf.yaml in robots/, point defined.yaml at it, re-compile. If a task uses a verb the robot cannot satisfy, the compiler tells you exactly which capability is missing.

Add a new world — create a .yaml in worlds/, point defined.yaml at it. The sim image must include the matching environment model, or you will need a custom sim image.

Add a custom verb — create a .yaml + .xml.j2 pair in verbs/ (no extends needed). See Create your first custom verb for a step-by-step guide.