Exploring the PID controller with JavaScript
Motivation
Modern systems in engineering and software are inherently unstable due to their dynamic nature. An example would be a thermostat inside our homes that maintains the desired temperature during summers or winters. It achieves this by a PID controller that varies the temperature up or down to reach the target temperature. The unstable disturbance here would be the room temperature itself that doesn't want to stay constant. So a PID controller can help stabilize any dynamic system that is inherently unstable or could get unstable under certain circumstances.
Technical Background
The PID controller is a concept in control systems theory. It tries to minimize the error of a system. This error is equal to the difference between the desired state and the current state. So it helps the current state of the system closely match the desired state of the system. The PID controller consists of proportional, integral, and derivative controllers. They are different tuning constants for proportional, derivative, and integral controllers which should all be non-negative. The PID control system looks like this:
Then the control equation turns out to be:
Where e(t) = r(t) - y(t). Here r(t) represents the desired state and y(t) represents the current state.
The gif above shows a sample PID controller to demonstrate how different controller constants are tuned and how it affects the PID controller response for a given step function. A step function is the desired value. In this case, the desired value is 1 (red dashed lines), but in real applications, it can be a complex function. The blue line shows the PID controller response that is trying to match the desired value. The Zeigler-Nichols tuning method is a popular method to tune the PID controller constants. Find out more about the Zeigler-Nichols tuning method in this article.
PID Controller with JavaScript
The node-pid-controller package has all the essential bells and whistles to use JavaScript-based PID controller in your projects. This package should be installed with this command:
$ npm install node-pid-controller
Then the PID controller can be instantiated like this:
let Controller = require('node-pid-controller'); let ctr = new Controller({ k_p: 0.25, k_i: 0.01, k_d: 0.01, dt: 1 });
Finally the PID controller should be run in a closed loop to reach a desired value:
ctr.setTarget(23); // 23ºC let goalReached = false while (!goalReached) { let output = getCurrentTemperature(); //this can be a function you use to get temperature from a hardware sensor or API let input = ctr.update(output); applyInputToThermostat(input);//Send signal to the thermostat to turn temperature up or down goalReached = false; // because we want to continously control the temperature this variable remains false and the loop is endless }
In the above sample code, the target temperature for the thermostat is 23ºC that is the desired value. The loop keeps running indefinitely. For each cycle, the temperature value is retrieved from the hardware sensor or an API. Then the current value in the PID controller is updated to calculate the error from the equation e(t) = r(t) - y(t). The controller output value is sent to the thermostat so that it may bring the current temperature to 23ºC. Finally, the room can always be close to 23ºC.