Proportional-integral-derivative (PID) control algorithm

Proportional-integral-derivative controller and ramping functions.

Note

See pyfuzzy for fuzzy logic in Python.

class pyhard2.pid.PidController(proportional=2.0, integral_time=0.0, derivative_time=0.0, vmin=0.0, vmax=100.0)

A software PID controller.

Parameters:
  • proportional (float) – \(K_p\) (no unit).
  • integral_time (float) – \(T_i = K_p/K_i\), in seconds (or samples).
  • derivative_time (float) – \(T_d = K_d/K_p\), in seconds (or sample).
  • vmin (float) – minimum value for the output.
  • vmax (float) – maximum value for the output.
setpoint

float

Setpoint value.

proportional

float

Proportional gain \(K_p\) (no unit).

integral

float

Integral gain \(K_i\) (1/second).

derivative

float

Derivative gain \(K_d\) (seconds).

integral_limit

float

Limit integral value to \(\pm \mathrm{integral_limit} / {\Delta}t\) to prevent windup.

derivative_limit

float

Limit derivative value to \(\pm \mathrm{derivative_limit} / {/Delta}t\) to prevent spikes. Set derivative to 0.0 if derivative is not in the range.

anti_windup

float

Soft integrator, 1.0 to disable, recommended range [0.005-0.25].

proportional_on_pv

bool

Compute proportional gain based on the process variable.

Note

The controller follows either the ideal form

\[u(t) = K_p e(t) + K_i \int_0^t e(t)dt + K_d \frac{d}{dt}e(t),\]

or the standard form

\[u(t) = K_p \left(e(t) + \frac{1}{T_i} \int_0^t e(t)dt + T_d \frac{d}{dt} e(t) \right).\]

Two anti-windup strategies are implemented: - a soft integrator anti_windup and - an integral limitor integral_limit.

The derivative value is computed from the average value of the previous five \(\Delta E / \Delta t\) values to avoid spikes upon large setpoint changes.

Reference:
reset()

Reset time to now.

compute_output(measure, now=None)

Compute next output.

Parameters:
  • measure (float) – Process value.
  • now (float, optional) – Time in s or time.time() if the value is omitted.
Returns:

output – Output value.

Return type:

float

class pyhard2.pid.Profile(profile)

Make a profile ramp.

Parameters:profile (iterable) – A list of (time, setpoint) tuples, time in s.

Note

A \(t_0\) point is created by default. Overwrite by adding a value at \(t_0 = 0\) in the profile.

setpoint(now)

Return the setpoint stored in the profile for time now.

Parameters:now (float) – In seconds.
Returns:setpoint – Profile value at time now.
Return type:float
ramp()

Calculate setpoint values.

Returns:setpoint – generates calculated setpoints.
Return type:generator

Example

>>> from time import sleep
>>> profile = Profile([(0, 0.0), (0.2, 10.0), (0.4, 4.0)])
>>> for setpoint in profile.ramp():
...     print("%i" % round(setpoint)),
...     sleep(0.1)
0 5 10 7