66 */
77
88#include < BayesFilters/UKFCorrection.h>
9+ #include < BayesFilters/utils.h>
910
1011using namespace bfl ;
1112using namespace bfl ::sigma_point;
@@ -61,6 +62,21 @@ MeasurementModel& UKFCorrection::getMeasurementModel()
6162}
6263
6364
65+ std::pair<bool , VectorXd> UKFCorrection::getLikelihood ()
66+ {
67+ if ((innovations_.rows () == 0 ) || (innovations_.cols () == 0 ))
68+ return std::make_pair (false , VectorXd ());
69+
70+ VectorXd likelihood (innovations_.cols ());
71+ for (std::size_t i = 0 ; i < innovations_.cols (); i++)
72+ {
73+ likelihood (i) = utils::multivariate_gaussian_density (innovations_.col (i), VectorXd::Zero (innovations_.rows ()), predicted_meas_.covariance (i)).coeff (0 );
74+ }
75+
76+ return std::make_pair (true , likelihood);
77+ }
78+
79+
6480void UKFCorrection::correctStep (const GaussianMixture& pred_state, GaussianMixture& corr_state)
6581{
6682 /* Pick the correct measurement model. */
@@ -80,7 +96,8 @@ void UKFCorrection::correctStep(const GaussianMixture& pred_state, GaussianMixtu
8096 /* Initialize predicted measurement GaussianMixture. */
8197 std::pair<std::size_t , std::size_t > meas_sizes = model.getOutputSize ();
8298 std::size_t meas_size = meas_sizes.first + meas_sizes.second ;
83- GaussianMixture pred_meas (pred_state.components , meas_size);
99+ /* GaussianMixture will effectively resize only if it needs to. */
100+ predicted_meas_.resize (pred_state.components , meas_size);
84101
85102 /* Evaluate the joint state-measurement statistics, if possible. */
86103 bool valid = false ;
@@ -94,11 +111,11 @@ void UKFCorrection::correctStep(const GaussianMixture& pred_state, GaussianMixtu
94111 std::tie (std::ignore, noise_covariance_matrix) = model.getNoiseCovarianceMatrix ();
95112 pred_state_augmented.augmentWithNoise (noise_covariance_matrix);
96113
97- std::tie (valid, pred_meas , Pxy) = sigma_point::unscented_transform (pred_state_augmented, ut_weight_, *measurement_model_);
114+ std::tie (valid, predicted_meas_ , Pxy) = sigma_point::unscented_transform (pred_state_augmented, ut_weight_, *measurement_model_);
98115 }
99116 else if (type_ == UKFCorrectionType::Additive)
100117 {
101- std::tie (valid, pred_meas , Pxy) = sigma_point::unscented_transform (pred_state, ut_weight_, *additive_measurement_model_);
118+ std::tie (valid, predicted_meas_ , Pxy) = sigma_point::unscented_transform (pred_state, ut_weight_, *additive_measurement_model_);
102119 }
103120
104121 if (!valid)
@@ -113,8 +130,8 @@ void UKFCorrection::correctStep(const GaussianMixture& pred_state, GaussianMixtu
113130 /* This temporary is required since some MeasurementModel::innovation methods may try to cast from
114131 const Ref<const MatrixXd> to MatrixXd resulting in a bfl::any::bad_any_cast.
115132
116- Hopefully, using std::move, it is possible to steal the memory from pred_meas .mean(). */
117- MatrixXd y_p = std::move (pred_meas .mean ());
133+ Hopefully, using std::move, it is possible to steal the memory from predicted_meas_ .mean(). */
134+ MatrixXd y_p = std::move (predicted_meas_ .mean ());
118135 std::tie (valid_innovation, innovation) = model.innovation (y_p, measurement);
119136
120137 if (!valid_innovation)
@@ -124,21 +141,21 @@ void UKFCorrection::correctStep(const GaussianMixture& pred_state, GaussianMixtu
124141 }
125142
126143 /* Cast innovations once for all. */
127- MatrixXd innovations = any::any_cast<MatrixXd&&>(std::move (innovation));
144+ innovations_ = any::any_cast<MatrixXd&&>(std::move (innovation));
128145
129146 /* Process all the components in the mixture. */
130147 for (size_t i=0 ; i < pred_state.components ; i++)
131148 {
132149 /* Evaluate the Kalman Gain
133150 K = Pxy * (Py)^{-1} */
134- MatrixXd K = Pxy.middleCols (meas_size * i, meas_size) * pred_meas .covariance (i).inverse ();
151+ MatrixXd K = Pxy.middleCols (meas_size * i, meas_size) * predicted_meas_ .covariance (i).inverse ();
135152
136153 /* Evaluate the filtered mean.
137154 x_{k}+ = x{k}- + K * innovation */
138- corr_state.mean (i) = pred_state.mean (i) + K * innovations .col (i);
155+ corr_state.mean (i) = pred_state.mean (i) + K * innovations_ .col (i);
139156
140157 /* Evaluate the filtered covariance
141158 P_{k}+ = P_{k}- - K * Py * K' */
142- corr_state.covariance (i) = pred_state.covariance (i) - K * pred_meas .covariance (i) * K.transpose ();
159+ corr_state.covariance (i) = pred_state.covariance (i) - K * predicted_meas_ .covariance (i) * K.transpose ();
143160 }
144161}
0 commit comments