# `BB.Servo.Feetech.Controller`
[🔗](https://github.com/beam-bots/bb_servo_feetech/blob/main/lib/bb/servo/feetech/controller.ex#L5)

A controller that manages a Feetech servo bus.

This controller wraps the `Feetech` GenServer and provides a shared ETS table
for actuators to write commands to. The controller runs a fixed-rate control
loop that batches all pending commands into efficient bulk writes (`sync_write`)
and reads positions via bulk reads (`sync_read`).

On each loop tick, the controller:

1. Reads all pending commands from the ETS table
2. Batches them into `sync_write` operations for the serial bus
3. Clears the command fields
4. Reads all servo positions via `sync_read`
5. Updates the ETS table with current positions
6. Publishes `JointState` messages for positions that exceed deadband

## Configuration

The controller is typically defined in the robot DSL:

    controller :feetech, {BB.Servo.Feetech.Controller,
      port: "/dev/ttyUSB0",
      baud_rate: 1_000_000,
      control_table: Feetech.ControlTable.STS3215,
      loop_interval_ms: 10
    }

## Options

- `:port` - (required) The serial port path, e.g., `"/dev/ttyUSB0"`
- `:baud_rate` - Baud rate in bps (default: 1_000_000)
- `:control_table` - The servo control table to use (default: `Feetech.ControlTable.STS3215`)
- `:loop_interval_ms` - Control loop interval in ms (default: 10, i.e. 100Hz)
- `:status_poll_interval_ms` - Status polling interval in ms (default: 1000, set to 0 to disable)
- `:disarm_action` - Action to take when robot is disarmed (default: `:disable_torque`)
  - `:disable_torque` - Disable torque on all servos (safe default)
  - `:hold` - Keep torque enabled (servos hold position)

## ETS Table Structure

Each registered servo has a row in the ETS table:

    {servo_id, joint_name, center_angle, reverse?, position_deadband,
     last_position_raw, goal_position, goal_speed}

Actuators write `goal_position` (raw units) and `goal_speed` (rad/s) via
`:ets.update_element/3`. The controller reads and clears them each tick.

## Safety

This controller implements the `BB.Safety` behaviour. When the robot is disarmed
or crashes, torque is disabled on all known servo IDs using sync_write for speed.

# `disarm`

Handle disarm based on the configured `disarm_action`.

Called by `BB.Safety.Controller` when the robot is disarmed or crashes.
By default, disables torque on all registered servo IDs.

---

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