00001 #pragma ident "$Id: SolverPPP.cpp 2645 2011-06-08 03:23:24Z yanweignss $"
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 "SolverPPP.hpp"
00032 #include "MatrixFunctors.hpp"
00033
00034
00035 namespace gpstk
00036 {
00037
00038
00039 int SolverPPP::classIndex = 9300000;
00040
00041
00042
00043 int SolverPPP::getIndex() const
00044 { return index; }
00045
00046
00047
00048 std::string SolverPPP::getClassName() const
00049 { return "SolverPPP"; }
00050
00051
00052
00053
00054
00055
00056
00057 SolverPPP::SolverPPP(bool useNEU)
00058 : firstTime(true)
00059 {
00060
00061
00062 setNEU(useNEU);
00063
00064
00065 setIndex();
00066
00067
00068 Init();
00069
00070 }
00071
00072
00073
00074
00075 void SolverPPP::Init(void)
00076 {
00077
00078
00079 rwalkModel.setQprime(3e-8);
00080
00081
00082 pTropoStoModel = &rwalkModel;
00083
00084
00085 setCoordinatesModel( &constantModel );
00086
00087 whitenoiseModelX.setSigma(100.0);
00088 whitenoiseModelY.setSigma(100.0);
00089 whitenoiseModelZ.setSigma(100.0);
00090
00091
00092 pClockStoModel = &whitenoiseModel;
00093
00094
00095 pBiasStoModel = &biasModel;
00096
00097
00098
00099 weightFactor = 10000.0;
00100
00101
00102 }
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121 int SolverPPP::Compute( const Vector<double>& prefitResiduals,
00122 const Matrix<double>& designMatrix,
00123 const Vector<double>& weightVector )
00124 throw(InvalidSolver)
00125 {
00126
00127
00128 valid = false;
00129
00130
00131 int wSize = static_cast<int>(weightVector.size());
00132 int pSize = static_cast<int>(prefitResiduals.size());
00133 if (!(wSize==pSize))
00134 {
00135 InvalidSolver e("prefitResiduals size does not match dimension \
00136 of weightVector");
00137 GPSTK_THROW(e);
00138 }
00139
00140 Matrix<double> wMatrix(wSize,wSize,0.0);
00141
00142
00143
00144 for( int i=0; i<wSize; i++ )
00145 {
00146 wMatrix(i,i) = weightVector(i);
00147 }
00148
00149
00150 return SolverPPP::Compute( prefitResiduals,
00151 designMatrix,
00152 wMatrix );
00153
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 int SolverPPP::Compute( const Vector<double>& prefitResiduals,
00173 const Matrix<double>& designMatrix,
00174 const Matrix<double>& weightMatrix )
00175 throw(InvalidSolver)
00176 {
00177
00178
00179 valid = false;
00180
00181 if (!(weightMatrix.isSquare()))
00182 {
00183 InvalidSolver e("Weight matrix is not square");
00184 GPSTK_THROW(e);
00185 }
00186
00187 int wRow = static_cast<int>(weightMatrix.rows());
00188 int pRow = static_cast<int>(prefitResiduals.size());
00189 if (!(wRow==pRow))
00190 {
00191 InvalidSolver e("prefitResiduals size does not match dimension of \
00192 weightMatrix");
00193 GPSTK_THROW(e);
00194 }
00195
00196 int gRow = static_cast<int>(designMatrix.rows());
00197 if (!(gRow==pRow))
00198 {
00199 InvalidSolver e("prefitResiduals size does not match dimension \
00200 of designMatrix");
00201 GPSTK_THROW(e);
00202 }
00203
00204 if (!(phiMatrix.isSquare()))
00205 {
00206 InvalidSolver e("phiMatrix is not square");
00207 GPSTK_THROW(e);
00208 }
00209
00210 int phiRow = static_cast<int>(phiMatrix.rows());
00211 if (!(phiRow==numUnknowns))
00212 {
00213 InvalidSolver e("Number of unknowns does not match dimension \
00214 of phiMatrix");
00215 GPSTK_THROW(e);
00216 }
00217
00218 if (!(qMatrix.isSquare()))
00219 {
00220 InvalidSolver e("qMatrix is not square");
00221 GPSTK_THROW(e);
00222 }
00223
00224 int qRow = static_cast<int>(qMatrix.rows());
00225 if (!(qRow==numUnknowns))
00226 {
00227 InvalidSolver e("Number of unknowns does not match dimension \
00228 of qMatrix");
00229 GPSTK_THROW(e);
00230 }
00231
00232
00233
00234
00235 Matrix<double> measNoiseMatrix;
00236
00237 try
00238 {
00239 measNoiseMatrix = inverseChol(weightMatrix);
00240 }
00241 catch(...)
00242 {
00243 InvalidSolver e("Correct(): Unable to compute measurements noise \
00244 covariance matrix.");
00245 GPSTK_THROW(e);
00246 }
00247
00248
00249 try
00250 {
00251
00252
00253 kFilter.Compute( phiMatrix,
00254 qMatrix,
00255 prefitResiduals,
00256 designMatrix,
00257 measNoiseMatrix );
00258
00259 }
00260 catch(InvalidSolver& e)
00261 {
00262 GPSTK_RETHROW(e);
00263 }
00264
00265
00266 solution = kFilter.xhat;
00267
00268
00269 covMatrix = kFilter.P;
00270
00271
00272 postfitResiduals = prefitResiduals - (designMatrix * solution);
00273
00274
00275 valid = true;
00276
00277 return 0;
00278
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288 gnssSatTypeValue& SolverPPP::Process(gnssSatTypeValue& gData)
00289 throw(ProcessingException)
00290 {
00291
00292 try
00293 {
00294
00295
00296 gnssRinex g1;
00297 g1.header = gData.header;
00298 g1.body = gData.body;
00299
00300
00301 Process(g1);
00302
00303
00304 gData.body = g1.body;
00305
00306 return gData;
00307
00308 }
00309 catch(Exception& u)
00310 {
00311
00312 ProcessingException e( getClassName() + ":"
00313 + StringUtils::asString( getIndex() ) + ":"
00314 + u.what() );
00315
00316 GPSTK_THROW(e);
00317
00318 }
00319
00320 }
00321
00322
00323
00324
00325
00326
00327
00328
00329 gnssRinex& SolverPPP::Process(gnssRinex& gData)
00330 throw(ProcessingException)
00331 {
00332
00333 try
00334 {
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347 SatIDSet currSatSet( gData.body.getSatID() );
00348
00349
00350 int numCurrentSV( gData.numSats() );
00351
00352
00353 satSet.insert( currSatSet.begin(), currSatSet.end() );
00354
00355
00356 int numSV( satSet.size() );
00357
00358
00359 numMeas = 2 * numCurrentSV;
00360
00361
00362 numVar = defaultEqDef.body.size();
00363
00364
00365 numUnknowns = numVar + numSV;
00366
00367
00368 phiMatrix.resize(numUnknowns, numUnknowns, 0.0);
00369
00370
00371 qMatrix.resize(numUnknowns, numUnknowns, 0.0);
00372
00373
00374
00375 measVector.resize(numMeas, 0.0);
00376
00377 Vector<double> prefitC(gData.getVectorOfTypeID(defaultEqDef.header));
00378 Vector<double> prefitL(gData.getVectorOfTypeID(TypeID::prefitL));
00379 for( int i=0; i<numCurrentSV; i++ )
00380 {
00381 measVector( i ) = prefitC(i);
00382 measVector( numCurrentSV + i ) = prefitL(i);
00383 }
00384
00385
00386
00387 rMatrix.resize(numMeas, numMeas, 0.0);
00388
00389
00390
00391 satTypeValueMap dummy(gData.body.extractTypeID(TypeID::weight));
00392
00393
00394 if ( dummy.numSats() == numCurrentSV )
00395 {
00396
00397
00398 Vector<double>
00399 weightsVector(gData.getVectorOfTypeID(TypeID::weight));
00400
00401 for( int i=0; i<numCurrentSV; i++ )
00402 {
00403
00404 rMatrix( i , i ) = weightsVector(i);
00405 rMatrix( i + numCurrentSV, i + numCurrentSV )
00406 = weightsVector(i) * weightFactor;
00407
00408 }
00409
00410 }
00411 else
00412 {
00413
00414
00415 for( int i=0; i<numCurrentSV; i++ )
00416 {
00417 rMatrix( i , i ) = 1.0;
00418
00419
00420 rMatrix( i + numCurrentSV, i + numCurrentSV )
00421 = 1.0 * weightFactor;
00422
00423 }
00424
00425 }
00426
00427
00428
00429
00430 hMatrix.resize(numMeas, numUnknowns, 0.0);
00431
00432
00433 Matrix<double> dMatrix(gData.body.getMatrixOfTypes(defaultEqDef.body));
00434
00435
00436 for( int i=0; i<numCurrentSV; i++ )
00437 {
00438
00439
00440 for( int j=0; j<numVar; j++ )
00441 {
00442
00443 hMatrix( i , j ) = dMatrix(i,j);
00444 hMatrix( i + numCurrentSV, j ) = dMatrix(i,j);
00445
00446 }
00447
00448 }
00449
00450
00451
00452
00453
00454 int count1(0);
00455 for( SatIDSet::const_iterator itSat = currSatSet.begin();
00456 itSat != currSatSet.end();
00457 ++itSat )
00458 {
00459
00460
00461
00462 int j(0);
00463 SatIDSet::const_iterator itSat2( satSet.begin() );
00464 while( (*itSat2) != (*itSat) )
00465 {
00466 ++j;
00467 ++itSat2;
00468 }
00469
00470
00471
00472 hMatrix( count1 + numCurrentSV, j + numVar ) = 1.0;
00473
00474 ++count1;
00475
00476 }
00477
00478
00479
00480
00481 SatID dummySat;
00482
00483
00484 pTropoStoModel->Prepare( dummySat,
00485 gData );
00486 phiMatrix(0,0) = pTropoStoModel->getPhi();
00487 qMatrix(0,0) = pTropoStoModel->getQ();
00488
00489
00490
00491 pCoordXStoModel->Prepare(dummySat, gData);
00492 phiMatrix(1,1) = pCoordXStoModel->getPhi();
00493 qMatrix(1,1) = pCoordXStoModel->getQ();
00494
00495 pCoordYStoModel->Prepare(dummySat, gData);
00496 phiMatrix(2,2) = pCoordYStoModel->getPhi();
00497 qMatrix(2,2) = pCoordYStoModel->getQ();
00498
00499 pCoordZStoModel->Prepare(dummySat, gData);
00500 phiMatrix(3,3) = pCoordZStoModel->getPhi();
00501 qMatrix(3,3) = pCoordZStoModel->getQ();
00502
00503
00504
00505 pClockStoModel->Prepare( dummySat,
00506 gData );
00507 phiMatrix(4,4) = pClockStoModel->getPhi();
00508 qMatrix(4,4) = pClockStoModel->getQ();
00509
00510
00511
00512 int count2(numVar);
00513 for( SatIDSet::const_iterator itSat = satSet.begin();
00514 itSat != satSet.end();
00515 ++itSat )
00516 {
00517
00518
00519 pBiasStoModel->Prepare( *itSat,
00520 gData );
00521
00522
00523 phiMatrix(count2,count2) = pBiasStoModel->getPhi();
00524 qMatrix(count2,count2) = pBiasStoModel->getQ();
00525
00526 ++count2;
00527 }
00528
00529
00530
00531
00532 if(firstTime)
00533 {
00534
00535 Vector<double> initialState(numUnknowns, 0.0);
00536 Matrix<double> initialErrorCovariance( numUnknowns,
00537 numUnknowns,
00538 0.0 );
00539
00540
00541
00542
00543
00544 initialErrorCovariance(0,0) = 0.25;
00545
00546
00547 for( int i=1; i<4; i++ )
00548 {
00549 initialErrorCovariance(i,i) = 10000.0;
00550 }
00551
00552
00553 initialErrorCovariance(4,4) = 9.0e10;
00554
00555
00556 for( int i=5; i<numUnknowns; i++ )
00557 {
00558 initialErrorCovariance(i,i) = 4.0e14;
00559 }
00560
00561
00562
00563 kFilter.Reset( initialState, initialErrorCovariance );
00564
00565
00566 firstTime = false;
00567
00568 }
00569 else
00570 {
00571
00572
00573 Vector<double> currentState(numUnknowns, 0.0);
00574 Matrix<double> currentErrorCov(numUnknowns, numUnknowns, 0.0);
00575
00576
00577
00578 for( int i=0; i<numVar; i++ )
00579 {
00580 currentState(i) = solution(i);
00581
00582
00583 for( int j=0; j<numVar; j++ )
00584 {
00585 currentErrorCov(i,j) = covMatrix(i,j);
00586 }
00587 }
00588
00589
00590
00591
00592 int c1(numVar);
00593 for( SatIDSet::const_iterator itSat = satSet.begin();
00594 itSat != satSet.end();
00595 ++itSat )
00596 {
00597
00598
00599 currentState(c1) = KalmanData[*itSat].ambiguity;
00600
00601
00602
00603 int c2(numVar);
00604 SatIDSet::const_iterator itSat2;
00605 for( itSat2 = satSet.begin(); itSat2 != satSet.end(); ++itSat2 )
00606 {
00607
00608 currentErrorCov(c1,c2) = KalmanData[*itSat].aCovMap[*itSat2];
00609 currentErrorCov(c2,c1) = KalmanData[*itSat].aCovMap[*itSat2];
00610
00611 ++c2;
00612 }
00613
00614
00615
00616
00617 int c3(0);
00618 TypeIDSet::const_iterator itType;
00619 for( itType = defaultEqDef.body.begin();
00620 itType != defaultEqDef.body.end();
00621 ++itType )
00622 {
00623
00624 currentErrorCov(c1,c3) = KalmanData[*itSat].vCovMap[*itType];
00625 currentErrorCov(c3,c1) = KalmanData[*itSat].vCovMap[*itType];
00626
00627 ++c3;
00628 }
00629
00630 ++c1;
00631 }
00632
00633
00634
00635 kFilter.Reset( currentState, currentErrorCov );
00636
00637 }
00638
00639
00640
00641
00642
00643
00644
00645 Compute( measVector,
00646 hMatrix,
00647 rMatrix );
00648
00649
00650
00651
00652
00653 int c1(numVar);
00654 for( SatIDSet::const_iterator itSat = satSet.begin();
00655 itSat != satSet.end();
00656 ++itSat )
00657 {
00658
00659
00660 KalmanData[*itSat].ambiguity = solution(c1);
00661
00662
00663 int c2(numVar);
00664 SatIDSet::const_iterator itSat2;
00665 for( itSat2 = satSet.begin(); itSat2 != satSet.end(); ++itSat2 )
00666 {
00667
00668 KalmanData[*itSat].aCovMap[*itSat2] = covMatrix(c1,c2);
00669
00670 ++c2;
00671 }
00672
00673
00674 int c3(0);
00675 TypeIDSet::const_iterator itType;
00676 for( itType = defaultEqDef.body.begin();
00677 itType != defaultEqDef.body.end();
00678 ++itType )
00679 {
00680
00681 KalmanData[*itSat].vCovMap[*itType] = covMatrix(c1,c3);
00682
00683 ++c3;
00684 }
00685
00686 ++c1;
00687
00688 }
00689
00690
00691
00692 Vector<double> postfitCode(numCurrentSV,0.0);
00693 Vector<double> postfitPhase(numCurrentSV,0.0);
00694 for( int i=0; i<numCurrentSV; i++ )
00695 {
00696 postfitCode(i) = postfitResiduals( i );
00697 postfitPhase(i) = postfitResiduals( i + numCurrentSV );
00698 }
00699
00700 gData.insertTypeIDVector(TypeID::postfitC, postfitCode);
00701 gData.insertTypeIDVector(TypeID::postfitL, postfitPhase);
00702
00703
00704 satSet = currSatSet;
00705
00706 return gData;
00707
00708 }
00709 catch(Exception& u)
00710 {
00711
00712 ProcessingException e( getClassName() + ":"
00713 + StringUtils::asString( getIndex() ) + ":"
00714 + u.what() );
00715
00716 GPSTK_THROW(e);
00717
00718 }
00719
00720 }
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 SolverPPP& SolverPPP::setNEU( bool useNEU )
00731 {
00732
00733
00734 TypeIDSet tempSet;
00735
00736
00737 tempSet.insert(TypeID::wetMap);
00738
00739 if (useNEU)
00740 {
00741 tempSet.insert(TypeID::dLat);
00742 tempSet.insert(TypeID::dLon);
00743 tempSet.insert(TypeID::dH);
00744 }
00745 else
00746 {
00747 tempSet.insert(TypeID::dx);
00748 tempSet.insert(TypeID::dy);
00749 tempSet.insert(TypeID::dz);
00750 }
00751 tempSet.insert(TypeID::cdt);
00752
00753
00754 defaultEqDef.header = TypeID::prefitC;
00755 defaultEqDef.body = tempSet;
00756
00757 return (*this);
00758
00759 }
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774 SolverPPP& SolverPPP::setCoordinatesModel( StochasticModel* pModel )
00775 {
00776
00777
00778 pCoordXStoModel = pModel;
00779 pCoordYStoModel = pModel;
00780 pCoordZStoModel = pModel;
00781
00782 return (*this);
00783
00784 }
00785
00786
00787
00790 SolverPPP& SolverPPP::setKinematic( bool kinematicMode,
00791 double sigmaX,
00792 double sigmaY,
00793 double sigmaZ )
00794 {
00795 if(kinematicMode)
00796 {
00797 whitenoiseModelX.setSigma(sigmaX);
00798 whitenoiseModelY.setSigma(sigmaY);
00799 whitenoiseModelZ.setSigma(sigmaZ);
00800
00801 setXCoordinatesModel(&whitenoiseModelX);
00802 setYCoordinatesModel(&whitenoiseModelY);
00803 setZCoordinatesModel(&whitenoiseModelZ);
00804 }
00805 else
00806 {
00807 setCoordinatesModel(&constantModel);
00808 }
00809
00810 return (*this);
00811
00812 }
00813
00814
00815 }