35template <
typename SystemModelT>
42 chol_Q_(Q.llt().matrixL().transpose()),
45 state_(
std::move(state0)),
51template <
typename SystemModelT>
62 Eigen::LLT<StateCovT> llt = P.llt();
63 if (llt.info() != Eigen::ComputationInfo::Success)
65 P = calculateClosestPosSemidefMatrix(P);
66 P +=
eps * StateCovT::Identity();
68 ARMARX_CHECK(llt.info() == Eigen::ComputationInfo::Success);
71 weights_.state.sqrt_d_lambda * llt.matrixL().transpose().toDenseMatrix();
75 auto propagate_and_retract = [&omega, &
dt, &state_after](
long row,
88 xi_j.rowwise() -= xi_0.transpose();
89 StateCovT cov_after = wj * xi_j.transpose() * xi_j + w0 * xi_0 * xi_0.transpose();
93 for (
long j = 0; j < dim::state; j++)
98 propagate_and_retract(j, 0, sig_j_plus, w, xi_j_after);
99 propagate_and_retract(j, dim::state, sig_j_minus, w, xi_j_after);
102 StateCovT P_after = calculate_covariance(weights_.state.wj, weights_.state.w0, xi_j_after);
104 for (
long j = 0; j < dim::control; j++)
106 const ControlNoiseT w_plus = weights_.control.sqrt_d_lambda * chol_Q_.row(j);
107 const ControlNoiseT w_minus = -weights_.control.sqrt_d_lambda * chol_Q_.row(j);
108 propagate_and_retract(j, 0, state_, w_plus, w_j_after);
109 propagate_and_retract(j, dim::control, state_, w_minus, w_j_after);
112 StateCovT Q = calculate_covariance(weights_.control.wj, weights_.control.w0, w_j_after);
115 P_ = std::move((new_P + new_P.transpose()) / 2.0f);
116 state_ = std::move(state_after);
119template <
typename SystemModelT>
125 StateCovT xi_j = weights_.state.sqrt_d_lambda * P.llt().matrixL().transpose().toDenseMatrix();
126 ARMARX_CHECK(P.llt().info() == Eigen::ComputationInfo::Success);
132 for (
long j = 0; j < dim::state; j++)
142 weights_.update.wm * y_hat + weights_.update.wj * y_j.colwise().sum().transpose();
143 y_j.rowwise() -= y_mean.transpose();
146 const ObsCovT P_yy = weights_.update.w0 * y_hat * y_hat.transpose() +
147 weights_.update.wj * y_j.transpose() * y_j + R_;
155 P_yy.colPivHouseholderQr().solve(P_xiy.transpose()).transpose();
156 FloatT relative_error = (P_yy * K.transpose() - P_xiy.transpose()).norm() / P_xiy.norm();
162 StateCovT new_P = P - K * (P_yy)*K.transpose();
165 P_ = calculateClosestPosSemidefMatrix(new_P);
168template <
typename SystemModelT>
175template <
typename SystemModelT>
182template <
typename SystemModelT>
184UnscentedKalmanFilter<SystemModelT>::calculateClosestPosSemidefMatrix(
187 const StateCovT new_P = ((cov + cov.transpose()) / 2.0f);
188 Eigen::EigenSolver<StateCovT> solver(new_P);
193 return (V * D * V.inverse());
196template <
typename SystemModelT>
197UnscentedKalmanFilter<SystemModelT>::Weights::Weights(AlphaT alpha) :
202template <
typename SystemModelT>
206 FloatT m = (alpha * alpha - 1) * l;
208 wj = 1 / (2 * (l + m));
210 w0 = m / (m + l) + 3 - alpha * alpha;
224template <
typename SystemModelT>
230 R_(
std::move(R)), alpha_(alpha), state_(
std::move(state0)), P_(
std::move(P0)), weights_(alpha)
234template <
typename SystemModelT>
245 Eigen::LLT<StateCovT> llt = P.llt();
246 if (llt.info() != Eigen::ComputationInfo::Success)
248 P = calculateClosestPosSemidefMatrix(P);
249 P +=
eps * StateCovT::Identity();
251 ARMARX_CHECK(llt.info() == Eigen::ComputationInfo::Success);
254 weights_.state.sqrt_d_lambda * llt.matrixL().transpose().toDenseMatrix();
258 auto propagate_and_retract =
259 [&
dt, &state_after](
long row,
long offset,
const StateT& state,
auto& xi_j) ->
void
268 xi_j.rowwise() -= xi_0.transpose();
269 StateCovT cov_after = wj * xi_j.transpose() * xi_j + w0 * xi_0 * xi_0.transpose();
273 for (
long j = 0; j < dim::state; j++)
278 propagate_and_retract(j, 0, sig_j_plus, xi_j_after);
279 propagate_and_retract(j, dim::state, sig_j_minus, xi_j_after);
282 StateCovT P_after = calculate_covariance(weights_.state.wj, weights_.state.w0, xi_j_after);
295 P_ = std::move((new_P + new_P.transpose()) / 2.0f);
297 state_ = std::move(state_after);
300template <
typename SystemModelT>
306 StateCovT xi_j = weights_.state.sqrt_d_lambda * P.llt().matrixL().transpose().toDenseMatrix();
307 ARMARX_CHECK(P.llt().info() == Eigen::ComputationInfo::Success);
313 for (
long j = 0; j < dim::state; j++)
323 weights_.update.wm * y_hat + weights_.update.wj * y_j.colwise().sum().transpose();
324 y_j.rowwise() -= y_mean.transpose();
327 const ObsCovT P_yy = weights_.update.w0 * y_hat * y_hat.transpose() +
328 weights_.update.wj * y_j.transpose() * y_j + R_;
336 P_yy.colPivHouseholderQr().solve(P_xiy.transpose()).transpose();
337 FloatT relative_error = (P_yy * K.transpose() - P_xiy.transpose()).norm() / P_xiy.norm();
341 const auto residual = y - y_mean;
346 StateCovT new_P = P - K * (P_yy)*K.transpose();
349 P_ = calculateClosestPosSemidefMatrix(new_P);
352template <
typename SystemModelT>
359template <
typename SystemModelT>
366template <
typename SystemModelT>
368UnscentedKalmanFilterWithoutControl<SystemModelT>::calculateClosestPosSemidefMatrix(
371 const StateCovT new_P = ((cov + cov.transpose()) / 2.0f);
372 Eigen::EigenSolver<StateCovT> solver(new_P);
377 return (V * D * V.inverse());
380template <
typename SystemModelT>
381UnscentedKalmanFilterWithoutControl<SystemModelT>::Weights::Weights(AlphaT alpha) :
382 state(dim::state, alpha(0)),
update(dim::state, alpha(2))
386template <
typename SystemModelT>
390 FloatT m = (alpha * alpha - 1) * l;
392 wj = 1 / (2 * (l + m));
394 w0 = m / (m + l) + 3 - alpha * alpha;
typename SystemModelT::StateT StateT
UnscentedKalmanFilterWithoutControl()=delete
void propagation(FloatT dt)
const StateCovT & getCurrentStateCovariance() const
Eigen::Matrix< FloatT, dim::obs, dim::obs > ObsCovT
void update(const ObsT &y)
Eigen::Matrix< FloatT, 3, 1 > AlphaT
typename SystemModelT::FloatT FloatT
typename SystemModelT::SigmaPointsT SigmaPointsT
const StateT & getCurrentState() const
Eigen::Matrix< FloatT, dim::state, dim::state > StateCovT
static constexpr float eps
Eigen::Matrix< FloatT, dim::obs, 1 > ObsT
typename SystemModelT::StateT StateT
const StateT & getCurrentState() const
void propagation(const ControlT &omega, FloatT dt)
UnscentedKalmanFilter()=delete
UnscentedKalmanFilter(const PropCovT &Q, ObsCovT R, const AlphaT &alpha, StateT state0, StateCovT P0)
Eigen::Matrix< FloatT, dim::control, dim::control > PropCovT
const StateCovT & getCurrentStateCovariance() const
Eigen::Matrix< FloatT, dim::obs, dim::obs > ObsCovT
void update(const ObsT &y)
typename SystemModelT::ControlNoiseT ControlNoiseT
Eigen::Matrix< FloatT, 3, 1 > AlphaT
typename SystemModelT::FloatT FloatT
typename SystemModelT::SigmaPointsT SigmaPointsT
Eigen::Matrix< FloatT, dim::state, dim::state > StateCovT
static constexpr float eps
Eigen::Matrix< FloatT, dim::obs, 1 > ObsT
typename SystemModelT::ControlT ControlT
#define ARMARX_CHECK_GREATER(lhs, rhs)
This macro evaluates whether lhs is greater (>) than rhs and if it turns out to be false it will thro...
#define ARMARX_CHECK(expression)
Shortcut for ARMARX_CHECK_EXPRESSION.
bool update(mongocxx::collection &coll, const nlohmann::json &query, const nlohmann::json &update)
This file is part of ArmarX.
static ObsT observationFunction(const StateT &state)
static StateT retraction(const StateT &state, const SigmaPointsT &sigmaPoints)
static StateT propagationFunction(const StateT &state, const ControlT &control, const ControlNoiseT &noise, FloatT dt)
static SigmaPointsT inverseRetraction(const StateT &state1, const StateT &state2)
W(size_t l, FloatT alpha)
W(size_t l, FloatT alpha)