Beam Bots (bb) is a framework for building resilient robotics applications in Elixir. It provides a declarative DSL for defining robot topologies, automatic supervision tree generation that mirrors physical structure, and a comprehensive suite of subsystems for motion control, safety management, sensor integration, and external system communication. The framework leverages the BEAM's fault-tolerance primitives to isolate failures and enable autonomous recovery.
This page provides a high-level introduction to the Beam Bots architecture, its core concepts, and how its major subsystems interact. For detailed information about specific aspects:
Sources: README.md1-92 mix.exs1-29 AGENTS.md11-13
Beam Bots treats robot systems as distributed fault-tolerant applications. The framework applies BEAM supervision principles to physical robot components, where hardware failures (sensor crashes, actuator timeouts, communication errors) are handled through automatic process restart and recovery. Each robot component runs as a supervised process, enabling fine-grained fault isolation—a crashed servo driver only affects its supervision subtree, not the entire robot.
The framework uses a compile-time DSL powered by Spark to define robot structure declaratively. This DSL undergoes multi-stage transformation and verification at compile time, producing optimized runtime structures and supervision specifications. Runtime behavior is coordinated through a hierarchical pub-sub messaging system, a global safety controller, and a state machine that manages command execution.
Sources: AGENTS.md11-16 README.md20-31
The Beam Bots architecture is organized into seven functional layers:
DSL-to-Runtime Compilation Layers:
| Layer | Primary Modules | Purpose |
|---|---|---|
| Application Layer | BB.Application | Entry point and application supervision |
| Robot Definition Layer | BB.Dsl, Spark transformers | Declarative robot specification and compile-time processing |
Runtime Coordination Layers:
| Layer | Primary Modules | Purpose |
|---|---|---|
| Supervision & Process Management | BB.Supervisor, Registry, BB.Safety.Controller, BB.PubSub | Fault isolation, process discovery, safety coordination, message routing |
| Runtime Execution Layer | BB.Robot.Runtime, BB.Parameter, BB.Robot.State | State machine, command execution, configuration storage |
Hardware Interface and Control Layers:
| Layer | Primary Modules | Purpose |
|---|---|---|
| Robot Component Layer | BB.Sensor, BB.Actuator, BB.Controller, BB.Bridge | Hardware drivers and external system integration |
| Motion Control Layer | BB.Command, BB.Motion, BB.IK.Solver, BB.Collision | Command execution, inverse kinematics, collision detection |
| External Interfaces | BB.Urdf.Exporter, bridge implementations | URDF export and external system synchronization |
Sources: mix.exs69-154 AGENTS.md58-104
Application Entry Point Diagram: The BB.Application module starts the global safety controller and supervises individual robot instances. Each robot runs under a BB.Supervisor that is monitored by the safety controller.
The framework is started automatically as an OTP application mix.exs49-54 Users start individual robots by calling BB.Supervisor.start_link(MyRobotModule) with a module that uses the BB DSL.
Sources: mix.exs49-54 AGENTS.md89-91
DSL Compilation Pipeline Diagram: User modules use the BB DSL, which is processed through transformers and verifiers at compile time to produce an optimized BB.Robot struct.
Robot definitions are written using the BB.Dsl extension lib/bb/dsl.ex The DSL provides sections for settings, topology, sensors, actuators, controllers, commands, parameters, and states. At compile time, transformers in lib/bb/dsl/transformer/ process the DSL through multiple stages:
DefaultNameTransformer - sets default robot nameTopologyTransformer - validates link/joint hierarchySupervisorTransformer - generates supervision tree specsRobotTransformer - builds optimized BB.Robot structCommandTransformer - processes command definitionsParameterTransformer - processes parameter schemasVerifiers in lib/bb/dsl/verifier/ validate the structure (e.g., checking for unique names, valid parameter references).
Sources: AGENTS.md58-82 README.md34-92
Runtime Coordination Diagram: The runtime layer consists of per-robot coordination processes (Runtime, State, Parameters) and global infrastructure (Safety Controller, Registry, PubSub). Component processes register with these subsystems and communicate through pub-sub messaging.
The BB.Robot.Runtime GenServer coordinates each robot's operation lib/bb/robot/runtime.ex It maintains a state machine (:disarmed, :idle, :executing, custom states) and manages command execution. The BB.Robot.State module provides ETS tables for fast concurrent access to joint positions and velocities lib/bb/robot/state.ex
The global BB.Safety.Controller manages arm/disarm operations across all robots lib/bb/safety/controller.ex Components that control hardware implement the BB.Safety behavior and register disarm callbacks with the controller.
Sources: AGENTS.md83-104 lib/bb/robot/runtime.ex lib/bb/safety/controller.ex
Complete Execution Flow Diagram: The sequence from DSL definition through compilation to runtime operation. The robot starts disarmed and must be explicitly armed before accepting commands.
Sources: AGENTS.md76-104
Command Execution Flow Diagram: Commands are spawned as GenServer processes that implement BB.Command behavior. Motion commands use BB.Motion to solve inverse kinematics and dispatch actuator commands through pub-sub.
Commands are defined in the DSL commands section and implement the BB.Command behavior lib/bb/command.ex Each command executes as a short-lived GenServer that calls handle_command/3 and returns results via result/1. Commands can specify allowed states, categories for concurrency control, and state transitions.
The BB.Motion module provides high-level motion control lib/bb/motion.ex integrating with BB.IK.Solver implementations for inverse kinematics and dispatching position commands to actuators through BB.PubSub.
Sources: AGENTS.md100-102 lib/bb/command.ex lib/bb/motion.ex
The BB.Robot struct is the central optimized representation of a robot lib/bb/robot.ex It contains:
| Field | Type | Purpose |
|---|---|---|
:name | atom | Robot identifier |
:links | %{atom => BB.Dsl.Link} | Flat map for O(1) link lookup |
:joints | %{atom => BB.Dsl.Joint} | Flat map for O(1) joint lookup |
:sensors | %{atom => BB.Dsl.Sensor} | Sensor definitions |
:actuators | %{atom => BB.Dsl.Actuator} | Actuator definitions |
:controllers | %{atom => BB.Dsl.Controller} | Controller definitions |
:bridges | %{atom => BB.Dsl.Bridge} | Bridge definitions |
:parameters | %{atom => BB.Dsl.Parameter} | Parameter schemas |
:commands | %{atom => BB.Dsl.Command} | Command definitions |
:states | %{atom => BB.Dsl.State} | Custom operational states |
:topology | list | Pre-computed traversal order |
:transforms | map | Pre-computed transform matrices (Nx tensors) |
All physical units are converted to SI base units (meters, radians, kilograms) during compilation. The struct is injected into the user's robot module as a robot/0 function by the RobotTransformer.
Sources: AGENTS.md85-89 lib/bb/robot.ex
The BB.Robot.Runtime state machine manages robot operational states:
| State | Description | Allowed Transitions |
|---|---|---|
:disarmed | Hardware is safe, no commands accepted | → :idle (via arm/1) |
:idle | Armed and ready, awaiting commands | → :executing, → custom states, → :disarming |
:executing | Commands are running (backward compatibility) | → :idle, → :disarming |
| Custom states | User-defined operational states (e.g., :recording) | → :idle, → other custom states, → :disarming |
:disarming | Running disarm callbacks with timeout | → :disarmed, → :error |
:error | Disarm failed, hardware may be unsafe | → :disarmed (via force_disarm/1) |
Commands can specify allowed_states and next_state transitions in their definitions. The :executing state exists for backward compatibility with commands that don't specify custom states.
Sources: AGENTS.md96-99 lib/bb/robot/runtime.ex
Process Discovery Diagram: Components register themselves in the Registry using :via tuples. The BB.lookup/2 and BB.whereis/2 functions provide convenient access.
All robot components register themselves with a partitioned Registry using :via tuples. The framework provides BB.whereis/2 and BB.lookup/2 functions for process discovery lib/bb.ex
Sources: AGENTS.md181 lib/bb.ex
Message Flow Diagram: Messages are published through BB.PubSub with typed payloads wrapped in BB.Message structs. Subscribers receive messages via handle_info/2.
Messages are published using BB.PubSub.publish/3 with a hierarchical path (e.g., [:sensor, :base, :imu]). Payloads implement the BB.Message behavior and are wrapped in BB.Message structs with metadata (timestamp, frame_id). Subscribers use BB.PubSub.subscribe/3 with path patterns and optional message type filters.
Sources: AGENTS.md92-93 lib/bb/pub_sub.ex lib/bb/message.ex
Safety Operations Diagram: The BB.Safety module provides the public API for arm/disarm operations. The global controller manages state transitions and invokes registered callbacks.
The BB.Safety module provides arm/1, disarm/1, disarm/2 (with timeout), and force_disarm/1 functions lib/bb/safety.ex Components that control hardware implement the BB.Safety behavior with a disarm/1 callback. During disarm, the safety controller invokes all registered callbacks concurrently with a configurable timeout (default 5 seconds). Failed callbacks transition the robot to the :error state.
Sources: AGENTS.md125-136 lib/bb/safety.ex lib/bb/safety/controller.ex
The codebase is organized by functional domain:
lib/bb/
├── dsl.ex # DSL definition (Spark extension)
├── dsl/
│ ├── entities/ # DSL entity structs (Link, Joint, Sensor, etc.)
│ ├── transformer/ # Compile-time transformers
│ └── verifier/ # Compile-time verifiers
├── robot.ex # BB.Robot struct
├── robot/
│ ├── runtime.ex # State machine and command coordination
│ ├── state.ex # ETS storage for joint positions
│ └── kinematics.ex # Forward kinematics (Nx)
├── supervisor.ex # Per-robot supervision tree
├── pub_sub.ex # Hierarchical message routing
├── safety.ex # Safety API
├── safety/
│ └── controller.ex # Global safety controller
├── command.ex # Command behavior
├── command/
│ ├── arm.ex # Built-in Arm command
│ ├── disarm.ex # Built-in Disarm command
│ └── move_to.ex # Built-in MoveTo command
├── sensor.ex # Sensor behavior
├── actuator.ex # Actuator behavior
├── controller.ex # Controller behavior
├── bridge.ex # Bridge behavior
├── motion.ex # Motion control integration
├── ik/
│ └── solver.ex # IK solver behavior
├── collision.ex # Collision detection
├── collision/
│ └── mesh.ex # Mesh loading and bounding geometry
├── parameter.ex # Parameter storage and access
├── message.ex # Message behavior and wrapper
├── message/ # Standard message types
├── error.ex # Structured error base
├── error/ # Error class implementations
├── urdf/
│ └── exporter.ex # URDF XML generation
├── sim/ # Simulation mode components
├── math/ # Mathematical utilities (Transform, Vec3, etc.)
└── unit.ex # Physical unit helpers
Sources: mix.exs69-154
| Dependency | Purpose | Version |
|---|---|---|
spark | DSL framework | ~> 2.3 |
nx | Numerical computing (kinematics, transforms) | ~> 0.10 |
ex_cldr_units | Physical unit handling | ~> 3.0 |
splode | Structured error handling | ~> 0.2 |
ease | Easing functions (simulation) | ~> 1.0 |
| Dependency | Purpose |
|---|---|
igniter | Project scaffolding and installation |
mimic | Mocking in tests |
ex_doc | Documentation generation |
credo | Static analysis |
dialyxir | Type checking |
Sources: mix.exs199-218
Current version: 0.15.1 mix.exs12
The framework is licensed under Apache-2.0 and maintained by James Harton. The project follows semantic versioning and maintains a detailed changelog CHANGELOG.md1-270
Sources: mix.exs12 mix.exs37-46 CHANGELOG.md1-14
Refresh this wiki
This wiki was recently refreshed. Please wait 2 days to refresh again.