|
rllib
1
|
00001 /*************************************************************************** 00002 rlcontroller.cpp - description 00003 ------------------- 00004 begin : Wed Jun 16 2004 00005 copyright : (C) 2004 by Rainer Lehrig 00006 email : lehrig@t-online.de 00007 ***************************************************************************/ 00008 00009 /*************************************************************************** 00010 * * 00011 * This library is free software; you can redistribute it and/or modify * 00012 * it under the terms of the GNU LESSER GENERAL PUBLIC LICENSE as * 00013 * published by the Free Software Foundation * 00014 * * 00015 ***************************************************************************/ 00016 #include "rlcontroller.h" 00017 00018 static void *control(void *arg) 00019 { 00020 THREAD_PARAM *p = (THREAD_PARAM *) arg; 00021 rlController *c = (rlController *) p->user; 00022 while(c->running == 1) 00023 { 00024 if(c->sleepLocally) rlsleep(c->dt); 00025 c->measurement = c->getMeasurement(); 00026 c->lock(); // lock mutex because user might set another controller type 00027 c->ydk_1 = c->ydk; 00028 c->y1k_1 = c->y1k; 00029 c->yk_2 = c->yk_1; 00030 c->yk_1 = c->yk; 00031 c->ek_2 = c->ek_1; 00032 c->ek_1 = c->ek; 00033 c->ek = c->reference - c->measurement; 00034 switch(c->type) 00035 { 00036 case rlController::P: 00037 c->yk = c->d0*c->ek; 00038 break; 00039 case rlController::I: 00040 case rlController::D_T1: 00041 case rlController::PI: 00042 case rlController::PD_T1: 00043 c->yk = c->d0*c->ek + c->d1*c->ek_1 + c->c1*c->yk_1; 00044 break; 00045 case rlController::PID_T1: 00046 c->yk = c->d0*c->ek + c->d1*c->ek_1 + c->d2*c->ek_2 + c->c1*c->yk_1 + c->c2*c->yk_2; 00047 break; 00048 case rlController::PI_SUM: 00049 c->yk = c->Kp*c->ek + c->y1k; 00050 c->y1k = c->y1k_1 + c->d1*(c->ek+c->ek_1); 00051 break; 00052 case rlController::PD_T1_SUM: 00053 c->yk = c->Kp*c->ek + c->ydk; 00054 c->ydk = c->cD*c->ydk_1 + c->dD*(c->ek-c->ek_1); 00055 break; 00056 case rlController::PID_T1_SUM: 00057 c->yk = c->Kp*c->ek + c->y1k + c->ydk; 00058 c->y1k = c->y1k_1 + c->d1*(c->ek+c->ek_1); 00059 c->ydk = c->cD*c->ydk_1 + c->dD*(c->ek-c->ek_1); 00060 break; 00061 default: 00062 break; 00063 } 00064 c->unlock(); 00065 c->writeOutput(c->yk); 00066 } 00067 return arg; 00068 } 00069 00070 rlController::rlController(double (*_getMeasurement)() ,void (_writeOutput)(double output)) 00071 :rlThread() 00072 { 00073 type = -1; 00074 running = 0; 00075 getMeasurement = _getMeasurement; 00076 writeOutput = _writeOutput; 00077 ydk_1 = 0.0f; 00078 ydk = 0.0f; 00079 y1k_1 = 0.0f; 00080 y1k = 0.0f; 00081 yk_2 = 0.0f; 00082 yk_1 = 0.0f; 00083 yk = 0.0f; 00084 ek_2 = 0.0f; 00085 ek_1 = 0.0f; 00086 ek = 0.0f; 00087 reference = measurement = 0.0; 00088 sleepLocally = 1; 00089 } 00090 00091 rlController::~rlController() 00092 { 00093 stop(); 00094 } 00095 00096 void rlController::start() 00097 { 00098 running = 1; 00099 ydk_1 = 0.0f; 00100 ydk = 0.0f; 00101 y1k_1 = 0.0f; 00102 y1k = 0.0f; 00103 yk_2 = 0.0f; 00104 yk_1 = 0.0f; 00105 yk = 0.0f; 00106 ek_2 = 0.0f; 00107 ek_1 = 0.0f; 00108 ek = 0.0f; 00109 rlThread::create(control,this); 00110 } 00111 00112 void rlController::stop() 00113 { 00114 if(running) rlThread::cancel(); 00115 running = 0; 00116 } 00117 00118 void rlController::setReference(double _reference) 00119 { 00120 reference = _reference; 00121 } 00122 00123 void rlController::setP(double _T, double _Kp) 00124 { 00125 rlThread::lock(); 00126 type = P; 00127 T = _T; 00128 Kp = _Kp; 00129 dt = (int) (1000.0 * T); 00130 d0 = Kp; 00131 rlThread::unlock(); 00132 } 00133 00134 void rlController::setI(double _T, double _T1) 00135 { 00136 rlThread::lock(); 00137 type = I; 00138 T = _T; 00139 T1 = _T1; 00140 dt = (int) (1000.0 * T); 00141 d0 = T/(2.0*T1); 00142 d1 = T/(2.0*T1); 00143 c1 = 1.0; 00144 rlThread::unlock(); 00145 } 00146 00147 void rlController::setD_T1(double _T, double _TD, double _Td) 00148 { 00149 rlThread::lock(); 00150 type = D_T1; 00151 T = _T; 00152 TD = _TD; 00153 Td = _Td; 00154 dt = (int) (1000.0 * T); 00155 d0 = TD / (Td + T/2.0); 00156 d1 = -TD / (Td + T/2.0); 00157 c1 = (Td-T/2.0)/(Td+T/2.0); 00158 rlThread::unlock(); 00159 } 00160 00161 void rlController::setPI(double _T, double _Kp, double _Tn) 00162 { 00163 rlThread::lock(); 00164 type = PI; 00165 T = _T; 00166 Kp = _Kp; 00167 Tn = _Tn; 00168 dt = (int) (1000.0 * T); 00169 d0 = Kp * (Tn+T/2.0) / Tn; 00170 d1 = -Kp * (Tn - T/2.0) / Tn; 00171 c1 = 1.0; 00172 rlThread::unlock(); 00173 } 00174 00175 void rlController::setPD_T1(double _T, double _Kp, double _TvP, double _Td) 00176 { 00177 rlThread::lock(); 00178 type = PD_T1; 00179 T = _T; 00180 Kp = _Kp; 00181 TvP = _TvP; 00182 Td = _Td; 00183 dt = (int) (1000.0 * T); 00184 d0 = Kp * (TvP+T/2.0) / (Td + T/2.0); 00185 d1 = -Kp * (TvP - T/2.0) / (Td + T/2.0); 00186 c1 = (Td - T/2.0)/(Td + T/2.0); 00187 rlThread::unlock(); 00188 } 00189 00190 void rlController::setPID_T1(double _T, double _Kpp, double _TnP, double _TvP, double _Td) 00191 { 00192 rlThread::lock(); 00193 type = PID_T1; 00194 T = _T; 00195 Kpp = _Kpp; 00196 TnP = _TnP; 00197 TvP = _TvP; 00198 Td = _Td; 00199 dt = (int) (1000.0 * T); 00200 d0 = Kpp * ((TnP+T/2.0) / TnP) * ((TvP+T/2.0))/(Td+T/2.0); 00201 d1 = -2.0*Kpp * (TnP*TvP - (T/2.0)*(T/2.0)) / (TnP*(Td+T/2.0)); 00202 d2 = Kpp*((TnP-T/2.0)/TnP)*((TvP-T/2.0)/(Td+T/2.0)); 00203 c1 = 2*Td/(Td+T/2.0); 00204 c2 = -(Td-T/2.0)/(Td+T/2.0); 00205 rlThread::unlock(); 00206 } 00207 00208 void rlController::setPI_SUM(double _T, double _Kp, double _Tn) 00209 { 00210 rlThread::lock(); 00211 type = PI_SUM; 00212 T = _T; 00213 Kp = _Kp; 00214 Tn = _Tn; 00215 dt = (int) (1000.0 * T); 00216 d1 = Kp * (T/2.0)/Tn; 00217 rlThread::unlock(); 00218 } 00219 00220 void rlController::setPD_T1_SUM(double _T, double _Kp, double _Tv, double _Td) 00221 { 00222 rlThread::lock(); 00223 type = PD_T1_SUM; 00224 T = _T; 00225 Kp = _Kp; 00226 Tv = _Tv; 00227 Td = _Td; 00228 dt = (int) (1000.0 * T); 00229 dD = Kp * (Tv/(Td+T/2.0)); 00230 cD = (Td-T/2.0)/(Td+T/2.0); 00231 rlThread::unlock(); 00232 } 00233 00234 void rlController::setPID_T1_SUM(double _T, double _Kp, double _Tn, double _Tv, double _Td) 00235 { 00236 rlThread::lock(); 00237 type = PID_T1_SUM; 00238 T = _T; 00239 Kp = _Kp; 00240 Tn = _Tn; 00241 Tv = _Tv; 00242 Td = _Td; 00243 dt = (int) (1000.0 * T); 00244 d1 = Kp*T/(2.0*Tn); 00245 dD = Kp * (Tv/(Td+T/2.0)); 00246 cD = (Td-T/2.0)/(Td+T/2.0); 00247 rlThread::unlock(); 00248 } 00249
1.7.5.1