Odometry.h

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------------
00002 //
00003 // $Id$
00004 //
00005 // Copyright 2008, 2009, 2010, 2011, 2012  Antonio Franchi and Paolo Stegagno    
00006 //
00007 // This file is part of MIP.
00008 //
00009 // MIP is free software: you can redistribute it and/or modify
00010 // it under the terms of the GNU General Public License as published by
00011 // the Free Software Foundation, either version 3 of the License, or
00012 // (at your option) any later version.
00013 //
00014 // MIP is distributed in the hope that it will be useful,
00015 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00016 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00017 // GNU General Public License for more details.
00018 //
00019 // You should have received a copy of the GNU General Public License
00020 // along with MIP. If not, see <http://www.gnu.org/licenses/>.
00021 //
00022 // Contact info: antonio.franchi@tuebingen.mpg.de stegagno@diag.uniroma1.it
00023 //
00024 // ----------------------------------------------------------------------------
00025 
00026 
00030 
00034 
00035 
00037 /* @{ */
00038 
00039 #ifndef __ODOMETRY_H
00040 #define __ODOMETRY_H
00041 
00042 #ifdef MIP_HOST_APPLE
00043 #include <applePatch.h>
00044 #endif
00045 
00046 #include "TrajControl.h"
00047 //TODO cancellare le define
00048 #define E_d 0.1
00049 #define E_b 0.1
00050 #define wheel_diameter 0.1
00051 #define axle_length 1.0
00052 
00053 // ///\class DiffDriveOdometerPar
00054 // ///\brief Contains the parameters needed to compute the odometric update equations of a differential drive.
00055 // ///\author Antonio Franchi
00056 // ///\todo 
00057 // class DiffDriveOdometerPar{
00058 //  private:
00059 //   Decimal _leftWheelDiam;   ///< Left-wheel diameter.
00060 //   Decimal _rightWheelDiam;  ///< Right-wheel diameter.
00061 //   Decimal _axelTrack;     ///< Axel track.
00062 //   Decimal _encoderResol;   ///< Encoder resolution.
00063 //   
00064 //   Decimal _leftRatio;  ///< Left-wheel conversion-ratio between pulses and linear movement of the wheel.
00065 //   Decimal _rightRatio; ///< Right-wheel conversion-ratio between pulses and linear movement of the wheel.
00066 //  public:
00067 //   /// \brief Constructor.
00068 //   /// \param ld Left-wheel diameter (m).
00069 //   /// \param rd Right-wheel diameter (m).
00070 //   /// \param wb Axel track (m).
00071 //   /// \param er Encoder resolution, number of pulses per radians (pulses/rad).
00072 //   DiffDriveOdometerPar(Decimal ld=1.0,Decimal rd=1.0,Decimal wb=1.0,Decimal er=1.0);
00073 //   /// \brief Copy constructor.
00074 //    DiffDriveOdometerPar(const DiffDriveOdometerPar &p);
00075 //   /// \brief Assigment operator =.
00076 //   DiffDriveOdometerPar& operator=(const DiffDriveOdometerPar& p){
00077 //    if (this != &p){
00078 //     _leftWheelDiam = p._leftWheelDiam;
00079 //     _rightWheelDiam = p._rightWheelDiam;
00080 //     _axelTrack   = p._axelTrack;
00081 //     _encoderResol  = p._encoderResol;
00082 //     _leftRatio   = p._leftRatio;
00083 //     _rightRatio   = p._rightRatio;
00084 //    }
00085 //    return *this;
00086 //   }
00087 //   
00088 //   /// \brief Gets Left-wheel diameter (m).
00089 //   Decimal getLeftWheelDiam();
00090 //   /// \brief Gets Right-wheel diameter (m).
00091 //   Decimal getRightWheelDiam();
00092 //   /// \brief Gets Axel track (m).
00093 //   Decimal getAxelTrack();
00094 //   /// \brief Gets Encoder resolution, number of pulses per radians (pulses/rad).
00095 //   Decimal getEncoderResol();
00096 //   /// \brief Gets Left-wheel conversion-ratio between pulses and linear movement of the wheel.
00097 //   Decimal getLeftRatio();
00098 //   /// \brief Gets Right-wheel conversion-ratio between pulses and linear movement of the wheel.
00099 //   Decimal getRightRatio();
00100 //   /// \brief Prints the parameters.
00101 //   string print();
00102 // };
00103 // 
00104 // 
00105 // ///\class DiffDriveEncoderReading
00106 // ///\brief Contains the readings of the encoders of a differential drive.
00107 // ///\author Antonio Franchi
00108 // ///\todo Public or private variables?
00109 // class DiffDriveEncoderReading{
00110 //  private:
00111 //  public:
00112 //   long int leftPulses; ///< Left-wheel/motor encoder pulses.
00113 //   long int rightPulses; ///< Right-wheel/motor encoder pulses.
00114 //   Time leftTime;    ///< Time in which leftPulses was aquired.
00115 //   Time rightTime;    ///< Time in which rightPulses was aquired.
00116 // 
00117 //   /// \brief Constructor.
00118 //   /// \param lp Left-wheel/motor encoder pulses.
00119 //   /// \param rp Right-wheel/motor encoder pulses.
00120 //   /// \param lt Time in which the left-wheel/motor encoder pulses is aquired.
00121 //   /// \param lt Time in which the right-wheel/motor encoder pulses is aquired.
00122 //   DiffDriveEncoderReading(long int lp=0,long int rp=0,Time lt=Time(0.0),Time rt=Time(0.0));
00123 //   /// \brief Copy constructor.
00124 //   DiffDriveEncoderReading(const DiffDriveEncoderReading &p);
00125 //   /// \brief Assigment operator =.
00126 //   DiffDriveEncoderReading& operator=(const DiffDriveEncoderReading& p){
00127 //    if (this != &p){
00128 //     leftPulses = p.leftPulses;
00129 //     rightPulses = p.rightPulses;
00130 //     leftTime  = p.leftTime;
00131 //     rightTime  = p.rightTime;
00132 //    }
00133 //    return *this;
00134 //   }
00135 //   /// \brief Prints the readings.
00136 //   string print();
00137 // };
00138 //  
00139 //  
00140 // ///\class DiffDriveOdometerVar
00141 // ///\brief Contains the variables needed to compute the odometric update equations of a differential drive.
00142 // ///\author Antonio Franchi
00143 // ///\todo Public or private variables?
00144 // class DiffDriveOdometerVar{
00145 //  private:
00146 //  public:
00147 //   Pose pose; ///< Current Pose, x,y,theta.
00148 //   DiffDriveEncoderReading encodRead; ///< Readings (pulses,times) of the encoders of the wheels.
00149 // 
00150 //   /// \brief default constructor.
00151 // //   DiffDriveOdometerVar(Pose p, long int lp,long int rp,Time lt,Time rt);
00152 //   /// \brief Constructor.
00153 //   /// \param p  Initial Pose of the unicycle: x,y,theta.
00154 //   /// \param lp Initial left-wheel/motor encoder pulses.
00155 //   /// \param rp Initial right-wheel/motor encoder pulses.
00156 //   /// \param lt Time in which the initial left-wheel/motor encoder pulses was aquired.
00157 //   /// \param lt Time in which the initial right-wheel/motor encoder pulses was aquired.
00158 //   DiffDriveOdometerVar(Pose p=Pose(),DiffDriveEncoderReading r=DiffDriveEncoderReading());
00159 // //   DiffDriveOdometerVar(Pose p, long int lp,long int rp,Time lt,Time rt);
00160 // 
00161 //   /// \brief Copy constructor.
00162 //   DiffDriveOdometerVar(const DiffDriveOdometerVar &p);
00163 //   /// \brief Assigment operator =.
00164 //   DiffDriveOdometerVar& operator=(const DiffDriveOdometerVar& p){
00165 //    if (this != &p){
00166 //     pose    = p.pose;
00167 //     encodRead  = p.encodRead;
00168 //    }
00169 //    return *this;
00170 //   }
00171 //    /// \brief Prints the variables.
00172 //    string print();
00173 // };
00174 // 
00175 // 
00176 // ///\class DiffDriveOdometerIn
00177 // ///\brief Contains the iputs needed to compute the odometric update equations of a differential drive.
00178 // ///\author Antonio Franchi
00179 // ///\todo
00180 // typedef DiffDriveEncoderReading DiffDriveOdometerIn;
00181 // 
00182 // ///\class DiffDriveOdometerOut
00183 // ///\brief Contains the outputs returned by the odometric update equations of a differential drive.
00184 // ///\author Antonio Franchi
00185 // ///\todo Public or private variables?
00186 // class DiffDriveOdometerOut{
00187 //  private:
00188 //  public:
00189 //   Pose  pose;   ///< Pose, x,y,theta.
00190 //   Decimal speed;  ///< Current linear speed (m/sec).
00191 //   Decimal turnrate; ///< Current angular velocity (rad/sec).
00192 // 
00193 //   /// \brief Constructor.
00194 //   /// \param p New computed pose of the differntial drive: x,y,theta.
00195 //   /// \param s New computed linear speed.
00196 //   /// \param t New computed angular velocity.
00197 //   DiffDriveOdometerOut(Pose p,Decimal s,Decimal t);
00198 //   /// \brief Copy constructor.
00199 //   DiffDriveOdometerOut(const DiffDriveOdometerOut &p);
00200 //   /// \brief Assigment operator =.
00201 //   DiffDriveOdometerOut& operator=(const DiffDriveOdometerOut& p){
00202 //    if (this != &p){
00203 //     pose   = p.pose;
00204 //     speed   = p.speed;
00205 //     turnrate = p.turnrate;
00206 //    }
00207 //    return *this;
00208 //   }
00209 //    /// \brief Prints the output.
00210 //   string print();
00211 // };
00212 // 
00213 // 
00214 // ///\class DiffDriveOdometer
00215 // ///\brief Algorithm which may be used to update the state of a differential drive. It make use of the odometric equations.
00216 // ///\author Antonio Franchi
00217 // ///\todo Add logging.
00218 // class DiffDriveOdometer{
00219 //  private:
00220 //   DiffDriveOdometerPar par;
00221 //   DiffDriveOdometerVar var;
00222 //  public:
00223 //   /// \brief Constructor.
00224 //   /// \param p Parameters.
00225 //   /// \param v Initial variables (state).
00226 //   DiffDriveOdometer(const DiffDriveOdometerPar& p,const DiffDriveOdometerVar& v);
00227 //   
00228 //   /// \brief Reset the pose to a certain value.
00229 //   /// \param p New pose.
00230 //   void poseReset(Pose p);
00231 //   
00232 //   /// \brief Reset the variables of the algorithm to a certain value.
00233 //   /// \param p New variables.
00234 //   void varReset(DiffDriveOdometerVar v);
00235 //   
00236 //   /// \brief Fundamental step of the algorithm.
00237 //   /// \param in Inputs of the step (new pulses and times).
00238 //   /// \return Output of the step (new pose, new linear speed, new angular speed).
00239 //   DiffDriveOdometerOut step(DiffDriveOdometerIn in);
00240 // };
00241 
00242 
00251 class Odometry{
00252  private:
00253   bool first;//TODO si può omettere se inizializzo tutto nel costruttore?
00254 //   long int N_LeftW_prec,N_RightW_prec;//Input di update
00255   long int _leastLeftRead, _leastRightRead;
00256 //    Timer _encTimer;
00257   Time _leastLeftTime,_leastRightTime;
00258  public:
00259   
00260   bool updateOdometry(long int currLeftRead, long int currRightRead, long int encRes, Time currLeftTime, Time currRightTime,TrajectoryState &trajStatus){
00261    Decimal dT,dTR,dTL;  
00262    Decimal vr, vl;
00263    long   N_LeftW, N_RightW;
00264    Decimal vel_tick_r,vel_tick_l;
00265 //    Time currLeftTime,currRightTime;
00266    
00267    static Decimal Deltang=(2.0*M_PI/encRes);
00268    if(first){//TODO verifica
00269     _leastLeftRead  = 0;//NOTE origine della lettura?
00270     _leastRightRead = 0;//NOTE origine della lettura?
00271     _leastLeftTime=Time(0,0);
00272     _leastRightTime=Time(0,0);
00273 //     _encTimer.reset();
00274     first = false;
00275    }
00276   
00277 //   wheelCountersL = getLeftEncoder();//NOTE nuova della lettura?
00278 //   double ltime   = leggiTempo3(tvl);
00279 //   currLeftTime=_encTimer.get();
00280 //   wheelCountersR = getRightEncoder();//NOTE nuova della lettura?
00281 // //   double rtime   = leggiTempo3(tvr);
00282 //   currRightTime=_encTimer.get();
00283   
00284   int tent = 0;
00285   int maxTent =2;
00286   while( ( (currLeftRead - _leastLeftRead > 200) || (currLeftRead - _leastLeftRead < -200) ) && (tent<maxTent) ){/*provo a filtrare letture fallaci*/
00287 //    wheelCountersL = getLeftEncoder();
00288 //    ltime          = leggiTempo3(tvl);
00289    //TODO aggiornare comunque least readings?qui wheelCountersL
00290    tent++;
00291    return false;
00292   }
00293   tent=0;
00294   N_LeftW = currLeftRead - _leastLeftRead;
00295   while( ( (currRightRead - _leastRightRead > 200)|| (currRightRead - _leastRightRead < -200) )  && (tent<maxTent) ){/*provo a filtrare letture fallaci*/
00296 //    wheelCountersR = getRightEncoder();
00297 //    rtime          = leggiTempo3(tvr);
00298    //TODO aggiornare comunque least readings?qui wheelCountersR
00299    tent++;
00300    return false;
00301   }
00302   N_RightW = currRightRead - _leastRightRead;
00304 //  if(wheelCountersL > 2765){
00305 //    wheelCountersL  = getLeftEncoder();
00306 //    ltime = leggiTempo3(tvl);
00307 //  }
00308 //  N_LeftW=wheelCountersL-N_LeftW_prec;
00309   //  /*!filtraggio per evitare letture incoerenti (maggiori della risoluzione max dell'encoder)*/
00310 //  if(wheelCountersR > 2765){ 
00311 //   wheelCountersR  = getRightEncoder();
00312 //   rtime = leggiTempo3(tvr);
00313 //  }
00314 //  N_RightW=wheelCountersR-N_RightW_prec;
00315   Time dtLeft=currLeftTime-_leastLeftTime;
00316   Time dtRight=currRightTime-_leastRightTime;
00317   dTL = dtLeft.dCast();
00318   dTR =dtRight.dCast();
00319   Time dTime=(Time)(dtRight+dtLeft)*0.5;
00320   dT=dTime.dCast();
00321  
00322  //Calcolo di vl, vr, v & omega
00323   vel_tick_l = rint(N_LeftW/dTL);  //pulse/s
00324   vel_tick_r = rint(N_RightW/dTR); //pulse/s
00325 
00326   _leastLeftTime = currLeftTime;
00327   _leastRightTime = currRightTime;
00328   vl=(2.0/ (E_d+1.0))          * (N_LeftW  * Deltang * (wheel_diameter/2.0)) / dTL;  // m/s
00329   vr=(2.0/ ( (1.0/E_d) +1.0) ) * (N_RightW * Deltang * (wheel_diameter/2.0)) / dTR; // m/s
00330   
00331   trajStatus.setDtWheel((Position)(dTR,dTL));
00332 //   MState.dTL = dTL;
00333 //   MState.dTR = dTR;
00334   trajStatus.setWheelVel((Position)(vr,vl));
00335 //   MState.vl = vl;
00336 //   MState.vr = vr;
00337   trajStatus.setStatusVel(VelVec(0.5*(vr+vl),(vr-vl)/(E_b*axle_length),dTime));
00338 //   MState.V  = 0.5*(vr+vl);
00339 //   MState.W  = (vr-vl)/(E_b*axle_length);
00340 //   dT        = 0.5*(dTR + dTL);
00341  
00342   //Integrazione Runge-Kutta del II ordine
00343   Angle theta=trajStatus.statusPose().ori();
00344   Decimal V=trajStatus.statusVel().linVel();
00345   Decimal W=trajStatus.statusVel().angVel();
00346 //   Pose dPose=Pose (cos(theta.dCast() + W*dT*0.5 )*V*dT,sin(theta.dCast() + W*dT*0.5 )*V*dT,(Angle)(normalize(theta.dCast()+(W*dT))));
00347   Pose dPose=Pose (cos(theta.dCast2Pi() + W*dT*0.5 )*V*dT,sin(theta.dCast2Pi() + W*dT*0.5 )*V*dT,(Angle)(theta.dCast2Pi()+(W*dT)));
00348   trajStatus.setStatusPose(trajStatus.statusPose()+dPose);
00349     
00350 //   MState.x +=  cos( MState.theta + MState.W*dT*0.5 )*MState.V*dT.dCast();
00351 //   MState.y +=  sin( MState.theta + MState.W*dT*0.5 )*MState.V*dT.dCast();
00352 //   MState.theta = normalizza( MState.theta + MState.W * dT);
00353          
00354   //Aggiornamento dello stato
00355   _leastLeftRead  = currLeftRead;
00356   _leastRightRead = currRightRead; 
00357 
00358 //   if(log_flag){
00359 //    MLogState.x = MState.x;
00360 //    MLogState.y = MState.y;
00361 //    MLogState.theta = MState.theta;
00362 //    MLogState.leftTicks  = wheelCountersL;
00363 //    MLogState.rightTicks = wheelCountersR;
00364 //    MLogState.leftTv = tvl;
00365 //    MLogState.rightTv = tvr;
00366 //   }
00367   return true;
00368  }
00369 };
00370 
00371 
00372 #endif
00373 
00374 
00375 /* @} */
00376 
00377 

Generated on Mon Feb 20 07:01:06 2017 for MIP by  doxygen 1.5.6