# `BB.Kino.Examples.TestRobot`
[🔗](https://github.com/beam-bots/bb_kino/blob/main/lib/bb/kino/examples/test_robot.ex#L5)

An example robot for testing BB.Kino widgets.

This robot has a simple 2-joint arm topology with commands for:
- Arming/disarming
- Cycling joints through their range of motion
- Moving to home position

## Usage in Livebook

    {:ok, _pid} = BB.Kino.Examples.TestRobot.start_link()

    # Create the management widget
    BB.Kino.safety(BB.Kino.Examples.TestRobot)

# `arm`

```elixir
@spec arm(keyword()) :: {:ok, pid()} | {:error, term()}
```

Execute the `arm` command.

## Returns

- `{:ok, pid()}` - Command started, use `BB.Command.await/2` for the result
- `{:error, term()}` - Command could not be started

## Example

    {:ok, cmd} = arm(goal_args)
    {:ok, result} = BB.Command.await(cmd)

# `child_spec`

```elixir
@spec child_spec(Keyword.t()) :: Supervisor.child_spec()
```

Returns a child specification for starting this robot under a supervisor.

# `cycle_joint`

```elixir
@spec cycle_joint(keyword()) :: {:ok, pid()} | {:error, term()}
```

Execute the `cycle_joint` command.

## Arguments

- `joint`: `:atom`, default: `:shoulder_joint` - Joint to cycle (shoulder_joint or elbow_joint)
- `duration`: `:integer`, default: `2000` - Duration in milliseconds

## Returns

- `{:ok, pid()}` - Command started, use `BB.Command.await/2` for the result
- `{:error, term()}` - Command could not be started

## Example

    {:ok, cmd} = cycle_joint(goal_args)
    {:ok, result} = BB.Command.await(cmd)

# `disarm`

```elixir
@spec disarm(keyword()) :: {:ok, pid()} | {:error, term()}
```

Execute the `disarm` command.

## Returns

- `{:ok, pid()}` - Command started, use `BB.Command.await/2` for the result
- `{:error, term()}` - Command could not be started

## Example

    {:ok, cmd} = disarm(goal_args)
    {:ok, result} = BB.Command.await(cmd)

# `go_home`

```elixir
@spec go_home(keyword()) :: {:ok, pid()} | {:error, term()}
```

Execute the `go_home` command.

## Arguments

- `duration`: `:integer`, default: `1000` - Duration in milliseconds

## Returns

- `{:ok, pid()}` - Command started, use `BB.Command.await/2` for the result
- `{:error, term()}` - Command could not be started

## Example

    {:ok, cmd} = go_home(goal_args)
    {:ok, result} = BB.Command.await(cmd)

# `robot`

```elixir
@spec robot() :: BB.Robot.t()
```

Returns the optimised robot representation.

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

## Examples

    robot = Elixir.BB.Kino.Examples.TestRobot.robot()
    link = BB.Robot.get_link(robot, :base_link)
    joint = BB.Robot.get_joint(robot, :shoulder)

# `start_link`

```elixir
@spec start_link(Keyword.t()) :: Supervisor.on_start()
```

Starts the robot's supervision tree.

## Options

All options are passed through to sensor and actuator child processes.

# `wave`

```elixir
@spec wave(keyword()) :: {:ok, pid()} | {:error, term()}
```

Execute the `wave` command.

## Arguments

- `cycles`: `:integer`, default: `3` - Number of wave cycles
- `speed`: `:float`, default: `1.0` - Speed multiplier (0.5 = half speed, 2.0 = double speed)

## Returns

- `{:ok, pid()}` - Command started, use `BB.Command.await/2` for the result
- `{:error, term()}` - Command could not be started

## Example

    {:ok, cmd} = wave(goal_args)
    {:ok, result} = BB.Command.await(cmd)

---

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