00001 #pragma ident "$Id: $"
00002
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "SuperKalmanFilter.hpp"
00034 #include "MatrixFunctors.hpp"
00035
00036
00037 namespace gpstk
00038 {
00040 SuperKalmanFilter::SuperKalmanFilter()
00041 : xhat(1,0.0), P(1,1,0.0), xhatminus(1,0.0), Pminus(1,1,0.0),
00042 weightFactor(ident<double>(1))
00043 {
00044 }
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 SuperKalmanFilter::SuperKalmanFilter( const Vector<double>& initialState,
00055 const Matrix<double>& initialErrorCovariance )
00056 : xhat(initialState), P(initialErrorCovariance),
00057 xhatminus(initialState.size(), 0.0),
00058 Pminus(initialErrorCovariance.rows(),
00059 initialErrorCovariance.cols(), 0.0),
00060 weightFactor(ident<double>(initialState.size()))
00061 {
00062 }
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 SuperKalmanFilter::SuperKalmanFilter( const double& initialValue,
00073 const double& initialErrorVariance )
00074 : xhat(1,initialValue),
00075 P(1,1,initialErrorVariance), xhatminus(1,0.0),
00076 Pminus(1,1,0.0),
00077 weightFactor(ident<double>(1))
00078 {
00079 }
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void SuperKalmanFilter::Reset( const Vector<double>& initialState,
00093 const Matrix<double>& initialErrorCovariance )
00094 {
00095
00096 xhat = initialState;
00097 P = initialErrorCovariance;
00098 xhatminus.resize(initialState.size(), 0.0);
00099 Pminus.resize( initialErrorCovariance.rows(),
00100 initialErrorCovariance.cols(), 0.0);
00101
00102 weightFactor = ident<double>(xhat.size());
00103
00104 }
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117 void SuperKalmanFilter::Reset( const double& initialValue,
00118 const double& initialErrorVariance )
00119 {
00120
00121 xhat.resize(1, initialValue);
00122 P.resize(1,1, initialErrorVariance);
00123 xhatminus.resize(1, 0.0);
00124 Pminus.resize(1, 1, 0.0);
00125
00126 weightFactor = ident<double>(xhat.size());
00127
00128 }
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147 int SuperKalmanFilter::Predict( const Matrix<double>& phiMatrix,
00148 const Vector<double>& previousState,
00149 const Matrix<double>& previousErrorCovariance,
00150 const Matrix<double>& controlMatrix,
00151 const Vector<double>& controlInput,
00152 const Matrix<double>& processNoiseCovariance )
00153 throw(InvalidSolver)
00154 {
00155
00156 int aposterioriStateRow(previousState.size());
00157 int controlInputRow(controlInput.size());
00158
00159 int phiCol(phiMatrix.cols());
00160 int phiRow(phiMatrix.rows());
00161
00162 int covCol(previousErrorCovariance.cols());
00163 int covRow(previousErrorCovariance.rows());
00164
00165 int controlCol(controlMatrix.cols());
00166 int controlRow(controlMatrix.rows());
00167
00168 int processNoiseRow(processNoiseCovariance.rows());
00169
00170 if ( phiCol != phiRow )
00171 {
00172 InvalidSolver e("Predict(): State transition matrix is not square, \
00173 and it must be.");
00174 GPSTK_THROW(e);
00175 }
00176
00177 if ( phiCol != aposterioriStateRow )
00178 {
00179 InvalidSolver e("Predict(): Sizes of state transition matrix and \
00180 a posteriori state estimation vector do not match.");
00181 GPSTK_THROW(e);
00182 }
00183
00184 if ( controlCol != controlInputRow )
00185 {
00186 InvalidSolver e("Predict(): Sizes of control matrix and a control \
00187 input vector do not match.");
00188 GPSTK_THROW(e);
00189 }
00190
00191 if ( aposterioriStateRow != controlRow )
00192 {
00193 InvalidSolver e("Predict(): Sizes of control matrix and a \
00194 posteriori state estimation vector do not match.");
00195 GPSTK_THROW(e);
00196 }
00197
00198 if ( phiRow != processNoiseRow )
00199 {
00200 InvalidSolver e("Predict(): Sizes of state transition matrix and \
00201 process noise covariance matrix do not match.");
00202 GPSTK_THROW(e);
00203 }
00204
00205 if( (aposterioriStateRow != covRow) || (covRow != covCol) )
00206 {
00207 InvalidSolver e("Predict(): Sizes of state vector and \
00208 state error covariance matrix do not match.");
00209 GPSTK_THROW(e);
00210 }
00211
00212
00213 try
00214 {
00215
00216 xhatminus = phiMatrix*previousState + controlMatrix * controlInput;
00217
00218 Matrix<double> phiT(transpose(phiMatrix));
00219
00220
00221 Pminus = phiMatrix * previousErrorCovariance * phiT
00222 + processNoiseCovariance;
00223 }
00224 catch(...)
00225 {
00226 InvalidSolver e("Predict(): Unable to predict next state.");
00227 GPSTK_THROW(e);
00228 return -1;
00229 }
00230
00231 return 0;
00232
00233 }
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252 int SuperKalmanFilter::Correct( const Vector<double>& measurements,
00253 const Matrix<double>& measurementsMatrix,
00254 const Matrix<double>& measurementsNoiseCovariance )
00255 throw(InvalidSolver)
00256 {
00257
00258 int measRow(measurements.size());
00259 int aprioriStateRow(xhatminus.size());
00260
00261 int mMRow(measurementsMatrix.rows());
00262
00263 int mNCCol(measurementsNoiseCovariance.cols());
00264 int mNCRow(measurementsNoiseCovariance.rows());
00265
00266 int pMCol(Pminus.cols());
00267 int pMRow(Pminus.rows());
00268
00269 if ( ( mNCCol != mNCRow ) ||
00270 ( pMCol != pMRow ) )
00271 {
00272 InvalidSolver e("Correct(): Either Pminus or measurement covariance \
00273 matrices are not square, and therefore not invertible.");
00274 GPSTK_THROW(e);
00275 }
00276
00277 if ( mMRow != mNCRow )
00278 {
00279 InvalidSolver e("Correct(): Sizes of measurements matrix and \
00280 measurements noise covariance matrix do not match.");
00281 GPSTK_THROW(e);
00282 }
00283
00284 if ( mNCCol != measRow )
00285 {
00286 InvalidSolver e("Correct(): Sizes of measurements matrix and \
00287 measurements vector do not match.");
00288 GPSTK_THROW(e);
00289 }
00290
00291 if ( pMCol != aprioriStateRow )
00292 {
00293 InvalidSolver e("Correct(): Sizes of a priori error covariance \
00294 matrix and a priori state estimation vector do not match.");
00295 GPSTK_THROW(e);
00296 }
00297
00298
00299 Matrix<double> invR;
00300 Matrix<double> invPMinus;
00301 Matrix<double> measMatrixT( transpose(measurementsMatrix) );
00302
00303 try
00304 {
00305
00306 invR = inverseChol(measurementsNoiseCovariance);
00307
00308
00309 Matrix<double> weightMatrix(invR);
00310
00311 invR = weightMatrix;
00312 }
00313 catch(...)
00314 {
00315 InvalidSolver e("Correct(): Unable to compute invR matrix.");
00316 GPSTK_THROW(e);
00317 return -1;
00318 }
00319
00320 try
00321 {
00322
00323 invPMinus = inverseChol(Pminus);
00324
00325
00326
00327
00328
00329
00330
00331 Matrix<double> weightMatrix(invPMinus);
00332
00333 invPMinus = weightFactor * weightMatrix * weightFactor;
00334
00335 }
00336 catch(...)
00337 {
00338 InvalidSolver e("Correct(): Unable to compute invPMinus matrix.");
00339 GPSTK_THROW(e);
00340 return -1;
00341 }
00342
00343 try
00344 {
00345
00346 Matrix<double> invTemp( measMatrixT * invR * measurementsMatrix
00347 +invPMinus );
00348
00349
00350 P = inverseChol( invTemp );
00351
00352 }
00353 catch(...)
00354 {
00355 InvalidSolver e("Correct(): Unable to compute P matrix.");
00356 GPSTK_THROW(e);
00357 return -1;
00358 }
00359
00360 try
00361 {
00362
00363
00364 xhat = P * ( (measMatrixT * invR * measurements)
00365 +(invPMinus * xhatminus) );
00366
00367 }
00368 catch(Exception e)
00369 {
00370 InvalidSolver eis("Correct(): Unable to compute xhat.");
00371 GPSTK_THROW(eis);
00372 return -1;
00373 }
00374
00375 return 0;
00376
00377 }
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 int SuperKalmanFilter::Compute( const Matrix<double>& phiMatrix,
00398 const Matrix<double>& controlMatrix,
00399 const Vector<double>& controlInput,
00400 const Matrix<double>& processNoiseCovariance,
00401 const Vector<double>& measurements,
00402 const Matrix<double>& measurementsMatrix,
00403 const Matrix<double>& measurementsNoiseCovariance )
00404 throw(InvalidSolver)
00405 {
00406
00407 try
00408 {
00409 Predict( phiMatrix,
00410 xhat,
00411 P,
00412 controlMatrix,
00413 controlInput,
00414 processNoiseCovariance );
00415
00416 Correct( measurements,
00417 measurementsMatrix,
00418 measurementsNoiseCovariance );
00419 }
00420 catch(InvalidSolver e)
00421 {
00422 GPSTK_THROW(e);
00423 return -1;
00424 }
00425
00426 return 0;
00427
00428 }
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 int SuperKalmanFilter::Compute( const Vector<double>& stateVector,
00450 const Matrix<double>& phiMatrix,
00451 const Matrix<double>& controlMatrix,
00452 const Vector<double>& controlInput,
00453 const Matrix<double>& processNoiseCovariance,
00454 const Vector<double>& measurements,
00455 const Matrix<double>& measurementsMatrix,
00456 const Matrix<double>& measurementsNoiseCovariance )
00457 throw(InvalidSolver)
00458 {
00459 try
00460 {
00461
00462 if(stateVector.size() != xhat.size())
00463 {
00464 InvalidSolver e("Compute(): Sizes of predicted state vector and \
00465 a priori state vector do not match.");
00466 GPSTK_THROW(e);
00467 }
00468
00469 Predict( phiMatrix,
00470 xhat,
00471 P,
00472 controlMatrix,
00473 controlInput,
00474 processNoiseCovariance );
00475
00476 xhatminus = stateVector;
00477
00478 Correct( measurements,
00479 measurementsMatrix,
00480 measurementsNoiseCovariance );
00481 }
00482 catch(InvalidSolver e)
00483 {
00484 GPSTK_THROW(e);
00485 return -1;
00486 }
00487
00488 return 0;
00489
00490 }
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506
00507
00508
00509 int SuperKalmanFilter::Compute( const Matrix<double>& phiMatrix,
00510 const Matrix<double>& processNoiseCovariance,
00511 const Vector<double>& measurements,
00512 const Matrix<double>& measurementsMatrix,
00513 const Matrix<double>& measurementsNoiseCovariance )
00514 throw(InvalidSolver)
00515 {
00516
00517 try
00518 {
00519 Matrix<double> dummyControMatrix(xhat.size(),1,0.0);
00520 Vector<double> dummyControlInput(1,0.0);
00521
00522 Predict( phiMatrix,
00523 xhat,
00524 P,
00525 dummyControMatrix,
00526 dummyControlInput,
00527 processNoiseCovariance );
00528
00529 Correct( measurements,
00530 measurementsMatrix,
00531 measurementsNoiseCovariance );
00532 }
00533 catch(InvalidSolver e)
00534 {
00535 GPSTK_THROW(e);
00536 return -1;
00537 }
00538
00539 return 0;
00540
00541 }
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 int SuperKalmanFilter::Compute( const Vector<double>& stateVector,
00562 const Matrix<double>& phiMatrix,
00563 const Matrix<double>& processNoiseCovariance,
00564 const Vector<double>& measurements,
00565 const Matrix<double>& measurementsMatrix,
00566 const Matrix<double>& measurementsNoiseCovariance )
00567 throw(InvalidSolver)
00568 {
00569 try
00570 {
00571
00572 if(stateVector.size() != xhat.size())
00573 {
00574 InvalidSolver e("Compute(): Sizes of predicted state vector and \
00575 a priori state vector do not match.");
00576 GPSTK_THROW(e);
00577 }
00578
00579 Matrix<double> dummyControMatrix(xhat.size(),1,0.0);
00580 Vector<double> dummyControlInput(1,0.0);
00581
00582 Predict( phiMatrix,
00583 xhat,
00584 P,
00585 dummyControMatrix,
00586 dummyControlInput,
00587 processNoiseCovariance );
00588
00589 xhatminus = stateVector;
00590
00591 Correct( measurements,
00592 measurementsMatrix,
00593 measurementsNoiseCovariance );
00594 }
00595 catch(InvalidSolver e)
00596 {
00597 GPSTK_THROW(e);
00598 return -1;
00599 }
00600
00601 return 0;
00602
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622 int SuperKalmanFilter::Compute( const double& phiValue,
00623 const double& controlGain,
00624 const double& controlInput,
00625 const double& processNoiseVariance,
00626 const double& measurement,
00627 const double& measurementsGain,
00628 const double& measurementsNoiseVariance )
00629 throw(InvalidSolver)
00630 {
00631
00632 try
00633 {
00634 const int size = xhat.size();
00635
00636 Matrix<double> phiMatrix(size,size,phiValue);
00637 Matrix<double> dummyControlMatrix(size,1,controlGain);
00638 Vector<double> dummyControlInput(1,controlInput);
00639 Matrix<double> prvMatrix(size,size,processNoiseVariance);
00640
00641 Vector<double> dummyMeasurements(1,measurement);
00642 Matrix<double> measurementsMatrix(1,size,measurementsGain);
00643 Matrix<double> mnvMatrix(1,1,measurementsNoiseVariance);
00644
00645 Compute(phiMatrix,dummyControlMatrix,dummyControlInput,prvMatrix,
00646 dummyMeasurements,measurementsMatrix,mnvMatrix);
00647 }
00648 catch(InvalidSolver e)
00649 {
00650 GPSTK_THROW(e);
00651 return -1;
00652 }
00653
00654 return 0;
00655
00656 }
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673
00674
00675
00676 int SuperKalmanFilter::Compute( const double& stateValue,
00677 const double& phiValue,
00678 const double& controlGain,
00679 const double& controlInput,
00680 const double& processNoiseVariance,
00681 const double& measurement,
00682 const double& measurementsGain,
00683 const double& measurementsNoiseVariance )
00684 throw(InvalidSolver)
00685 {
00686
00687 try
00688 {
00689 const int size = xhat.size();
00690
00691 Matrix<double> phiMatrix(size,size,phiValue);
00692 Matrix<double> dummyControlMatrix(size,1,controlGain);
00693 Vector<double> dummyControlInput(1,controlInput);
00694 Matrix<double> prvMatrix(size,size,processNoiseVariance);
00695
00696 Vector<double> dummyMeasurements(1,measurement);
00697 Matrix<double> measurementsMatrix(1,size,measurementsGain);
00698 Matrix<double> mnvMatrix(1,1,measurementsNoiseVariance);
00699
00700 Vector<double> stateVector(size,stateValue);
00701
00702 Compute(stateVector,phiMatrix,dummyControlMatrix,dummyControlInput,prvMatrix,
00703 dummyMeasurements,measurementsMatrix,mnvMatrix);
00704 }
00705 catch(InvalidSolver e)
00706 {
00707 GPSTK_THROW(e);
00708 return -1;
00709 }
00710
00711 return 0;
00712
00713 }
00714
00715
00716
00717
00718
00719
00720
00721
00722
00723
00724
00725
00726
00727
00728
00729
00730 int SuperKalmanFilter::Compute( const double& phiValue,
00731 const double& processNoiseVariance,
00732 const double& measurement,
00733 const double& measurementsGain,
00734 const double& measurementsNoiseVariance )
00735 throw(InvalidSolver)
00736 {
00737
00738 try
00739 {
00740 const int size = xhat.size();
00741
00742 Matrix<double> phiMatrix(size,size,phiValue);
00743 Matrix<double> dummyControlMatrix(size,1,0.0);
00744 Vector<double> dummyControlInput(1,0.0);
00745 Matrix<double> prvMatrix(size,size,processNoiseVariance);
00746
00747 Vector<double> dummyMeasurements(1,measurement);
00748 Matrix<double> measurementsMatrix(1,size,measurementsGain);
00749 Matrix<double> mnvMatrix(1,1,measurementsNoiseVariance);
00750
00751 Compute(phiMatrix,dummyControlMatrix,dummyControlInput,prvMatrix,
00752 dummyMeasurements,measurementsMatrix,mnvMatrix);
00753 }
00754 catch(InvalidSolver e)
00755 {
00756 GPSTK_THROW(e);
00757 return -1;
00758 }
00759
00760 return 0;
00761
00762 }
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780 int SuperKalmanFilter::Compute( const double& stateValue,
00781 const double& phiValue,
00782 const double& processNoiseVariance,
00783 const double& measurement,
00784 const double& measurementsGain,
00785 const double& measurementsNoiseVariance )
00786 throw(InvalidSolver)
00787 {
00788
00789 try
00790 {
00791 const int size = xhat.size();
00792
00793 Matrix<double> phiMatrix(size,size,phiValue);
00794 Matrix<double> dummyControlMatrix(size,1,0.0);
00795 Vector<double> dummyControlInput(1,0.0);
00796 Matrix<double> prvMatrix(size,size,processNoiseVariance);
00797
00798 Vector<double> dummyMeasurements(1,measurement);
00799 Matrix<double> measurementsMatrix(1,size,measurementsGain);
00800 Matrix<double> mnvMatrix(1,1,measurementsNoiseVariance);
00801
00802 Vector<double> stateVector(size,stateValue);
00803
00804 Compute(stateVector,phiMatrix,dummyControlMatrix,dummyControlInput,prvMatrix,
00805 dummyMeasurements,measurementsMatrix,mnvMatrix);
00806 }
00807 catch(InvalidSolver e)
00808 {
00809 GPSTK_THROW(e);
00810 return -1;
00811 }
00812
00813 return 0;
00814
00815 }
00816
00817 }
00818
00819