rllib  1
rlcontroller.cpp
Go to the documentation of this file.
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