Skip to content

Commit c85400f

Browse files
LiDAR intensity data support in GLIM (#247)
* intensity support for glimGPU * removed dependency on glk, using gtsam_point::PointCloud instead * refactor submap point transform to Eigen::Vector4d * check raw_frame intensities before adding
1 parent 333cad4 commit c85400f

9 files changed

Lines changed: 81 additions & 24 deletions

include/glim/mapping/async_global_mapping.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ class AsyncGlobalMapping {
7272
*/
7373
void save(const std::string& path);
7474

75-
std::vector<Eigen::Vector4d> export_points();
75+
gtsam_points::PointCloud::Ptr export_points();
7676

7777
std::shared_ptr<glim::GlobalMappingBase> get_global_mapping() {
7878
std::lock_guard<std::mutex> lock(global_mapping_mutex);

include/glim/mapping/global_mapping.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ class GlobalMapping : public GlobalMappingBase {
6969
virtual void optimize() override;
7070

7171
virtual void save(const std::string& path) override;
72-
virtual std::vector<Eigen::Vector4d> export_points() override;
72+
virtual gtsam_points::PointCloud::Ptr export_points() override;
7373

7474
/**
7575
* @brief Load a mapping result from a dumped directory
@@ -109,4 +109,4 @@ class GlobalMapping : public GlobalMappingBase {
109109

110110
std::shared_ptr<void> tbb_task_arena;
111111
};
112-
} // namespace glim
112+
} // namespace glim

include/glim/mapping/global_mapping_base.hpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#endif
88

99
#include <glim/mapping/sub_map.hpp>
10+
#include <gtsam_points/types/point_cloud.hpp>
1011

1112
namespace spdlog {
1213
class logger;
@@ -70,7 +71,7 @@ class GlobalMappingBase {
7071
/**
7172
* @brief Export all the submap points
7273
*/
73-
virtual std::vector<Eigen::Vector4d> export_points() { return std::vector<Eigen::Vector4d>(); }
74+
virtual gtsam_points::PointCloud::Ptr export_points() { return nullptr; }
7475

7576
/**
7677
* @brief Load a global mapping module from a shared library

include/glim/mapping/global_mapping_pose_graph.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ class GlobalMappingPoseGraph : public GlobalMappingBase {
9797
virtual void optimize() override;
9898

9999
virtual void save(const std::string& path) override;
100-
virtual std::vector<Eigen::Vector4d> export_points() override;
100+
virtual gtsam_points::PointCloud::Ptr export_points() override;
101101

102102
private:
103103
void insert_submap(int current, const SubMap::Ptr& submap);
@@ -131,4 +131,4 @@ class GlobalMappingPoseGraph : public GlobalMappingBase {
131131

132132
std::shared_ptr<void> tbb_task_arena;
133133
};
134-
} // namespace glim
134+
} // namespace glim

src/glim/mapping/async_global_mapping.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ void AsyncGlobalMapping::save(const std::string& path) {
6767
logger->info("saved");
6868
}
6969

70-
std::vector<Eigen::Vector4d> AsyncGlobalMapping::export_points() {
70+
gtsam_points::PointCloud::Ptr AsyncGlobalMapping::export_points() {
7171
std::lock_guard<std::mutex> lock(global_mapping_mutex);
7272
logger->info("exporting points");
7373
auto points = global_mapping->export_points();
@@ -139,4 +139,4 @@ void AsyncGlobalMapping::run() {
139139
}
140140
}
141141

142-
} // namespace glim
142+
} // namespace glim

src/glim/mapping/global_mapping.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -634,22 +634,57 @@ void GlobalMapping::save(const std::string& path) {
634634
GlobalConfig::instance()->dump(path + "/config");
635635
}
636636

637-
std::vector<Eigen::Vector4d> GlobalMapping::export_points() {
638-
int num_all_points = 0;
637+
638+
gtsam_points::PointCloud::Ptr GlobalMapping::export_points() {
639+
auto merged = std::make_shared<gtsam_points::PointCloudCPU>();
640+
641+
size_t total_points = 0;
639642
for (const auto& submap : submaps) {
640-
num_all_points += submap->frame->size();
643+
if (!submap || !submap->frame) {
644+
continue;
645+
}
646+
total_points += submap->frame->size();
641647
}
642648

643-
std::vector<Eigen::Vector4d> all_points;
644-
all_points.reserve(num_all_points);
649+
std::vector<Eigen::Vector4d> points;
650+
points.reserve(total_points);
645651

652+
bool export_intensities = true;
646653
for (const auto& submap : submaps) {
647-
std::transform(submap->frame->points, submap->frame->points + submap->frame->size(), std::back_inserter(all_points), [&](const Eigen::Vector4d& p) {
648-
return submap->T_world_origin * p;
649-
});
654+
if (!submap || !submap->frame || !submap->frame->has_intensities()) {
655+
export_intensities = false;
656+
break;
657+
}
658+
}
659+
660+
std::vector<double> intensities;
661+
if (export_intensities) {
662+
intensities.reserve(total_points);
663+
}
664+
665+
for (const auto& submap : submaps) {
666+
if (!submap || !submap->frame) {
667+
continue;
668+
}
669+
670+
for (int i = 0; i < submap->frame->size(); i++) {
671+
const Eigen::Vector4d point = submap->T_world_origin * submap->frame->points[i];
672+
points.push_back(point);
673+
674+
if (export_intensities) {
675+
intensities.push_back(submap->frame->intensities[i]);
676+
}
677+
}
678+
}
679+
680+
if (!points.empty()) {
681+
merged->add_points(points);
682+
if (export_intensities) {
683+
merged->add_intensities(intensities);
684+
}
650685
}
651686

652-
return all_points;
687+
return merged;
653688
}
654689

655690
bool GlobalMapping::load(const std::string& path) {

src/glim/mapping/global_mapping_pose_graph.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include <gtsam/slam/BetweenFactor.h>
99

1010
#include <gtsam_points/ann/kdtree.hpp>
11+
#include <gtsam_points/types/point_cloud_cpu.hpp>
1112
#include <gtsam_points/types/gaussian_voxelmap_cpu.hpp>
1213
#include <gtsam_points/factors/integrated_gicp_factor.hpp>
1314
#include <gtsam_points/factors/integrated_vgicp_factor.hpp>
@@ -243,8 +244,8 @@ void GlobalMappingPoseGraph::save(const std::string& path) {
243244
}
244245
}
245246

246-
std::vector<Eigen::Vector4d> GlobalMappingPoseGraph::export_points() {
247-
return {};
247+
gtsam_points::PointCloud::Ptr GlobalMappingPoseGraph::export_points() {
248+
return std::make_shared<gtsam_points::PointCloudCPU>();
248249
}
249250

250251
void GlobalMappingPoseGraph::insert_submap(int current, const SubMap::Ptr& submap) {
@@ -477,4 +478,4 @@ void GlobalMappingPoseGraph::update_submaps() {
477478
}
478479
}
479480

480-
} // namespace glim
481+
} // namespace glim

src/glim/mapping/sub_mapping.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,6 @@ void SubMapping::insert_frame(const EstimationFrame::ConstPtr& odom_frame_) {
338338

339339
void SubMapping::insert_keyframe(const int current, const EstimationFrame::ConstPtr& odom_frame) {
340340
gtsam_points::PointCloud::ConstPtr deskewed_frame = odom_frame->frame;
341-
342341
// Re-perform deskewing with smoothed IMU poses
343342
if (params.enable_imu && odom_frame->raw_frame && odom_frame->imu_rate_trajectory.cols() >= 2) {
344343
if (std::abs(odom_frame->stamp - odom_frame->imu_rate_trajectory(0, 0)) > 1e-3) {
@@ -370,7 +369,9 @@ void SubMapping::insert_keyframe(const int current, const EstimationFrame::Const
370369
frame->points[i] = odom_frame->T_lidar_imu.inverse() * frame->points[i];
371370
}
372371
frame->add_covs(covariance_estimation->estimate(frame->points_storage, odom_frame->raw_frame->neighbors));
373-
372+
if (!odom_frame->raw_frame->intensities.empty()) {
373+
frame->add_intensities(odom_frame->raw_frame->intensities);
374+
}
374375
deskewed_frame = frame;
375376
}
376377

src/glim/viewer/offline_viewer.cpp

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,12 +215,31 @@ bool OfflineViewer::export_map(guik::ProgressInterface& progress, const std::str
215215
progress.set_text("Concatenating submaps");
216216
progress.set_maximum(3);
217217
progress.increment();
218-
const auto points = async_global_mapping->export_points();
218+
auto points = async_global_mapping->export_points();
219+
220+
if (!points || !points->has_points()) {
221+
logger->warn("No points available for export");
222+
return false;
223+
}
219224

220225
progress.set_text("Writing to file");
221226
progress.increment();
222-
glk::save_ply_binary(path, points.data(), points.size());
223227

228+
glk::PLYData ply;
229+
ply.vertices.reserve(points->size());
230+
const bool has_intensities = points->has_intensities();
231+
if (has_intensities) {
232+
ply.intensities.reserve(points->size());
233+
}
234+
235+
for (size_t i = 0; i < points->size(); ++i) {
236+
ply.vertices.push_back(points->points[i].head<3>().cast<float>());
237+
if (has_intensities) {
238+
ply.intensities.push_back(points->intensities[i]);
239+
}
240+
}
241+
242+
glk::save_ply_binary(path, ply);
224243
return true;
225244
}
226245

0 commit comments

Comments
 (0)