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) – Kp (no unit).
  • integral_time (float) – Ti=Kp/Ki, in seconds (or samples).
  • derivative_time (float) – Td=Kd/Kp, 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 Kp (no unit).

integral

float

Integral gain Ki (1/second).

derivative

float

Derivative gain Kd (seconds).

integral_limit

float

Limit integral value to ±integrallimit/Δt to prevent windup.

derivative_limit

float

Limit derivative value to ±derivativelimit//Deltat 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)=Kpe(t)+Kit0e(t)dt+Kdddte(t),

or the standard form

u(t)=Kp(e(t)+1Tit0e(t)dt+Tdddte(t)).

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 ΔE/Δ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 t0 point is created by default. Overwrite by adding a value at t0=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