PID
Download Flojoy Studio to try this app
Model a PID (proportional-integral-derivative) system. The returned value will be modified according to the PID parameters Kp, Ki, and Kd.
Inputs
------
single_input : Scalar
The data to apply the PID function to. Params: Kp : float The proprotional PID parameter. Ki : float The integral PID parameter. Kd : float The derivative PID parameter. Returns: out : Scalar c: The PID function output.
Python Code
from numpy import zeros, append, ndarray
from flojoy import flojoy, Scalar, DefaultParams, SmallMemory
memory_key = "pid-info"
@flojoy(inject_node_metadata=True)
def PID(
single_input: Scalar,
default_params: DefaultParams,
Kp: float = 5,
Ki: float = 0.0143,
Kd: float = 356.25,
) -> Scalar:
"""Model a PID (proportional-integral-derivative) system.
The returned value will be modified according to the PID parameters Kp, Ki, and Kd.
Inputs
------
single_input : Scalar
The data to apply the PID function to.
Parameters
----------
Kp : float
The proprotional PID parameter.
Ki : float
The integral PID parameter.
Kd : float
The derivative PID parameter.
Returns
-------
Scalar
c: The PID function output.
"""
# First let's get the parameters that won't change
node_id = default_params.node_id
# Now we need some memory! We need to keep track of the running
# integral value of the inputs (regulation errors), as well as
# the previous 3 values of the regulation error
data = SmallMemory().read_memory(node_id, memory_key)
if data is None:
initialize = True
elif type(data) == ndarray:
initialize = False
else:
raise TypeError("Issue reading memory from REDIS.")
integral: int = 0 if initialize else data[0]
regulation_error_primes = zeros(3) if initialize else data[1:]
regulation_error = single_input.c
integral: float = integral + 0.5 * Ki * (
regulation_error + regulation_error_primes[0]
)
output_signal = -1 * (
Kp * regulation_error
+ integral
+ 0.1667
* Kd
* (
regulation_error
- regulation_error_primes[2]
+ 3.0 * (regulation_error_primes[0] - regulation_error_primes[1])
)
)
regulation_error_primes[2] = regulation_error_primes[1]
regulation_error_primes[1] = regulation_error_primes[0]
regulation_error_primes[0] = regulation_error
# Now write to memory ...
SmallMemory().write_to_memory(
node_id, memory_key, append(integral, regulation_error_primes)
)
# ... and return the result
return Scalar(c=output_signal)
Example App
Having problems with this example app? Join our Discord community and we will help you out!
This example demonstrates an active PID controller for a mock non-linear system to be driven to a given setpoint.