00001
00002 #include "Tools/Math/MVTools.h"
00003 #include "FixedPositionModel.h"
00004 #include "Tools/Debugging/Debugging.h"
00005
00006
00007 double KalmanFixedPositionModel::defaultA[4] =
00008 {
00009 1.0, 0.0,
00010 0.0, 1.0
00011 };
00012
00013 double KalmanFixedPositionModel::defaultP[4] =
00014 {
00015 1.0, 0.0,
00016 0.0, 1.0
00017 };
00018
00019
00020
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
00027
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
00062 if (!inited)
00063 {
00064
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
00076 double dt = time - lastTime;
00077 if (MVTools::isNearZero(dt))
00078 {
00079
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
00090 double dt2 = dt*dt;
00091 Q = globQ;
00092 Q[0][0] *= dt2;
00093 Q[1][1] *= dt2;
00094
00095 try
00096 {
00097
00098 try
00099 {
00100 x_minus = A*x_act;
00101 P_minus = A*P*transpose(A) + Q;
00102 }
00103 catch (MVException m)
00104 {
00105
00106 OutputException("time update", m);
00107 reset();
00108 res.liklihood = 0.0;
00109 return res;
00110 }
00111
00112
00113 z[0] = x;
00114 z[1] = y;
00115
00116
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
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
00143
00144 exponent = MVTools::getMaxExpDouble();
00145 }
00146 res.liklihood = exp(exponent)/(2*pi * sqrt(determinant));
00147
00148
00149 try
00150 {
00151 K = P_minus * C_inv;
00152 x_act = x_minus + K*(z - x_minus);
00153 P = (P.eye() - K)*P_minus;
00154 }
00155 catch (MVException m)
00156 {
00157
00158 OutputException("measurement update", m);
00159 reset();
00160 res.liklihood = 0.0;
00161 return res;
00162 }
00163
00164
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
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
00190 if (!inited)
00191 return res;
00192
00193
00194 try
00195 {
00196 x_predict = A*x_act;
00197 }
00198 catch (MVException m)
00199 {
00200
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
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
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245