00001 #pragma ident "$Id: CodeKalmanSolver.cpp 2580 2011-04-28 14:53:04Z architest $"
00002
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include "CodeKalmanSolver.hpp"
00032 #include "MatrixFunctors.hpp"
00033
00034
00035 namespace gpstk
00036 {
00037
00038
00039 int CodeKalmanSolver::classIndex = 9200000;
00040
00041
00042
00043 int CodeKalmanSolver::getIndex() const
00044 { return index; }
00045
00046
00047
00048 std::string CodeKalmanSolver::getClassName() const
00049 { return "CodeKalmanSolver"; }
00050
00051
00052
00053 CodeKalmanSolver::CodeKalmanSolver()
00054 {
00055
00056
00057 TypeIDSet tempSet;
00058 tempSet.insert(TypeID::dx);
00059 tempSet.insert(TypeID::dy);
00060 tempSet.insert(TypeID::dz);
00061 tempSet.insert(TypeID::cdt);
00062
00063
00064
00065 defaultEqDef.header = TypeID::prefitC;
00066 defaultEqDef.body = tempSet;
00067
00068
00069 Init();
00070
00071 }
00072
00073
00074
00075
00076 void CodeKalmanSolver::Init()
00077 {
00078
00079
00080 setIndex();
00081
00082 numUnknowns = defaultEqDef.body.size();
00083
00084 Vector<double> initialState(numUnknowns, 0.0);
00085 Matrix<double> initialErrorCovariance(numUnknowns, numUnknowns, 0.0);
00086
00087
00088 for (int i=0; i<3; i++)
00089 {
00090 initialErrorCovariance(i,i) = 100.0;
00091 }
00092
00093 initialErrorCovariance(3,3) = 9.0e10;
00094
00095 kFilter.Reset( initialState, initialErrorCovariance );
00096
00097
00098 setCoordinatesModel(&constantModel);
00099
00100
00101
00102 pClockStoModel = &whitenoiseModel;
00103
00104
00105 solution.resize(numUnknowns);
00106
00107 }
00108
00109
00110
00111
00112
00113
00114
00115
00116 CodeKalmanSolver::CodeKalmanSolver(const gnssEquationDefinition& eqDef)
00117 {
00118
00119 setDefaultEqDefinition(eqDef);
00120
00121 Init();
00122
00123 }
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145 int CodeKalmanSolver::Compute( const Vector<double>& prefitResiduals,
00146 const Matrix<double>& designMatrix,
00147 const Vector<double>& weightVector )
00148 throw(InvalidSolver)
00149 {
00150
00151
00152 valid = false;
00153
00154
00155 int wSize = static_cast<int>(weightVector.size());
00156 int pSize = static_cast<int>(prefitResiduals.size());
00157 if (!(wSize==pSize))
00158 {
00159 InvalidSolver e("prefitResiduals size does not match dimension \
00160 of weightVector");
00161
00162 GPSTK_THROW(e);
00163 }
00164
00165 Matrix<double> wMatrix(wSize,wSize,0.0);
00166
00167
00168
00169 for (int i=0; i<wSize; i++)
00170 {
00171 wMatrix(i,i) = weightVector(i);
00172 }
00173
00174
00175 return CodeKalmanSolver::Compute( prefitResiduals,
00176 designMatrix,
00177 wMatrix );
00178
00179 }
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200 int CodeKalmanSolver::Compute( const Vector<double>& prefitResiduals,
00201 const Matrix<double>& designMatrix,
00202 const Matrix<double>& weightMatrix )
00203 throw(InvalidSolver)
00204 {
00205
00206
00207 valid = false;
00208
00209 if (!(weightMatrix.isSquare()))
00210 {
00211 InvalidSolver e("Weight matrix is not square");
00212 GPSTK_THROW(e);
00213 }
00214
00215 int wRow = static_cast<int>(weightMatrix.rows());
00216 int pRow = static_cast<int>(prefitResiduals.size());
00217 if (!(wRow==pRow))
00218 {
00219 InvalidSolver e("prefitResiduals size does not match dimension of \
00220 weightMatrix");
00221
00222 GPSTK_THROW(e);
00223 }
00224
00225 int gRow = static_cast<int>(designMatrix.rows());
00226 if (!(gRow==pRow))
00227 {
00228 InvalidSolver e("prefitResiduals size does not match dimension \
00229 of designMatrix");
00230
00231 GPSTK_THROW(e);
00232 }
00233
00234 if (!(phiMatrix.isSquare()))
00235 {
00236 InvalidSolver e("phiMatrix is not square");
00237
00238 GPSTK_THROW(e);
00239 }
00240
00241 int phiRow = static_cast<int>(phiMatrix.rows());
00242 if (!(phiRow==numUnknowns))
00243 {
00244 InvalidSolver e("prefitResiduals size does not match dimension \
00245 of phiMatrix");
00246
00247 GPSTK_THROW(e);
00248 }
00249
00250 if (!(qMatrix.isSquare()))
00251 {
00252 InvalidSolver e("qMatrix is not square");
00253
00254 GPSTK_THROW(e);
00255 }
00256
00257 int qRow = static_cast<int>(qMatrix.rows());
00258 if (!(qRow==numUnknowns))
00259 {
00260 InvalidSolver e("prefitResiduals size does not match dimension \
00261 of qMatrix");
00262
00263 GPSTK_THROW(e);
00264 }
00265
00266
00267
00268
00269 Matrix<double> measNoiseMatrix;
00270
00271 try
00272 {
00273 measNoiseMatrix = inverseChol(weightMatrix);
00274 }
00275 catch(...)
00276 {
00277 InvalidSolver e("Correct(): Unable to compute measurements noise \
00278 covariance matrix.");
00279
00280 GPSTK_THROW(e);
00281 }
00282
00283 try
00284 {
00285
00286 kFilter.Compute( phiMatrix,
00287 qMatrix,
00288 prefitResiduals,
00289 designMatrix,
00290 measNoiseMatrix );
00291 }
00292 catch(InvalidSolver& e)
00293 {
00294 GPSTK_RETHROW(e);
00295 }
00296
00297
00298 solution = kFilter.xhat;
00299
00300
00301 covMatrix = kFilter.P;
00302
00303
00304 postfitResiduals = prefitResiduals - designMatrix * solution;
00305
00306
00307 valid = true;
00308
00309 return 0;
00310
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320 gnssSatTypeValue& CodeKalmanSolver::Process(gnssSatTypeValue& gData)
00321 throw(ProcessingException)
00322 {
00323
00324 try
00325 {
00326
00327
00328 gnssRinex g1;
00329 g1.header = gData.header;
00330 g1.body = gData.body;
00331
00332
00333 Process(g1);
00334
00335
00336 gData.body = g1.body;
00337
00338 return gData;
00339
00340 }
00341 catch(Exception& u)
00342 {
00343
00344 ProcessingException e( getClassName() + ":"
00345 + StringUtils::asString( getIndex() ) + ":"
00346 + u.what() );
00347
00348 GPSTK_THROW(e);
00349
00350 }
00351
00352 }
00353
00354
00355
00356
00357
00358
00359
00360
00361 gnssRinex& CodeKalmanSolver::Process(gnssRinex& gData)
00362 throw(ProcessingException)
00363 {
00364
00365 try
00366 {
00367
00368
00369 numMeas = gData.numSats();
00370
00371
00372 phiMatrix.resize(numUnknowns, numUnknowns, 0.0);
00373
00374
00375 qMatrix.resize(numUnknowns, numUnknowns, 0.0);
00376
00377
00378 hMatrix.resize(numMeas, numUnknowns, 0.0);
00379
00380
00381 rMatrix.resize(numMeas, numMeas, 0.0);
00382
00383
00384 measVector.resize(numMeas, 0.0);
00385
00386
00387 measVector = gData.getVectorOfTypeID(defaultEqDef.header);
00388
00389
00390
00391
00392 satTypeValueMap dummy(gData.body.extractTypeID(TypeID::weight));
00393
00394
00395 int nW(dummy.numSats());
00396 for (int i=0; i<numMeas; i++)
00397 {
00398 if (nW == numMeas)
00399 {
00400 Vector<double>
00401 weightsVector(gData.getVectorOfTypeID(TypeID::weight));
00402
00403 rMatrix(i,i) = weightsVector(i);
00404 }
00405 else
00406 {
00407
00408
00409 rMatrix(i,i) = 1.0;
00410
00411 }
00412 }
00413
00414
00415
00416 hMatrix = gData.body.getMatrixOfTypes((*this).defaultEqDef.body);
00417
00418 SatID dummySat;
00419
00420
00421
00422 pCoordXStoModel->Prepare(dummySat, gData);
00423 phiMatrix(0,0) = pCoordXStoModel->getPhi();
00424 qMatrix(0,0) = pCoordXStoModel->getQ();
00425
00426 pCoordYStoModel->Prepare(dummySat, gData);
00427 phiMatrix(1,1) = pCoordYStoModel->getPhi();
00428 qMatrix(1,1) = pCoordYStoModel->getQ();
00429
00430 pCoordZStoModel->Prepare(dummySat, gData);
00431 phiMatrix(2,2) = pCoordZStoModel->getPhi();
00432 qMatrix(2,2) = pCoordZStoModel->getQ();
00433
00434
00435
00436 pClockStoModel->Prepare(dummySat, gData);
00437 phiMatrix(3,3) = pClockStoModel->getPhi();
00438 qMatrix(3,3) = pClockStoModel->getQ();
00439
00440
00441
00442
00443
00444 Compute(measVector, hMatrix, rMatrix);
00445
00446
00447
00448 if ( defaultEqDef.header == TypeID::prefitC )
00449 {
00450 gData.insertTypeIDVector(TypeID::postfitC, postfitResiduals);
00451 }
00452
00453 return gData;
00454
00455 }
00456 catch(Exception& u)
00457 {
00458
00459 ProcessingException e( getClassName() + ":"
00460 + StringUtils::asString( getIndex() ) + ":"
00461 + u.what() );
00462
00463 GPSTK_THROW(e);
00464
00465 }
00466
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482 CodeKalmanSolver& CodeKalmanSolver::setCoordinatesModel(
00483 StochasticModel* pModel)
00484 {
00485
00486
00487 pCoordXStoModel = pModel;
00488 pCoordYStoModel = pModel;
00489 pCoordZStoModel = pModel;
00490
00491 return (*this);
00492
00493 }
00494
00495
00496
00497 }