376 lines
14 KiB
Groff
376 lines
14 KiB
Groff
.TH PID "9" "2007-01-16" "LinuxCNC Documentation" "HAL Component"
|
|
|
|
.SH NAME
|
|
pid \- proportional/integral/derivative controller
|
|
.SH SYNOPSIS
|
|
\fBloadrt pid [num_chan=\fInum\fB | names=\fIname1\fB[,\fIname2...\fB]] [\fBdebug=\fIdbg\fR]
|
|
|
|
.SH DESCRIPTION
|
|
\fBpid\fR is a classic Proportional/Integral/Derivative controller,
|
|
used to control position or speed feedback loops for servo motors and
|
|
other closed-loop applications.
|
|
.P
|
|
\fBpid\fR supports a maximum of sixteen controllers. The number that
|
|
are actually loaded is set by the \fBnum_chan\fR argument when
|
|
the module is loaded. Alternatively, specify names= and unique names
|
|
separated by commas.
|
|
.P
|
|
The \fBnum_chan=\fR and \fBnames=\fR specifiers are mutually exclusive.
|
|
If neither \fBnum_chan=\fR nor \fBnames=\fR are specified, the default
|
|
value is three. If \fBdebug\fR is set to 1 (the default is 0), some
|
|
additional HAL parameters will be exported, which might be useful
|
|
for tuning, but are otherwise unnecessary.
|
|
|
|
.P
|
|
In the following description, it is assumed that we are discussing
|
|
position loops. However this component can be used to implement other
|
|
loops such as speed loops, torch height control, and others.
|
|
|
|
.P
|
|
Each loop has a number of pins and parameters, whose names begin
|
|
with 'pid.N.', where 'N' is the channel number. Channel numbers start
|
|
at zero.
|
|
.P
|
|
The three most important pins are 'command', 'feedback', and 'output'.
|
|
For a position loop, 'command' and 'feedback' are in position units.
|
|
For a linear axis, this could be inches, mm, metres, or whatever is
|
|
relevant. Likewise, for a angular axis, it could be degrees, radians,
|
|
etc. The units of the 'output' pin represent the change needed to
|
|
make the feedback match the command. As such, for a position
|
|
loop 'Output' is a velocity, in inches/sec, mm/sec, degrees/sec, etc.
|
|
.P
|
|
Each loop has several other pins as well. 'error' is equal
|
|
to 'command' minus 'feedback'. 'enable' is a bit that enables the
|
|
loop. If 'enable' is false, all integrators are reset, and the output
|
|
is forced to zero. If 'enable' is true, the loop operates normally.
|
|
.P
|
|
The PID gains, limits, and other 'tunable' features of the loop are
|
|
implemented as parameters. These are as follows:
|
|
|
|
.PP
|
|
\fBPgain\fR Proportional gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBIgain\fR Integral gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBDgain\fR Derivative gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBbias\fR Constant offset on output
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBFF0\fR \fR Zeroth order Feedforward gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBFF1\fR \fR First order Feedforward gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBFF2\fR \fR Second order Feedforward gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBFF3\fR \fR Third order Feedforward gain
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBdeadband\fR Amount of error that will be ignored
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxerror\fR Limit on error
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxerrorI\fR Limit on error integrator
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxerrorD\fR Limit on error differentiator
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxcmdD\fR Limit on command differentiator
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxcmdDD\fR Limit on command 2nd derivative
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxcmdDDD\fR Limit on command 3rd derivative
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBmaxoutput\fR Limit on output value
|
|
.P
|
|
All of the limits (max____) are implemented such that if the parameter
|
|
value is zero, there is no limit.
|
|
.P
|
|
A number of internal values which may be useful for testing and tuning
|
|
are also available as parameters. To avoid cluttering the parameter
|
|
list, these are only exported if "debug=1" is specified on the insmod
|
|
command line.
|
|
|
|
.PP
|
|
\fBerrorI\fR Integral of error
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBerrorD\fR Derivative of error
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBcommandD\fR Derivative of the command
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBcommandDD\fR 2nd derivative of the command
|
|
.PD 0
|
|
.P
|
|
.PD
|
|
\fBcommandDDD\fR 3rd derivative of the command
|
|
|
|
.P
|
|
The PID loop calculations are as follows (see the code in pid.c for
|
|
all the nitty gritty details):
|
|
.IP
|
|
.nf
|
|
error = command - feedback
|
|
if ( abs(error) < deadband ) then error = 0
|
|
limit error to +/- maxerror
|
|
errorI += error * period
|
|
limit errorI to +/- maxerrorI
|
|
errorD = (error - previouserror) / period
|
|
limit errorD to +/- maxerrorD
|
|
commandD = (command - previouscommand) / period
|
|
limit commandD to +/- maxcmdD
|
|
commandDD = (commandD - previouscommandD) / period
|
|
limit commandDD to +/- maxcmdDD
|
|
commandDDD = (commandDD - previouscommandDD) / period
|
|
limit commandDDD to +/- maxcmdDDD
|
|
output = bias + error * Pgain + errorI * Igain +
|
|
errorD * Dgain + command * FF0 + commandD * FF1 +
|
|
commandDD * FF2 + commandDDD * FF3
|
|
limit output to +/- maxoutput
|
|
.fi
|
|
|
|
.SH NAMING
|
|
The names for pins, parameters, and functions are prefixed as:
|
|
\fBpid.N.\fR for N=0,1,...,num\-1 when using \fBnum_chan=num\fR
|
|
\fBnameN.\fR for nameN=name1,name2,... when using \fBnames=name1,name2,...\fR
|
|
|
|
The \fBpid.N.\fR format is shown in the following descriptions.
|
|
|
|
.SH FUNCTIONS
|
|
|
|
\fBpid.\fIN\fB.do\-pid\-calcs\fR (uses floating-point)
|
|
Does the PID calculations for control loop \fIN\fR.
|
|
|
|
.SH PINS
|
|
|
|
.TP
|
|
\fBpid.\fIN\fB.command\fR float in
|
|
The desired (commanded) value for the control loop.
|
|
.TP
|
|
\fBpid.\fIN\fB.Pgain\fR float in
|
|
Proportional gain. Results in a contribution to the output that is the error
|
|
multiplied by \fBPgain\fR.
|
|
.TP
|
|
\fBpid.\fIN\fB.Igain\fR float in
|
|
Integral gain. Results in a contribution to the output that is the integral
|
|
of the error multiplied by \fBIgain\fR. For example an error of 0.02 that
|
|
lasted 10 seconds would result in an integrated error (\fBerrorI\fR) of 0.2,
|
|
and if \fBIgain\fR is 20, the integral term would add 4.0 to the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.Dgain\fR float in
|
|
Derivative gain. Results in a contribution to the output that is the rate of
|
|
change (derivative) of the error multiplied by \fBDgain\fR. For example an
|
|
error that changed from 0.02 to 0.03 over 0.2 seconds would result in an error
|
|
derivative (\fBerrorD\fR) of of 0.05, and if \fBDgain\fR is 5, the derivative
|
|
term would add 0.25 to the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.feedback\fR float in
|
|
The actual (feedback) value, from some sensor such as an encoder.
|
|
.TP
|
|
\fBpid.\fIN\fB.output\fR float out
|
|
The output of the PID loop, which goes to some actuator such as a motor.
|
|
.TP
|
|
\fBpid.\fIN\fB.command\-deriv\fR float in
|
|
The derivative of the desired (commanded) value for the control loop. If no
|
|
signal is connected then the derivative will be estimated numerically.
|
|
.TP
|
|
\fBpid.\fIN\fB.feedback\-deriv\fR float in
|
|
The derivative of the actual (feedback) value for the control loop. If no
|
|
signal is connected then the derivative will be estimated numerically. When
|
|
the feedback is from a quantized position source (e.g., encoder feedback
|
|
position), behavior of the D term can be improved by using a better velocity
|
|
estimate here, such as the velocity output of encoder(9) or hostmot2(9).
|
|
.TP
|
|
\fBpid.\fIN\fB.error\-previous\-target\fR bit in
|
|
Use previous invocation's target vs. current position for error calculation,
|
|
like the motion controller expects. This may make torque-mode position loops
|
|
and loops requiring a large I gain easier to tune, by eliminating
|
|
velocity\-dependent following error.
|
|
.TP
|
|
\fBpid.\fIN\fB.error\fR float out
|
|
The difference between command and feedback.
|
|
.TP
|
|
\fBpid.\fIN\fB.enable\fR bit in
|
|
When true, enables the PID calculations. When false, \fBoutput\fR is zero,
|
|
and all internal integrators, etc, are reset.
|
|
.TP
|
|
\fBpid.\fIN\fB.index\-enable\fR bit in
|
|
On the falling edge of \fBindex\-enable\fR, pid does not update the
|
|
internal command derivative estimate. On systems which use the encoder
|
|
index pulse, this pin should be connected to the index\-enable signal.
|
|
When this is not done, and FF1 is nonzero, a step change in the input
|
|
command causes a single-cycle spike in the PID output. On systems which use
|
|
exactly one of the \fB\-deriv\fR inputs, this affects the D term as well.
|
|
.TP
|
|
\fBpid.\fIN\fB.bias\fR float in
|
|
\fBbias\fR is a constant amount that is added to the output. In most cases
|
|
it should be left at zero. However, it can sometimes be useful to compensate
|
|
for offsets in servo amplifiers, or to balance the weight of an object that
|
|
moves vertically. \fBbias\fR is turned off when the PID loop is disabled,
|
|
just like all other components of the output. If a non-zero output is needed
|
|
even when the PID loop is disabled, it should be added with an external HAL
|
|
sum2 block.
|
|
.TP
|
|
\fBpid.\fIN\fB.FF0\fR float in
|
|
Zero order feed-forward term. Produces a contribution to the output that is
|
|
\fBFF0\fR multiplied by the commanded value. For position loops, it should
|
|
usually be left at zero. For velocity loops, \fBFF0\fR can compensate for
|
|
friction or motor counter-EMF and may permit better tuning if used properly.
|
|
.TP
|
|
\fBpid.\fIN\fB.FF1\fR float in
|
|
First order feed-forward term. Produces a contribution to the output that
|
|
is \fBFF1\fR multiplied by the derivative of the commanded value. For
|
|
position loops, the contribution is proportional to speed, and can be used
|
|
to compensate for friction or motor CEMF. For velocity loops, it is
|
|
proportional to acceleration and can compensate for inertia. In both
|
|
cases, it can result in better tuning if used properly.
|
|
.TP
|
|
\fBpid.\fIN\fB.FF2\fR float in
|
|
Second order feed-forward term. Produces a contribution to the output that is
|
|
\fBFF2\fR multiplied by the second derivative of the commanded value. For
|
|
position loops, the contribution is proportional to acceleration, and can be
|
|
used to compensate for inertia. For velocity loops, the contribution is
|
|
proportional to jerk, and should usually be left at zero.
|
|
.TP
|
|
\fBpid.\fIN\fB.FF3\fR float in
|
|
Third order feed-forward term. Produces a contribution to the output that is
|
|
\fBFF3\fR multiplied by the third derivative of the commanded value. For
|
|
position loops, the contribution is proportional to jerk, and can be
|
|
used to compensate for residual errors during acceleration. For velocity
|
|
loops, the contribution is proportional to snap(jounce), and should usually
|
|
be left at zero.
|
|
.TP
|
|
\fBpid.\fIN\fB.deadband\fR float in
|
|
Defines a range of "acceptable" error. If the absolute value of \fBerror\fR
|
|
is less than \fBdeadband\fR, it will be treated as if the error is zero.
|
|
When using feedback devices such as encoders that are inherently quantized,
|
|
the deadband should be set slightly more than one-half count, to prevent
|
|
the control loop from hunting back and forth if the command is between two
|
|
adjacent encoder values. When the absolute value of the error is greater
|
|
than the deadband, the deadband value is subtracted from the error before
|
|
performing the loop calculations, to prevent a step in the transfer function
|
|
at the edge of the deadband. (See \fBBUGS\fR.)
|
|
.TP
|
|
\fBpid.\fIN\fB.maxoutput\fR float in
|
|
Output limit. The absolute value of the output will not be permitted
|
|
to exceed \fBmaxoutput\fR, unless \fBmaxoutput\fR is zero. When the output
|
|
is limited, the error integrator will hold instead of integrating, to prevent
|
|
windup and overshoot.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxerror\fR float in
|
|
Limit on the internal error variable used for P, I, and D. Can be used to
|
|
prevent high \fBPgain\fR values from generating large outputs under conditions
|
|
when the error is large (for example, when the command makes a step change).
|
|
Not normally needed, but can be useful when tuning non-linear systems.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxerrorD\fR float in
|
|
Limit on the error derivative. The rate of change of error used by the
|
|
\fBDgain\fR term will be limited to this value, unless the value is
|
|
zero. Can be used to limit the effect of \fBDgain\fR and prevent large
|
|
output spikes due to steps on the command and/or feedback. Not normally
|
|
needed.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxerrorI\fR float in
|
|
Limit on error integrator. The error integrator used by the \fBIgain\fR
|
|
term will be limited to this value, unless it is zero. Can be used to prevent
|
|
integrator windup and the resulting overshoot during/after sustained errors.
|
|
Not normally needed.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxcmdD\fR float in
|
|
Limit on command derivative. The command derivative used by \fBFF1\fR will
|
|
be limited to this value, unless the value is zero. Can be used to prevent
|
|
\fBFF1\fR from producing large output spikes if there is a step change on the
|
|
command. Not normally needed.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxcmdDD\fR float in
|
|
Limit on command second derivative. The command second derivative used by
|
|
\fBFF2\fR will be limited to this value, unless the value is zero. Can be
|
|
used to prevent \fBFF2\fR from producing large output spikes if there is a
|
|
step change on the command. Not normally needed.
|
|
.TP
|
|
\fBpid.\fIN\fB.maxcmdDDD\fR float in
|
|
Limit on command third derivative. The command third derivative used by
|
|
\fBFF3\fR will be limited to this value, unless the value is zero. Can be
|
|
used to prevent \fBFF3\fR from producing large output spikes if there is a
|
|
step change on the command. Not normally needed.
|
|
.TP
|
|
\fBpid.\fIN\fB.saturated\fR bit out
|
|
When true, the current PID output is saturated. That is,
|
|
.RS 12
|
|
\fBoutput\fR = \(+- \fBmaxoutput\fR.
|
|
.RE
|
|
.TP
|
|
\fBpid.\fIN\fB.saturated\-s\fR float out
|
|
.br
|
|
.ns
|
|
.TP
|
|
\fBpid.\fIN\fB.saturated\-count\fR s32 out
|
|
When true, the output of PID was continually saturated for this many seconds
|
|
(\fBsaturated\-s\fR) or periods (\fBsaturated\-count\fR).
|
|
.SH PARAMETERS
|
|
.TP
|
|
\fBpid.\fIN\fB.errorI\fR float ro (only if debug=1)
|
|
Integral of error. This is the value that is multiplied by \fBIgain\fR to produce the Integral term of the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.errorD\fR float ro (only if debug=1)
|
|
Derivative of error. This is the value that is multiplied by \fBDgain\fR to produce the Derivative term of the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.commandD\fR float ro (only if debug=1)
|
|
Derivative of command. This is the value that is multiplied by \fBFF1\fR to produce the first order feed-forward term of the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.commandDD\fR float ro (only if debug=1)
|
|
Second derivative of command. This is the value that is multiplied by
|
|
\fBFF2\fR to produce the second order feed-forward term of the output.
|
|
.TP
|
|
\fBpid.\fIN\fB.commandDDD\fR float ro (only if debug=1)
|
|
Third derivative of command. This is the value that is multiplied by
|
|
\fBFF3\fR to produce the third order feed-forward term of the output.
|
|
|
|
.SH BUGS
|
|
Some people would argue that deadband should be implemented such that error is
|
|
treated as zero if it is within the deadband, and be unmodified if it is outside
|
|
the deadband. This was not done because it would cause a step in the transfer
|
|
function equal to the size of the deadband. People who prefer that behavior are
|
|
welcome to add a parameter that will change the behavior, or to write their own
|
|
version of \fBpid\fR. However, the default behavior should not be changed.
|
|
|
|
Negative gains may lead to unwanted behavior. It is possible in some
|
|
situations that negative FF gains make sense, but in general all gains
|
|
should be positive. If some output is in the wrong direction, negating
|
|
gains to fix it is a mistake; set the scaling correctly elsewhere
|
|
instead.
|
|
|
|
.SH SEE ALSO
|
|
\fBat_pid\fR(9)
|