General-purpose PID controller for BB robots.
Subscribes to configurable topics for setpoint and measurement values, runs a periodic PID loop, and publishes output to a configurable topic.
Architecture
Setpoint Topic ─────────────────────────┐
(configurable message/field) │
▼
┌─────────────────┐
Measurement Topic ────────────►│ BB.PID.Controller│
(configurable message/field) │ │
│ PIDControl │
│ .step() │
└────────┬─────────┘
│
▼
Output Topic
(configurable message/field)One controller instance = one PID loop. Instantiate multiple controllers for multiple control loops.
Example Usage
defmodule MyRobot do
use BB
controller :shoulder_pid, {BB.PID.Controller,
kp: 2.0, ki: 0.1, kd: 0.05,
output_min: -1.0, output_max: 1.0,
setpoint_topic: [:actuator, :base_link, :shoulder, :pid],
setpoint_message: BB.Message.Actuator.Command.Position,
setpoint_path: [:position],
measurement_topic: [:sensor, :base_link, :shoulder, :encoder],
measurement_message: BB.Message.Sensor.JointState,
measurement_path: [:positions, 0],
output_topic: [:actuator, :base_link, :shoulder, :servo],
output_message: BB.Message.Actuator.Command.Velocity,
output_field: :velocity,
output_frame_id: :shoulder,
rate: 100
}
# ... rest of robot definition
endPath Extraction
The *_path options are lists of atoms (field names) and integers (list indices):
setpoint_path: [:position] # extracts payload.position
measurement_path: [:positions, 0] # extracts payload.positions |> Enum.at(0)
path: [:data, :readings, 0, :value] # extracts payload.data.readings[0].value