diff --git a/include/laser/processor/processor_odom_icp_3d.h b/include/laser/processor/processor_odom_icp_3d.h index ecb8d369014ed43ffa42550ae88502d32657269a..cbeaf79675d7a3ea01bb39b52a92a50bdbcf94fc 100644 --- a/include/laser/processor/processor_odom_icp_3d.h +++ b/include/laser/processor/processor_odom_icp_3d.h @@ -51,6 +51,7 @@ WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorOdomIcp3d); struct ParamsProcessorOdomIcp3d : public ParamsProcessorTracker, public ParamsMotionProvider { double max_time_span; + double max_fitness_score; // maximum Euclidean fitness score (e.g., mean of squared distances from the source to the target) bool pcl_downsample; double pcl_downsample_voxel_size; @@ -68,6 +69,7 @@ struct ParamsProcessorOdomIcp3d : public ParamsProcessorTracker, public ParamsMo : ParamsProcessorTracker(_unique_name, _server), ParamsMotionProvider(_unique_name, _server) { max_time_span = _server.getParam<double>(prefix + _unique_name + "/keyframe_vote/max_time_span"); + max_fitness_score = _server.getParam<double>(prefix + _unique_name + "/keyframe_vote/max_fitness_score"); pcl_downsample = _server.getParam<bool>(prefix + _unique_name + "/pcl_downsample"); pcl_downsample_voxel_size = _server.getParam<double>(prefix + _unique_name + "/pcl_downsample_voxel_size"); diff --git a/include/laser/utils/laser3d_tools.h b/include/laser/utils/laser3d_tools.h index 308897875928b16390d5b0adb2a783668b71fd2a..f3509027f07fcdd1d5a6583e94e56519587af917 100644 --- a/include/laser/utils/laser3d_tools.h +++ b/include/laser/utils/laser3d_tools.h @@ -101,17 +101,9 @@ inline void pairAlign(const pcl::PointCloud<pcl::PointXYZ>::Ptr _cloud_ref, auto start = std::chrono::high_resolution_clock::now(); // DURATION -------------------------------------------------------- - // Internal PointCloud pointers (boost::shared_ptr) - pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_ref = pcl::make_shared<pcl::PointCloud<pcl::PointXYZ>>(); - pcl::PointCloud<pcl::PointXYZ>::Ptr cloud_other = pcl::make_shared<pcl::PointCloud<pcl::PointXYZ>>(); - - // Point clouds are considered already downsampled - *cloud_ref = *_cloud_ref; - *cloud_other = *_cloud_other; - // Set input clouds - _registration_solver->setInputSource(cloud_ref); - _registration_solver->setInputTarget(cloud_other); + _registration_solver->setInputSource(_cloud_ref); + _registration_solver->setInputTarget(_cloud_other); // Declare variables Eigen::Matrix4f transform_pcl; @@ -120,7 +112,8 @@ inline void pairAlign(const pcl::PointCloud<pcl::PointXYZ>::Ptr _cloud_ref, Eigen::Matrix4f transform_guess = _transform_guess.matrix().cast<float>(); // Alignment - _registration_solver->align(*cloud_ref, transform_guess); + pcl::PointCloud<pcl::PointXYZ>cloud_out; + _registration_solver->align(cloud_out, transform_guess); transform_pcl = _registration_solver->getFinalTransformation(); // Output the transformation as Isometry of double(s) diff --git a/src/processor/processor_odom_icp_3d.cpp b/src/processor/processor_odom_icp_3d.cpp index 95f249f5ce921893e2ba5f04ebc65e4d485ed931..8b10b650c7744de29524afbd8b45c0ab263223ad 100644 --- a/src/processor/processor_odom_icp_3d.cpp +++ b/src/processor/processor_odom_icp_3d.cpp @@ -179,14 +179,24 @@ unsigned int ProcessorOdomIcp3d::processNew(const int& _max_features) */ bool ProcessorOdomIcp3d::voteForKeyFrame() const { + // 1. vote by time if (last_ptr_->getTimeStamp() - origin_ptr_->getTimeStamp() > params_odom_icp_->max_time_span) { + WOLF_DEBUG("ProcessorOdomIcp3d: vote KF by time"); return true; } // TODO: - // - vote by distance - // - vote by angle - // - vote by nbr. of captures + // 2. vote by distance + // 3. vote by angle + // 4. vote by nbr. of captures + + // 5. vote by fitness score + if (registration_solver_->getFitnessScore() > params_odom_icp_->max_fitness_score) + { + WOLF_DEBUG("ProcessorOdomIcp3d: vote KF by fitness score"); + return true; + } + return false; }; diff --git a/test/gtest_processor_odom_icp_3d.cpp b/test/gtest_processor_odom_icp_3d.cpp index a33b3c2e07641934efc5d18fb824e13c976b7f4e..8ebb485410b0f69c9a3f54f6982a6fbe60dc2e8c 100644 --- a/test/gtest_processor_odom_icp_3d.cpp +++ b/test/gtest_processor_odom_icp_3d.cpp @@ -49,6 +49,8 @@ using namespace wolf; std::string laser_root_dir = _WOLF_LASER_ROOT_DIR; + + class Test_ProcessorOdomIcp3D_yaml : public testing::Test { public: diff --git a/test/yaml/problem_odom_icp_3d.yaml b/test/yaml/problem_odom_icp_3d.yaml index 02f558aaaf334238f81bc4ffd033dfb4a3056a50..8291a5714b1ff457bee9be7c1bef41a54b10639d 100644 --- a/test/yaml/problem_odom_icp_3d.yaml +++ b/test/yaml/problem_odom_icp_3d.yaml @@ -37,6 +37,7 @@ config: voting_active: true min_features_for_keyframe : 0 max_time_span: 0.99 + max_fitness_score: 0.0001 # maximum Euclidean fitness score (e.g., mean of squared distances from the source to the target) angle_turned: 1.0 state_getter: true state_priority: 1 @@ -44,7 +45,7 @@ config: pcl_downsample_voxel_size: 0.05 icp_algorithm: "icp_nl" # "icp", "icp_nl", "gicp" icp_max_iterations: 20 - icp_transformation_rotation_epsilon: 0.99 # this is cos(alpha) + icp_transformation_rotation_epsilon: 0.9999 # this is cos(alpha) icp_transformation_translation_epsilon: 1e-9 # this is translation squared icp_max_correspondence_distance: 0.05