# `BB.Robot`
[🔗](https://github.com/beam-bots/bb/blob/main/lib/bb/robot.ex#L5)

An optimised robot representation for kinematic computations.

This struct is built from the Spark DSL at compile-time and contains:
- All physical values converted to SI base units (floats)
- Flat maps for O(1) lookup of links, joints, sensors, and actuators by name
- Pre-computed topology metadata for efficient traversal
- Bidirectional parent/child references

## Structure

The robot is organised as flat maps indexed by name:

- `links` - all links in the robot, keyed by atom name
- `joints` - all joints in the robot, keyed by atom name
- `sensors` - all sensors (at any level), keyed by atom name
- `actuators` - all actuators, keyed by atom name

## Unit Conventions

All physical quantities are stored as native floats in SI base units:

- Length: meters
- Angle: radians
- Mass: kilograms
- Moment of inertia: kg·m²
- Force: newtons
- Torque: newton-meters
- Linear velocity: m/s
- Angular velocity: rad/s

# `actuator_info`

```elixir
@type actuator_info() :: %{name: atom(), joint: atom()}
```

# `param_location`

```elixir
@type param_location() :: {:joint, atom(), [atom()]}
```

# `sensor_info`

```elixir
@type sensor_info() :: %{
  name: atom(),
  attached_to: {:link, atom()} | {:joint, atom()} | :robot
}
```

# `t`

```elixir
@type t() :: %BB.Robot{
  actuators: %{required(atom()) =&gt; actuator_info()},
  joints: %{required(atom()) =&gt; BB.Robot.Joint.t()},
  links: %{required(atom()) =&gt; BB.Robot.Link.t()},
  name: atom(),
  param_subscriptions: %{required([atom()]) =&gt; [param_location()]},
  root_link: atom(),
  sensors: %{required(atom()) =&gt; sensor_info()},
  topology: BB.Robot.Topology.t()
}
```

# `child_joints`

```elixir
@spec child_joints(t(), atom()) :: [BB.Robot.Joint.t()]
```

Get the child joints of a link.

# `get_joint`

```elixir
@spec get_joint(t(), atom()) :: BB.Robot.Joint.t() | nil
```

Get a joint by name.

# `get_link`

```elixir
@spec get_link(t(), atom()) :: BB.Robot.Link.t() | nil
```

Get a link by name.

# `joints_in_order`

```elixir
@spec joints_in_order(t()) :: [BB.Robot.Joint.t()]
```

Get all joints in traversal order.

# `links_in_order`

```elixir
@spec links_in_order(t()) :: [BB.Robot.Link.t()]
```

Get all links in topological order (root first).

# `parent_joint`

```elixir
@spec parent_joint(t(), atom()) :: BB.Robot.Joint.t() | nil
```

Get the parent joint of a link (nil for root link).

# `path_to`

```elixir
@spec path_to(t(), atom()) :: [atom()] | nil
```

Get the path from root to a given link or joint.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
