diff --git a/include/laser/processor/processor_odom_icp.h b/include/laser/processor/processor_odom_icp.h index 68b2a5f3d191dbffeec539bc4e6fd6ed154cb608..a323fe5429f24c8f567ebb863e3a6d4e8b4ded34 100644 --- a/include/laser/processor/processor_odom_icp.h +++ b/include/laser/processor/processor_odom_icp.h @@ -43,7 +43,7 @@ class ProcessorOdomIcp : public ProcessorTracker, public MotionProvider // Useful sensor stuff SensorLaser2dPtr sensor_laser_; // casted pointer to parent laserscanutils::LaserScanParams laser_scan_params_; - SizeEigen dim_; // dimension of the problem (2 or 3) + unsigned int dim_; // dimension of the problem (2 or 3) // temporary and carry-on transformations laserscanutils::icpOutput trf_origin_last_; diff --git a/schema/processor/ProcessorOdomIcp.schema b/schema/processor/ProcessorOdomIcp.schema index 70ebdb448788f979668dae829ece7331980be573..7981c597013b626f1acd4f5dd0603e58b9633ac9 100644 --- a/schema/processor/ProcessorOdomIcp.schema +++ b/schema/processor/ProcessorOdomIcp.schema @@ -2,6 +2,12 @@ follow: ProcessorTracker.schema follow: MotionProvider.schema +dimension: + _mandatory: true + _type: unsigned int + _options: [2, 3] + _doc: "The dimension of the problem representation: 2D or 3D" + keyframe_vote: dist_traveled: _mandatory: true diff --git a/src/processor/processor_loop_closure_falko.cpp b/src/processor/processor_loop_closure_falko.cpp index 8f1dbfe8ddfef7f0e0c16803077540b5bee3280b..57aa8dcd831edaf0bf45954882ad16a5eae153db 100644 --- a/src/processor/processor_loop_closure_falko.cpp +++ b/src/processor/processor_loop_closure_falko.cpp @@ -22,7 +22,7 @@ namespace wolf { ProcessorLoopClosureFalko::ProcessorLoopClosureFalko(const YAML::Node& _params) - : ProcessorLoopClosure("ProcessorLoopClosureFalko", 2, _params) + : ProcessorLoopClosure("ProcessorLoopClosureFalko", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params) { // PARAMS min_keypoints_ = _params["min_keypoints"].as<int>(); diff --git a/src/processor/processor_loop_closure_icp.cpp b/src/processor/processor_loop_closure_icp.cpp index f854b5c5d4e7efb3767de02e4e98c480ea265df0..c2f3da0d2752014fcb860878f5306c535feb4936 100644 --- a/src/processor/processor_loop_closure_icp.cpp +++ b/src/processor/processor_loop_closure_icp.cpp @@ -28,7 +28,7 @@ using namespace Eigen; namespace wolf { ProcessorLoopClosureIcp::ProcessorLoopClosureIcp(const YAML::Node& _params) - : ProcessorLoopClosure("ProcessorLoopClosureIcp", 2, _params), last_loop_closure_(nullptr) + : ProcessorLoopClosure("ProcessorLoopClosureIcp", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params), last_loop_closure_(nullptr) { icp_params_ = getIcpParams(_params["icp"]); recent_frames_ignored_ = _params["recent_frames_ignored"].as<int>(); diff --git a/src/processor/processor_odom_icp.cpp b/src/processor/processor_odom_icp.cpp index 8593d11c275b568113b18eb7d914cae43525075f..a336bc663f2a24598f088c1a3e1c9ccc973fabcf 100644 --- a/src/processor/processor_odom_icp.cpp +++ b/src/processor/processor_odom_icp.cpp @@ -39,9 +39,13 @@ using namespace Eigen; namespace wolf { ProcessorOdomIcp::ProcessorOdomIcp(const YAML::Node& _params) - : ProcessorTracker("ProcessorOdomIcp", "PO", 0, _params), - MotionProvider({}, _params), // uninitialized types - dim_(0), // uninitialized + : ProcessorTracker("ProcessorOdomIcp", + {{'P', _params["dimension"].as<unsigned int>() == 2 ? "StatePoint2d" : "StatePoint3d"}, + {'O', _params["dimension"].as<unsigned int>() == 2 ? "StateAngle" : "StateQuaternion"}}, + _params), + MotionProvider({{'P', _params["dimension"].as<unsigned int>() == 2 ? "StatePoint2d" : "StatePoint3d"}, + {'O', _params["dimension"].as<unsigned int>() == 2 ? "StateAngle" : "StateQuaternion"}}, + _params), // uninitialized types odom_origin_(VectorXd::Zero(3)), odom_last_(VectorXd::Zero(3)), odom_incoming_(VectorXd::Zero(3)), @@ -58,6 +62,7 @@ ProcessorOdomIcp::ProcessorOdomIcp(const YAML::Node& _params) trf_last_incoming_.res_covar = Matrix3d::Identity(); // PARAMS + dim_ = _params["dimension"].as<unsigned int>(); icp_params_ = getIcpParams(_params["icp"]); initial_guess_ = _params["initial_guess"].as<std::string>(); dist_th_ = _params["keyframe_vote"]["dist_traveled"].as<double>(); @@ -117,17 +122,6 @@ void ProcessorOdomIcp::configure(SensorBasePtr _sensor) ro_T_so_ = laser::trf2isometry(sensor_laser_->getP()->getState(), sensor_laser_->getO()->getState()); rl_T_sl_ = ro_T_so_; } - - // initialize problem dimension - if (_sensor->getProblem()) - dim_ = _sensor->getProblem()->getDim(); - else - throw std::runtime_error( - "ProcessorOdomIcp::configure: SensorLaser2d not linked to a problem. Impossible to find out dimension."); - - // Motion provider state_types - MotionProvider::setStateTypes(dim_ == 2 ? TypeComposite{{'P', "StatePoint2d"}, {'O', "StateAngle"}} - : TypeComposite{{'P', "StatePoint3d"}, {'O', "StateQuaternion"}}); } void ProcessorOdomIcp::updateExtrinsicsIsometries() @@ -469,31 +463,31 @@ FactorBasePtr ProcessorOdomIcp::emplaceFactor(FeatureBasePtr _feature) VectorComposite ProcessorOdomIcp::getState(StateKeys _keys) const { + // We do not have any info of where to find a valid state + // Further checking here for origin_ptr is redundant: if last=null, then origin=null too. + if (origin_ptr_ == nullptr or origin_ptr_->isRemoving() or last_ptr_ == nullptr) + { + WOLF_WARN("Processor has no state. Returning an empty VectorComposite"); + return VectorComposite(); // return empty state + } + // empty _keys means all keys if (_keys.empty()) - _keys = state_types_.getKeys(); + _keys = getStateKeys(); else { - if (not state_types_.has(_keys)) + if (not getStateTypes().has(_keys)) { StateKeys keys_available; for (auto key : _keys) { - if (state_types_.has(key)) keys_available += key; + if (getStateTypes().has(key)) keys_available += key; } + WOLF_DEBUG("Processor has no all keys asked (", _keys, "). Returning the available ones: ", keys_available); _keys = keys_available; - WOLF_DEBUG("Processor has no all keys asked (", _keys, "). Returning the available ones: ", _keys); } } - // We do not have any info of where to find a valid state - // Further checking here for origin_ptr is redundant: if last=null, then origin=null too. - if (origin_ptr_ == nullptr or origin_ptr_->isRemoving() or last_ptr_ == nullptr) - { - WOLF_WARN("Processor has no state. Returning an empty VectorComposite"); - return VectorComposite(); // return empty state - } - // NOTE: we cannot update extrinsics since the function is const // origin-last transf. diff --git a/src/processor/processor_tracker_feature_polyline_2d.cpp b/src/processor/processor_tracker_feature_polyline_2d.cpp index d90c83383412bc374d389738aeac8a27497f63fc..ac0c0be34e86a4a3922f230e9a050e204129e626 100644 --- a/src/processor/processor_tracker_feature_polyline_2d.cpp +++ b/src/processor/processor_tracker_feature_polyline_2d.cpp @@ -24,7 +24,7 @@ namespace wolf { ProcessorTrackerFeaturePolyline2d::ProcessorTrackerFeaturePolyline2d(const YAML::Node& _params) - : ProcessorTrackerFeature("ProcessorTrackerFeature", "PO", 3, _params), + : ProcessorTrackerFeature("ProcessorTrackerFeature", {{'P', "StatePoint2d"}, {'O', "StateAngle"}}, _params), line_finder_(getLineFinderIterativeParams(_params["line_finder"])), extrinsics_transformation_computed_(false) { @@ -1394,8 +1394,8 @@ bool ProcessorTrackerFeaturePolyline2d::tryUpdateMatchTransformation(LandmarkMat void ProcessorTrackerFeaturePolyline2d::computeTransformations() { // WOLF_DEBUG("ProcessorTrackerFeaturePolyline::computeTransformations: "); - const auto& vehicle_pose_incoming = getProblem()->getState(incoming_ptr_->getTimeStamp()).vector("PO"); - const auto& vehicle_pose_last = getProblem()->getState(last_ptr_->getTimeStamp()).vector("PO"); + const auto& vehicle_pose_incoming = getProblem()->getState(incoming_ptr_->getTimeStamp(), "PO").vector("PO"); + const auto& vehicle_pose_last = getProblem()->getState(last_ptr_->getTimeStamp(), "PO").vector("PO"); // world_robot Eigen::Matrix2d R_world_robot_incoming = Eigen::Rotation2Dd(vehicle_pose_incoming(2)).matrix(); diff --git a/test/gtest_processor_odom_icp.cpp b/test/gtest_processor_odom_icp.cpp index d2218ab1e942ff7b5986da272bb5bdcb2687dc81..5eb6119f931856d58d03bb9059de318ff1d6764f 100644 --- a/test/gtest_processor_odom_icp.cpp +++ b/test/gtest_processor_odom_icp.cpp @@ -74,7 +74,7 @@ class ProcessorOdomIcp_Test : public testing::Test TEST(ProcessorOdomIcp, Constructor_file) { auto prc = FactoryProcessorYaml::create( - "ProcessorOdomIcp", laser_dir + "/test/yaml/processor_odom_icp.yaml", {laser_dir, wolf_schema_dir}); + "ProcessorOdomIcp", laser_dir + "/test/yaml/processor_odom_icp_2d.yaml", {laser_dir, wolf_schema_dir}); ASSERT_TRUE(prc); // not nullptr ASSERT_EQ(prc->getType(), "ProcessorOdomIcp"); @@ -82,7 +82,7 @@ TEST(ProcessorOdomIcp, Constructor_file) TEST(ProcessorOdomIcp, creator_node) { - yaml_schema_cpp::YamlServer server({laser_dir, wolf_schema_dir}, laser_dir + "/test/yaml/processor_odom_icp.yaml"); + yaml_schema_cpp::YamlServer server({laser_dir, wolf_schema_dir}, laser_dir + "/test/yaml/processor_odom_icp_2d.yaml"); auto node = server.getNode(); auto prc = FactoryProcessorNode::create("ProcessorOdomIcp", server.getNode(), {laser_dir, wolf_schema_dir}); @@ -93,7 +93,7 @@ TEST(ProcessorOdomIcp, creator_node) TEST_F(ProcessorOdomIcp_Test, zero_motion_2d) { - init(2, laser_pose_offset_2d, laser_dir + "/test/yaml/processor_odom_icp_vote_all.yaml"); + init(2, laser_pose_offset_2d, laser_dir + "/test/yaml/processor_odom_icp_vote_all_2d.yaml"); TimeStamp t(t0); int N = 7; @@ -146,7 +146,7 @@ TEST_F(ProcessorOdomIcp_Test, zero_motion_2d) TEST_F(ProcessorOdomIcp_Test, motion_2d) { - init(2, laser_pose_offset_2d, laser_dir + "/test/yaml/processor_odom_icp.yaml"); + init(2, laser_pose_offset_2d, laser_dir + "/test/yaml/processor_odom_icp_2d.yaml"); TimeStamp t(t0); // squared infinite shaped motion @@ -254,7 +254,7 @@ TEST_F(ProcessorOdomIcp_Test, motion_2d) // 3D TEST_F(ProcessorOdomIcp_Test, setup_sloped) { - init(3, (Vector7d() << 0, 0, 0, 0, 0, 0, 1).finished(), laser_dir + "/test/yaml/processor_odom_icp.yaml"); + init(3, (Vector7d() << 0, 0, 0, 0, 0, 0, 1).finished(), laser_dir + "/test/yaml/processor_odom_icp_3d.yaml"); } TEST_F(ProcessorOdomIcp_Test, motion_3d) @@ -313,7 +313,7 @@ TEST_F(ProcessorOdomIcp_Test, motion_3d) traj_3d_file.close(); // init problem - init(3, gt_poses_3d.row(0), laser_dir + "/test/yaml/processor_odom_icp.yaml"); + init(3, gt_poses_3d.row(0), laser_dir + "/test/yaml/processor_odom_icp_3d.yaml"); TimeStamp t(t0); for (int i = 0; i < gt_poses_3d.rows(); i++) diff --git a/test/yaml/processor_odom_icp.yaml b/test/yaml/processor_odom_icp_2d.yaml similarity index 95% rename from test/yaml/processor_odom_icp.yaml rename to test/yaml/processor_odom_icp_2d.yaml index f94f821b575ef5cd32abd5d0cded3b333df382e9..ef3db71e3a8e3969b1c762100b5b3840c4acc6e4 100644 --- a/test/yaml/processor_odom_icp.yaml +++ b/test/yaml/processor_odom_icp_2d.yaml @@ -14,6 +14,7 @@ state_provider : true state_provider_order : 1 # from processor odom ICP +dimension : 2 keyframe_vote: dist_traveled : 1e9 angle_turned : 1e9 diff --git a/test/yaml/processor_odom_icp_3d.yaml b/test/yaml/processor_odom_icp_3d.yaml new file mode 100644 index 0000000000000000000000000000000000000000..7915997a54c22d3a3718fe5dca4746112454170e --- /dev/null +++ b/test/yaml/processor_odom_icp_3d.yaml @@ -0,0 +1,29 @@ +type: ProcessorOdomIcp +plugin: laser +name: cool_processor_icp +sensor_name: cool_laser + +# from processor base +time_tolerance : 0.04 +apply_loss_function : false +keyframe_vote: + voting_active : true + +# from motion provider +state_provider : true +state_provider_order : 1 + +# from processor odom ICP +dimension : 3 +keyframe_vote: + dist_traveled : 1e9 + angle_turned : 1e9 + time_span : 1.05 + invalid_icp : false + consecutive_invalid_icp_patience : 1.0 + consecutive_invalid_icp_timeout : 5.0 + +initial_guess : "zero" + +icp: + follow: ./icp.yaml \ No newline at end of file diff --git a/test/yaml/processor_odom_icp_vote_all.yaml b/test/yaml/processor_odom_icp_vote_all_2d.yaml similarity index 95% rename from test/yaml/processor_odom_icp_vote_all.yaml rename to test/yaml/processor_odom_icp_vote_all_2d.yaml index 35c04cf4af2d4321b61808476a0983242f55448e..23a7b9b503a1b1120b12f05d64d5f135cb4afb7d 100644 --- a/test/yaml/processor_odom_icp_vote_all.yaml +++ b/test/yaml/processor_odom_icp_vote_all_2d.yaml @@ -14,6 +14,7 @@ state_provider : true state_provider_order : 1 # from processor odom ICP +dimension : 2 keyframe_vote: dist_traveled : 0 angle_turned : 0