www.pudn.com > truetime-1.2-compiled.zip > threeservos_init.cpp
// Task scheduling and control.
//
// This example extends the simple PID control example (located in
// $DIR/examples/simple_pid) to the case of three PID-tasks running
// concurrently on the same CPU controlling three different servo
// systems. The effect of the scheduling policy on the global control
// performance is demonstrated.
#define S_FUNCTION_NAME threeservos_init
#include "ttkernel.cpp"
// PID data structure
class PID_Data {
public:
struct { // states
double u, Iold, Dold, yold;
} s;
struct { // params
double K, Ti, Td, N, h;
int rChan, yChan, uChan;
} p;
};
// calculate PID control signal and update states
void pidcalc(PID_Data* d, double r, double y) {
double P = d->p.K*(r-y);
double I = d->s.Iold;
double D = d->p.Td/(d->p.N*d->p.h+d->p.Td)*d->s.Dold+d->p.N*d->p.K*d->p.Td/(d->p.N*d->p.h+d->p.Td)*(d->s.yold-y);
d->s.u = P + I + D;
d->s.Iold = d->s.Iold + d->p.K*d->p.h/d->p.Ti*(r-y);
d->s.Dold = D;
d->s.yold = y;
};
// --------- Generic code function ----------
double pidcode(int seg, void* data) {
PID_Data* d = (PID_Data*) data;
switch (seg) {
case 1:
pidcalc(d, ttAnalogIn(d->p.rChan), ttAnalogIn(d->p.yChan));
return 0.002;
case 2:
ttAnalogOut(d->p.uChan, d->s.u);
return FINISHED;
}
}
#define NBROFINPUTS 6
#define NBROFOUTPUTS 3
#define SCHEDULER RM
// Task parameters
double periods[] = {0.006, 0.005, 0.004};
char* names[] = {"pid_task1", "pid_task2", "pid_task3"};
int rChans[] = {1, 3, 5};
int yChans[] = {2, 4, 6};
int uChans[] = {1, 2, 3};
PID_Data *d[3];
void init() {
// Initialize TrueTime kernel
ttInitKernel(NBROFINPUTS, NBROFOUTPUTS, SCHEDULER);
// Create the three tasks
for (int i = 0; i < 3; i++) {
d[i] = new PID_Data;
d[i]->p.K = 0.96;
d[i]->p.Ti = 0.12;
d[i]->p.Td = 0.049;
d[i]->p.N = 10;
d[i]->p.h = periods[i];
d[i]->s.u = 0.0;
d[i]->s.Iold = 0.0;
d[i]->s.Dold = 0.0;
d[i]->s.yold = 0.0;
d[i]->p.rChan = rChans[i];
d[i]->p.yChan = yChans[i];
d[i]->p.uChan = uChans[i];
// Offset=0 and prio=1 for all tasks
ttCreatePeriodicTask(names[i], 0.0, periods[i], 1.0, pidcode, d[i]);
}
}
void cleanup() {
for (int i = 0; i < 3; i++) {
delete d[i];
}
}