ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 13.06.2025
Просмотров: 4195
Скачиваний: 0
4 Control
Let us take a look at how to implement step 1. In the RoBIOS operating system there are functions available for reading encoder input and setting motor output (see Appendix B.5 and Figure 4.4).
1.Write a control subroutine
a.Read encoder data (INPUT)
b.Compute new output value R(t)
c.Set motor speed (OUTPUT)
See library.html:
int QUADRead(QuadHandle handle); |
||
Input: |
(handle) ONE decoder-handle |
|
Output: |
32bit counter-value (-2^31 .. 2^31-1) |
|
Semantics: |
Read actual Quadrature-Decoder counter, initially zero. |
|
Note: A wrong handle will ALSO result in a 0 counter value!! |
||
int MOTORDrive (MotorHandle handle,int speed); |
||
Input: |
(handle) logical-or of all MotorHandles which should be driven |
|
(speed) motor speed in percent |
||
Valid values: -100 - 100 (full backward to full forward) |
||
Output: |
0 |
for full stop |
(return code) 0 |
= ok |
|
Semantics: |
-1 |
= error wrong handle |
Set the given motors to the same given speed |
||
Figure 4.4: RoBIOS motor functions
The program code for this subroutine would then look like Program 4.1. Variable r_mot denotes the control parameter R(t). The dotted line has to be replaced by the control function “KC if vact<vdes” from Figure 4.1.
Program 4.1: Control subroutine framework
1void controller()
2{ int enc_new, r_mot, err;
3enc_new = QUADRead(enc1);
4...
5err = MOTORDrive(mot1, r_mot);
6if (err) printf(“error: motor”);
7}
Program 4.2 shows the completed control program, assuming this routine is called every 1/100 of a second.
So far we have not considered any potential problems with counter overflow or underflow. However, as the following examples will show, it turns out that overflow/underflow does still result in the correct difference values when using standard signed integers.
Overflow example from positive to negative values:
7F |
FF |
FF |
FC |
= |
+2147483644Dec |
80 |
00 |
00 |
06 |
= |
-6Dec |
54
On-Off Control
Program 4.2: On-off controller
Overflow and
underflow
1 |
int v_des; |
75 |
/* |
user input in ticks/s */ |
|
2 |
#define Kc |
/* |
const speed setting |
*/ |
|
3 |
|||||
4void onoff_controller()
5{ int enc_new, v_act, r_mot, err;
6static int enc_old;
7
8enc_new = QUADRead(enc1);
9v_act = (enc_new-enc_old) * 100;
10if (v_act < v_des) r_mot = Kc;
11 |
else r_mot = 0; |
12err = MOTORDrive(mot1, r_mot);
13if (err) printf("error: motor");
14enc_old = enc_new;
15}
The difference, second value minus first value, results in:
00 00 00 0A |
= +10Dec |
This is the correct number of encoder ticks.
Overflow Example from negative to positive values:
FF |
FF |
FF |
FD |
= |
-3Dec |
00 |
00 |
00 |
04 |
= |
+4Dec |
The difference, second value minus first value, results in +7, which is the correct number of encoder ticks.
2.Call control subroutine periodically
e.g. every 1/100 s
See library.html:
TimerHandle OSAttachTimer(int scale, TimerFnc function);
Input: |
(scale) prescale value for 100Hz Timer (1 to ...) |
Output: |
(TimerFnc) function to be called periodically |
(TimerHandle) handle to reference the IRQ-slot |
|
Semantics: |
A value of 0 indicates an error due to a full list(max. 16). |
Attach a irq-routine (void function(void)) to the irq-list. |
|
The scale parameter adjusts the call frequency (100/scale Hz) |
|
of this routine to allow many different applications. |
|
int OSDetachTimer(TimerHandle handle) |
|
Input: |
(handle) handle of a previous installed timer irq |
Output: |
0 = handle not valid |
Semantics: |
1 = function successfully removed from timer irq list |
Detach a previously installed irq-routine from the irq-list. |
|
Figure 4.5: RoBIOS timer functions
Let us take a look at how to implement step 2, using the timer functions in the RoBIOS operating system (see Appendix B.5 and Figure 4.5). There are
55
4 Control
operating system routines available to initialize a periodic timer function, to be called at certain intervals and to terminate it.
Program 4.3 shows a straightforward implementation using these routines. In the otherwise idle while-loop, any top-level user programs should be executed. In that case, the while-condition should be changed from:
while (1) /* endless loop - never returns */ to something than can actually terminate, for example:
while (KEYRead() != KEY4)
in order to check for a specific end-button to be pressed.
Program 4.3: Timer start
1int main()
2{ TimerHandle t1;
4t1 = OSAttachTimer(1, onoff_controller);
5while (1) /* endless loop - never returns */
6{ /* other tasks or idle */ }
7OSDetachTimer(t1); /* free timer, not used */
8 |
return 0; |
/* not used */ |
9 |
} |
Figure 4.6 shows a typical measurement of the step response of an on-off controller. The saw-tooth shape of the velocity curve is clearly visible.
2500 |
||||||
|
[ticks/sec] |
2000 |
|||||
1500 |
||||||
|
velocity |
1000 |
|||||
500 |
Vdesired |
|||||
Vmotor |
||||||
0 |
||||||
0.0 |
0.1 |
0.2 |
0.3 |
0.4 |
0.5 |
time [sec]
Figure 4.6: Measured step response of on-off controller
4.2 PID Control
PID = P + I + D The simplest method of control is not always the best. A more advanced controller and almost industry standard is the PID controller. It comprises a proportional, an integral, and a derivative control part. The controller parts are introduced in the following sections individually and in combined operation.
56
PID Control
4.2.1 Proportional Controller
For many control applications, the abrupt change between a fixed motor control value and zero does not result in a smooth control behavior. We can improve this by using a linear or proportional term instead. The formula for the proportional controller (P controller) is:
R(t) = KP · (vdes(t) – vact(t))
The difference between the desired and actual speed is called the “error function”. Figure 4.7 shows the schematics for the P controller, which differs only slightly from the on-off controller. Figure 4.8 shows measurements of characteristic motor speeds over time. Varying the “controller gain” KP will change the controller behavior. The higher the KP chosen, the faster the controller responds; however, a too high value will lead to an undesirable oscillating system. Therefore it is important to choose a value for KP that guarantees a fast response but does not lead the control system to overshoot too much or even oscillate.
desired speed |
actual speed |
||||||||
* KP |
Motor |
||||||||
encoder |
|||||||||
subtract |
|||||||||
measurement |
|||||||||
feedback
Figure 4.7: Proportional controller
Vdesired
6000 |
Vmotor Kp = 0.85 |
|||||
Vmotor Kp = 0.45 |
||||||
Vmotor Kp = 0.20 |
||||||
Vmotor Kp = 0.15 |
||||||
|
[ticks/sec] |
4000 |
|||||
|
velocity |
2000 |
|||||
0 |
||||||
0.0 |
0.1 |
0.2 |
0.3 |
0.4 |
0.5 |
time [sec]
Figure 4.8: Step response for proportional controller
Steady state error
Note that the P controller’s equilibrium state is not at the desired velocity. If the desired speed is reached exactly, the motor output is reduced to zero, as
57
4 Control
defined in the P controller formula shown above. Therefore, each P controller will keep a certain “steady-state error” from the desired velocity, depending on the controller gain KP. As can be seen in Figure 4.8, the higher the gain KP, the lower the steady-state error. However, the system starts to oscillate if the selected gain is too high.
Program 4.4 shows the brief P controller code that can be inserted into the control frame of Program 4.1, in order to form a complete program.
Program 4.4: P controller code
1 |
e_func |
= |
v_des - v_act; |
/* |
error |
function */ |
2 |
r_mot |
= |
Kp*e_func; |
/* |
motor |
output */ |
4.2.2 Integral Controller
Unlike the P controller, the I controller (integral controller) is rarely used alone, but mostly in combination with the P or PD controller. The idea for the I controller is to reduce the steady-state error of the P controller. With an additional integral term, this steady-state error can be reduced to zero, as seen in the measurements in Figure 4.9. The equilibrium state is reached somewhat later than with a pure P controller, but the steady-state error has been eliminated.
4500 |
||||||
4000 |
||||||
3500 |
||||||
|
[ticks/sec] |
3000 |
|||||
2500 |
||||||
2000 |
||||||
|
velocity |
||||||
1500 |
Vdesired |
|||||
1000 |
||||||
500 |
P control only (Kp=0.2) |
|||||
PI control (Kp=0.2 KI=0.05) |
||||||
0 |
||||||
0.0 |
0.1 |
0.2 |
0.3 |
0.4 |
0.5 |
|
time [sec]
Figure 4.9: Step response for integral controller
When using e(t) as the error function, the formula for the PI controller is: R(t) = KP · [ e(t) + 1/TI · 0³t e(t)dt ]
We rewrite this formula by substituting QI = KP/TI, so we receive independent additive terms for P and I:
R(t) = KP · e(t) + QI · 0³t e(t)dt
58