BB.Command behaviour (bb v0.2.1)
View SourceBehaviour for implementing robot commands.
Commands execute in a supervised task and receive a goal (arguments) and context (robot state). The handler runs to completion and returns a result.
Example
defmodule NavigateToPose do
@behaviour BB.Command
@impl true
def handle_command(%{target_pose: pose, tolerance: tol}, context) do
# Access robot state
current_pose = get_current_pose(context.robot_state)
# Do the work (this runs in a task, so blocking is fine)
case navigate_to(pose, tolerance: tol) do
:ok -> {:ok, %{final_pose: pose}}
{:error, reason} -> {:error, reason}
end
end
endState Transitions
By default, when a command completes successfully, the robot transitions to
:idle. Commands can override this by returning a next_state option:
def handle_command(_goal, _context) do
{:ok, :disarmed, next_state: :disarmed}
endThis is useful for commands like Arm and Disarm that need to control
the robot's state machine.
Execution Model
Commands run in supervised tasks spawned by the Runtime. The caller receives
a Task.t() and can use Task.await/2 or Task.yield/2 to get the result.
Cancellation is handled by killing the task - handlers don't need to implement cancellation logic. If graceful shutdown is needed, handlers can trap exits.
Summary
Callbacks
Execute the command with the given goal.
Types
@type goal() :: map()
@type options() :: [{:next_state, BB.Robot.Runtime.robot_state()}]
@type result() :: term()
Callbacks
@callback handle_command(goal(), BB.Command.Context.t()) :: {:ok, result()} | {:ok, result(), options()} | {:error, term()}
Execute the command with the given goal.
Called in a supervised task. The handler should perform the work and return the result. Blocking operations are fine since this runs in a separate process.
The context provides access to:
robot_module- The robot modulerobot- The static robot struct (topology)robot_state- The dynamic robot state (ETS-backed joint positions etc)execution_id- Unique identifier for this execution
Return Values
{:ok, result}- Command succeeded, robot transitions to:idle{:ok, result, options}- Command succeeded with options:next_state: state- Robot transitions to specified state instead of:idle
{:error, reason}- Command failed, robot transitions to:idle