The task
The .task file is what the robot must do, as a behavior tree: actions such as Navigate and Spin, arranged by control nodes such as Sequence and Retry.
Task drone_demo(timeout_s = 120) {
Retry(count = 2) {
Navigate(goal = @world/goal)
}
Sequence {
Spin(angle_rad = 1.57),
Wait(duration_s = 2),
Stop()
}
}The nodes in the task's body run in order. timeout_s bounds the whole task; when it runs out, the run ends with status timeout.
Actions
| Action | Does |
|---|---|
Navigate(goal = @world/...) | Drive to a goal or an entity, avoiding obstacles |
Spin(angle_rad = ...) | Turn in place by a signed angle |
Advance(distance_m = ..., speed_mps = ...) | Drive straight ahead; the speed is optional |
BackUp(distance_m = ..., speed_mps = ...) | Drive straight back |
Strafe(distance_m = ..., speed_mps = ...) | Drive sideways, positive to the left |
Wait(duration_s = ...) | Do nothing for a while |
Stop() | Come to rest |
An action with no arguments keeps its parentheses, Stop(), so two nodes in a row never read as one.
Control flow
| Node | Runs its children |
|---|---|
Sequence { ... } | In order, stopping at the first failure |
Fallback { ... } | In order, stopping at the first success |
Parallel(policy = "success_on_all") { ... } | Together; "success_on_one" succeeds when any child does |
Retry(count = n) { ... } | Its one child again until it succeeds, at most n times |
Repeat(count = n) { ... } | Its one child n times |
Timeout(timeout_s = t) { ... } | Its one child, failing it after t seconds |
Inverter { ... } | Its one child, swapping success and failure |
Conditions are leaves that succeed or fail without moving: GoalReached(goal = ...), DistanceTraveled(distance_m = ...) and TimeExpired(duration_s = ...).
Task deliver(timeout_s = 180) {
Fallback {
GoalReached(goal = @world/goal),
Retry(count = 3) {
Navigate(goal = @world/goal)
}
}
Stop()
}What, not how
The task names what the robot must accomplish, not how a navigation stack does it. There is no node for a planner, a controller or a costmap, and no syntax to pick one; the target binds each action to its stack. The output contract lists what each action becomes.
The base has to be able to do what the task asks. Spin needs a base that turns in place, and Strafe a holonomic one; a tricycle asked to spin is an error at compile time, not a surprise in the simulator.
Next
The evaluation says how a run of this task is judged.