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