error signal. The function returns the control effort for later
use. The PID controller's code looks as follows:
float acPidController(float var_k, float theta_,
float kp_, float ki_, float kd_,
float dt_)
{
// Implement controller
derivativeValue = acDerivate(var_k, dt_);
integralValue = acIntegrate(var_k, dt_);
controlEffort = kp_*var_k +
ki_*integralValue +
kd_*derivativeValue;
return controlEffort;
}
This function is pretty much returning u = Kp e + Ki *
acIntegrate(e,0.001) + Kp acDerivate(e,0.001), where Kp
* e is the proportional controller. Next, we have the integral
controller and its code looks as follows:
float acIntegrate(float var_k,float dt_)
{
static float area = 0; // Signal area
float delta_area = 0;
// Sample at time k-1
static float var_k_1 = 0;
// Use Tustin's rule to integrate
delta_area = ( var_k_1 + var_k ) dt_ / 2.0;
area += delta_area;
// Update samples
var_k_1 = var_k;
return area;
}
This function integrates the error signal using Tustin's
rule, a numeric integration technique. The idea behind it is
to find the area under the error's curve. Assuming we have
an error signal as shown in Figure 7, the area at time t is
calculated using Equation 3:
A = A + ∆A
t t−1 t
Delta area may be estimated using the area of a trapezoid given by Equation 4, where T is the sampling period:
(B + b)×h (e + e )×T
∆A = = t−1 t
t
22
The final term in the PID is the derivate controller. Its
code looks as follows:
float acDerivate(float var_k,float dt_)
{
float dV_dt = 0;
static float var_k_1 = 0;// Sample at time k-1
dV_dt = (var_k - var_k_1) / dt_;
return dV_dt;
}
This function takes the derivative of the error signal
using the discrete approximation shown in Equation 5.
main()
runAeroPendubotController()
Device
Initialization
Routine
Read Encoders
and ref
Calculate Error
e ref
Calculate Control Effort
u = acPidController(e, ,Kp, Ki, Kd, T)
Compensate Friction
U1 = uBias1 + u
Activate Motor
acCtrlEffortMotor1(U1)
■ FIGURE 6.
Software flow diagram.
Here, we approximate the rate of chance of the error within
period T:
d e −e
e(t ) ≈
t t−1
dt T
Tuning The Controller
Once the code is up and running, we need to find the
right values for the control effort bias and the Kp, Ki, and
Kd gains. There are many methods to determine good gain
values. We used Zigler and Nichols method as a guideline.
The first gain we tuned was Kp. Once we got a steady
response, we increased Ki to eliminate the steady state
error. Our final results — for a set point of 0.08 radians —
are shown in Figure 8.
The controller we tuned responds pretty well for a set
point of 0.08, however, it becomes unstable for other set
points. Figure 9 shows a stability graph where unstable set
points are represented by zeros
and the stable set
points are represented by ones.
Tuning servo
controllers is an
art. When tuning
a PID controller,
you must know
the system really
■ FIGURE 7.
Error signal.
SERVO 02.2009
55