BB.Command behaviour (bb v0.2.1)

View Source

Behaviour 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
end

State 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}
end

This 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

goal()

@type goal() :: map()

options()

@type options() :: [{:next_state, BB.Robot.Runtime.robot_state()}]

result()

@type result() :: term()

Callbacks

handle_command(goal, t)

@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 module
  • robot - 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