36 #ifdef RTABMAP_MSCKF_VIO 37 #include <msckf_vio/image_processor.h> 38 #include <msckf_vio/msckf_vio.h> 39 #include <msckf_vio/math_utils.hpp> 40 #include <eigen_conversions/eigen_msg.h> 41 #include <boost/math/distributions/chi_squared.hpp> 42 #include <pcl/common/transforms.h> 47 #ifdef RTABMAP_MSCKF_VIO 48 class ImageProcessorNoROS:
public msckf_vio::ImageProcessor
53 const Transform & imuLocalTransform,
54 const StereoCameraModel & model,
56 msckf_vio::ImageProcessor(0)
60 if(model.left().D_raw().cols == 6)
63 cam0_distortion_model =
"equidistant";
64 cam0_distortion_coeffs[0] = rectified?0:model.left().D_raw().at<
double>(0,0);
65 cam0_distortion_coeffs[1] = rectified?0:model.left().D_raw().at<
double>(0,1);
66 cam0_distortion_coeffs[2] = rectified?0:model.left().D_raw().at<
double>(0,4);
67 cam0_distortion_coeffs[3] = rectified?0:model.left().D_raw().at<
double>(0,5);
72 cam0_distortion_model =
"radtan";
73 cam0_distortion_coeffs[0] = rectified?0:model.left().D_raw().at<
double>(0,0);
74 cam0_distortion_coeffs[1] = rectified?0:model.left().D_raw().at<
double>(0,1);
75 cam0_distortion_coeffs[2] = rectified?0:model.left().D_raw().at<
double>(0,2);
76 cam0_distortion_coeffs[3] = rectified?0:model.left().D_raw().at<
double>(0,3);
78 if(model.right().D_raw().cols == 6)
81 cam1_distortion_model =
"equidistant";
82 cam1_distortion_coeffs[0] = rectified?0:model.right().D_raw().at<
double>(0,0);
83 cam1_distortion_coeffs[1] = rectified?0:model.right().D_raw().at<
double>(0,1);
84 cam1_distortion_coeffs[2] = rectified?0:model.right().D_raw().at<
double>(0,4);
85 cam1_distortion_coeffs[3] = rectified?0:model.right().D_raw().at<
double>(0,5);
90 cam1_distortion_model =
"radtan";
91 cam1_distortion_coeffs[0] = rectified?0:model.right().D_raw().at<
double>(0,0);
92 cam1_distortion_coeffs[1] = rectified?0:model.right().D_raw().at<
double>(0,1);
93 cam1_distortion_coeffs[2] = rectified?0:model.right().D_raw().at<
double>(0,2);
94 cam1_distortion_coeffs[3] = rectified?0:model.right().D_raw().at<
double>(0,3);
97 cam0_resolution[0] = model.left().imageWidth();
98 cam0_resolution[1] = model.left().imageHeight();
100 cam1_resolution[0] = model.right().imageWidth();
101 cam1_resolution[1] = model.right().imageHeight();
103 cam0_intrinsics[0] = rectified?model.left().fx():model.left().K_raw().at<
double>(0,0);
104 cam0_intrinsics[1] = rectified?model.left().fy():model.left().K_raw().at<
double>(1,1);
105 cam0_intrinsics[2] = rectified?model.left().cx():model.left().K_raw().at<
double>(0,2);
106 cam0_intrinsics[3] = rectified?model.left().cy():model.left().K_raw().at<
double>(1,2);
108 cam1_intrinsics[0] = rectified?model.right().fx():model.right().K_raw().at<
double>(0,0);
109 cam1_intrinsics[1] = rectified?model.right().fy():model.right().K_raw().at<
double>(1,1);
110 cam1_intrinsics[2] = rectified?model.right().cx():model.right().K_raw().at<
double>(0,2);
111 cam1_intrinsics[3] = rectified?model.right().cy():model.right().K_raw().at<
double>(1,2);
113 Transform imuCam = model.localTransform().inverse() * imuLocalTransform;
114 cv::Mat T_imu_cam0 = imuCam.dataMatrix();
115 cv::Matx33d R_imu_cam0(T_imu_cam0(cv::Rect(0,0,3,3)));
116 cv::Vec3d t_imu_cam0 = T_imu_cam0(cv::Rect(3,0,1,3));
117 R_cam0_imu = R_imu_cam0.t();
118 t_cam0_imu = -R_imu_cam0.t() * t_imu_cam0;
123 cam0cam1 = Transform(
124 1, 0, 0, -model.baseline(),
130 cam0cam1 = model.stereoTransform();
134 Transform imuCam1 = cam0cam1 * imuCam;
135 cv::Mat T_imu_cam1 = imuCam1.dataMatrix();
136 cv::Matx33d R_imu_cam1(T_imu_cam1(cv::Rect(0,0,3,3)));
137 cv::Vec3d t_imu_cam1 = T_imu_cam1(cv::Rect(3,0,1,3));
138 R_cam1_imu = R_imu_cam1.t();
139 t_cam1_imu = -R_imu_cam1.t() * t_imu_cam1;
143 uInsert(parameters, parameters_in);
145 Parameters::parse(parameters, Parameters::kOdomMSCKFGridRow(), processor_config.grid_row);
146 Parameters::parse(parameters, Parameters::kOdomMSCKFGridCol(), processor_config.grid_col);
147 Parameters::parse(parameters, Parameters::kOdomMSCKFGridMinFeatureNum(), processor_config.grid_min_feature_num);
148 Parameters::parse(parameters, Parameters::kOdomMSCKFGridMaxFeatureNum(), processor_config.grid_max_feature_num);
149 Parameters::parse(parameters, Parameters::kOdomMSCKFPyramidLevels(), processor_config.pyramid_levels);
150 Parameters::parse(parameters, Parameters::kOdomMSCKFPatchSize(), processor_config.patch_size);
151 Parameters::parse(parameters, Parameters::kOdomMSCKFFastThreshold(), processor_config.fast_threshold);
152 Parameters::parse(parameters, Parameters::kOdomMSCKFMaxIteration(), processor_config.max_iteration);
153 Parameters::parse(parameters, Parameters::kOdomMSCKFTrackPrecision(), processor_config.track_precision);
154 Parameters::parse(parameters, Parameters::kOdomMSCKFRansacThreshold(), processor_config.ransac_threshold);
155 Parameters::parse(parameters, Parameters::kOdomMSCKFStereoThreshold(), processor_config.stereo_threshold);
157 UINFO(
"===========================================");
158 UINFO(
"cam0_resolution: %d, %d",
159 cam0_resolution[0], cam0_resolution[1]);
160 UINFO(
"cam0_intrinscs: %f, %f, %f, %f",
161 cam0_intrinsics[0], cam0_intrinsics[1],
162 cam0_intrinsics[2], cam0_intrinsics[3]);
163 UINFO(
"cam0_distortion_model: %s",
164 cam0_distortion_model.c_str());
165 UINFO(
"cam0_distortion_coefficients: %f, %f, %f, %f",
166 cam0_distortion_coeffs[0], cam0_distortion_coeffs[1],
167 cam0_distortion_coeffs[2], cam0_distortion_coeffs[3]);
169 UINFO(
"cam1_resolution: %d, %d",
170 cam1_resolution[0], cam1_resolution[1]);
171 UINFO(
"cam1_intrinscs: %f, %f, %f, %f",
172 cam1_intrinsics[0], cam1_intrinsics[1],
173 cam1_intrinsics[2], cam1_intrinsics[3]);
174 UINFO(
"cam1_distortion_model: %s",
175 cam1_distortion_model.c_str());
176 UINFO(
"cam1_distortion_coefficients: %f, %f, %f, %f",
177 cam1_distortion_coeffs[0], cam1_distortion_coeffs[1],
178 cam1_distortion_coeffs[2], cam1_distortion_coeffs[3]);
180 std::cout <<
"R_imu_cam0: " << R_imu_cam0 << std::endl;
181 std::cout <<
"t_imu_cam0.t(): " << t_imu_cam0.t() << std::endl;
182 std::cout <<
"R_imu_cam1: " << R_imu_cam1 << std::endl;
183 std::cout <<
"t_imu_cam1.t(): " << t_imu_cam1.t() << std::endl;
185 UINFO(
"grid_row: %d",
186 processor_config.grid_row);
187 UINFO(
"grid_col: %d",
188 processor_config.grid_col);
189 UINFO(
"grid_min_feature_num: %d",
190 processor_config.grid_min_feature_num);
191 UINFO(
"grid_max_feature_num: %d",
192 processor_config.grid_max_feature_num);
193 UINFO(
"pyramid_levels: %d",
194 processor_config.pyramid_levels);
195 UINFO(
"patch_size: %d",
196 processor_config.patch_size);
197 UINFO(
"fast_threshold: %d",
198 processor_config.fast_threshold);
199 UINFO(
"max_iteration: %d",
200 processor_config.max_iteration);
201 UINFO(
"track_precision: %f",
202 processor_config.track_precision);
203 UINFO(
"ransac_threshold: %f",
204 processor_config.ransac_threshold);
205 UINFO(
"stereo_threshold: %f",
206 processor_config.stereo_threshold);
207 UINFO(
"===========================================");
210 detector_ptr = cv::FastFeatureDetector::create(
211 processor_config.fast_threshold);
214 virtual ~ImageProcessorNoROS() {}
216 msckf_vio::CameraMeasurementPtr stereoCallback2(
217 const sensor_msgs::ImageConstPtr& cam0_img,
218 const sensor_msgs::ImageConstPtr& cam1_img) {
230 createImagePyramids();
235 initializeFirstFrame();
238 is_first_img =
false;
278 msckf_vio::CameraMeasurementPtr measurements = publish();
283 cam0_prev_img_ptr = cam0_curr_img_ptr;
284 prev_features_ptr = curr_features_ptr;
285 std::swap(prev_cam0_pyramid_, curr_cam0_pyramid_);
288 curr_features_ptr.reset(
new GridFeatures());
289 for (
int code = 0; code <
290 processor_config.grid_row*processor_config.grid_col; ++code) {
291 (*curr_features_ptr)[code] = std::vector<FeatureMetaData>(0);
297 msckf_vio::CameraMeasurementPtr publish() {
300 msckf_vio::CameraMeasurementPtr feature_msg_ptr(
new msckf_vio::CameraMeasurement);
301 feature_msg_ptr->header.stamp = cam0_curr_img_ptr->header.stamp;
303 std::vector<FeatureIDType> curr_ids(0);
304 std::vector<cv::Point2f> curr_cam0_points(0);
305 std::vector<cv::Point2f> curr_cam1_points(0);
307 for (
const auto& grid_features : (*curr_features_ptr)) {
308 for (
const auto& feature : grid_features.second) {
309 curr_ids.push_back(feature.id);
310 curr_cam0_points.push_back(feature.cam0_point);
311 curr_cam1_points.push_back(feature.cam1_point);
315 std::vector<cv::Point2f> curr_cam0_points_undistorted(0);
316 std::vector<cv::Point2f> curr_cam1_points_undistorted(0);
319 curr_cam0_points, cam0_intrinsics, cam0_distortion_model,
320 cam0_distortion_coeffs, curr_cam0_points_undistorted);
322 curr_cam1_points, cam1_intrinsics, cam1_distortion_model,
323 cam1_distortion_coeffs, curr_cam1_points_undistorted);
325 for (
unsigned int i = 0; i < curr_ids.size(); ++i) {
326 feature_msg_ptr->features.push_back(msckf_vio::FeatureMeasurement());
327 feature_msg_ptr->features[i].id = curr_ids[i];
328 feature_msg_ptr->features[i].u0 = curr_cam0_points_undistorted[i].x;
329 feature_msg_ptr->features[i].v0 = curr_cam0_points_undistorted[i].y;
330 feature_msg_ptr->features[i].u1 = curr_cam1_points_undistorted[i].x;
331 feature_msg_ptr->features[i].v1 = curr_cam1_points_undistorted[i].y;
345 return feature_msg_ptr;
349 class MsckfVioNoROS:
public msckf_vio::MsckfVio
352 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
355 const Transform & imuLocalTransform,
356 const StereoCameraModel & model,
358 msckf_vio::MsckfVio(0)
363 uInsert(parameters_, parameters_in);
368 Parameters::parse(parameters_, Parameters::kOdomMSCKFPositionStdThreshold(), position_std_threshold);
370 Parameters::parse(parameters_, Parameters::kOdomMSCKFRotationThreshold(), rotation_threshold);
371 Parameters::parse(parameters_, Parameters::kOdomMSCKFTranslationThreshold(), translation_threshold);
372 Parameters::parse(parameters_, Parameters::kOdomMSCKFTrackingRateThreshold(), tracking_rate_threshold);
375 Parameters::parse(parameters_, Parameters::kOdomMSCKFOptTranslationThreshold(), msckf_vio::Feature::optimization_config.translation_threshold);
378 Parameters::parse(parameters_, Parameters::kOdomMSCKFNoiseGyro(), msckf_vio::IMUState::gyro_noise);
379 Parameters::parse(parameters_, Parameters::kOdomMSCKFNoiseAcc(), msckf_vio::IMUState::acc_noise);
380 Parameters::parse(parameters_, Parameters::kOdomMSCKFNoiseGyroBias(), msckf_vio::IMUState::gyro_bias_noise);
381 Parameters::parse(parameters_, Parameters::kOdomMSCKFNoiseAccBias(), msckf_vio::IMUState::acc_bias_noise);
382 Parameters::parse(parameters_, Parameters::kOdomMSCKFNoiseFeature(), msckf_vio::Feature::observation_noise);
385 msckf_vio::IMUState::gyro_noise *= msckf_vio::IMUState::gyro_noise;
386 msckf_vio::IMUState::acc_noise *= msckf_vio::IMUState::acc_noise;
387 msckf_vio::IMUState::gyro_bias_noise *= msckf_vio::IMUState::gyro_bias_noise;
388 msckf_vio::IMUState::acc_bias_noise *= msckf_vio::IMUState::acc_bias_noise;
389 msckf_vio::Feature::observation_noise *= msckf_vio::Feature::observation_noise;
403 double gyro_bias_cov, acc_bias_cov, velocity_cov;
404 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovVel(), velocity_cov);
405 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovGyroBias(), gyro_bias_cov);
406 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovAccBias(), acc_bias_cov);
408 double extrinsic_rotation_cov, extrinsic_translation_cov;
409 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovExRot(), extrinsic_rotation_cov);
410 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovExTrans(), extrinsic_translation_cov);
412 state_server.state_cov = Eigen::MatrixXd::Zero(21, 21);
413 for (
int i = 3; i < 6; ++i)
414 state_server.state_cov(i, i) = gyro_bias_cov;
415 for (
int i = 6; i < 9; ++i)
416 state_server.state_cov(i, i) = velocity_cov;
417 for (
int i = 9; i < 12; ++i)
418 state_server.state_cov(i, i) = acc_bias_cov;
419 for (
int i = 15; i < 18; ++i)
420 state_server.state_cov(i, i) = extrinsic_rotation_cov;
421 for (
int i = 18; i < 21; ++i)
422 state_server.state_cov(i, i) = extrinsic_translation_cov;
425 Transform imuCam = model.localTransform().inverse() * imuLocalTransform;
426 Eigen::Isometry3d T_imu_cam0(imuCam.toEigen4d());
427 Eigen::Isometry3d T_cam0_imu = T_imu_cam0.inverse();
429 state_server.imu_state.R_imu_cam0 = T_cam0_imu.linear().transpose();
430 state_server.imu_state.t_cam0_imu = T_cam0_imu.translation();
434 cam0cam1 = Transform(
435 1, 0, 0, -model.baseline(),
441 cam0cam1 = model.stereoTransform();
443 msckf_vio::CAMState::T_cam0_cam1 = cam0cam1.toEigen3d().matrix();
447 Parameters::parse(parameters_, Parameters::kOdomMSCKFMaxCamStateSize(), max_cam_state_size);
449 UINFO(
"===========================================");
450 UINFO(
"fixed frame id: %s", fixed_frame_id.c_str());
451 UINFO(
"child frame id: %s", child_frame_id.c_str());
452 UINFO(
"publish tf: %d", publish_tf);
453 UINFO(
"frame rate: %f", frame_rate);
454 UINFO(
"position std threshold: %f", position_std_threshold);
455 UINFO(
"Keyframe rotation threshold: %f", rotation_threshold);
456 UINFO(
"Keyframe translation threshold: %f", translation_threshold);
457 UINFO(
"Keyframe tracking rate threshold: %f", tracking_rate_threshold);
458 UINFO(
"gyro noise: %.10f", msckf_vio::IMUState::gyro_noise);
459 UINFO(
"gyro bias noise: %.10f", msckf_vio::IMUState::gyro_bias_noise);
460 UINFO(
"acc noise: %.10f", msckf_vio::IMUState::acc_noise);
461 UINFO(
"acc bias noise: %.10f", msckf_vio::IMUState::acc_bias_noise);
462 UINFO(
"observation noise: %.10f", msckf_vio::Feature::observation_noise);
463 UINFO(
"initial velocity: %f, %f, %f",
464 state_server.imu_state.velocity(0),
465 state_server.imu_state.velocity(1),
466 state_server.imu_state.velocity(2));
467 UINFO(
"initial gyro bias cov: %f", gyro_bias_cov);
468 UINFO(
"initial acc bias cov: %f", acc_bias_cov);
469 UINFO(
"initial velocity cov: %f", velocity_cov);
470 UINFO(
"initial extrinsic rotation cov: %f",
471 extrinsic_rotation_cov);
472 UINFO(
"initial extrinsic translation cov: %f",
473 extrinsic_translation_cov);
475 std::cout <<
"T_imu_cam0.linear(): " << T_imu_cam0.linear() << std::endl;
476 std::cout <<
"T_imu_cam0.translation().transpose(): " << T_imu_cam0.translation().transpose() << std::endl;
477 std::cout <<
"CAMState::T_cam0_cam1.linear(): " << msckf_vio::CAMState::T_cam0_cam1.linear() << std::endl;
478 std::cout <<
"CAMState::T_cam0_cam1.translation().transpose(): " << msckf_vio::CAMState::T_cam0_cam1.translation().transpose() << std::endl;
479 std::cout <<
"IMUState::T_imu_body.linear(): " << msckf_vio::IMUState::T_imu_body.linear() << std::endl;
480 std::cout <<
"IMUState::T_imu_body.translation().transpose(): " << msckf_vio::IMUState::T_imu_body.translation().transpose() << std::endl;
482 UINFO(
"max camera state #: %d", max_cam_state_size);
483 UINFO(
"===========================================");
489 state_server.continuous_noise_cov =
490 Eigen::Matrix<double, 12, 12>::Zero();
491 state_server.continuous_noise_cov.block<3, 3>(0, 0) =
492 Eigen::Matrix3d::Identity()*msckf_vio::IMUState::gyro_noise;
493 state_server.continuous_noise_cov.block<3, 3>(3, 3) =
494 Eigen::Matrix3d::Identity()*msckf_vio::IMUState::gyro_bias_noise;
495 state_server.continuous_noise_cov.block<3, 3>(6, 6) =
496 Eigen::Matrix3d::Identity()*msckf_vio::IMUState::acc_noise;
497 state_server.continuous_noise_cov.block<3, 3>(9, 9) =
498 Eigen::Matrix3d::Identity()*msckf_vio::IMUState::acc_bias_noise;
502 for (
int i = 1; i < 100; ++i) {
503 boost::math::chi_squared chi_squared_dist(i);
504 chi_squared_test_table[i] =
505 boost::math::quantile(chi_squared_dist, 0.05);
511 virtual ~MsckfVioNoROS() {}
514 nav_msgs::Odometry featureCallback2(
515 const msckf_vio::CameraMeasurementConstPtr& msg,
516 pcl::PointCloud<pcl::PointXYZ>::Ptr & localMap) {
518 nav_msgs::Odometry odom;
523 UINFO(
"Gravity not set yet... waiting for 200 IMU msgs (%d/200)...", (
int)imu_msg_buffer.size());
531 is_first_img =
false;
532 state_server.imu_state.time = msg->header.stamp.toSec();
542 batchImuProcessing(msg->header.stamp.toSec());
549 stateAugmentation(msg->header.stamp.toSec());
556 addFeatureObservations(msg);
562 removeLostFeatures();
567 pruneCamStateBuffer();
573 odom = publish(localMap);
604 void onlineReset2() {
608 if (position_std_threshold <= 0)
return;
609 static long long int online_reset_counter = 0;
613 double position_x_std =
std::sqrt(state_server.state_cov(12, 12));
614 double position_y_std =
std::sqrt(state_server.state_cov(13, 13));
615 double position_z_std =
std::sqrt(state_server.state_cov(14, 14));
617 if (position_x_std < position_std_threshold &&
618 position_y_std < position_std_threshold &&
619 position_z_std < position_std_threshold)
return;
621 UWARN(
"Start %lld online reset procedure...",
622 ++online_reset_counter);
623 UINFO(
"Stardard deviation in xyz: %f, %f, %f",
624 position_x_std, position_y_std, position_z_std);
627 state_server.cam_states.clear();
633 double gyro_bias_cov, acc_bias_cov, velocity_cov;
634 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovVel(), velocity_cov);
635 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovGyroBias(), gyro_bias_cov);
636 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovAccBias(), acc_bias_cov);
638 double extrinsic_rotation_cov, extrinsic_translation_cov;
639 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovExRot(), extrinsic_rotation_cov);
640 Parameters::parse(parameters_, Parameters::kOdomMSCKFInitCovExTrans(), extrinsic_translation_cov);
643 state_server.state_cov = Eigen::MatrixXd::Zero(21, 21);
644 for (
int i = 3; i < 6; ++i)
645 state_server.state_cov(i, i) = gyro_bias_cov;
646 for (
int i = 6; i < 9; ++i)
647 state_server.state_cov(i, i) = velocity_cov;
648 for (
int i = 9; i < 12; ++i)
649 state_server.state_cov(i, i) = acc_bias_cov;
650 for (
int i = 15; i < 18; ++i)
651 state_server.state_cov(i, i) = extrinsic_rotation_cov;
652 for (
int i = 18; i < 21; ++i)
653 state_server.state_cov(i, i) = extrinsic_translation_cov;
655 UWARN(
"%lld online reset complete...", online_reset_counter);
659 nav_msgs::Odometry publish(pcl::PointCloud<pcl::PointXYZ>::Ptr & feature_msg_ptr) {
662 const msckf_vio::IMUState& imu_state = state_server.imu_state;
663 Eigen::Isometry3d T_i_w = Eigen::Isometry3d::Identity();
664 T_i_w.linear() = msckf_vio::quaternionToRotation(imu_state.orientation).transpose();
665 T_i_w.translation() = imu_state.position;
667 Eigen::Isometry3d T_b_w = msckf_vio::IMUState::T_imu_body * T_i_w *
668 msckf_vio::IMUState::T_imu_body.inverse();
669 Eigen::Vector3d body_velocity =
670 msckf_vio::IMUState::T_imu_body.linear() * imu_state.velocity;
681 nav_msgs::Odometry odom_msg;
683 odom_msg.header.frame_id = fixed_frame_id;
684 odom_msg.child_frame_id = child_frame_id;
686 tf::poseEigenToMsg(T_b_w, odom_msg.pose.pose);
687 tf::vectorEigenToMsg(body_velocity, odom_msg.twist.twist.linear);
690 Eigen::Matrix3d P_oo = state_server.state_cov.block<3, 3>(0, 0);
691 Eigen::Matrix3d P_op = state_server.state_cov.block<3, 3>(0, 12);
692 Eigen::Matrix3d P_po = state_server.state_cov.block<3, 3>(12, 0);
693 Eigen::Matrix3d P_pp = state_server.state_cov.block<3, 3>(12, 12);
694 Eigen::Matrix<double, 6, 6> P_imu_pose = Eigen::Matrix<double, 6, 6>::Zero();
695 P_imu_pose << P_pp, P_po, P_op, P_oo;
697 Eigen::Matrix<double, 6, 6> H_pose = Eigen::Matrix<double, 6, 6>::Zero();
698 H_pose.block<3, 3>(0, 0) = msckf_vio::IMUState::T_imu_body.linear();
699 H_pose.block<3, 3>(3, 3) = msckf_vio::IMUState::T_imu_body.linear();
700 Eigen::Matrix<double, 6, 6> P_body_pose = H_pose *
701 P_imu_pose * H_pose.transpose();
703 for (
int i = 0; i < 6; ++i)
704 for (
int j = 0; j < 6; ++j)
705 odom_msg.pose.covariance[6*i+j] = P_body_pose(i, j);
708 Eigen::Matrix3d P_imu_vel = state_server.state_cov.block<3, 3>(6, 6);
709 Eigen::Matrix3d H_vel = msckf_vio::IMUState::T_imu_body.linear();
710 Eigen::Matrix3d P_body_vel = H_vel * P_imu_vel * H_vel.transpose();
711 for (
int i = 0; i < 3; ++i)
712 for (
int j = 0; j < 3; ++j)
713 odom_msg.twist.covariance[i*6+j] = P_body_vel(i, j);
719 feature_msg_ptr.reset(
new pcl::PointCloud<pcl::PointXYZ>());
720 feature_msg_ptr->header.frame_id = fixed_frame_id;
721 feature_msg_ptr->height = 1;
722 for (
const auto& item : map_server) {
723 const auto& feature = item.second;
724 if (feature.is_initialized) {
725 Eigen::Vector3d feature_position =
726 msckf_vio::IMUState::T_imu_body.linear() * feature.position;
727 feature_msg_ptr->points.push_back(pcl::PointXYZ(
728 feature_position(0), feature_position(1), feature_position(2)));
731 feature_msg_ptr->width = feature_msg_ptr->points.size();
745 #ifdef RTABMAP_MSCKF_VIO
749 parameters_(parameters),
750 flipXY_(-1, 0, 0, 0, 0, -1, 0, 0, 0, 0, 1, 0),
760 #ifdef RTABMAP_MSCKF_VIO 761 delete imageProcessor_;
769 #ifdef RTABMAP_MSCKF_VIO 774 delete imageProcessor_;
783 previousPose_.setIdentity();
785 initGravity_ =
false;
798 #ifdef RTABMAP_MSCKF_VIO 803 UDEBUG(
"IMU update stamp=%f acc=%f %f %f gyr=%f %f %f", data.
stamp(),
810 if(imageProcessor_ && msckf_)
812 sensor_msgs::ImuPtr msg(
new sensor_msgs::Imu);
819 msg->header.stamp.fromSec(data.
stamp());
820 imageProcessor_->imuCallback(msg);
821 msckf_->imuCallback(msg);
825 UWARN(
"Ignoring IMU, waiting for an image to initialize...");
826 lastImu_ = data.
imu();
837 UINFO(
"Initialization");
840 UWARN(
"Ignoring Image, waiting for imu to initialize...");
843 UINFO(
"Creating ImageProcessorNoROS...");
844 imageProcessor_ =
new ImageProcessorNoROS(
846 lastImu_.localTransform(),
849 UINFO(
"Creating MsckfVioNoROS...");
850 msckf_ =
new MsckfVioNoROS(
852 lastImu_.localTransform(),
863 if(data.
imageRaw().type() == CV_8UC3)
865 cv::cvtColor(data.
imageRaw(), cam0.image, CV_BGR2GRAY);
871 if(data.
rightRaw().type() == CV_8UC3)
880 sensor_msgs::ImagePtr cam0Msg(
new sensor_msgs::Image);
881 sensor_msgs::ImagePtr cam1Msg(
new sensor_msgs::Image);
882 cam0.toImageMsg(*cam0Msg);
887 msckf_vio::CameraMeasurementPtr measurements = imageProcessor_->stereoCallback2(cam0Msg, cam1Msg);
888 pcl::PointCloud<pcl::PointXYZ>::Ptr localMap;
889 nav_msgs::Odometry odom = msckf_->featureCallback2(measurements, localMap);
892 odom.pose.pose.position.x,
893 odom.pose.pose.position.y,
894 odom.pose.pose.position.z,
895 odom.pose.pose.orientation.x,
896 odom.pose.pose.orientation.y,
897 odom.pose.pose.orientation.z,
898 odom.pose.pose.orientation.w);
903 p = flipXY_*p*lastImu_.localTransform();
911 if(previousPose_.isIdentity())
918 t = previousPoseInv*p;
924 info->
features = measurements->features.size();
927 cv::Mat twistCov(6,6,CV_64FC1, odom.twist.covariance.elems);
930 cv::Matx31f covWorldFrame(twistCov.at<
double>(0, 0),
931 twistCov.at<
double>(1, 1),
932 twistCov.at<
double>(2, 2));
933 cv::Matx31f covBaseFrame = cv::Matx33f(previousPoseInv.
rotationMatrix()) * covWorldFrame;
935 info->
reg.
covariance.at<
double>(0, 0) = fabs(covBaseFrame.val[0])/10.0;
936 info->
reg.
covariance.at<
double>(1, 1) = fabs(covBaseFrame.val[1])/10.0;
937 info->
reg.
covariance.at<
double>(2, 2) = fabs(covBaseFrame.val[2])/10.0;
950 info->
reg.
covariance.at<
double>(3, 3) = msckf_vio::IMUState::gyro_noise*10.0;
956 if(localMap.get() && localMap->size())
958 Eigen::Affine3f flip = (this->
getPose()*previousPoseInv*flipXY_).toEigen3f();
959 for(
unsigned int i=0; i<localMap->size(); ++i)
962 info->
localMap.insert(std::make_pair(i, cv::Point3f(pt.x, pt.y, pt.z)));
967 info->
newCorners.resize(measurements->features.size());
973 for(
unsigned int i=0; i<measurements->features.size(); ++i)
975 info->
newCorners[i].x = measurements->features[i].u0*fx+cx;
976 info->
newCorners[i].y = measurements->features[i].v0*fy+cy;
989 UERROR(
"RTAB-Map is not built with MSCKF_VIO support! Select another visual odometry approach.");
CvImageConstPtr toCvShare(const sensor_msgs::ImageConstPtr &source, const std::string &encoding=std::string())
static bool parse(const ParametersMap ¶meters, const std::string &key, bool &value)
OdometryMSCKF(const rtabmap::ParametersMap ¶meters=rtabmap::ParametersMap())
cv::Point3f RTABMAP_EXP transformPoint(const cv::Point3f &pt, const Transform &transform)
bool isInfoDataFilled() const
bool imagesAlreadyRectified() const
virtual void reset(const Transform &initialPose=Transform::getIdentity())
GLM_FUNC_DECL vecType< T, P > sqrt(vecType< T, P > const &x)
std::map< int, cv::Point3f > localMap
std::map< std::string, std::string > ParametersMap
const Transform & getPose() const
virtual Odometry::Type getType()
std::vector< int > inliersIDs
const cv::Mat & imageRaw() const
#define UASSERT(condition)
Wrappers of STL for convenient functions.
bool isValidForProjection() const
const CameraModel & left() const
const cv::Vec3d linearAcceleration() const
virtual Transform computeTransform(SensorData &image, const Transform &guess=Transform(), OdometryInfo *info=0)
GLM_FUNC_DECL detail::tquat< T, P > rotation(detail::tvec3< T, P > const &orig, detail::tvec3< T, P > const &dest)
GLM_FUNC_DECL bool isIdentity(matType< T, P > const &m, T const &epsilon)
static const ParametersMap & getDefaultParameters()
ULogger class and convenient macros.
const StereoCameraModel & stereoCameraModel() const
std::vector< cv::Point2f > newCorners
virtual void reset(const Transform &initialPose=Transform::getIdentity())
sensor_msgs::ImagePtr toImageMsg() const
const cv::Vec3d & angularVelocity() const
void uInsert(std::map< K, V > &map, const std::pair< K, V > &pair)