Skip to content

Commit f746d63

Browse files
committed
Added params as gflags
1 parent e98d046 commit f746d63

File tree

2 files changed

+34
-98
lines changed

2 files changed

+34
-98
lines changed

console-plugins/dense-reconstruction-plugin/include/dense-reconstruction/balm/bavoxel.h

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <Eigen/Core>
55
#include <aslam/common/pose-types.h>
6+
#include <gflags/gflags.h>
67
#include <kindr/minimal/common.h>
78
#include <maplab-common/threading-helpers.h>
89
#include <resources-common/point-cloud.h>
@@ -19,12 +20,12 @@
1920
Eigen::Matrix<double, a, 1>, \
2021
Eigen::aligned_allocator<Eigen::Matrix<double, a, 1>>>
2122

22-
size_t layer_limit = 3;
23-
float eigen_value_array[4] = {1.0 / 40, 1.0 / 40, 1.0 / 40, 1.0 / 40};
24-
size_t min_ps = 15;
23+
DECLARE_double(balm_voxel_size);
24+
DECLARE_uint32(balm_max_layers);
25+
DECLARE_uint32(balm_min_plane_points);
26+
DECLARE_double(balm_max_eigen_value);
2527

26-
double voxel_size = 1;
27-
int win_size = 20;
28+
int win_size;
2829

2930
class OctoTreeNode;
3031
typedef std::unordered_map<resources::VoxelPosition, OctoTreeNode*> SurfaceMap;
@@ -275,17 +276,16 @@ class OctoTreeNode {
275276
}
276277
}
277278

278-
bool judge_eigen(Eigen::Vector3d& normal) {
279+
bool judge_eigen() {
279280
PointCluster covMat;
280281
for (const PointCluster& p : sig_tran) {
281282
covMat += p;
282283
}
283284

284285
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> saes(covMat.cov());
285286
double decision = saes.eigenvalues()[0] / saes.eigenvalues()[1];
286-
normal = saes.eigenvectors().col(0);
287287

288-
return (decision < eigen_value_array[layer]);
288+
return (decision < FLAGS_balm_max_eigen_value);
289289
}
290290

291291
void cut_func() {
@@ -326,21 +326,18 @@ class OctoTreeNode {
326326
vec_tran = std::vector<PLV(3)>();
327327
}
328328

329-
bool recut(
330-
VoxHess* vox_opt, std::vector<PLV(3)>* normals,
331-
resources::PointCloud* points_G) {
329+
bool recut(VoxHess* vox_opt, resources::PointCloud* points_G) {
332330
size_t point_size = 0;
333331
for (const PointCluster& p : sig_tran) {
334332
point_size += p.N;
335333
}
336334

337335
const size_t num_pointclouds = index.size();
338-
if (num_pointclouds < 2 || point_size <= min_ps) {
336+
if (num_pointclouds < 2 || point_size <= FLAGS_balm_min_plane_points) {
339337
return false;
340338
}
341339

342-
Eigen::Vector3d normal;
343-
if (judge_eigen(normal)) {
340+
if (judge_eigen()) {
344341
// Push planes into visualization if requested.
345342
if (points_G != nullptr) {
346343
const float intensity = 255.0 * rand() / (RAND_MAX + 1.0f);
@@ -360,16 +357,11 @@ class OctoTreeNode {
360357
vec_tran = std::vector<PLV(3)>();
361358
sig_tran = std::vector<PointCluster>();
362359

363-
// Return the normal of the plane we found.
364-
for (const size_t i : index) {
365-
(*normals)[i].emplace_back(normal);
366-
}
367-
368360
// Push plane into optimization.
369361
vox_opt->push_voxel(&index, &sig_orig, &fix_point);
370362

371363
return true;
372-
} else if (layer == layer_limit) {
364+
} else if (layer == FLAGS_balm_max_layers) {
373365
return false;
374366
}
375367

@@ -380,7 +372,7 @@ class OctoTreeNode {
380372
bool keep = false;
381373
for (size_t i = 0; i < 8; ++i) {
382374
if (leaves[i] != nullptr) {
383-
if (leaves[i]->recut(vox_opt, normals, points_G)) {
375+
if (leaves[i]->recut(vox_opt, points_G)) {
384376
keep = true;
385377
} else {
386378
delete leaves[i];
@@ -454,20 +446,6 @@ class BALM2 {
454446
}
455447

456448
void damping_iter(aslam::TransformationVector& x_stats, VoxHess& voxhess) {
457-
/*std::vector<int> planes(x_stats.size(), 0);
458-
for (size_t i = 0; i < voxhess.plvec_voxels.size(); i++) {
459-
for (size_t j = 0; j < voxhess.plvec_voxels[i]->size(); j++)
460-
if (voxhess.plvec_voxels[i]->at(j).N != 0)
461-
planes[j]++;
462-
}
463-
sort(planes.begin(), planes.end());
464-
if (planes[0] < 20) {
465-
printf("Initial error too large.\n");
466-
printf("Please loose plane determination criteria for more planes.\n");
467-
printf("The optimization is terminated.\n");
468-
exit(0);
469-
}*/
470-
471449
double u = 0.01, v = 2;
472450
Eigen::MatrixXd D(6 * win_size, 6 * win_size),
473451
Hess(6 * win_size, 6 * win_size);
@@ -538,7 +516,7 @@ void cut_voxel(
538516
const Eigen::Vector3d pvec_orig = xyz_S.col(i);
539517
const Eigen::Vector3d pvec_tran = xyz_G.col(i);
540518

541-
resources::VoxelPosition position(pvec_tran, voxel_size);
519+
resources::VoxelPosition position(pvec_tran, FLAGS_balm_voxel_size);
542520
auto iter = surface_map.find(position);
543521
if (iter != surface_map.end()) {
544522
if (iter->second->index.back() != index) {
@@ -562,10 +540,10 @@ void cut_voxel(
562540
node->sig_orig.back().push(pvec_orig);
563541
node->sig_tran.back().push(pvec_tran);
564542

565-
node->voxel_center[0] = (0.5 + position.x) * voxel_size;
566-
node->voxel_center[1] = (0.5 + position.y) * voxel_size;
567-
node->voxel_center[2] = (0.5 + position.z) * voxel_size;
568-
node->quater_length = voxel_size / 4.0;
543+
node->voxel_center[0] = (0.5 + position.x) * FLAGS_balm_voxel_size;
544+
node->voxel_center[1] = (0.5 + position.y) * FLAGS_balm_voxel_size;
545+
node->voxel_center[2] = (0.5 + position.z) * FLAGS_balm_voxel_size;
546+
node->quater_length = FLAGS_balm_voxel_size / 4.0;
569547
node->layer = 0;
570548

571549
surface_map[position] = node;

console-plugins/dense-reconstruction-plugin/src/dense-reconstruction-plugin.cc

Lines changed: 16 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,20 @@ DEFINE_double(
7979
balm_kf_time_threshold_s, 1.0,
8080
"BALM force a keyframe at fixed time intervals [s].");
8181

82+
DEFINE_double(
83+
balm_voxel_size, 1.0, "BALM voxel size to use to look for planes in.");
84+
DEFINE_uint32(
85+
balm_max_layers, 3,
86+
"BALM maximum number of subdividing of a voxel when looking for a plane.");
87+
DEFINE_uint32(
88+
balm_min_plane_points, 15,
89+
"BALM minimum number of points needed when looking for a plane.");
90+
DEFINE_double(
91+
balm_max_eigen_value, 0.05,
92+
"BALM maximum least significant eigen value, when looking for a plane in a "
93+
"voxel. Smaller values will result in flatter planes, but will need better "
94+
"initial poses.");
95+
8296
DEFINE_double(
8397
balm_vis_voxel_size, 0.2,
8498
"Voxel size to use for visualization when publishing pointclouds from "
@@ -837,73 +851,17 @@ DenseReconstructionPlugin::DenseReconstructionPlugin(
837851
}
838852

839853
VoxHess voxhess;
840-
std::vector<PLV(3)> normals(win_size);
841854
resources::PointCloud planes_G;
842855
for (auto iter = surface_map.begin(); iter != surface_map.end();) {
843-
if (iter->second->recut(&voxhess, &normals, &planes_G)) {
856+
if (iter->second->recut(&voxhess, &planes_G)) {
844857
++iter;
845858
} else {
846859
delete iter->second;
847860
iter = surface_map.erase(iter);
848861
}
849862
}
850863

851-
// Check if all poses are well constrained.
852-
size_t num_under_constrained = 0;
853-
std::vector<bool> under_constrained(win_size);
854-
for (size_t i = 0; i < win_size; ++i) {
855-
under_constrained[i] = false;
856-
// First check we have enough planes.
857-
if (normals[i].size() < FLAGS_balm_min_plane_count) {
858-
++num_under_constrained;
859-
under_constrained[i] = true;
860-
continue;
861-
}
862-
863-
// Perform SVD on the normals that constrain one point cloud.
864-
Eigen::Matrix3Xd index_normals(3, normals[i].size());
865-
// index_normals.resize(Eigen::NoChange, normals[i].size());
866-
for (size_t j = 0; j < normals[i].size(); ++j) {
867-
index_normals.col(j) = normals[i][j];
868-
}
869-
870-
Eigen::JacobiSVD<Eigen::Matrix3Xd> svd;
871-
svd.compute(index_normals, Eigen::ComputeThinU | Eigen::ComputeThinV);
872-
873-
// If one singular value is very small it means that direction is not
874-
// well constrained. If the ratio of singular values is very
875-
// imbalanced it means one direction is much better constrained and
876-
// might cause the optimization to ignore the other ones.
877-
const double sv0 = svd.singularValues()[0];
878-
const double sv1 = svd.singularValues()[1];
879-
const double sv2 = svd.singularValues()[2];
880-
if ((sv2 < FLAGS_balm_min_normal_svd) ||
881-
(sv2 < sv1 / FLAGS_balm_min_normal_svd_ratio) ||
882-
(sv1 < sv0 / FLAGS_balm_min_normal_svd_ratio)) {
883-
++num_under_constrained;
884-
under_constrained[i] = true;
885-
}
886-
}
887-
888-
LOG(INFO) << "Found " << num_under_constrained << " poses that are "
889-
<< "under constrained. Removing them from the optimization "
890-
<< "and proceeding.";
891-
892-
// Visualize the under constrained poses.
893-
{
894-
Eigen::Matrix3Xd positions_G(3, num_under_constrained);
895-
int eigen_i = 0;
896-
for (size_t i = 0; i < under_constrained.size(); ++i) {
897-
if (under_constrained[i]) {
898-
positions_G.col(eigen_i++) = poses_G_S[i].getPosition();
899-
}
900-
}
901-
visualization::publish3DPointsAsPointCloud(
902-
positions_G, visualization::kCommonRed, 0.7, FLAGS_tf_map_frame,
903-
"balm_path_under_constrained");
904-
}
905-
906-
// Publish planes computed by BALM ro rviz.
864+
// Publish planes computed by BALM to rviz.
907865
sensor_msgs::PointCloud2 ros_planes_G;
908866
backend::convertPointCloudType(planes_G, &ros_planes_G);
909867
ros_planes_G.header.frame_id = FLAGS_tf_map_frame;

0 commit comments

Comments
 (0)