BB.Robot.Runtime (bb v0.27.0)

Copy Markdown View Source

Runtime process for a BB robot.

Manages the robot's runtime state including:

  • The BB.Robot struct (static topology)
  • The BB.Robot.State ETS table (dynamic joint state)
  • Robot state machine (disarmed/idle/executing)
  • Command execution lifecycle
  • Sensor telemetry collection (subscribes to JointState messages)

Robot States

The robot progresses through these states:

  • :disarmed - Robot is not armed, commands restricted
  • :idle - Robot is armed and ready for commands
  • :executing - A command is currently executing

State Transitions

:disarmed arm :idle
:idle execute :executing
:executing complete :idle
:executing disarm :disarmed
:idle disarm :disarmed

Command Execution

Commands execute as supervised GenServers. The caller receives the command pid and can use BB.Command.await/2 or BB.Command.yield/2 to get the result. The Runtime monitors the command server and transitions back to :idle when it completes.

Summary

Functions

Cancel the currently executing command.

Get the availability of each command category.

Check if the robot is in one of the allowed states.

Returns a specification to start this module under a supervisor.

Get all joint configurations as a map.

Execute a command with the given goal.

Check if any command is currently executing.

Check if a specific category has commands executing.

Get information about all currently executing commands.

Get the static robot struct (topology).

Get the robot state (ETS-backed joint positions/velocities).

Get the actual operational state, without backwards compatibility translation.

Get the simulation mode for a robot.

Starts the runtime for a robot module.

Get the current robot state machine state.

Transition the robot to a new state.

Transition the operational state during command execution.

Get all joint velocities as a map.

Returns the via tuple for process registration.

Types

robot_state()

@type robot_state() :: :disarmed | :disarming | :idle | :executing | :error | atom()

simulation_mode()

@type simulation_mode() :: nil | :kinematic | :external

t()

@type t() :: %BB.Robot.Runtime{
  category_counts: %{required(atom()) => non_neg_integer()},
  category_limits: %{required(atom()) => pos_integer()},
  commands: %{required(atom()) => BB.Dsl.Command.t()},
  current_command_name: atom() | nil,
  current_command_pid: pid() | nil,
  current_command_ref: reference() | nil,
  current_execution_id: reference() | nil,
  executing_commands: %{required(reference()) => BB.Robot.CommandInfo.t()},
  operational_state: atom(),
  parameter_store: module() | nil,
  parameter_store_state: term() | nil,
  robot: BB.Robot.t(),
  robot_module: module(),
  robot_state: BB.Robot.State.t(),
  simulation_mode: simulation_mode(),
  valid_states: [atom()]
}

Functions

cancel(robot_module)

@spec cancel(module()) :: :ok | {:error, :no_execution}

Cancel the currently executing command.

Stops the command server with :cancelled reason. Awaiting callers will receive the result from the command's result/1 callback.

category_availability(robot_module)

@spec category_availability(module()) :: %{
  required(atom()) => {non_neg_integer(), pos_integer()}
}

Get the availability of each command category.

Returns a map of category names to {current_count, limit} tuples.

check_allowed(robot_module, allowed_states)

@spec check_allowed(module(), [robot_state()]) ::
  :ok | {:error, BB.Error.State.NotAllowed.t()}

Check if the robot is in one of the allowed states.

Reads directly from ETS for fast concurrent access.

child_spec(init_arg)

Returns a specification to start this module under a supervisor.

See Supervisor.

configurations(robot_module)

@spec configurations(module()) :: %{
  required(atom()) => BB.Robot.State.configuration()
}

Get all joint configurations as a map.

Reads directly from ETS for fast concurrent access. Returns a map of joint names to their current configurations, each shaped to its joint's type — a float for single-DoF joints, a BB.Math.Transform2D for planar and a BB.Math.Transform for floating. See BB.Robot.State for the full table.

Configurations are updated automatically by the Runtime when sensors publish JointState messages.

Examples

iex> BB.Robot.Runtime.configurations(MyRobot)
%{pan_joint: 0.0, tilt_joint: 0.0}

execute(robot_module, command_name, goal)

@spec execute(module(), atom(), map()) :: {:ok, pid()} | {:error, term()}

Execute a command with the given goal.

Returns {:ok, pid} where pid is the command server process. Use BB.Command.await/2 or BB.Command.yield/2 to get the result.

Examples

{:ok, cmd} = Runtime.execute(MyRobot, :navigate, %{target: pose})
{:ok, result} = BB.Command.await(cmd)

# Or with timeout
case BB.Command.yield(cmd, 5000) do
  nil -> still_running()
  {:ok, result} -> handle_result(result)
  {:error, reason} -> handle_error(reason)
end

Errors

  • {:error, %StateError{}} - Robot not in allowed state
  • {:error, {:unknown_command, name}} - Command not found
  • Other errors are returned through BB.Command.await/2

executing?(robot_module)

@spec executing?(module()) :: boolean()

Check if any command is currently executing.

Reads directly from ETS for fast concurrent access.

executing?(robot_module, category)

@spec executing?(module(), atom()) :: boolean()

Check if a specific category has commands executing.

executing_commands(robot_module)

@spec executing_commands(module()) :: [map()]

Get information about all currently executing commands.

get_robot(robot_module)

@spec get_robot(module()) :: BB.Robot.t()

Get the static robot struct (topology).

get_robot_state(robot_module)

@spec get_robot_state(module()) :: BB.Robot.State.t()

Get the robot state (ETS-backed joint positions/velocities).

operational_state(robot_module)

@spec operational_state(module()) :: atom()

Get the actual operational state, without backwards compatibility translation.

Unlike state/1, this returns the actual operational state regardless of whether commands are executing. Use this when you need to know the true operational context (e.g., :idle, :recording, :reacting).

Reads directly from ETS for fast concurrent access.

simulation_mode(robot_module)

@spec simulation_mode(module()) :: simulation_mode()

Get the simulation mode for a robot.

Returns nil if running in hardware mode, or the simulation mode atom (e.g., :kinematic, :external) if running in simulation.

start_link(arg)

Starts the runtime for a robot module.

state(robot_module)

@spec state(module()) :: robot_state()

Get the current robot state machine state.

Returns :disarmed if the robot is not armed (via BB.Safety), otherwise returns the internal operational state.

For backwards compatibility:

  • When operational_state is :idle but commands are executing, returns :executing
  • Custom operational states (e.g., :recording) are returned directly

Reads directly from ETS for fast concurrent access.

transition(robot_module, new_state)

@spec transition(module(), robot_state()) :: {:ok, robot_state()} | {:error, term()}

Transition the robot to a new state.

transition_operational_state(robot_module, execution_id, target_state)

@spec transition_operational_state(module(), reference(), atom()) ::
  :ok | {:error, term()}

Transition the operational state during command execution.

This is called by BB.Command.transition_state/2 to change the robot's operational state mid-execution. Only the command with the matching execution_id can trigger a transition.

velocities(robot_module)

@spec velocities(module()) :: %{required(atom()) => BB.Robot.State.velocity()}

Get all joint velocities as a map.

Reads directly from ETS for fast concurrent access. Returns a map of joint names to their current velocities, each shaped to its joint's type — a float for single-DoF joints, a BB.Message.Geometry.Twist2D for planar and a BB.Message.Geometry.Twist for floating. See BB.Robot.State for the full table.

Velocities are updated automatically by the Runtime when sensors publish JointState messages.

Examples

iex> BB.Robot.Runtime.velocities(MyRobot)
%{pan_joint: 0.0, tilt_joint: 0.0}

via(robot_module)

Returns the via tuple for process registration.