Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | File List | Namespace Members | Class Members | File Members | Related Pages

Modules/BallLocator/GT2004ProcessModels/FixedPositionModel.cpp

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 #include "Tools/Math/MVTools.h"
00003 #include "FixedPositionModel.h"
00004 #include "Tools/Debugging/Debugging.h"
00005 //------------------------------------------------------------------------------
00006 // Discrete process model update matrix
00007 double KalmanFixedPositionModel::defaultA[4] =
00008 {
00009   1.0, 0.0,
00010   0.0, 1.0
00011 };
00012 // Initial internal covarinace matrix of filter
00013 double KalmanFixedPositionModel::defaultP[4] =
00014 {
00015   1.0, 0.0,
00016   0.0, 1.0
00017 };
00018 // Process covariance matrix
00019 // Assume a variance of 0.0001 m^2
00020 // Must be multiplied with powers of dt
00021 double KalmanFixedPositionModel::defaultQ[4] =
00022 {
00023   0.01*0.01, 0.00*0.00,
00024   0.00*0.00, 0.01*0.01
00025 };
00026 // Measurement covariance matrix
00027 // Assume a variance of 0.0016 m^2
00028 double KalmanFixedPositionModel::defaultR[4] =
00029 {
00030   0.04*0.04, 0.00*0.00,
00031   0.00*0.00, 0.04*0.04
00032 };
00033 //------------------------------------------------------------------------------
00034 KalmanFixedPositionModel::KalmanFixedPositionModel() : KalmanProcessModelBase()
00035 {
00036   A = defaultA;
00037   globQ = defaultQ;
00038   globR = defaultR;
00039   reset();
00040 }
00041 //------------------------------------------------------------------------------
00042 KalmanFixedPositionModel::~KalmanFixedPositionModel()
00043 {
00044 }
00045 //------------------------------------------------------------------------------
00046 void KalmanFixedPositionModel::reset()
00047 {
00048   inited = false;
00049   lastLiklihood = 0.0;
00050   P = defaultP;
00051   lastTime = 0.0;
00052   x_act[0] = 0.0;
00053   x_act[1] = 0.0;
00054 }
00055 //------------------------------------------------------------------------------
00056 KalmanUpdateResult
00057   KalmanFixedPositionModel::update(double time, double x, double y)
00058 {
00059   KalmanUpdateResult res;
00060   
00061   // If no measurement exists the model can't perform a time update
00062   if (!inited)
00063   {
00064     // Set state to measured state
00065     x_act[0] = x;
00066     x_act[1] = y;
00067 
00068     inited = true;
00069     lastTime = time;
00070     
00071     res.liklihood = 0.0;
00072     return res;
00073   }
00074 
00075   // Check time step
00076   double dt = time - lastTime;
00077   if (MVTools::isNearZero(dt))
00078   {
00079     // Time difference is too small --> return last state
00080     res.state.x = x_act[0];
00081     res.state.y = x_act[1];
00082     res.state.vx = 0.0;
00083     res.state.vy = 0.0;
00084     res.liklihood = lastLiklihood;
00085     lastTime = time;
00086     return res;
00087   }
00088   
00089   // Adapt covariance matrix
00090   double dt2 = dt*dt;
00091   Q = globQ;
00092   Q[0][0] *= dt2;
00093   Q[1][1] *= dt2;
00094 
00095   try
00096   {
00097     // Perform time update
00098     try
00099     {
00100       x_minus = A*x_act;                              // (2.1)
00101       P_minus = A*P*transpose(A) + Q;                 // (2.2)
00102     }
00103     catch (MVException m)
00104     {
00105       // We should not end up here
00106       OutputException("time update", m);
00107       reset();
00108       res.liklihood = 0.0;
00109       return res;
00110     }
00111 
00112     // Set measured state
00113     z[0] = x;
00114     z[1] = y;
00115 
00116     // Calculate weight (see equation 2.6)
00117     R = globR;
00118     C = P_minus + R;
00119     double determinant;
00120     
00121     try
00122     {
00123       C_inv = invert(C);  
00124       determinant = det(C);
00125       if (determinant < 0.0)
00126         throw MVException();
00127       if (MVTools::isNearZero(determinant))
00128         throw MVException();
00129     }
00130     catch (MVException m)
00131     {
00132       // We should not end up here
00133       OutputException("weight calculation", m);
00134       reset();
00135       res.liklihood = 0.0;
00136       return res;
00137     }   
00138     
00139     double exponent = -0.5*(z-x_minus)*(C_inv*(z-x_minus));
00140     if (exponent > MVTools::getMaxExpDouble())
00141     {
00142       // Sometimes exponent ist too high to represent the result with
00143       // a double. Set it to the maximum value
00144       exponent = MVTools::getMaxExpDouble();
00145     }
00146     res.liklihood = exp(exponent)/(2*pi * sqrt(determinant));
00147 
00148     // Measurement update
00149     try
00150     {
00151       K = P_minus * C_inv;                            // (2.3)
00152       x_act = x_minus + K*(z - x_minus);              // (2.4)
00153       P = (P.eye() - K)*P_minus;                      // (2.5)
00154     }
00155     catch (MVException m)
00156     {
00157       // We should not end up here
00158       OutputException("measurement update", m);
00159       reset();
00160       res.liklihood = 0.0;
00161       return res;
00162     }
00163 
00164     // Set state und save information of this update step
00165     lastLiklihood = res.liklihood;
00166     res.state.x = x_act[0];
00167     res.state.y = x_act[1];
00168     res.state.vx = 0.0;
00169     res.state.vy = 0.0;
00170     lastTime = time;
00171   }
00172   catch (...)
00173   {
00174     // We should not end up here
00175     OUTPUT(idText, text,
00176            "UnknownException in KalmanFixedPositionModel::update()");
00177     reset();
00178     res.liklihood = 0.0;
00179     return res;
00180   }
00181 
00182   return res;
00183 }
00184 //------------------------------------------------------------------------------
00185 KalmanPredictResult KalmanFixedPositionModel::predict(double time)
00186 {
00187   KalmanPredictResult res;
00188 
00189   // If model was not initialised yet we can't predict a state
00190   if (!inited)
00191     return res;
00192 
00193   // Predict a state using the process model
00194   try
00195   {
00196     x_predict = A*x_act;
00197   }
00198   catch (MVException m)
00199   {
00200     // We should not end up here
00201     OutputException("prediction", m);
00202     reset();
00203     res.liklihood = 0.0;
00204     return res;
00205   }
00206   res.state.x = x_predict[0];
00207   res.state.y = x_predict[1];
00208   res.state.vx = 0.0;
00209   res.state.vy = 0.0;
00210   res.liklihood = lastLiklihood;
00211 
00212   return res;
00213 }
00214 //------------------------------------------------------------------------------
00215 void KalmanFixedPositionModel::adapt(const OdometryData& lastOdometry,
00216                                      const OdometryData& actualOdometry)
00217 {
00218   // Adapt state to the new position of the robot
00219   Vector2<double> tempBallPosition = 
00220     (lastOdometry + Pose2D(x_act[0]*1000.0, x_act[1]*1000.0) -
00221      actualOdometry).translation;
00222   x_act[0] = tempBallPosition.x / 1000.0;
00223   x_act[1] = tempBallPosition.y / 1000.0;
00224 }
00225 //------------------------------------------------------------------------------
00226 
00227 /*
00228  * Change log :
00229  * $Log: FixedPositionModel.cpp,v $
00230  * Revision 1.1  2004/07/14 21:40:15  spranger
00231  * moved kalmanprocessmodel to gt2004processmodel
00232  *
00233  * Revision 1.1.1.1  2004/05/22 17:15:26  cvsadm
00234  * created new repository GT2004_WM
00235  *
00236  * Revision 1.3  2004/04/20 14:12:16  uhrig
00237  *  - odometry processing corrected
00238  *  - fixed position model disabled
00239  *  - covariance matrices tuned
00240  *
00241  * Revision 1.2  2004/03/15 12:28:52  risler
00242  * change log added
00243  *
00244  *
00245  */

Generated on Thu Sep 23 19:57:25 2004 for GT2004 by doxygen 1.3.6