|
@@ -8,199 +8,8 @@
|
|
|
|
|
|
namespace faster_lio {
|
|
|
|
|
|
-bool LaserMapping::InitROS(ros::NodeHandle &nh) {
|
|
|
- LoadParams(nh);
|
|
|
- SubAndPubToROS(nh);
|
|
|
|
|
|
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool LaserMapping::InitWithoutROS(const std::string &config_yaml) {
|
|
|
- /*LOG(INFO) << "init laser mapping from " << config_yaml;
|
|
|
- if (!LoadParamsFromYAML(config_yaml)) {
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- // localmap init (after LoadParams)
|
|
|
- ivox_ = std::make_shared<IVoxType>(ivox_options_);
|
|
|
-
|
|
|
- // esekf init
|
|
|
- std::vector<double> epsi(23, 0.001);
|
|
|
- kf_.init_dyn_share(
|
|
|
- get_f, df_dx, df_dw,
|
|
|
- [this](state_ikfom &s, esekfom::dyn_share_datastruct<double> &ekfom_data) { ObsModel(s, ekfom_data); },
|
|
|
- options::NUM_MAX_ITERATIONS, epsi.data());
|
|
|
-
|
|
|
- if (std::is_same<IVoxType, IVox<3, IVoxNodeType::PHC, pcl::PointXYZI>>::value == true) {
|
|
|
- LOG(INFO) << "using phc ivox";
|
|
|
- } else if (std::is_same<IVoxType, IVox<3, IVoxNodeType::DEFAULT, pcl::PointXYZI>>::value == true) {
|
|
|
- LOG(INFO) << "using default ivox";
|
|
|
- }
|
|
|
-*/
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool LaserMapping::LoadParams(ros::NodeHandle &nh) {
|
|
|
- // get params from param server
|
|
|
- int lidar_type, ivox_nearby_type;
|
|
|
- double gyr_cov, acc_cov, b_gyr_cov, b_acc_cov;
|
|
|
- double filter_size_surf_min;
|
|
|
- common::V3D lidar_T_wrt_IMU;
|
|
|
- common::M3D lidar_R_wrt_IMU;
|
|
|
-
|
|
|
- nh.param<bool>("path_save_en", path_save_en_, true);
|
|
|
- nh.param<bool>("publish/path_publish_en", path_pub_en_, true);
|
|
|
- nh.param<bool>("publish/scan_publish_en", scan_pub_en_, true);
|
|
|
- nh.param<bool>("publish/dense_publish_en", dense_pub_en_, false);
|
|
|
- nh.param<bool>("publish/scan_bodyframe_pub_en", scan_body_pub_en_, true);
|
|
|
- nh.param<bool>("publish/scan_effect_pub_en", scan_effect_pub_en_, false);
|
|
|
-
|
|
|
- nh.param<int>("max_iteration", options::NUM_MAX_ITERATIONS, 4);
|
|
|
- nh.param<float>("esti_plane_threshold", options::ESTI_PLANE_THRESHOLD, 0.1);
|
|
|
- //nh.param<std::string>("map_file_path", map_file_path_, "");
|
|
|
- nh.param<bool>("common/time_sync_en", mapper_.time_sync_en_, false);
|
|
|
- nh.param<double>("filter_size_surf", filter_size_surf_min, 0.5);
|
|
|
- nh.param<double>("filter_size_map", mapper_.filter_size_map_min_, 0.0);
|
|
|
- nh.param<double>("cube_side_length", mapper_.cube_len_, 200);
|
|
|
- nh.param<float>("mapping/det_range", mapper_.det_range_, 300.f);
|
|
|
- nh.param<double>("mapping/gyr_cov", gyr_cov, 0.1);
|
|
|
- nh.param<double>("mapping/acc_cov", acc_cov, 0.1);
|
|
|
- nh.param<double>("mapping/b_gyr_cov", b_gyr_cov, 0.0001);
|
|
|
- nh.param<double>("mapping/b_acc_cov", b_acc_cov, 0.0001);
|
|
|
- nh.param<double>("preprocess/blind", preprocess_->Blind(), 0.01);
|
|
|
- nh.param<float>("preprocess/time_scale", preprocess_->TimeScale(), 1e-3);
|
|
|
- nh.param<int>("preprocess/lidar_type", lidar_type, 1);
|
|
|
- nh.param<int>("preprocess/scan_line", preprocess_->NumScans(), 16);
|
|
|
- nh.param<int>("point_filter_num", preprocess_->PointFilterNum(), 2);
|
|
|
- nh.param<bool>("feature_extract_enable", preprocess_->FeatureEnabled(), false);
|
|
|
- nh.param<bool>("runtime_pos_log_enable", runtime_pos_log_, true);
|
|
|
- nh.param<bool>("mapping/extrinsic_est_en", mapper_.extrinsic_est_en_, true);
|
|
|
- nh.param<bool>("pcd_save/pcd_save_en", pcd_save_en_, false);
|
|
|
- nh.param<int>("pcd_save/interval", pcd_save_interval_, -1);
|
|
|
- nh.param<std::vector<double>>("mapping/extrinsic_T", mapper_.extrinT_, std::vector<double>());
|
|
|
- nh.param<std::vector<double>>("mapping/extrinsic_R", mapper_.extrinR_, std::vector<double>());
|
|
|
-
|
|
|
- nh.param<float>("ivox_grid_resolution", mapper_.ivox_options_.resolution_, 0.2);
|
|
|
- nh.param<int>("ivox_nearby_type", ivox_nearby_type, 18);
|
|
|
-
|
|
|
-
|
|
|
- LOG(INFO) << "lidar_type " << lidar_type;
|
|
|
- if (lidar_type == 1) {
|
|
|
- preprocess_->SetLidarType(LidarType::AVIA);
|
|
|
- LOG(INFO) << "Using AVIA Lidar";
|
|
|
- } else if (lidar_type == 2) {
|
|
|
- preprocess_->SetLidarType(LidarType::VELO32);
|
|
|
- LOG(INFO) << "Using Velodyne 32 Lidar";
|
|
|
- } else if (lidar_type == 3) {
|
|
|
- preprocess_->SetLidarType(LidarType::OUST64);
|
|
|
- LOG(INFO) << "Using OUST 64 Lidar";
|
|
|
- } else {
|
|
|
- LOG(WARNING) << "unknown lidar_type";
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- mapper_.Init(ivox_nearby_type,gyr_cov,
|
|
|
- acc_cov, b_gyr_cov, b_acc_cov,filter_size_surf_min);
|
|
|
-
|
|
|
- path_.header.stamp = ros::Time::now();
|
|
|
- path_.header.frame_id = "camera_init";
|
|
|
-
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
-bool LaserMapping::LoadParamsFromYAML(const std::string &yaml_file) {
|
|
|
- // get params from yaml
|
|
|
- /*int lidar_type, ivox_nearby_type;
|
|
|
- double gyr_cov, acc_cov, b_gyr_cov, b_acc_cov;
|
|
|
- double filter_size_surf_min;
|
|
|
- common::V3D lidar_T_wrt_IMU;
|
|
|
- common::M3D lidar_R_wrt_IMU;
|
|
|
-
|
|
|
- auto yaml = YAML::LoadFile(yaml_file);
|
|
|
- try {
|
|
|
- path_pub_en_ = yaml["publish"]["path_publish_en"].as<bool>();
|
|
|
- scan_pub_en_ = yaml["publish"]["scan_publish_en"].as<bool>();
|
|
|
- dense_pub_en_ = yaml["publish"]["dense_publish_en"].as<bool>();
|
|
|
- scan_body_pub_en_ = yaml["publish"]["scan_bodyframe_pub_en"].as<bool>();
|
|
|
- scan_effect_pub_en_ = yaml["publish"]["scan_effect_pub_en"].as<bool>();
|
|
|
- path_save_en_ = yaml["path_save_en"].as<bool>();
|
|
|
-
|
|
|
- options::NUM_MAX_ITERATIONS = yaml["max_iteration"].as<int>();
|
|
|
- options::ESTI_PLANE_THRESHOLD = yaml["esti_plane_threshold"].as<float>();
|
|
|
- time_sync_en_ = yaml["common"]["time_sync_en"].as<bool>();
|
|
|
-
|
|
|
- filter_size_surf_min = yaml["filter_size_surf"].as<float>();
|
|
|
- filter_size_map_min_ = yaml["filter_size_map"].as<float>();
|
|
|
- cube_len_ = yaml["cube_side_length"].as<int>();
|
|
|
- det_range_ = yaml["mapping"]["det_range"].as<float>();
|
|
|
- gyr_cov = yaml["mapping"]["gyr_cov"].as<float>();
|
|
|
- acc_cov = yaml["mapping"]["acc_cov"].as<float>();
|
|
|
- b_gyr_cov = yaml["mapping"]["b_gyr_cov"].as<float>();
|
|
|
- b_acc_cov = yaml["mapping"]["b_acc_cov"].as<float>();
|
|
|
- preprocess_->Blind() = yaml["preprocess"]["blind"].as<double>();
|
|
|
- preprocess_->TimeScale() = yaml["preprocess"]["time_scale"].as<double>();
|
|
|
- lidar_type = yaml["preprocess"]["lidar_type"].as<int>();
|
|
|
- preprocess_->NumScans() = yaml["preprocess"]["scan_line"].as<int>();
|
|
|
- preprocess_->PointFilterNum() = yaml["point_filter_num"].as<int>();
|
|
|
- preprocess_->FeatureEnabled() = yaml["feature_extract_enable"].as<bool>();
|
|
|
- extrinsic_est_en_ = yaml["mapping"]["extrinsic_est_en"].as<bool>();
|
|
|
- pcd_save_en_ = yaml["pcd_save"]["pcd_save_en"].as<bool>();
|
|
|
- pcd_save_interval_ = yaml["pcd_save"]["interval"].as<int>();
|
|
|
- extrinT_ = yaml["mapping"]["extrinsic_T"].as<std::vector<double>>();
|
|
|
- extrinR_ = yaml["mapping"]["extrinsic_R"].as<std::vector<double>>();
|
|
|
-
|
|
|
- ivox_options_.resolution_ = yaml["ivox_grid_resolution"].as<float>();
|
|
|
- ivox_nearby_type = yaml["ivox_nearby_type"].as<int>();
|
|
|
- } catch (...) {
|
|
|
- LOG(ERROR) << "bad conversion";
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- LOG(INFO) << "lidar_type " << lidar_type;
|
|
|
- if (lidar_type == 1) {
|
|
|
- preprocess_->SetLidarType(LidarType::AVIA);
|
|
|
- LOG(INFO) << "Using AVIA Lidar";
|
|
|
- } else if (lidar_type == 2) {
|
|
|
- preprocess_->SetLidarType(LidarType::VELO32);
|
|
|
- LOG(INFO) << "Using Velodyne 32 Lidar";
|
|
|
- } else if (lidar_type == 3) {
|
|
|
- preprocess_->SetLidarType(LidarType::OUST64);
|
|
|
- LOG(INFO) << "Using OUST 64 Lidar";
|
|
|
- } else {
|
|
|
- LOG(WARNING) << "unknown lidar_type";
|
|
|
- return false;
|
|
|
- }
|
|
|
-
|
|
|
- if (ivox_nearby_type == 0) {
|
|
|
- ivox_options_.nearby_type_ = IVoxType::NearbyType::CENTER;
|
|
|
- } else if (ivox_nearby_type == 6) {
|
|
|
- ivox_options_.nearby_type_ = IVoxType::NearbyType::NEARBY6;
|
|
|
- } else if (ivox_nearby_type == 18) {
|
|
|
- ivox_options_.nearby_type_ = IVoxType::NearbyType::NEARBY18;
|
|
|
- } else if (ivox_nearby_type == 26) {
|
|
|
- ivox_options_.nearby_type_ = IVoxType::NearbyType::NEARBY26;
|
|
|
- } else {
|
|
|
- LOG(WARNING) << "unknown ivox_nearby_type, use NEARBY18";
|
|
|
- ivox_options_.nearby_type_ = IVoxType::NearbyType::NEARBY18;
|
|
|
- }
|
|
|
-
|
|
|
- voxel_scan_.setLeafSize(filter_size_surf_min, filter_size_surf_min, filter_size_surf_min);
|
|
|
-
|
|
|
- lidar_T_wrt_IMU = common::VecFromArray<double>(extrinT_);
|
|
|
- lidar_R_wrt_IMU = common::MatFromArray<double>(extrinR_);
|
|
|
-
|
|
|
- p_imu_->SetExtrinsic(lidar_T_wrt_IMU, lidar_R_wrt_IMU);
|
|
|
- p_imu_->SetGyrCov(common::V3D(gyr_cov, gyr_cov, gyr_cov));
|
|
|
- p_imu_->SetAccCov(common::V3D(acc_cov, acc_cov, acc_cov));
|
|
|
- p_imu_->SetGyrBiasCov(common::V3D(b_gyr_cov, b_gyr_cov, b_gyr_cov));
|
|
|
- p_imu_->SetAccBiasCov(common::V3D(b_acc_cov, b_acc_cov, b_acc_cov));
|
|
|
-
|
|
|
- run_in_offline_ = true;*/
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
void LaserMapping::SubAndPubToROS(ros::NodeHandle &nh) {
|
|
|
// ROS subscribe initialization
|
|
|
std::string lidar_topic, imu_topic;
|
|
@@ -234,43 +43,11 @@ LaserMapping::LaserMapping() {
|
|
|
|
|
|
}
|
|
|
|
|
|
-void LaserMapping::Run() {
|
|
|
-
|
|
|
- if (!mapper_.Run())
|
|
|
- return;
|
|
|
- // publish or save map pcd
|
|
|
- if (run_in_offline_) {
|
|
|
- if (pcd_save_en_) {
|
|
|
- PublishFrameWorld();
|
|
|
- }
|
|
|
- if (path_save_en_) {
|
|
|
- PublishPath(pub_path_);
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (pub_odom_aft_mapped_) {
|
|
|
- PublishOdometry(pub_odom_aft_mapped_);
|
|
|
- }
|
|
|
- if (path_pub_en_ || path_save_en_) {
|
|
|
- PublishPath(pub_path_);
|
|
|
- }
|
|
|
- if (scan_pub_en_ || pcd_save_en_) {
|
|
|
- PublishFrameWorld();
|
|
|
- }
|
|
|
- if (scan_pub_en_ && scan_body_pub_en_) {
|
|
|
- PublishFrameBody(pub_laser_cloud_body_);
|
|
|
- }
|
|
|
- if (scan_pub_en_ && scan_effect_pub_en_) {
|
|
|
- PublishFrameEffectWorld(pub_laser_cloud_effect_world_);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Debug variables
|
|
|
- mapper_.frame_num_++;
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
|
|
|
void LaserMapping::StandardPCLCallBack(const sensor_msgs::PointCloud2::ConstPtr &msg) {
|
|
|
+
|
|
|
+ printf(" LaserMapping::StandardPCLCallBack\n ");
|
|
|
mapper_.mtx_buffer_.lock();
|
|
|
Timer::Evaluate(
|
|
|
[&, this]() {
|
|
@@ -291,6 +68,8 @@ void LaserMapping::StandardPCLCallBack(const sensor_msgs::PointCloud2::ConstPtr
|
|
|
}
|
|
|
|
|
|
void LaserMapping::LivoxPCLCallBack(const livox_ros_driver::CustomMsg::ConstPtr &msg) {
|
|
|
+
|
|
|
+ printf(" LaserMapping::LivoxPCLCallBack\n ");
|
|
|
mapper_.mtx_buffer_.lock();
|
|
|
Timer::Evaluate(
|
|
|
[&, this]() {
|
|
@@ -318,8 +97,6 @@ void LaserMapping::LivoxPCLCallBack(const livox_ros_driver::CustomMsg::ConstPtr
|
|
|
PointCloudType::Ptr ptr(new PointCloudType());
|
|
|
preprocess_->Process(msg, ptr);
|
|
|
mapper_.AddPointCloud(ptr,mapper_.last_timestamp_lidar_);
|
|
|
- /*lidar_buffer_.emplace_back(ptr);
|
|
|
- time_buffer_.emplace_back(last_timestamp_lidar_);*/
|
|
|
},
|
|
|
"Preprocess (Livox)");
|
|
|
|
|
@@ -327,7 +104,7 @@ void LaserMapping::LivoxPCLCallBack(const livox_ros_driver::CustomMsg::ConstPtr
|
|
|
}
|
|
|
|
|
|
void LaserMapping::IMUCallBack(const sensor_msgs::Imu::ConstPtr &msg_in) {
|
|
|
- //publish_count_++;
|
|
|
+ printf(" LaserMapping::IMUCallBack\n ");
|
|
|
sensor_msgs::Imu::Ptr msg(new sensor_msgs::Imu(*msg_in));
|
|
|
|
|
|
if (abs(mapper_.timediff_lidar_wrt_imu_) > 0.1 && mapper_.time_sync_en_) {
|
|
@@ -352,190 +129,6 @@ void LaserMapping::IMUCallBack(const sensor_msgs::Imu::ConstPtr &msg_in) {
|
|
|
}
|
|
|
|
|
|
|
|
|
-void LaserMapping::PrintState(const state_ikfom &s) {
|
|
|
- LOG(INFO) << "state r: " << s.rot.coeffs().transpose() << ", t: " << s.pos.transpose()
|
|
|
- << ", off r: " << s.offset_R_L_I.coeffs().transpose() << ", t: " << s.offset_T_L_I.transpose();
|
|
|
-}
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-///////////////////////////////////// debug save / show /////////////////////////////////////////////////////
|
|
|
-
|
|
|
-void LaserMapping::PublishPath(const ros::Publisher pub_path) {
|
|
|
- SetPosestamp(msg_body_pose_);
|
|
|
- msg_body_pose_.header.stamp = ros::Time().fromSec(mapper_.lidar_end_time_);
|
|
|
- msg_body_pose_.header.frame_id = "camera_init";
|
|
|
-
|
|
|
- /*** if path is too large, the rvis will crash ***/
|
|
|
- path_.poses.push_back(msg_body_pose_);
|
|
|
- if (run_in_offline_ == false) {
|
|
|
- pub_path.publish(path_);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::PublishOdometry(const ros::Publisher &pub_odom_aft_mapped) {
|
|
|
- odom_aft_mapped_.header.frame_id = "camera_init";
|
|
|
- odom_aft_mapped_.child_frame_id = "body";
|
|
|
- odom_aft_mapped_.header.stamp = ros::Time().fromSec(mapper_.lidar_end_time_); // ros::Time().fromSec(lidar_end_time_);
|
|
|
- SetPosestamp(odom_aft_mapped_.pose);
|
|
|
- pub_odom_aft_mapped.publish(odom_aft_mapped_);
|
|
|
- auto P = mapper_.kf_.get_P();
|
|
|
- for (int i = 0; i < 6; i++) {
|
|
|
- int k = i < 3 ? i + 3 : i - 3;
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 0] = P(k, 3);
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 1] = P(k, 4);
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 2] = P(k, 5);
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 3] = P(k, 0);
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 4] = P(k, 1);
|
|
|
- odom_aft_mapped_.pose.covariance[i * 6 + 5] = P(k, 2);
|
|
|
- }
|
|
|
-
|
|
|
- static tf::TransformBroadcaster br;
|
|
|
- tf::Transform transform;
|
|
|
- tf::Quaternion q;
|
|
|
- transform.setOrigin(tf::Vector3(odom_aft_mapped_.pose.pose.position.x, odom_aft_mapped_.pose.pose.position.y,
|
|
|
- odom_aft_mapped_.pose.pose.position.z));
|
|
|
- q.setW(odom_aft_mapped_.pose.pose.orientation.w);
|
|
|
- q.setX(odom_aft_mapped_.pose.pose.orientation.x);
|
|
|
- q.setY(odom_aft_mapped_.pose.pose.orientation.y);
|
|
|
- q.setZ(odom_aft_mapped_.pose.pose.orientation.z);
|
|
|
- transform.setRotation(q);
|
|
|
- br.sendTransform(tf::StampedTransform(transform, odom_aft_mapped_.header.stamp, "camera_init", "body"));
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::PublishFrameWorld() {
|
|
|
- if (!(run_in_offline_ == false && scan_pub_en_) && !pcd_save_en_) {
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- PointCloudType::Ptr laserCloudWorld;
|
|
|
- if (dense_pub_en_) {
|
|
|
- PointCloudType::Ptr laserCloudFullRes(mapper_.scan_undistort_);
|
|
|
- int size = laserCloudFullRes->points.size();
|
|
|
- laserCloudWorld.reset(new PointCloudType(size, 1));
|
|
|
- for (int i = 0; i < size; i++) {
|
|
|
- mapper_.PointBodyToWorld(&laserCloudFullRes->points[i], &laserCloudWorld->points[i]);
|
|
|
- }
|
|
|
- } else {
|
|
|
- laserCloudWorld = mapper_.scan_down_world_;
|
|
|
- }
|
|
|
-
|
|
|
- if (run_in_offline_ == false && scan_pub_en_) {
|
|
|
- sensor_msgs::PointCloud2 laserCloudmsg;
|
|
|
- pcl::toROSMsg(*laserCloudWorld, laserCloudmsg);
|
|
|
- laserCloudmsg.header.stamp = ros::Time().fromSec(mapper_.lidar_end_time_);
|
|
|
- laserCloudmsg.header.frame_id = "camera_init";
|
|
|
- pub_laser_cloud_world_.publish(laserCloudmsg);
|
|
|
- mapper_.publish_count_ -= options::PUBFRAME_PERIOD;
|
|
|
- }
|
|
|
-
|
|
|
- /**************** save map ****************/
|
|
|
- /* 1. make sure you have enough memories
|
|
|
- /* 2. noted that pcd save will influence the real-time performences **/
|
|
|
- if (pcd_save_en_) {
|
|
|
- *pcl_wait_save_ += *laserCloudWorld;
|
|
|
-
|
|
|
- static int scan_wait_num = 0;
|
|
|
- scan_wait_num++;
|
|
|
- if (pcl_wait_save_->size() > 0 && pcd_save_interval_ > 0 && scan_wait_num >= pcd_save_interval_) {
|
|
|
- mapper_.pcd_index_++;
|
|
|
- std::string all_points_dir(std::string(std::string(ROOT_DIR) + "PCD/scans_") + std::to_string(mapper_.pcd_index_) +
|
|
|
- std::string(".pcd"));
|
|
|
- pcl::PCDWriter pcd_writer;
|
|
|
- LOG(INFO) << "current scan saved to /PCD/" << all_points_dir;
|
|
|
- pcd_writer.writeBinary(all_points_dir, *pcl_wait_save_);
|
|
|
- pcl_wait_save_->clear();
|
|
|
- scan_wait_num = 0;
|
|
|
- }
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::PublishFrameBody(const ros::Publisher &pub_laser_cloud_body) {
|
|
|
- int size = mapper_.scan_undistort_->points.size();
|
|
|
- PointCloudType::Ptr laser_cloud_imu_body(new PointCloudType(size, 1));
|
|
|
-
|
|
|
- for (int i = 0; i < size; i++) {
|
|
|
- PointBodyLidarToIMU(&mapper_.scan_undistort_->points[i], &laser_cloud_imu_body->points[i]);
|
|
|
- }
|
|
|
-
|
|
|
- sensor_msgs::PointCloud2 laserCloudmsg;
|
|
|
- pcl::toROSMsg(*laser_cloud_imu_body, laserCloudmsg);
|
|
|
- laserCloudmsg.header.stamp = ros::Time().fromSec(mapper_.lidar_end_time_);
|
|
|
- laserCloudmsg.header.frame_id = "body";
|
|
|
- pub_laser_cloud_body.publish(laserCloudmsg);
|
|
|
- mapper_.publish_count_ -= options::PUBFRAME_PERIOD;
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::PublishFrameEffectWorld(const ros::Publisher &pub_laser_cloud_effect_world) {
|
|
|
- int size = mapper_.corr_pts_.size();
|
|
|
- PointCloudType::Ptr laser_cloud(new PointCloudType(size, 1));
|
|
|
-
|
|
|
- for (int i = 0; i < size; i++) {
|
|
|
- mapper_.PointBodyToWorld(mapper_.corr_pts_[i].head<3>(), &laser_cloud->points[i]);
|
|
|
- }
|
|
|
- sensor_msgs::PointCloud2 laserCloudmsg;
|
|
|
- pcl::toROSMsg(*laser_cloud, laserCloudmsg);
|
|
|
- laserCloudmsg.header.stamp = ros::Time().fromSec(mapper_.lidar_end_time_);
|
|
|
- laserCloudmsg.header.frame_id = "camera_init";
|
|
|
- pub_laser_cloud_effect_world.publish(laserCloudmsg);
|
|
|
- mapper_.publish_count_ -= options::PUBFRAME_PERIOD;
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::Savetrajectory(const std::string &traj_file) {
|
|
|
- std::ofstream ofs;
|
|
|
- ofs.open(traj_file, std::ios::out);
|
|
|
- if (!ofs.is_open()) {
|
|
|
- LOG(ERROR) << "Failed to open traj_file: " << traj_file;
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- ofs << "#timestamp x y z q_x q_y q_z q_w" << std::endl;
|
|
|
- for (const auto &p : path_.poses) {
|
|
|
- ofs << std::fixed << std::setprecision(6) << p.header.stamp.toSec() << " " << std::setprecision(15)
|
|
|
- << p.pose.position.x << " " << p.pose.position.y << " " << p.pose.position.z << " " << p.pose.orientation.x
|
|
|
- << " " << p.pose.orientation.y << " " << p.pose.orientation.z << " " << p.pose.orientation.w << std::endl;
|
|
|
- }
|
|
|
-
|
|
|
- ofs.close();
|
|
|
-}
|
|
|
-
|
|
|
-/////////////////////////// private method /////////////////////////////////////////////////////////////////////
|
|
|
-template <typename T>
|
|
|
-void LaserMapping::SetPosestamp(T &out) {
|
|
|
- out.pose.position.x = mapper_.state_point_.pos(0);
|
|
|
- out.pose.position.y = mapper_.state_point_.pos(1);
|
|
|
- out.pose.position.z = mapper_.state_point_.pos(2);
|
|
|
- out.pose.orientation.x = mapper_.state_point_.rot.coeffs()[0];
|
|
|
- out.pose.orientation.y = mapper_.state_point_.rot.coeffs()[1];
|
|
|
- out.pose.orientation.z = mapper_.state_point_.rot.coeffs()[2];
|
|
|
- out.pose.orientation.w = mapper_.state_point_.rot.coeffs()[3];
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::PointBodyLidarToIMU(PointType const *const pi, PointType *const po) {
|
|
|
- common::V3D p_body_lidar(pi->x, pi->y, pi->z);
|
|
|
- common::V3D p_body_imu(mapper_.state_point_.offset_R_L_I * p_body_lidar + mapper_.state_point_.offset_T_L_I);
|
|
|
-
|
|
|
- po->x = p_body_imu(0);
|
|
|
- po->y = p_body_imu(1);
|
|
|
- po->z = p_body_imu(2);
|
|
|
- po->intensity = pi->intensity;
|
|
|
-}
|
|
|
-
|
|
|
-void LaserMapping::Finish() {
|
|
|
- /**************** save map ****************/
|
|
|
- /* 1. make sure you have enough memories
|
|
|
- /* 2. pcd save will largely influence the real-time performences **/
|
|
|
- if (pcl_wait_save_->size() > 0 && pcd_save_en_) {
|
|
|
- std::string file_name = std::string("scans.pcd");
|
|
|
- std::string all_points_dir(std::string(std::string(ROOT_DIR) + "PCD/") + file_name);
|
|
|
- pcl::PCDWriter pcd_writer;
|
|
|
- LOG(INFO) << "current scan saved to /PCD/" << file_name;
|
|
|
- pcd_writer.writeBinary(all_points_dir, *pcl_wait_save_);
|
|
|
- }
|
|
|
-
|
|
|
- LOG(INFO) << "finish done";
|
|
|
-}
|
|
|
-
|
|
|
|
|
|
TTMapping::TTMapping() {
|
|
|
p_imu_.reset(new ImuProcess());
|