1. PID Controller

A proportional-integral-derivative controller (PID controller) is a common feedback loop component in industrial control systems.
[This Subsection is taken from an much more extensive article found at https://en.wikipedia.org/wiki/PID_controller]

The Controller compares a measured value from a process (typically an industrial process) with a reference set point value. The difference (or error signal) is then used to calculate a new value for a manipulable input to the process that brings the process measured value back to its desired set point.

Unlike simpler control algorithms, the PID controller can adjust process outputs based on the history and rate of change of the error signal, which gives more accurate and stable control. (It can be shown mathematically that a PID loop will produce accurate, stable control in cases where a simple proportional control would either have a steady-state error or would cause the process to oscillate).

1.1. Control loop basics

Intuitively, the PID loop tries to automate what an intelligent operator with a gauge and a control knob would do. The operator would read a gauge showing the output measurement of a process, and use the knob to adjust the input of the process (the action) until the process’s output measurement stabilizes at the desired value on the gauge.

In older control literature this adjustment process is called a reset action. The position of the needle on the gauge is a measurement, process value or process variable. The desired value on the gauge is called a set point (also called set value). The difference between the gauge’s needle and the set point is the error.

A control loop consists of three parts:

  1. Measurement by a sensor connected to the process (e.g. encoder),

  2. Decision in a controller element,

  3. Action through an output device such as an motor.

As the controller reads a sensor, it subtracts this measurement from the set point to determine the error. It then uses the error to calculate a correction to the process’s input variable (the action) so that this correction will remove the error from the process’s output measurement.

In a PID loop, correction is calculated from the error in three ways: cancel out the current error directly (Proportional), the amount of time the error has continued uncorrected (Integral), and anticipate the future error from the rate of change of the error over time (Derivative).

A PID controller can be used to control any measurable variable which can be affected by manipulating some other process variable. For example, it can be used to control temperature, pressure, flow rate, chemical composition, speed, or other variables. Automobile cruise control is an example of a process outside of industry which utilizes crude PID control.

Some control systems arrange PID controllers in cascades or networks. That is, a master control produces signals used by slave controllers. One common situation is motor controls: one often wants the motor to have a controlled speed, with the slave controller (often built into a variable frequency drive) directly managing the speed based on a proportional input. This slave input is fed by the master controller’s output, which is controlling based upon a related variable.

1.2. Theory

PID is named after its three correcting calculations, which all add to and adjust the controlled quantity. These additions are actually subtractions of error, because the proportions are usually negative:

Proportional

To handle the present, the error is multiplied by a (negative) constant P (for proportional), and added to (subtracting error from) the controlled quantity. P is only valid in the band over which a controller’s output is proportional to the error of the system. Note that when the error is zero, a proportional controller’s output is zero.

Integral

To learn from the past, the error is integrated (added up) over a period of time, and then multiplied by a (negative) constant I (making an average), and added to (subtracting error from) the controlled quantity. I averages the measured error to find the process output’s average error from the set point. A simple proportional system either oscillates, moving back and forth around the set point because there’s nothing to remove the error when it overshoots, or oscillates and/or stabilizes at a too low or too high value. By adding a negative proportion of (i.e. subtracting part of) the average error from the process input, the average difference between the process output and the set point is always being reduced. Therefore, eventually, a well-tuned PID loop’s process output will settle down at the set point.

Derivative

To handle the future, the first derivative (the slope of the error) over time is calculated, and multiplied by another (negative) constant D, and also added to (subtracting error from) the controlled quantity. The derivative term controls the response to a change in the system. The larger the derivative term, the more rapidly the controller responds to changes in the process’s output.

More technically, a PID loop can be characterized as a filter applied to a complex frequency-domain system. This is useful in order to calculate whether it will actually reach a stable value. If the values are chosen incorrectly, the controlled process input can oscillate, and the process output may never stay at the set point.

1.3. Loop Tuning

Tuning a control loop is the adjustment of its control parameters (gain/proportional band, integral gain/reset, derivative gain/rate) to the optimum values for the desired control response. The optimum behavior on a process change or set point change varies depending on the application. Some processes must not allow an overshoot of the process variable from the set point. Other processes must minimize the energy expended in reaching a new set point. Generally stability of response is required and the process must not oscillate for any combination of process conditions and set points.

Tuning of loops is made more complicated by the response time of the process; it may take minutes or hours for a set point change to produce a stable effect. Some processes have a degree of non-linearity and so parameters that work well at full-load conditions don’t work when the process is starting up from no-load. This section describes some traditional manual methods for loop tuning.

There are several methods for tuning a PID loop. The choice of method will depend largely on whether or not the loop can be taken offline for tuning, and the response speed of the system. If the system can be taken offline, the best tuning method often involves subjecting the system to a step change in input, measuring the output as a function of time, and using this response to determine the control parameters.

Simple method

If the system must remain on line, one tuning method is to first set the I and D values to zero. Increase the P until the output of the loop oscillates. Then increase I until oscillation stops. Finally, increase D until the loop is acceptably quick to reach its reference. A fast PID loop tuning usually overshoots slightly to reach the set point more quickly; however, some systems cannot accept overshoot.

Parameter Rise Time Overshoot Settling Time Steady State Error

P

Decrease

Increase

Small Change

Decrease

I

Decrease

Increase

Increase

Eliminate

D

Small Change

Decrease

Decrease

Small Change

Effects of increasing parameters

Ziegler-Nichols method Another tuning method is formally known as the

Ziegler-Nichols method, introduced by John G. Ziegler and Nathaniel B. Nichols in 1942
[Ziegler, J. G. and Nichols, N. B. (1942), Optimum Settings for Automatic Controllers, Transactions of the ASME, DOI 10.1115/1.2899060 and The Internet Archive.]
. It starts in the same way as the method described before: first set the I and D gains to zero and then increase the P gain and expose the loop to external interference for example knocking the motor axis to cause it to move out of equilibrium in order to determine critical gain and period of oscillation until the output of the loop starts to oscillate. Write down the critical gain (Kc) and the oscillation period of the output (Pc). Then adjust the P, I and D controls as the table shows:

Control type P I D

P

.5Kc

PI

.45Kc

Pc/1.2

PID

.6Kc

Pc/2

Pc/8

Final Steps

After tuning the axis check the following error with Halscope to make sure it is within your machine requirements. More information on Halscope is in the HAL User manual.

1.4. Automatic PID tuning

Since LinuxCNC version 2.9, the pid component support automatic tuning using the Relay method
[Åström, Karl Johan and Hägglund, Tore (1984), Automation paper Automatic Tuning of Simple Regulators with Specifications on Phase and Amplitude Margins, DOI 10.1016/0005-1098(84)90014-1]
. This is a replacement for the now removed and obsolete at_pid component.

The pid component uses several constants to calculate the output value based on current and wanted state, the most important among them being Pgain', Igain, Dgain, bias, FF0, FF1, FF2 and FF3. All of these need to have a sensible value for the controller to behave properly.

The current implementation of automatic tuning implement two different algorithms, selected using the tune-type pin. When tune-type is zero, it affects Pgain, Igain and Dgain while setting FF0, FF1 and FF2 to zero. If tune-type is 1, it affects Pgain, Igain and FF1 while setting Dgain, FF0 and FF2 to zero. Note type 1 require scaling be set so output is in user units per second.

When autotuning a motor with tune-type 0, the algorithm will produce a square wave pattern centered around the bias value on the output pin of the PID controller, moving from the positive extreme to the negative extreme of the output range. This can be seen using the HAL Scope provided by LinuxCNC. For a motor controller taking +-10 V as its control signal, this might accellerate the motor full speed in one direction for a short period before telling it to go full speed in the opposite direction. Make sure to have a lot of room on either side of the starting position, and start with a low tune-effort value to limit the speed used. The tune-effort value define the extreme output value used, so if tune-effort is 1, the output value during tuning will move from 1 to -1. In other words, the extremes of the wave pattern is controlled by the tune-effort pin. Using too high tune-effort might overload the motor driver.

The number of cycles in the tune pattern is controlled by the tune-cycles pin. Of course, trying to change the direction of a physical object instantly (as in going directly from a positive voltage to the equivalent negative voltage in the motor controller case) do not change velocity instantly, and it take some time for the object to slow down and move in the opposite direction. This result in a more smooth wave form on the position pin, as the axis in question were vibrating back and forth. When the axis reached the target speed in the opposing direction, the auto tuner change direction again. After several of these changes, the average time delay between the "peaks" and "valleys" of this movement graph is used to calculate proposed values for Pgain, Igain and Dgain, and insert them into the HAL model to use by the pid controller. The auto tuned settings are not perfect, but might provide a good starting point for further parameter tuning.

FIXME: The author of these instructions have not tested automatic tuning with tune-type set to 1, so this approach remain to be documented.

Armed with this knowledge, it is time to look at how to do the tuning. Lets say the HAL configuration in question load the PID component for X, Y and Z like this, using named pin names instead of count=3:

loadrt pid names=pid.x,pid.y,pid.z

If the component had used count=3 instead, all use of pid.x, pid,y and pid.z need to be changed to pid.1, pid.2 and pid.3 respectively. To start tuning the X axis, move the axis to the middle of its range, to make sure it do not hit anything when it start moving back and forth. You also want to extend the axis ferror limit (following error) to make LinuxCNC accept the higher position deviation during tuning. The sensible ferror limit depends on the machine and setup, but 1 inch or 20 mm might be useful starting points. Next, set the initial tune-effort to a low number in the output range, for example 1/100 of the maximum output, and slowly increase it to get more accurate tuning values. Assign 1 to the tune-mode value. Note, this will disable the pid controlling part and feed the bias value to the output pin, which can cause a lot of drift. It might be a good idea to tune the motor driver to ensure zero input voltage do not cause any motor rotation, or adjust the bias value for the same effect. Finally, after setting tune-mode, set tune-start to 1 to activate the auto tuning. If all go well, your axis will vibrate and move back and forth for a few seconds and when it is done, new values for Pgain, Igain and Dgain will be active. To test them, change tune-mode back to 0. Note that setting tune-mode back to zero might cause the axis to suddenly jerk as it bring the axis back to its commanded position, which it might have drifted away from during tuning. To summarize, these are the halcmd instructions you need to issue to do automatic tuning:

setp pid.x.tune-effort 0.1
setp pid.x.tune-mode 1
setp pid.x.tune-start 1
# wait for the tuning to complete
setp pid.x.tune-mode 0

A script to help doing the automatic tuning is provided in the LinuxCNC code repository as scripts/run-auto-pid-tuner. This will ensure the machine is powered on and ready to run, home all axes if it is not already done, check that the extra tuning pins are available, move the axis to its mid point, run the auto tuning and re-enable the pid controller when it is done. It can be run several times.