?? servo_init.cpp
字號(hào):
// PID-control of a DC servo process.//// This example shows four ways to implement a periodic controller// activity in TrueTime. The task implements a standard// PID-controller to control a DC-servo process (2nd order system). #define S_FUNCTION_NAME servo_init#include "ttkernel.cpp"// PID data structure used in Implementations 1a, 2, and 3 below.class PID_Data {public: struct { // states double u, Iold, Dold, yold, t; // t used only in Implementation 2 below } s; struct { // params double K, Ti, Td, N, h; int rChan, yChan, uChan; } p;};// calculate PID control signal and update statesvoid 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;};// Variables used in Implementation 1b below.const int nInp = 2; // nbr of inputs to controller block const int nOutp = 2; // nbr of outputs to controller block static double inp[] = {0.0, 0.0}; // block inputs static double outp[] = {0.0, 0.0}; // block outputs // ---- PID code function for Implementation 1a ----double pidcode1(int seg, void* data) { double r, y; PID_Data* d = (PID_Data*) data; switch (seg) { case 1: r = ttAnalogIn(d->p.rChan); y = ttAnalogIn(d->p.yChan); pidcalc(d, r, y); return 0.002; case 2: ttAnalogOut(d->p.uChan, d->s.u); return FINISHED; }}// ---- PID code function for Implementation 1b ----double blockcode(int seg, void* data) { switch (seg) { case 1: inp[0] = ttAnalogIn(1); inp[1] = ttAnalogIn(2); ttCallBlockSystem(nOutp, outp, nInp, inp, "controller"); return outp[1]; // execution time returned from block case 2: ttAnalogOut(1, outp[0]); return FINISHED; }}// ---- PID code function for Implementation 2 ----double pidcode2(int seg, void* data) { double r, y; PID_Data* d = (PID_Data*) data; switch (seg) { case 1: d->s.t = ttCurrentTime(); return 0.0; case 2: r = ttAnalogIn(d->p.rChan); y = ttAnalogIn(d->p.yChan); pidcalc(d, r, y); return 0.002; case 3: ttAnalogOut(d->p.uChan, d->s.u); // Sleep d->s.t += d->p.h; ttSleepUntil(d->s.t); return 0.0; case 4: ttSetNextSegment(2); // loop return 0.0; }}// ---- PID code function for Implementation 3 ----double pidcode3(int seg, void* data) { double r; double *y; PID_Data* d = (PID_Data*) data; switch (seg) { case 1: r = ttAnalogIn(d->p.rChan); y = (double*) ttTryFetch("Samples"); pidcalc(d, r, *y); delete y; return 0.0018; case 2: ttAnalogOut(d->p.uChan, d->s.u); return FINISHED; }}// ---- Sampler code function for Implementation 3 ----double samplercode(int seg, void* data) { double y; int* d = (int*) data; switch (seg) { case 1: y = ttAnalogIn(*d); ttTryPost("Samples", new double(y)); // put sample in mailbox ttCreateJob("pid_task"); // trigger task job return 0.0002; case 2: return FINISHED; }}#define NBROFINPUTS 2#define NBROFOUTPUTS 1#define SCHEDULER FPPID_Data *d;double *d2 = NULL;int *hdl_data = NULL;void init() { // Initialize TrueTime kernel ttInitKernel(NBROFINPUTS, NBROFOUTPUTS, SCHEDULER); // Task attributes double period = 0.006; double deadline = period; double offset = 0.0; // start of first task instance double prio = 1.0; // Create task data (local memory) d = new PID_Data; d->p.K = 0.96; d->p.Ti = 0.12; d->p.Td = 0.049; d->p.N = 10.0; d->p.h = period; d->s.u = 0.0; d->s.t = 0.0; // only used in Implementation 2 below d->s.Iold = 0.0; d->s.Dold = 0.0; d->s.yold = 0.0; d->p.rChan = 1; d->p.yChan = 2; d->p.uChan = 1; // IMPLEMENTATION 1a: using the built-in support for periodic tasks // ttCreatePeriodicTask("pid_task", offset, period, prio, pidcode1, d); // IMPLEMENTATION 1b: calling Simulink block within code function // // d2 = new double(0.0); // Only the control signal needs to be // stored between segments. Controller // states are stored internally by TrueTime. // ttCreatePeriodicTask("pid_task", offset, period, prio, blockcode, d2); // IMPLEMENTATION 2: sleepUntil and loop back // // ttCreateTask("pid_task", deadline, prio, pidcode2, d); // ttCreateJob("pid_task"); // IMPLEMENTATION 3: sampling in timer handler, triggers task job // // hdl_data = new int(2); // y_chan for reading samples // ttCreateInterruptHandler("timer_handler", prio, samplercode, hdl_data); // ttCreatePeriodicTimer("timer", offset, period, "timer_handler"); // // ttCreateMailbox("Samples", 10); // // ttCreateTask("pid_task", deadline, prio, pidcode3, d);}void cleanup() { delete d; if (d2) delete d2; if (hdl_data) delete hdl_data;}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -