Skip to content

Commit c476911

Browse files
committed
[Feat] add output format required by LiDAR-visual BA.
1 parent 9819553 commit c476911

File tree

9 files changed

+139
-56
lines changed

9 files changed

+139
-56
lines changed

.gitignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
1-
Log/*
21
build/*
File renamed without changes.

Log/pcd/.gitkeep

Whitespace-only changes.

config/HILTI22.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,13 @@ evo:
8888

8989
pcd_save:
9090
pcd_save_en: false
91+
type: 0 # 0: World Frame, 1: Body Frame;
9192
colmap_output_en: false # need to set interval = -1
9293
filter_size_pcd: 0.15
9394
interval: -1
9495
# how many LiDAR frames saved in each pcd file;
9596
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
97+
98+
image_save:
99+
img_save_en: false
100+
interval: 1

config/MARS_LVIG.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,13 @@ evo:
104104

105105
pcd_save:
106106
pcd_save_en: false
107+
type: 0 # 0: World Frame, 1: Body Frame;
107108
colmap_output_en: false # need to set interval = -1
108109
filter_size_pcd: 0.15
109110
interval: -1
110111
# how many LiDAR frames saved in each pcd file;
111-
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
112+
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
113+
114+
image_save:
115+
img_save_en: false
116+
interval: 1

config/NTU_VIRAL.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,8 +80,13 @@ evo:
8080

8181
pcd_save:
8282
pcd_save_en: false
83+
type: 0 # 0: World Frame, 1: Body Frame;
8384
colmap_output_en: false # need to set interval = -1
8485
filter_size_pcd: 0.15
8586
interval: -1
8687
# how many LiDAR frames saved in each pcd file;
87-
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
88+
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
89+
90+
image_save:
91+
img_save_en: false
92+
interval: 1

config/avia.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,13 @@ evo:
7878

7979
pcd_save:
8080
pcd_save_en: false
81+
type: 0 # 0: World Frame, 1: Body Frame;
8182
colmap_output_en: false # need to set interval = -1
8283
filter_size_pcd: 0.15
8384
interval: -1
8485
# how many LiDAR frames saved in each pcd file;
8586
# -1 : all frames will be saved in ONE pcd file, may lead to memory crash when having too much frames.
87+
88+
image_save:
89+
img_save_en: false
90+
interval: 1

include/LIVMapper.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ class LIVMapper
4343
void imu_prop_callback(const ros::TimerEvent &e);
4444
void transformLidar(const Eigen::Matrix3d rot, const Eigen::Vector3d t, const PointCloudXYZI::Ptr &input_cloud, PointCloudXYZI::Ptr &trans_cloud);
4545
void pointBodyToWorld(const PointType &pi, PointType &po);
46-
46+
void RGBpointBodyLidarToIMU(PointType const *const pi, PointType *const po);
4747
void RGBpointBodyToWorld(PointType const *const pi, PointType *const po);
4848
void standard_pcl_cbk(const sensor_msgs::PointCloud2::ConstPtr &msg);
4949
void livox_pcl_cbk(const livox_ros_driver::CustomMsg::ConstPtr &msg_in);
@@ -84,8 +84,8 @@ class LIVMapper
8484
double _first_lidar_time = 0.0;
8585
double match_time = 0, solve_time = 0, solve_const_H_time = 0;
8686

87-
bool lidar_map_inited = false, pcd_save_en = false, pub_effect_point_en = false, pose_output_en = false, ros_driver_fix_en = false, hilti_en = false;
88-
int pcd_save_interval = -1, pcd_index = 0;
87+
bool lidar_map_inited = false, pcd_save_en = false, img_save_en = false, pub_effect_point_en = false, pose_output_en = false, ros_driver_fix_en = false, hilti_en = false;
88+
int img_save_interval = 1, pcd_save_interval = -1, pcd_save_type = 0;
8989
int pub_scan_num = 1;
9090

9191
StatesGroup imu_propagate, latest_ekf_state;
@@ -139,7 +139,7 @@ class LIVMapper
139139
PointCloudXYZRGB::Ptr pcl_wait_save;
140140
PointCloudXYZI::Ptr pcl_wait_save_intensity;
141141

142-
ofstream fout_pre, fout_out, fout_pcd_pos, fout_points;
142+
ofstream fout_pre, fout_out, fout_visual_pos, fout_lidar_pos, fout_points;
143143

144144
pcl::VoxelGrid<PointType> downSizeFilterSurf;
145145

src/LIVMapper.cpp

Lines changed: 113 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ void LIVMapper::readParameters(ros::NodeHandle &nh)
9595

9696
nh.param<int>("pcd_save/interval", pcd_save_interval, -1);
9797
nh.param<bool>("pcd_save/pcd_save_en", pcd_save_en, false);
98+
nh.param<int>("pcd_save/type", pcd_save_type, 0);
99+
nh.param<bool>("image_save/img_save_en", img_save_en, false);
100+
nh.param<int>("image_save/interval", img_save_interval, 1);
101+
98102
nh.param<bool>("pcd_save/colmap_output_en", colmap_output_en, false);
99103
nh.param<double>("pcd_save/filter_size_pcd", filter_size_pcd, 0.5);
100104
nh.param<vector<double>>("extrin_calib/extrinsic_T", extrinT, vector<double>());
@@ -179,7 +183,8 @@ void LIVMapper::initializeFiles()
179183
}
180184
}
181185
if(colmap_output_en) fout_points.open(std::string(ROOT_DIR) + "Log/Colmap/sparse/0/points3D.txt", std::ios::out);
182-
if(pcd_save_interval > 0) fout_pcd_pos.open(std::string(ROOT_DIR) + "Log/PCD/scans_pos.json", std::ios::out);
186+
if(pcd_save_en) fout_lidar_pos.open(std::string(ROOT_DIR) + "Log/pcd/scans_lidar_pos.txt", std::ios::out);
187+
if(img_save_en) fout_visual_pos.open(std::string(ROOT_DIR) + "Log/image/scans_visual_pos.txt", std::ios::out);
183188
fout_pre.open(DEBUG_FILE_DIR("mat_pre.txt"), std::ios::out);
184189
fout_out.open(DEBUG_FILE_DIR("mat_out.txt"), std::ios::out);
185190
}
@@ -437,7 +442,7 @@ void LIVMapper::handleLIO()
437442
}
438443
*pcl_w_wait_pub = *laserCloudWorld;
439444

440-
if (!img_en) publish_frame_world(pubLaserCloudFullRes, vio_manager);
445+
publish_frame_world(pubLaserCloudFullRes, vio_manager);
441446
if (pub_effect_point_en) publish_effect_world(pubLaserCloudEffect, voxelmap_manager->ptpl_list_);
442447
if (voxelmap_manager->config_setting_.is_pub_plane_map_) voxelmap_manager->pubVoxelMap();
443448
publish_path(pubPath);
@@ -480,8 +485,8 @@ void LIVMapper::savePCD()
480485
{
481486
if (pcd_save_en && (pcl_wait_save->points.size() > 0 || pcl_wait_save_intensity->points.size() > 0) && pcd_save_interval < 0)
482487
{
483-
std::string raw_points_dir = std::string(ROOT_DIR) + "Log/PCD/all_raw_points.pcd";
484-
std::string downsampled_points_dir = std::string(ROOT_DIR) + "Log/PCD/all_downsampled_points.pcd";
488+
std::string raw_points_dir = std::string(ROOT_DIR) + "Log/pcd/all_raw_points.pcd";
489+
std::string downsampled_points_dir = std::string(ROOT_DIR) + "Log/pcd/all_downsampled_points.pcd";
485490
pcl::PCDWriter pcd_writer;
486491

487492
if (img_en)
@@ -684,6 +689,17 @@ void LIVMapper::RGBpointBodyToWorld(PointType const *const pi, PointType *const
684689
po->intensity = pi->intensity;
685690
}
686691

692+
void LIVMapper::RGBpointBodyLidarToIMU(PointType const *const pi, PointType *const po)
693+
{
694+
V3D p_body_lidar(pi->x, pi->y, pi->z);
695+
V3D p_body_imu(extR * p_body_lidar + extT);
696+
697+
po->x = p_body_imu(0);
698+
po->y = p_body_imu(1);
699+
po->z = p_body_imu(2);
700+
po->intensity = pi->intensity;
701+
}
702+
687703
void LIVMapper::standard_pcl_cbk(const sensor_msgs::PointCloud2::ConstPtr &msg)
688704
{
689705
if (!lidar_en) return;
@@ -1113,15 +1129,18 @@ void LIVMapper::publish_img_rgb(const image_transport::Publisher &pubImage, VIOM
11131129
pubImage.publish(out_msg.toImageMsg());
11141130
}
11151131

1132+
// Provide output format for LiDAR-visual BA
11161133
void LIVMapper::publish_frame_world(const ros::Publisher &pubLaserCloudFullRes, VIOManagerPtr vio_manager)
11171134
{
11181135
if (pcl_w_wait_pub->empty()) return;
11191136
PointCloudXYZRGB::Ptr laserCloudWorldRGB(new PointCloudXYZRGB());
1120-
if (img_en)
1137+
static int pub_num = 1;
1138+
pub_num++;
1139+
1140+
if (LidarMeasures.lio_vio_flg == VIO)
11211141
{
1122-
static int pub_num = 1;
11231142
*pcl_wait_pub += *pcl_w_wait_pub;
1124-
if(pub_num == pub_scan_num)
1143+
if(pub_num >= pub_scan_num)
11251144
{
11261145
pub_num = 1;
11271146
size_t size = pcl_wait_pub->points.size();
@@ -1146,30 +1165,22 @@ void LIVMapper::publish_frame_world(const ros::Publisher &pubLaserCloudFullRes,
11461165
pointRGB.g = pixel[1];
11471166
pointRGB.b = pixel[0];
11481167
// pointRGB.r = pixel[2] * inv_expo; pointRGB.g = pixel[1] * inv_expo; pointRGB.b = pixel[0] * inv_expo;
1149-
// if (pointRGB.r > 255) pointRGB.r = 255;
1150-
// else if (pointRGB.r < 0) pointRGB.r = 0;
1151-
// if (pointRGB.g > 255) pointRGB.g = 255;
1152-
// else if (pointRGB.g < 0) pointRGB.g = 0;
1153-
// if (pointRGB.b > 255) pointRGB.b = 255;
1154-
// else if (pointRGB.b < 0) pointRGB.b = 0;
1168+
// if (pointRGB.r > 255) pointRGB.r = 255; else if (pointRGB.r < 0) pointRGB.r = 0;
1169+
// if (pointRGB.g > 255) pointRGB.g = 255; else if (pointRGB.g < 0) pointRGB.g = 0;
1170+
// if (pointRGB.b > 255) pointRGB.b = 255; else if (pointRGB.b < 0) pointRGB.b = 0;
11551171
if (pf.norm() > blind_rgb_points) laserCloudWorldRGB->push_back(pointRGB);
11561172
}
11571173
}
11581174
}
1159-
else
1160-
{
1161-
pub_num++;
1162-
}
11631175
}
11641176

11651177
/*** Publish Frame ***/
11661178
sensor_msgs::PointCloud2 laserCloudmsg;
1167-
if (img_en)
1179+
if (slam_mode_ == LIVO && LidarMeasures.lio_vio_flg == VIO)
11681180
{
1169-
// cout << "RGB pointcloud size: " << laserCloudWorldRGB->size() << endl;
11701181
pcl::toROSMsg(*laserCloudWorldRGB, laserCloudmsg);
11711182
}
1172-
else
1183+
if (slam_mode_ == ONLY_LIO || slam_mode_ == ONLY_LO)
11731184
{
11741185
pcl::toROSMsg(*pcl_w_wait_pub, laserCloudmsg);
11751186
}
@@ -1180,49 +1191,102 @@ void LIVMapper::publish_frame_world(const ros::Publisher &pubLaserCloudFullRes,
11801191
/**************** save map ****************/
11811192
/* 1. make sure you have enough memories
11821193
/* 2. noted that pcd save will influence the real-time performences **/
1194+
double update_time = 0.0;
1195+
if (LidarMeasures.lio_vio_flg == VIO) {
1196+
update_time = LidarMeasures.measures.back().vio_time;
1197+
} else { // LIO / LO
1198+
update_time = LidarMeasures.measures.back().lio_time;
1199+
}
1200+
std::stringstream ss_time;
1201+
ss_time << std::fixed << std::setprecision(6) << update_time;
1202+
11831203
if (pcd_save_en)
11841204
{
1185-
int size = feats_undistort->points.size();
1186-
PointCloudXYZI::Ptr laserCloudWorld(new PointCloudXYZI(size, 1));
11871205
static int scan_wait_num = 0;
11881206

1189-
if (img_en)
1190-
{
1191-
*pcl_wait_save += *laserCloudWorldRGB;
1192-
}
1193-
else
1207+
switch (pcd_save_type)
11941208
{
1195-
*pcl_wait_save_intensity += *pcl_w_wait_pub;
1196-
}
1197-
scan_wait_num++;
1209+
case 0: /** world frame **/
1210+
if (slam_mode_ == LIVO)
1211+
{
1212+
*pcl_wait_save += *laserCloudWorldRGB;
1213+
}
1214+
else
1215+
{
1216+
*pcl_wait_save_intensity += *pcl_w_wait_pub;
1217+
}
1218+
if(LidarMeasures.lio_vio_flg == LIO || LidarMeasures.lio_vio_flg == LO) scan_wait_num++;
1219+
break;
11981220

1221+
case 1: /** body frame **/
1222+
if (LidarMeasures.lio_vio_flg == LIO || LidarMeasures.lio_vio_flg == LO)
1223+
{
1224+
int size = feats_undistort->points.size();
1225+
PointCloudXYZI::Ptr laserCloudBody(new PointCloudXYZI(size, 1));
1226+
for (int i = 0; i < size; i++)
1227+
{
1228+
RGBpointBodyLidarToIMU(&feats_undistort->points[i], &laserCloudBody->points[i]);
1229+
}
1230+
*pcl_wait_save_intensity += *laserCloudBody;
1231+
scan_wait_num++;
1232+
cout << "save body frame points: " << pcl_wait_save_intensity->points.size() << endl;
1233+
}
1234+
pcd_save_interval = 1;
1235+
1236+
break;
1237+
1238+
default:
1239+
pcd_save_interval = 1;
1240+
scan_wait_num++;
1241+
break;
1242+
}
11991243
if ((pcl_wait_save->size() > 0 || pcl_wait_save_intensity->size() > 0) && pcd_save_interval > 0 && scan_wait_num >= pcd_save_interval)
12001244
{
1201-
pcd_index++;
1202-
string all_points_dir(string(string(ROOT_DIR) + "Log/PCD/") + to_string(pcd_index) + string(".pcd"));
1245+
string all_points_dir(string(string(ROOT_DIR) + "Log/pcd/") + ss_time.str() + string(".pcd"));
1246+
12031247
pcl::PCDWriter pcd_writer;
1204-
if (pcd_save_en)
1248+
1249+
cout << "current scan saved to " << all_points_dir << endl;
1250+
if (pcl_wait_save->points.size() > 0)
12051251
{
1206-
cout << "current scan saved to /PCD/" << all_points_dir << endl;
1207-
if (img_en)
1208-
{
1209-
pcd_writer.writeBinary(all_points_dir, *pcl_wait_save); // pcl::io::savePCDFileASCII(all_points_dir, *pcl_wait_save);
1210-
PointCloudXYZRGB().swap(*pcl_wait_save);
1211-
}
1212-
else
1213-
{
1214-
pcd_writer.writeBinary(all_points_dir, *pcl_wait_save_intensity);
1215-
PointCloudXYZI().swap(*pcl_wait_save_intensity);
1216-
}
1217-
Eigen::Quaterniond q(_state.rot_end);
1218-
fout_pcd_pos << _state.pos_end[0] << " " << _state.pos_end[1] << " " << _state.pos_end[2] << " " << q.w() << " " << q.x() << " " << q.y()
1219-
<< " " << q.z() << " " << endl;
1220-
scan_wait_num = 0;
1252+
pcd_writer.writeBinary(all_points_dir, *pcl_wait_save); // pcl::io::savePCDFileASCII(all_points_dir, *pcl_wait_save);
1253+
PointCloudXYZRGB().swap(*pcl_wait_save);
1254+
}
1255+
if(pcl_wait_save_intensity->points.size() > 0)
1256+
{
1257+
pcd_writer.writeBinary(all_points_dir, *pcl_wait_save_intensity);
1258+
PointCloudXYZI().swap(*pcl_wait_save_intensity);
12211259
}
1260+
scan_wait_num = 0;
1261+
}
1262+
1263+
if(LidarMeasures.lio_vio_flg == LIO || LidarMeasures.lio_vio_flg == LO)
1264+
{
1265+
Eigen::Quaterniond q(_state.rot_end);
1266+
fout_lidar_pos << std::fixed << std::setprecision(6);
1267+
fout_lidar_pos << LidarMeasures.measures.back().lio_time << " " << _state.pos_end[0] << " " << _state.pos_end[1] << " " << _state.pos_end[2] << " " << q.w() << " " << q.x() << " " << q.y()
1268+
<< " " << q.z() << " " << endl;
1269+
}
1270+
}
1271+
if (img_save_en && LidarMeasures.lio_vio_flg == VIO)
1272+
{
1273+
static int img_wait_num = 0;
1274+
img_wait_num++;
1275+
1276+
if (img_save_interval > 0 && img_wait_num >= img_save_interval)
1277+
{
1278+
imwrite(string(string(ROOT_DIR) + "Log/image/") + ss_time.str() + string(".png"), vio_manager->img_rgb);
1279+
1280+
Eigen::Quaterniond q(_state.rot_end);
1281+
fout_visual_pos << std::fixed << std::setprecision(6);
1282+
fout_visual_pos << LidarMeasures.measures.back().vio_time << " " << _state.pos_end[0] << " " << _state.pos_end[1] << " " << _state.pos_end[2] << " "
1283+
<< q.x() << " " << q.y() << " " << q.z() << " " << q.w() << std::endl;
1284+
img_wait_num = 0;
12221285
}
12231286
}
1287+
12241288
if(laserCloudWorldRGB->size() > 0) PointCloudXYZI().swap(*pcl_wait_pub);
1225-
PointCloudXYZI().swap(*pcl_w_wait_pub);
1289+
if(LidarMeasures.lio_vio_flg == VIO) PointCloudXYZI().swap(*pcl_w_wait_pub);
12261290
}
12271291

12281292
void LIVMapper::publish_visual_sub_map(const ros::Publisher &pubSubVisualMap)

0 commit comments

Comments
 (0)