CCS does not monitor this forum on a regular basis. Please do not post bug Reports on this forum. Send them to support@ccsinfo.com
Author Message
wangine

Joined: 07 Jul 2009
Posts: 96
Location: Curtea de Arges, Romania

Dynamic autotune a regular PID
Posted: Sun Nov 08, 2015 10:03 pm

PID,PID,PID i hate so much this simple closed loop, i don't know if i can say algorithm but to control temperature or light or a simple stuff, it is enough. The problems come when you try to calculate terms or to change
room, sensor response and its so hard to make that loop to work reasonably. One of big problems is the overshoot and when you need a small resolution.
I search in last several days for autotune PID and sincerely as friend google became tired of me. I found some explanations and libraries mostly made for Arduino. I researched step by step, first time i see it's complicated, after some hours it became very simple, and no reasonable functions have been made just for Beginnerâ€™s and is no more than a regular PID in 2 steps (hard tune and normal tune). Finally i decide to think by myself. I lost too much time searching and i was too fogged to think . The first result, but its not very great, was trying to implement in a regular PID a Trapezoidal approximation rule.
Trapezoidal approximation just as reference, not for use, the result became nasty in some conditions with a BIG overshoot.
 Code: /*  *  T approximation => T = e(n) - e(n-1) / where e(n) is sample time  *  u(n) actual sample output(_output) , u(n-1) => _1st_temp , u(n-2) => _2st_temp  *  u(n-2) last 2 out sample (_2out_temp)  */ void trapez_appr(float _kp, float _ki, float _kd) {   unsigned int32 T;     static unsigned int32 temp_T;     float K1, K2, K3, err; //~~~~~~~~~~~~~~ get T ~~~~~~~~~~~~     T = temp_T - get_ticks(); //~~~~~~~~~~~~~~compute K1,K2,K3~~~~~~~~~     K1 = _kp + (2 * _kd/T) + (_ki * T/2);     K2 = _ki * T - (4*_kd/T);     K3 = (2*_kd/T) - _kp + (_ki*T/2); //~~~~~~~~~~~~~~        _output = _2out_temp + (K1*_input) + (K2*_1st_temp) + (K3*_2st_temp); //~~~~~~~~~~~~~~ remember inputs and time ~~~~~~~~     _2st_temp = _1st_temp;     _1st_temp = _input;     temp_T         = T; //~~~~~~~~~~~~~~ remember last 2 outputs~~~~~~~~~~     CLAMP(_output,0,500);     _2out_temp = _1out_temp;     _1out_temp = _output;    }

After some testing in real world and some days later, i found a simple and good solution, changing different rooms with different temperature sources. The tricky part is when temperature away from setpoint to modify the terms of PID, kp, ki, kd, without triggering an overshoot or to give a hard confusion to loop.
ATTENTION below function is not a PID controller, is a dynamic tune of PID terms according with input-output of a real controller and must be called at the end of each PID loop. This works with all PID codes, because the math formula is the same.

 Code: /*********************************************************************   Writer Tanase Bogdan   (c) copyright www.wangine.ro   ALL RIGHTS RESERVED   ********************************************************************  Ver 0.2 release 01/noiembrie/2015 ********************************************************************/ float kp=4f, ki=0.2f, kd=1f; #define enough(_abs, _min, _max) (_abs = ((_abs > _max) ? _max : ((_abs < _min) ? _min : _abs))) float _abs_osc = 0.2f; // how fast to move, between 0.1 & 0.8 is enouth void auto_tune() {     static float temp_gap;     float temp, temp1;    if (Kp<1 || Ki<0.05 || Kd<0.25)            {kp=1f, ki=0.05f, kd=0.25f;                return;}// normal conserv terms tune    if (Kp>8 || Ki>0.5 || Kd>2)           {kp=8f, ki=0.5f, kd=2f;                return;}// hard aggressive terms tune //~~~~~~~~~~~~~~~after this will become exp then limit~~~~~~~~~~~~~~~~~~~          float gap = abs(Setpoint-intrare); //verifica distanta fata de setpoint             gap *= _abs_osc;    // not so hard             temp = gap - temp_gap; //~~~~~~~~~~~~ limit some kamikaze~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~             enouth(temp,-0.8f,0.8f);    kp += (temp)*2;    kd += (temp)/2;    ki += (temp)/8; //~~~~~~~~~~~~~~ remember some for next~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~    temp_gap = gap;    }

And some tests with real sensors, force the controller to give an overshoot, extremely heating the sensor. I can't put too much collected data, without become annoying in post. The output<iesire> it's for PWM controller min/max 0-500. After first start of controller, as soon as the setpoint was reached, the function will start to tune the PID controller.
 Code: actual 29.91 setpoint 30.00 kp 1.000000 ki 0.050000 kd 0.250000 iesire 0.00 actual 29.76 setpoint 30.00 kp 1.016003 ki 0.051000 kd 0.254000 iesire 0.24 actual 29.63 setpoint 30.00 kp 1.256005 ki 0.066000 kd 0.314001 iesire 1.07 actual 29.50 setpoint 30.00 kp 1.480005 ki 0.080000 kd 0.370001 iesire 2.55 actual 29.36 setpoint 30.00 kp 1.688000 ki 0.093000 kd 0.422000 iesire 4.75 actual 29.24 setpoint 30.00 kp 1.912000 ki 0.107000 kd 0.478000 iesire 7.94 actual 29.11 setpoint 30.00 kp 2.104004 ki 0.119000 kd 0.526001 iesire 12.02 actual 29.00 setpoint 30.00 kp 2.296008 ki 0.131000 kd 0.574002 iesire 17.17 actual 28.86 setpoint 30.00 kp 2.488001 ki 0.143000 kd 0.622000 iesire 23.50 actual 28.76 setpoint 30.00 kp 2.696008 ki 0.156000 kd 0.674002 iesire 31.28 actual 28.64 setpoint 30.00 kp 2.871997 ki 0.166999 kd 0.717999 iesire 40.29 actual 28.54 setpoint 30.00 kp 3.064002 ki 0.179000 kd 0.766000 iesire 50.88 actual 28.41 setpoint 30.00 kp 3.223999 ki 0.189000 kd 0.805999 iesire 62.73 actual 28.32 setpoint 30.00 kp 3.416003 ki 0.201000 kd 0.854000 iesire 76.44 actual 28.21 setpoint 30.00 kp 3.576001 ki 0.211000 kd 0.894000 iesire 91.58 actual 28.11 setpoint 30.00 kp 3.752002 ki 0.222000 kd 0.938000 iesire 108.59 actual 28.01 setpoint 30.00 kp 3.896008 ki 0.231000 kd 0.974002 iesire 127.00 actual 27.91 setpoint 30.00 kp 4.056007 ki 0.241000 kd 1.014001 iesire 147.27 actual 27.83 setpoint 30.00 kp 4.216004 ki 0.251000 kd 1.054001 iesire 169.41 actual 27.72 setpoint 30.00 kp 4.359998 ki 0.259999 kd 1.089999 iesire 193.24 actual 27.64 setpoint 30.00 kp 4.520008 ki 0.270000 kd 1.130002 iesire 219.17 actual 27.54 setpoint 30.00 kp 4.664003 ki 0.279000 kd 1.166000 iesire 246.91 actual 27.47 setpoint 30.00 kp 4.808009 ki 0.288000 kd 1.202002 iesire 276.61 actual 27.54 setpoint 30.00 kp 4.920009 ki 0.295000 kd 1.230002 iesire 307.71 actual 27.90 setpoint 30.00 kp 4.824000 ki 0.289000 kd 1.206000 iesire 336.33 actual 28.44 setpoint 30.00 kp 4.247999 ki 0.252999 kd 1.061999 iesire 355.16 actual 29.05 setpoint 30.00 kp 3.368007 ki 0.198000 kd 0.842001 iesire 364.05 actual 29.68 setpoint 30.00 kp 2.392005 ki 0.137000 kd 0.598001 iesire 366.36 actual 30.24 setpoint 30.00 kp 1.384009 ki 0.074000 kd 0.346002 iesire 365.48 actual 30.82 setpoint 30.00 kp 1.271998 ki 0.066999 kd 0.317999 iesire 364.08 actual 31.40 setpoint 30.00 kp 2.200001 ki 0.125000 kd 0.550000 iesire 358.38 actual 32.03 setpoint 30.00 kp 3.143995 ki 0.183999 kd 0.785998 iesire 345.12 actual 32.72 setpoint 30.00 kp 4.136000 ki 0.246000 kd 1.034000 iesire 320.68 actual 33.39 setpoint 30.00 kp 5.255995 ki 0.315999 kd 1.313998 iesire 279.36 actual 34.00 setpoint 30.00 kp 6.312002 ki 0.382000 kd 1.578000 iesire 219.22 actual 34.57 setpoint 30.00 kp 7.288002 ki 0.443000 kd 1.822000 iesire 138.81 actual 35.08 setpoint 30.00 kp 8.000000 ki 0.500000 kd 2.000000 iesire 37.72 actual 35.50 setpoint 30.00 kp 8.000000 ki 0.500000 kd 2.000000 iesire 0.00
 Display posts from previous: All Posts1 Day7 Days2 Weeks1 Month3 Months6 Months1 Year Oldest FirstNewest First
 All times are GMT - 6 Hours Page 1 of 1

 Jump to: Select a forum Software----------------General CCS C DiscussionCode LibraryEZ App LynxBest Of Hardware----------------CCS ICD / Mach X / Load-n-Go
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum