PIFFController.c
Go to the documentation of this file.
00001 /*********************************************************************
00002 * Software License Agreement (BSD License)
00003 *
00004 *  Copyright (c) 2010, LABUST, UNIZG-FER
00005 *  All rights reserved.
00006 *
00007 *  Redistribution and use in source and binary forms, with or without
00008 *  modification, are permitted provided that the following conditions
00009 *  are met:
00010 *
00011 *   * Redistributions of source code must retain the above copyright
00012 *     notice, this list of conditions and the following disclaimer.
00013 *   * Redistributions in binary form must reproduce the above
00014 *     copyright notice, this list of conditions and the following
00015 *     disclaimer in the documentation and/or other materials provided
00016 *     with the distribution.
00017 *   * Neither the name of the LABUST nor the names of its
00018 *     contributors may be used to endorse or promote products derived
00019 *     from this software without specific prior written permission.
00020 *
00021 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00022 *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00023 *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00024 *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00025 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00026 *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00027 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00028 *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00029 *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00030 *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00031 *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00032 *  POSSIBILITY OF SUCH DAMAGE.
00033 *********************************************************************/
00034 #include <labust/control/PIFFController.h>
00035 #include <labust/math/NumberManipulation.hpp>
00036 #include <math.h>
00037 #include <ros/ros.h>
00038 
00039 void PIFF_modelTune(PIDBase* self,
00040                 const PT1Model* const model,
00041                 float w, float a)
00042 {
00043         self->Kp = 2*w*model->alpha-model->beta;
00044         self->Kd = self->Kt = self->Tf = 0;
00045         self->Ki = model->alpha*w*w;
00046 
00047         //The empirical parameter for overshoot ~5%
00048         self->b = a*self->Ki/(self->Kp*w);
00049         ROS_ERROR("b-value dyn: %f %f",self->b,w);
00050         //self->b = 1;
00051 
00052         self->model.alpha = model->alpha;
00053         self->model.beta = model->beta;
00054         self->model.betaa = model->betaa;
00055 
00056         self->w = w;
00057 }
00058 
00059 void PIFF_tune(PIDBase* self, float w, float a)
00060 {
00061         self->Kp = 2*w;
00062         self->Ki = w*w;
00063         self->Kd = self->Kt = self->Tf = 0;
00064         //The empirical parameter for overshoot ~5%
00065         self->b = a*self->Ki/(self->Kp*w);
00066         //self->b = 1;
00067         ROS_ERROR("b-value kin: %f %f",self->b,w);
00068 
00069         self->w = w;
00070 }
00071 
00072 void PIFF_wffIdle(PIDBase* self, float Ts, float error, float perror, float ff)
00073 {
00074         self->lastError = error;
00075         self->lastPError = perror;
00076         self->lastRef = self->desired;
00077         self->lastFF = ff;
00078         self->lastState = self->state;
00079         self->internalState = self->Kp*perror;
00080         self->internalState += ff;
00081         self->I = self->track - self->internalState;
00082         self->output = self->internalState = self->track;
00083 }
00084 
00085 //void PIFF_wffStep(PIDBase* self, float Ts, float error, float perror, float ff)
00086 //{
00087 //      //Perform windup test if automatic mode is enabled.
00088 //      if (self->autoWindup == 1)
00089 //      {
00090 //              self->windup = (self->internalState > self->output) && (error>0);
00091 //              self->windup = (self->windup) ||
00092 //                              ((self->internalState < self->output) && (error<0));
00093 //      }
00094 //      else
00095 //      {
00096 //              //Experimental
00097 //              //self->windup = ((self->windup >0) && (error>0)) ||
00098 //              //              ((self->windup <0) && (error<0));
00099 //      }
00100 //
00101 //      //Proportional term
00102 //      self->internalState += self->Kp*(error-self->lastError);
00103 //      //Integral term
00104 //      //Disabled if windup is in progress.
00105 //  if (!self->windup) self->internalState += self->Ki*Ts*error;
00106 //  //Derivative
00107 // // self->internalState += self->Kd*1/Ts*(error-2*self->lastError+self->llastError);
00108 //      //Feed forward term
00109 //     self->internalState += ff - self->lastFF;
00110 //      //Set final output
00111 //      self->output = self->internalState;
00112 //
00113 //      if (self->autoWindup == 1)
00114 //      {
00115 //              self->output = sat(self->output,-self->outputLimit, self->outputLimit);
00116 //      }
00117 //
00118 //      self->llastError = self->lastError;
00119 //      self->lastError = error;
00120 //      self->lastRef = self->desired;
00121 //      self->lastFF = ff;
00122 //}
00123 
00124 void PIFF_wffStep(PIDBase* self, float Ts, float error, float perror, float ff)
00125 {
00126         //Perform windup test if automatic mode is enabled.
00127         if (self->autoWindup == 1)
00128         {
00129                 //self->windup = (self->internalState > self->output) && (error>0);
00130                 //self->windup = (self->windup) ||
00131                 //              ((self->internalState < self->output) && (error<0));
00132                 //Set the wind-up sign for cascade controllers.
00134                 self->track = self->output;
00135                 self->windup = (self->internalState != self->track) && (error*self->track > 0);
00136         }
00137         else
00138         {
00139                 //Experimental
00140                 /*self->windup = ((self->extWindup > 0) && (error > 0)) ||
00141                                 ((self->extWindup < 0) && (error < 0));*/
00142                 //Experimental 2
00143                 self->windup = (self->extWindup && (error*self->output > 0));
00144         }
00145 
00146         //Backward recalculation
00147         if ((self->lastI != 0) && self->windup && self->useBackward)
00148         {
00149                 //Calculate the proportional influence
00150                 //float diff = self->track - self->internalState + self->lastI;
00151                 //If the proportional part is already in windup remove the whole last integral
00152                 //Otherwise recalculate the integral to be on the edge of windup
00153                 //self->internalState -= ((diff*self->track <= 0)?self->lastI:(self->lastI - diff));
00154 
00155                 //self->I = self->track - self->internalState;
00156 
00157         }
00158 
00159         if (self->windup && self->useBackward)
00160         {
00161                 //Proportional difference
00162                 float diff = self->track - self->output + self->lastI;
00163                 //ROS_ERROR("Windup diff=%f track=%f output=%f", diff, self->track, self->output);
00164                 //ROS_ERROR("Windup I=%f, lI = %f, lerror=%f, error=%f", self->I, self->lastI, self->lastError, error);
00165                 //if ((diff*self->track <= 0) || (self->output*self->track <=0))
00166                 {
00167                         //Unwind
00168                         self->I -= self->lastI;
00169                         //ROS_ERROR("Unwinding");
00170                 }
00171                 /*else
00172                 {
00173                         //ROS_ERROR("Recalculating");
00174                         self->I -= self->lastI - diff;
00175                 }*/
00176         }
00177 
00178 
00179 
00180         //Proportional term
00181         //self->internalState += self->Kp*(error-self->lastError);
00182         //self->internalState += self->Kp*(perror - self->lastPError);
00183         self->internalState = self->Kp*perror;
00184         //Integral term
00185         //Disabled if windup is in progress.
00186         //if (!self->windup) self->internalState += (self->lastI = self->Ki*Ts*error);
00187         //else self->lastI = 0;
00188         //Feed forward term
00189         //self->internalState += ff - self->lastFF;
00190 
00191 
00192         self->internalState += ff;
00193 
00194 
00195 
00196         //if (!self->windup) self->I += (self->lastI = self->Ki*Ts*error);
00197 
00198         /*
00199         if (self->windup && self->useBackward && self->lastI != 0)
00200         {
00201                 //Proportional difference
00202                 float pcontrib = self->internalState;//- self->I;
00203                 ROS_ERROR("Windup diff=%f track=%f output=%f", pcontrib, self->track, self->internalState + self->I);
00204                 ROS_ERROR("Windup I=%f, lI = %f, lerror=%f, error=%f", self->I, self->lastI, self->lastError, error);
00205                 if (fabs(pcontrib) > fabs(self->track))
00206                 {
00207                         //Unwind
00208                         self->I -= self->lastI;
00209                         ROS_ERROR("Unwinding");
00210                 }
00211                 else
00212                 {
00213                         ROS_ERROR("Recalculating");
00214                         self->I -= self->lastI;
00215                         self->I += self->track - 0.98*pcontrib;
00216                         ROS_ERROR("New output: out=%f", self->internalState + self->I);
00217                 }
00218         }
00219 */
00220 
00221         /*if (self->windup && self->useBackward && self->lastI != 0)
00222         {
00223                 //Proportional difference
00224                 float diff = self->track - self->internalState - self->I;
00225                 ROS_ERROR("Windup diff=%f track=%f output=%f", diff, self->track, self->internalState + self->I);
00226                 ROS_ERROR("Windup I=%f, lI = %f, lerror=%f, error=%f", self->I, self->lastI, self->lastError, error);
00227         //      if ((diff*self->track < 0) )//|| (self->output*self->track <=0))
00228                 {
00229                         //Unwind
00230                     //self->I -= self->lastI;
00231                         //ROS_ERROR("Unwinding");
00232                 }
00233         //      else
00234                 {
00235                         ROS_ERROR("Recalculating");
00236                         self->I -= -diff + 0*0.98*self->Ki*Ts*error;
00237                         //ROS_ERROR("New output: out=%f", self->internalState + self->I);
00238                 }
00239         }
00240         */
00241 
00242         //self->I += self->lastI = self->Ki*Ts*error;
00243         if (!self->windup) self->I += self->lastI = self->Ki*Ts*error;
00244         else self->lastI=0 ;
00245         self->internalState += self->I;
00246 
00247         //Set final output
00248         self->output = self->internalState;
00249 
00250         //ROS_ERROR("I: %f, P: %f, ff: %f", self->I, self->Kp*perror, ff);
00251 
00252         if (self->autoWindup == 1)
00253         {
00254                 self->output = sat(self->output,-self->outputLimit, self->outputLimit);
00255         }
00256 
00257         self->lastError = error;
00258         self->lastPError = perror;
00259         self->lastRef = self->desired;
00260         self->lastFF = ff;
00261         self->lastState = self->state;
00262 }
00263 


labust_control
Author(s): Gyula Nagy
autogenerated on Fri Aug 28 2015 11:22:42