PIDControl

Build StatusHex.pmDocumentation

A discrete implementation of a PID controller for building closed-loop control into embedded systems.

PID

Installation

The package can be installed by adding pid_control to your list of dependencies in mix.exs:

def deps do
  [
    {:pid_control, "~> 0.1.0"}
  ]
end

Usage

The PIDControl.new/1 function returns an initialized PIDControl struct with the given configuration:

iex> pid = PIDControl.new(kp: 0.5, kd: 0.2, ki: 0.03)
%PIDControl{...}

Calling PIDControl.step/3 performs one discrete cycle of the PID loop for the given set_point and measurement values. The new PIDControl state is returned and the output can be accessed via the output key in the struct.

iex> pid = PIDControl.step(pid, 0.3, 0.312)
%PIDControl{
  output: -0.11448221
  #...
}

The step function can be called in each successive input-output cycle of the underling sensor/actuator.

Example

defmodule Controller do
  use GenServer
  # ...

  def init(_) do
    Sensor.subcribe()
    pid = PIDControl.new(kp: 0.5, kd: 0.2, ki: 0.03)
    {:ok, pid}
  end

  def handle_info({:sensor, measurment}, pid) do
    pid = PIDControl.step(pid, @set_point, measurment)
    Actuator.command(pid.output)
    {:noreply, pid}
  end
end

Config Options

Telemetry

If telemetry is set to true, telemetry for the PID state will be emitted each time the step function is called. By default, the event name will be [pid_control] and will contain the following measurements.

This is really useful for manual tuning when combined with something like PheonixLiveDashboard.