Controllers with PID and
Movitation for Neural Networks

By Max Kukartsev

Abstract

Controllers are useful for tasks such as temperature regulation and synchronizing electrical motors. Controllers govern such processes to reach some end goal. PID control is a commonly used implementation of a controller, but is not the only alternative. Another type of controller is based on neural networks. I experimented with the performance of PID control on several varieties of simulated motor systems, and discuss the differences I expect to see in a neural network controller.

Controllers

A basic controller takes from a sensor and supplies output to a device that affects the sensor indirectly. Its goal is to bring the sensor to some desired value. In temperature regulation for example, the controller cannot modify the temperature directly. It does it through a device such as a heater or cooler.

Before we continue, let us familiarize ourselves with some controller terminology. Examples are given for the temperature controller described above.

Controller terms

PID Control

PID is one way to implement a controller. PID stands for “Proportional, Integral, Derivative”. Each of the three terms refers to a specific strategy of controlling the manipulated variable. The image below, taken from the PID page on Wikipedia, shows how all three components are used together.

The contributions of each component are summed together, and the result is added to the manipulated variable. Except before the components are summed, each is weighted by a constant term that determines its significance among the three. The constant terms for proportional, integral, and derivative controls are KP, KI, and KD.

Weighting constants

The KP, KI, and KD constants are preset before the PID controller runs. The method by which they are set is called tuning. Tuning often happens manually, where a human tries different values and chooses the best ones.

The individual components of PID control

Proportional control

Proportional control is commonly used in non-PID controllers. Proportional control adjusts the manipulated variable proportionally to the current error. The larger the error, the more it tries to minimize it. Proportional control is implemented according to the following formula.

The following image, also from the Wikipedia PID page, shows the process variable as a function of time after the setpoint was changed from 0 to 1. The reference signal represents the setpoint, and other curves represent different values of the the constant term KP.

A human tuning this controller for KP is likely to select the value KP = 2, since it makes the process variable settle on its setpoint the quickest.

Integral control

Integral control takes into account the error accumulated up to the current point. The adjustment is described by the formula below. So the longer the process variable is far away from the setpoint, the more integral control will adjust it toward the setpoint. Here are some visual examples of how integral control influences the response of the controlled system.

Derivative control

Derivative control predicts the process variable's value in the future, and adjusts the manipulated variable accordingly. The following formula describes this. The faster the process variable converges on the setpoint, the more derivative control tries to keep the process variable at its current value. It effectively counteracts the adjustments made by the proportional and integral controls. The image below shows various system responses for various values of KD.

Derivative control is effective at countering oscillation.

P, PI, PD, PID controllers

Not all three PID components are necessary for a stable system. Sometimes a subset of these is sufficient. For some systems P, PI, and PD works and full PID is overkill. It all depends on the properties of the system being controlled.

PID quirks in digital systems

In digital systems input from the process variable is discrete, so we need to approximate derivatives and integrals we compute derivatives and integrals.

Derivative control

The derivative term is approximated as follows.

The higher the sampling timestep Δt (the delay between updates of the process variable), the higher the inaccuracy of the derivative term. This is especially evident when the process variable converges on the setpoint, and the error becomes small. In that case the approximated derivative term is relatively large and causes the process variable to oscillate.

As a result derivative control is either disabled or processed through a low-pass filter on digital systems.

Integral control

An integral is approximated by a Riemman sum. But in integral control, we are integrating from t = 0 to an arbitrarily large t. Similarly the resulting sum can get arbitrarily large. This means integral control will probably dominate the controller and destabilize the system.

To prevent this, I limited the resulting sum to a maximum allowed value.

Test system

I implemented several basic, simulated systems that are meant to test the performance of a PID controller. The systems all resemble a single motor, and the goal is to spin it at some desired RPM.

In the real version of the systems, the manipulated variable is likely a voltage applied to the motor. But to simplify things in my adaptation the manipulated variable is the process variable itself.

Each system attempts to capture some property of a motor. A motor is likely to have friction and momentum, so there are systems that implement them. A list of systems I implemented is listed in the table below.

Acceleration Resistance Cap on max
acceleration
Very simple/
ideal motor
discontinuous none no
Max
Acceleration
discontinuous none yes
Simple
friction
discontinuous constant no
Complex
friction
discontinuous variable no
Momentum continuous variable* no

* continuous acceleration continuous implicitly gives variable resistance

Implementation and results

I implemented the test systems using Matlab. Code is available in the Appendix.

I manually tuned my PID controller on each system listed in the above table and selected values for KP, KI, and KD that I felt gave the best results.

I show graphs of the system response below, motor RPM vs. time. System response is measured against some reference setpoint, which first starts out at 0 RPM, then jumps to 100 RPM, then to 150 RPM. The goal of the PID controller is to make the system to be as close as possible to the setpoint.

The reference setpoint is shown in blue, and the system response in red.

Simple motor

The simple motor is by far not meant to represent a motor accurately. It is mostly here for example.

KP = 0.5, KI = 0, KD = 0

The simple motor is also an example of where a P-only (proportional) controller is sufficient.

Maximum acceleration

This motor simulation imposes a cap on the maximum torque on the motor. In this context, torque is the change in RPM per unit time. As a result the slope of the red line below never exceeds a certain value.

KP = 0.25, KI = 0.1, KD = 0

Simple friction

The simple friction system works by scaling each change in RPM by a constant k where k < 1. In the actual code k = 0.2.

The graph below shows an example of a poorly tuned PID controller using the same KP, KI, and KD values from the system above. The system below never reaches stability past 0 RPM.

KP = 0.25, KI = 0.1, KD = 0

There are no universal values for KP, KI, and KD that will work well for all systems.

Simple friction, take two

This time the controller is tuned on the simple friction system, and the best constant values are shown below.

KP = 1, KI = 0.3, KD = 0

Compared to the last example, this one illustrates the importance of tuning the controller.

Complex friction

This type of friction is modeled after air friction. In particular, it resembles air friction on an object that increases proportionally with the velocity of the object through the medium.

Although there is no such air friction in a motor system (or at least it is minimal), it is beneficial to see how the controller will perform on it.

The larger the RPM is, the larger is the motor's resistance to changes in RPM.

KP = 10, KI = 1, KD = 0

Since resistance is higher at high RPMs, the system is sensitive on the first step up to 100 RPM, and then relatively insensitive on the second step up to 150 RPM. As a result the controller was difficult to tune on this system, since the controller would tend to overshoot in the first step and undershoot in the second. Even the tuned system has this behavior, as you can see in the graph above.

Momentum

In all previous cases the torque on the motor was discontinuous. If the torque on the motor were plotted against time on the same graph, it would a flat line at 0, then jump to some positive value like a step function.

In this motor system, the torque is continuous. The system does this by limiting the change in torque to some maximum value. This is strikingly similar from the motor with a cap on maximum torque, except that this one limits the change in torque.

KP = 13, KI = 0, KD = 80

Momentum in this system effectively makes the red line want to keep going in the direction it was already going in. This makes for a system that is sluggish and hard to control.

The derivative term is activated here for the first time in all examples. Without it, the system would be unstable. Specifically, when the error is high it would accelerate the RPM to a high value and would not be able to slow down before it passes the setpoint. It would end up overshooting the setpoint by more and more each time, and spin out of control.

The derivative term slows the system down when it predicts that it would get close to the setpoint. This is exactly what we need to make the system stable.

There is one minor problem, though. If you look closely at the red line after it settles, you'll see that it oscillates slightly about the setpoint. That is the effect of derivative control on digital systems which I mentioned earlier.

PID Disadvantages

PID controllers are far from ideal. They need to be tuned to a specific system for good performance. Also the constants KP, KI, and KD are static. They are preset before the PID controller runs, and stay constant during the controller's operation. This is especially disadvantageous for controlling the “complex friction” system, as its sensitivity is a function of the motor's RPM. Hence it is probably better to have the constants actually vary with the RPM.

A neural networks approach

Neural networks can be used instead of, or in conjunction with, PID control. For instance, a neural network can act as the controller itself. Or alternatively, it could be used to tune a PID controller.

Neural networks controller

Hagan and Demuth describe the process involved behind training a neural network to control a system.

They say the process is similar to the one used to approximate an unknown function using a neural network, and suggest to use a multi-layer perceptron for this purpose. By making the error of the network the difference between the actual function value and the network output, they have the network train to approximate the function.

On page 5 their paper, several graphs represent different response curves for the neural network with different neuron weights. Because a neural network is trained to optimize its weights to best satisfy the training data, this could mean the network trains to achieve the best response curve.

The authors suggest several architectures of integrating the neural network into the controller-system unit, with varying advantages and complexities.

Neural networks to tune PID controllers

An alternative to the above is to have a neural network act as the human in tuning a PID controller. It could possibly even perform a better job than the human, simply because it can evaluate far more combinations of KP, KI, and KD and settle the best one.

Future work

One possible direction for future work is to test Hagan and Demuth's various neural network-based controller architectures against the several simulated motor systems here.

Another alternative is to actually implement a network to train a PID controller on a specific system. If I were to design such a network, I would start with a time-delay multi-layer perceptron architecture with two layers and make it have three outputs, KP, KI, and KD. I would feed it 10 RPM values, where each is one timestep behind the previous. One of those 10 values would be the current RPM. After running the network on some step function of the setpoint, I would feed it the sum from the PID integral component as error.

References

[1]   Wikipedia. PID Control. http://en.wikipedia.org/wiki/PID_controller.
[2]   Martin T. Hagan, Howard B. Demuth. (June, 1999). Neural Networks for Control. http://hagan.okstate.edu/HaganDemuthACC99.pdf

Appendix

Code

maxaccelMotor.m

function [stateout] = maxaccelMotor(state, desired)
    current = state(1);
    difference = desired - current;
    % Up to a maximum force can be applied
    force = sign(difference) * min(abs(difference), 5);
    % Momentum coefficient * current
    stateout = [current + force 0];

simplefrictionMotor.m

function [final] = simpleFrictionMotor(current, desired)
    difference = desired - current;
    force = 0.2 * difference; % Damp the force applied
    final = current + force;

complexfrictionMotor.m

function [stateout] = complexFrictionMotor(state, desired)
    current = state(1);
    difference = desired - current;
    coeff = 0.2 / max(current, 2);
    coeff = min(coeff, 0.5); % Set maximum value
    coeff = max(coeff, 0.01); %
          Set minimum value
    force = coeff * difference; % Damp
            the force applied
    stateout = [current + force 0];

momentumMotor.m

function [stateout] = momentumMotor(state, desired)
    current = state(1);
    accel = desired - current;


    % Momentum coefficient * current
    prevforce = state(2);

    forcediff = 1*accel - prevforce;
    % Force can only change up to 5 units
    force = prevforce + sign(forcediff)*0.3;
    stateout = [current + force force];

main.m

% RPM goes from 0 to 200

minRPM = 0;
maxRPM = 200;

halfRPM = minRPM + floor((maxRPM - minRPM) / 2);
quarterRPM = minRPM + floor((halfRPM - minRPM) / 2);

dt = 1;
time = [0:dt:299]; % In milliseconds
%signal = halfRPM*ones(1, length(time));
signal = [zeros(1, 100) halfRPM*ones(1, 100) (halfRPM+quarterRPM)*ones(1,100)];
%signal = [halfRPM*ones(1, 100) (halfRPM+quarterRPM)*ones(1,100)];

% Holds history of all RPMs
RPMs = zeros(1, length(time)); % Start with zero


% ---PID CONTROLLER---

% Proportional, integral, and derivative coefficients
prpK = 13; intK = 0; drvK = 80;

% Sum of integration
intSum = 0;
% Maximum limit for numeric integration
intLimit = floor(halfRPM / 2);

% Previous error stored for derivative use
prevError = 0;

% Hold state for complex motor simulations
state = [0 0];

% PID control
for i=1:length(signal),
    desired = signal(i); % Desired RPM
    current = RPMs(max(1, i-1)); % Current RPM from before
    prev = RPMs(max(1, i-2)); % Immideately preceding RPM
    error = desired - current; % Error between desired and current

    final = current;

    % Add proportional term
    proportional = prpK * error;


    % Add integral term
    intSum = min(intSum + error, intLimit);
    integral = intK * intSum;


    % Add derivative term
    derivative = drvK * (error - prevError / dt);

    prevError = error;

    final = final + proportional + integral + derivative;


    % Simple motor
    %RPMs(i) = final;

    % Maximum acceleration motor
    %state = maxaccelMotor(current, final);

    % Simple friction motor
    %state = simpleFrictionMotor(state, final);

    % Complex friction motor
    %state = simpleFrictionMotor(state, final);

    % Momentum-based motor
    state = momentumMotor(state, final);

    RPMs(i) = state(1);
end


p1 = plot(time, signal);
set(p1, 'Color', 'yellow');
hold on
p2 = plot(RPMs);
set(p2, 'Color', 'cyan');
axis([0 length(time)-1 -10 maxRPM])
set([p1 p2], 'LineWidth', 3)
ylabel('RPM');
xlabel('time (ms)')
hold off