35 #include <boost/date_time/posix_time/posix_time.hpp>
36 #include <boost/math/distributions/chi_squared.hpp>
52 for (
int i = 1; i < 500; i++) {
53 boost::math::chi_squared chi_squared_dist(i);
58 void UpdaterMSCKF::update(std::shared_ptr<State> state, std::vector<std::shared_ptr<Feature>> &feature_vec) {
61 if (feature_vec.empty())
65 boost::posix_time::ptime rT0, rT1, rT2, rT3, rT4, rT5;
66 rT0 = boost::posix_time::microsec_clock::local_time();
70 for (
const auto &clone_imu : state->_clones_IMU) {
75 auto it0 = feature_vec.begin();
76 while (it0 != feature_vec.end()) {
83 for (
const auto &pair : (*it0)->timestamps) {
84 ct_meas += (*it0)->timestamps[pair.first].size();
89 (*it0)->to_delete =
true;
90 it0 = feature_vec.erase(it0);
95 rT1 = boost::posix_time::microsec_clock::local_time();
98 std::unordered_map<size_t, std::unordered_map<double, FeatureInitializer::ClonePose>> clones_cam;
99 for (
const auto &clone_calib : state->_calib_IMUtoCAM) {
102 std::unordered_map<double, FeatureInitializer::ClonePose> clones_cami;
103 for (
const auto &clone_imu : state->_clones_IMU) {
106 Eigen::Matrix<double, 3, 3> R_GtoCi = clone_calib.second->Rot() * clone_imu.second->Rot();
107 Eigen::Matrix<double, 3, 1> p_CioinG = clone_imu.second->pos() - R_GtoCi.transpose() * clone_calib.second->pos();
110 clones_cami.insert({clone_imu.first, FeatureInitializer::ClonePose(R_GtoCi, p_CioinG)});
114 clones_cam.insert({clone_calib.first, clones_cami});
118 auto it1 = feature_vec.begin();
119 while (it1 != feature_vec.end()) {
122 bool success_tri =
true;
130 bool success_refine =
true;
136 if (!success_tri || !success_refine) {
137 (*it1)->to_delete =
true;
138 it1 = feature_vec.erase(it1);
143 rT2 = boost::posix_time::microsec_clock::local_time();
146 size_t max_meas_size = 0;
147 for (
size_t i = 0; i < feature_vec.size(); i++) {
148 for (
const auto &pair : feature_vec.at(i)->timestamps) {
149 max_meas_size += 2 * feature_vec.at(i)->timestamps[pair.first].size();
155 size_t max_hx_size = state->max_covariance_size();
156 for (
auto &landmark : state->_features_SLAM) {
157 max_hx_size -= landmark.second->size();
161 Eigen::VectorXd res_big = Eigen::VectorXd::Zero(max_meas_size);
162 Eigen::MatrixXd Hx_big = Eigen::MatrixXd::Zero(max_meas_size, max_hx_size);
163 std::unordered_map<std::shared_ptr<Type>,
size_t> Hx_mapping;
164 std::vector<std::shared_ptr<Type>> Hx_order_big;
169 auto it2 = feature_vec.begin();
170 while (it2 != feature_vec.end()) {
174 feat.
featid = (*it2)->featid;
175 feat.
uvs = (*it2)->uvs;
181 if (state->_options.feat_rep_msckf == LandmarkRepresentation::Representation::ANCHORED_INVERSE_DEPTH_SINGLE) {
182 feat.
feat_representation = LandmarkRepresentation::Representation::ANCHORED_MSCKF_INVERSE_DEPTH;
189 feat.
p_FinA = (*it2)->p_FinA;
192 feat.
p_FinG = (*it2)->p_FinG;
200 std::vector<std::shared_ptr<Type>> Hx_order;
210 Eigen::MatrixXd S = H_x * P_marg * H_x.transpose();
212 double chi2 = res.dot(S.llt().solve(res));
216 if (res.rows() < 500) {
219 boost::math::chi_squared chi_squared_dist(res.rows());
220 chi2_check = boost::math::quantile(chi_squared_dist, 0.95);
226 (*it2)->to_delete =
true;
227 it2 = feature_vec.erase(it2);
238 for (
const auto &var : Hx_order) {
241 if (Hx_mapping.find(var) == Hx_mapping.end()) {
242 Hx_mapping.insert({var, ct_jacob});
243 Hx_order_big.push_back(var);
244 ct_jacob += var->size();
248 Hx_big.block(ct_meas, Hx_mapping[var], H_x.rows(), var->size()) = H_x.block(0, ct_hx, H_x.rows(), var->size());
249 ct_hx += var->size();
253 res_big.block(ct_meas, 0, res.rows(), 1) = res;
254 ct_meas += res.rows();
257 rT3 = boost::posix_time::microsec_clock::local_time();
261 for (
size_t f = 0;
f < feature_vec.size();
f++) {
262 feature_vec[
f]->to_delete =
true;
269 assert(ct_meas <= max_meas_size);
270 assert(ct_jacob <= max_hx_size);
271 res_big.conservativeResize(ct_meas, 1);
272 Hx_big.conservativeResize(ct_meas, ct_jacob);
276 if (Hx_big.rows() < 1) {
279 rT4 = boost::posix_time::microsec_clock::local_time();
282 Eigen::MatrixXd R_big =
_options.
sigma_pix_sq * Eigen::MatrixXd::Identity(res_big.rows(), res_big.rows());
286 rT5 = boost::posix_time::microsec_clock::local_time();
289 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds to clean\n", (rT1 - rT0).total_microseconds() * 1e-6);
290 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds to triangulate\n", (rT2 - rT1).total_microseconds() * 1e-6);
291 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds create system (%d features)\n", (rT3 - rT2).total_microseconds() * 1e-6, (
int)feature_vec.size());
292 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds compress system\n", (rT4 - rT3).total_microseconds() * 1e-6);
293 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds update state (%d size)\n", (rT5 - rT4).total_microseconds() * 1e-6, (
int)res_big.rows());
294 PRINT_ALL(
"[MSCKF-UP]: %.4f seconds total\n", (rT5 - rT1).total_microseconds() * 1e-6);