33 #include <visp3/ustk_needle_modeling/usUnscentedKalmanFilter.h>
37 #if defined(VISP_HAVE_EIGEN3)
38 #include <eigen3/Eigen/Cholesky>
42 vpMatrix root(
const vpMatrix &M)
44 if(M.getCols() != M.getRows())
throw vpException(vpException::dimensionError,
"NeedleUpdate::root(const vpMatrix&): input matrix should be square");
46 vpMatrix sqrtM(M.getRows(), M.getCols());
48 #if defined(VISP_HAVE_EIGEN3)
49 Eigen::MatrixXd Meigen(M.getRows(),M.getCols());
51 for(
unsigned int i =0 ; i<M.getRows() ; i++)
53 for(
unsigned int j=0 ; j<M.getCols() ; j++)
55 Meigen(i,j) = M[i][j];
59 Eigen::MatrixXd sqrtMeigen(Meigen.llt().matrixL());
61 for(
unsigned int i =0 ; i<M.getRows() ; i++)
63 for(
unsigned int j=0 ; j<M.getCols() ; j++)
65 sqrtM[i][j] = sqrtMeigen(i,j);
76 catch(std::exception &e)
80 A = M + std::numeric_limits<double>::epsilon() * I;
83 for(
unsigned int i=0 ; i<w.size() ; i++)
85 if(w[i] > 1e-8 * w[0]) sqrtM.insert(sqrt(w[i])*A.getCol(i), 0,i);
93 m_measureDimension(0),
94 m_processNoiseDimension(0),
95 m_measureNoiseDimension(0),
98 m_stateCovarianceMatrix(),
101 m_processNoiseCovarianceMatrix(),
102 m_computeProcessNoiseCovarianceMatrixAutomatically(false),
105 m_measureNoiseCovarianceMatrix(),
106 m_computeMeasureNoiseCovarianceMatrixAutomatically(false),
112 m_sigmaPointsPropagated(),
113 m_sigmaPointsMeasure(),
114 m_sigmaPointsMeanWeights(),
115 m_sigmaPointsCovarianceWeights(),
116 m_sigmaPointsScalingFactor(1),
117 m_sigmaPointsSpreadThreshold(std::numeric_limits<double>::max()),
120 m_measureSigmaMean(),
121 m_stateSigmaCovarianceMatrix(),
122 m_stateMeasureSigmaCovarianceMatrix(),
123 m_measureSigmaCovarianceMatrix()
140 if(dim <= 0)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setStateDimension: state dimension should be positive");
157 if(dim <= 0)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setMeasureDimension: measure dimension should be positive");
182 if(dim <= 0)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setProcessNoiseDimension: noise dimension should be positive");
205 if(dim <= 0)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setMeasureNoiseDimension: noise dimension should be positive");
249 if(state.getRows() !=
m_stateDimension)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setState: invalid state dimension");
261 if(mat.getRows() !=
m_stateDimension || mat.getCols() !=
m_stateDimension)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::setStateCovarianceMatrix: invalid matrix dimension");
314 if(measure.size() !=
m_measureDimension)
throw vpException(vpException::dimensionError,
"usUnscentedKalmanFilter::checkConsistency: invamid input measure dimension (%d), should be %d", measure.size(),
m_measureDimension);
331 int augmentedStateDimension = 0;
332 vpMatrix augmentedStateCovarianceMatrix;
336 case NoiseType::ADDITIVE_NOISE:
340 case NoiseType::ADDITIVE_NOISE:
346 case NoiseType::GENERIC_NOISE:
349 augmentedStateCovarianceMatrix.resize(augmentedStateDimension,augmentedStateDimension);
357 case NoiseType::GENERIC_NOISE:
361 case NoiseType::ADDITIVE_NOISE:
364 augmentedStateCovarianceMatrix.resize(augmentedStateDimension,augmentedStateDimension);
369 case NoiseType::GENERIC_NOISE:
372 augmentedStateCovarianceMatrix.resize(augmentedStateDimension,augmentedStateDimension);
387 rootP = root(augmentedStateCovarianceMatrix);
389 catch (std::exception &e)
391 std::cout <<
"usUnscentedKalmanFilter::generateSigmaPoints failed: " << e.what() << std::endl;
396 const double beta = 2;
400 case SigmaPointGenerationType::STANDARD_COVARIANCE:
405 case SigmaPointGenerationType::FIXED_SCALING_FACTOR:
410 case SigmaPointGenerationType::LIMITED_SPREAD:
416 if(val > max) max = val;
424 double lambda = alpha*alpha*(augmentedStateDimension+k)-augmentedStateDimension;
426 vpMatrix sqrtP = sqrt(fabs(augmentedStateDimension+lambda))*rootP;
430 vpColVector sigmaCenter(augmentedStateDimension, 0);
433 for(
int i=0 ; i<augmentedStateDimension ; i++)
436 for(
int j=0 ; j<augmentedStateDimension ; j++)
m_sigmaPointsInit[i][j+1] = sigmaCenter[i] + sqrtP[i][j];
437 for(
int j=0 ; j<augmentedStateDimension ; j++)
m_sigmaPointsInit[i][j+augmentedStateDimension+1] = sigmaCenter[i] - sqrtP[i][j];
462 vpColVector propagatedSigmaPoint;
467 catch(std::exception &e)
469 std::cout <<
"usUnscentedKalmanFilter::computePropagatedSigmaPoints failed: " << e.what() << std::endl;
480 vpColVector measureCenter;
485 catch(std::exception &e)
487 std::cout <<
"usUnscentedKalmanFilter::computeSigmaMeasures failed: " << e.what() << std::endl;
493 vpColVector sigmaMeasure;
498 catch(std::exception &e)
500 std::cout <<
"usUnscentedKalmanFilter::computeSigmaMeasures failed: " << e.what() << std::endl;
520 case NoiseType::ADDITIVE_NOISE:
525 case NoiseType::GENERIC_NOISE:
542 case NoiseType::ADDITIVE_NOISE:
547 case NoiseType::GENERIC_NOISE:
566 catch (std::exception &e)
568 std::cout <<
"usUnscentedKalmanFilter::updateState failed: " << e.what() << std::endl;
594 return state.frobeniusNorm();
bool computeProcessNoiseCovarianceMatrixAutomatically() const
virtual void computeProcessNoiseCovarianceMatrix()
double m_sigmaPointsScalingFactor
virtual vpColVector measureLog(const vpColVector &measure, const vpColVector &measureCenter) const
void setProcessNoiseCovarianceMatrix(const vpMatrix &cov)
vpMatrix m_sigmaPointsMeasure
NoiseType getProcessNoiseType() const
double getSigmaPointSpreadThreshold() const
void computeMeansAndCovarianceMatricesFromSigmaPoints()
vpMatrix m_stateCovarianceMatrix
usUnscentedKalmanFilter()
vpColVector m_sigmaPointsCovarianceWeights
void setMeasureNoiseCovarianceMatrix(const vpMatrix &cov)
vpMatrix m_sigmaPointsInit
int getProcessNoiseDimension() const
virtual double stateNorm(const vpColVector &state) const
unsigned int m_measureNoiseDimension
bool m_computeMeasureNoiseCovarianceMatrixAutomatically
void setSigmaPointSpreadThreshold(double threshold)
void setMeasureDimension(int dim)
void setProcessNoiseDimension(int dim)
vpMatrix m_measureNoiseCovarianceMatrix
NoiseType m_measureNoiseType
unsigned int m_stateDimension
void setProcessNoiseType(NoiseType type)
void setStateCovarianceMatrix(const vpMatrix &mat)
bool computePropagatedSigmaPoints()
void setMeasureNoiseType(NoiseType type)
virtual vpColVector stateLog(const vpColVector &state, const vpColVector &stateCenter) const
vpColVector m_sigmaPointsMeanWeights
NoiseType m_processNoiseType
unsigned int m_processNoiseDimension
vpColVector getState() const
vpMatrix getStateCovarianceMatrix() const
bool m_computeProcessNoiseCovarianceMatrixAutomatically
vpMatrix getMeasureNoiseCovarianceMatrix() const
int getStateDimension() const
bool filter(const vpColVector &measure)
void setState(const vpColVector &state)
vpMatrix getProcessNoiseCovarianceMatrix() const
vpMatrix m_measureSigmaCovarianceMatrix
void setSigmaPointScalingFactor(double factor)
vpMatrix m_stateMeasureSigmaCovarianceMatrix
int getMeasureDimension() const
SigmaPointGenerationType getSigmaPointGenerationType() const
virtual vpColVector computeMeasureFromSigmaPoint(const vpColVector &sigmaPoint)=0
bool computeMeasureNoiseCovarianceMatrixAutomatically() const
bool generateSigmaPoints()
virtual bool checkConsistency(const vpColVector &measure)
virtual ~usUnscentedKalmanFilter()
vpColVector m_measureSigmaMean
vpMatrix m_stateSigmaCovarianceMatrix
virtual vpColVector propagateSigmaPoint(const vpColVector &sigmaPoint)=0
void setMeasureNoiseDimension(int dim)
double getSigmaPointScalingFactor() const
double m_sigmaPointsSpreadThreshold
virtual void computeMeasureNoiseCovarianceMatrix()
int getMeasureNoiseDimension() const
void setStateDimension(int dim)
vpMatrix m_sigmaPointsPropagated
unsigned int m_measureDimension
void setSigmaPointGenerationType(SigmaPointGenerationType type)
SigmaPointGenerationType m_sigmaPointsGenerationType
vpMatrix m_processNoiseCovarianceMatrix
vpColVector m_stateSigmaMean
virtual vpColVector stateExp(const vpColVector &state, const vpColVector &stateCenter) const
NoiseType getMeasureNoiseType() const
bool computeSigmaMeasures()