diff --git a/CMakeLists.txt b/CMakeLists.txt index cab800a231b74a05eb9c466e0ec5d508ca561918..3cfdcb44eff879f3ea3934c3a79fc9ec6c4f4fd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -246,6 +246,7 @@ SET(HDRS_FACTOR include/core/factor/factor_pose_3d.h include/core/factor/factor_quaternion_absolute.h include/core/factor/factor_relative_2d_analytic.h + include/core/factor/factor_relative_pose_2d_with_extrinsics.h ) SET(HDRS_FEATURE include/core/feature/feature_base.h @@ -263,7 +264,7 @@ SET(HDRS_PROCESSOR include/core/processor/motion_buffer.h include/core/processor/processor_base.h include/core/processor/processor_diff_drive.h - include/core/processor/processor_factory.h + include/core/processor/factory_processor.h include/core/processor/processor_logging.h include/core/processor/processor_loopclosure.h include/core/processor/processor_motion.h @@ -277,15 +278,19 @@ SET(HDRS_PROCESSOR SET(HDRS_SENSOR include/core/sensor/sensor_base.h include/core/sensor/sensor_diff_drive.h - include/core/sensor/sensor_factory.h + include/core/sensor/factory_sensor.h include/core/sensor/sensor_odom_2d.h include/core/sensor/sensor_odom_3d.h ) SET(HDRS_SOLVER include/core/solver/solver_manager.h - include/core/solver/solver_factory.h + include/core/solver/factory_solver.h + ) +SET(HDRS_TREE_MANAGER + include/core/tree_manager/factory_tree_manager.h + include/core/tree_manager/tree_manager_base.h + include/core/tree_manager/tree_manager_sliding_window.h ) - SET(HDRS_YAML include/core/yaml/parser_yaml.h include/core/yaml/yaml_conversion.h @@ -371,6 +376,9 @@ SET(SRCS_SENSOR SET(SRCS_SOLVER src/solver/solver_manager.cpp ) +SET(SRCS_TREE_MANAGER + src/tree_manager/tree_manager_sliding_window.cpp + ) SET(SRCS_YAML src/yaml/parser_yaml.cpp src/yaml/processor_odom_3d_yaml.cpp @@ -400,8 +408,6 @@ ELSE(Ceres_FOUND) SET(SRCS_WRAPPER) ENDIF(Ceres_FOUND) -#SUBDIRECTORIES -add_subdirectory(hello_wolf) IF (cereal_FOUND) ADD_SUBDIRECTORY(serialization/cereal) ENDIF(cereal_FOUND) @@ -431,6 +437,7 @@ ADD_LIBRARY(${PROJECT_NAME} ${SRCS_SOLVER} ${SRCS_STATE_BLOCK} ${SRCS_TRAJECTORY} + ${SRCS_TREE_MANAGER} ${SRCS_UTILS} ${SRCS_WRAPPER} ${SRCS_YAML} @@ -471,44 +478,46 @@ INSTALL(TARGETS ${PROJECT_NAME} EXPORT ${PROJECT_NAME}Targets install(EXPORT ${PROJECT_NAME}Targets DESTINATION lib/cmake/${PROJECT_NAME}) #install headers -INSTALL(FILES ${HDRS_MATH} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/math) -INSTALL(FILES ${HDRS_UTILS} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/utils) -INSTALL(FILES ${HDRS_PROBLEM} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/problem) -INSTALL(FILES ${HDRS_HARDWARE} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/hardware) -INSTALL(FILES ${HDRS_TRAJECTORY} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/trajectory) -INSTALL(FILES ${HDRS_MAP} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/map) -INSTALL(FILES ${HDRS_FRAME} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/frame) -INSTALL(FILES ${HDRS_STATE_BLOCK} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/state_block) -INSTALL(FILES ${HDRS_COMMON} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/common) INSTALL(FILES ${HDRS_CAPTURE} DESTINATION include/iri-algorithms/wolf/plugin_core/core/capture) +INSTALL(FILES ${HDRS_COMMON} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/common) INSTALL(FILES ${HDRS_FACTOR} DESTINATION include/iri-algorithms/wolf/plugin_core/core/factor) INSTALL(FILES ${HDRS_FEATURE} DESTINATION include/iri-algorithms/wolf/plugin_core/core/feature) -INSTALL(FILES ${HDRS_SENSOR} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/sensor) -INSTALL(FILES ${HDRS_PROCESSOR} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/processor) +INSTALL(FILES ${HDRS_FRAME} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/frame) +INSTALL(FILES ${HDRS_HARDWARE} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/hardware) INSTALL(FILES ${HDRS_LANDMARK} DESTINATION include/iri-algorithms/wolf/plugin_core/core/landmark) -INSTALL(FILES ${HDRS_WRAPPER} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/ceres_wrapper) -INSTALL(FILES ${HDRS_SOLVER_SUITESPARSE} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver_suitesparse) -INSTALL(FILES ${HDRS_SOLVER} - DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver) +INSTALL(FILES ${HDRS_MAP} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/map) +INSTALL(FILES ${HDRS_MATH} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/math) +INSTALL(FILES ${HDRS_PROBLEM} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/problem) +INSTALL(FILES ${HDRS_PROCESSOR} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/processor) +INSTALL(FILES ${HDRS_SENSOR} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/sensor) INSTALL(FILES ${HDRS_SERIALIZATION} DESTINATION include/iri-algorithms/wolf/plugin_core/core/serialization) +INSTALL(FILES ${HDRS_SOLVER} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver) +INSTALL(FILES ${HDRS_SOLVER_SUITESPARSE} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/solver_suitesparse) +INSTALL(FILES ${HDRS_STATE_BLOCK} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/state_block) +INSTALL(FILES ${HDRS_TRAJECTORY} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/trajectory) +INSTALL(FILES ${HDRS_TREE_MANAGER} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/tree_manager) +INSTALL(FILES ${HDRS_UTILS} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/utils) +INSTALL(FILES ${HDRS_WRAPPER} + DESTINATION include/iri-algorithms/wolf/plugin_core/core/ceres_wrapper) INSTALL(FILES ${HDRS_YAML} DESTINATION include/iri-algorithms/wolf/plugin_core/core/yaml) diff --git a/demos/CMakeLists.txt b/demos/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..e6b2bb11cbe6b95dceba4095af5c57b2c76f16c0 --- /dev/null +++ b/demos/CMakeLists.txt @@ -0,0 +1,2 @@ +#Add hello_wolf demo +add_subdirectory(hello_wolf) diff --git a/demos/demo_map_yaml.cpp b/demos/demo_map_yaml.cpp deleted file mode 100644 index 87023e52856c9e3ba937882cd5311e05260b507b..0000000000000000000000000000000000000000 --- a/demos/demo_map_yaml.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/** - * \file test_map_yaml.cpp - * - * Created on: Jul 27, 2016 - * \author: jsola - */ - -#include "core/common/wolf.h" -#include "core/problem/problem.h" -#include "core/map/map_base.h" -#include "core/landmark/landmark_polyline_2d.h" -#include "core/landmark/landmark_AHP.h" -#include "core/state_block/state_block.h" -#include "core/yaml/yaml_conversion.h" - -#include <iostream> -using namespace wolf; - -void print(MapBase& _map) -{ - for (auto lmk_ptr : _map.getLandmarkList()) - { - std::cout << "Lmk ID: " << lmk_ptr->id(); - std::cout << "\nLmk type: " << lmk_ptr->getType(); - if (lmk_ptr->getType() == "POLYLINE 2d") - { - LandmarkPolyline2dPtr poly_ptr = std::static_pointer_cast<LandmarkPolyline2d>(lmk_ptr); - std::cout << "\npos: " << poly_ptr->getP()->getState().transpose() << " -- fixed: " << poly_ptr->getP()->isFixed(); - std::cout << "\nori: " << poly_ptr->getO()->getState().transpose() << " -- fixed: " << poly_ptr->getO()->isFixed(); - std::cout << "\nn points: " << poly_ptr->getNPoints(); - std::cout << "\nFirst idx: " << poly_ptr->getFirstId(); - std::cout << "\nFirst def: " << poly_ptr->isFirstDefined(); - std::cout << "\nLast def: " << poly_ptr->isLastDefined(); - for (int idx = poly_ptr->getFirstId(); idx <= poly_ptr->getLastId(); idx++) - std::cout << "\n point: " << idx << ": " << poly_ptr->getPointStateBlock(idx)->getState().transpose(); - break; - } - else if (lmk_ptr->getType() == "AHP") - { - LandmarkAHPPtr ahp_ptr = std::static_pointer_cast<LandmarkAHP>(lmk_ptr); - std::cout << "\npos: " << ahp_ptr->getP()->getState().transpose() << " -- fixed: " << ahp_ptr->getP()->isFixed(); - std::cout << "\ndescript: " << ahp_ptr->getCvDescriptor().t(); - break; - } - else - break; - - std::cout << std::endl; - } -} - -int main() -{ - using namespace Eigen; - - std::cout << "\nTesting Lmk creator and node saving..." << std::endl; - Vector4d v; - v << 1, 2, 3, 4; - cv::Mat d = (cv::Mat_<int>(8,1) << 1, 2, 3, 4, 5, 6, 7, 8); - LandmarkAHP lmk_1(v, nullptr, nullptr, d); - std::cout << "Pos 1 = " << lmk_1.getP()->getState().transpose() << std::endl; - std::cout << "Des 1 = " << lmk_1.getCvDescriptor().t() << std::endl; - - YAML::Node n = lmk_1.saveToYaml(); - std::cout << "Pos n = " << n["position"].as<VectorXd>().transpose() << std::endl; - std::cout << "Des n = " << n["descriptor"].as<VectorXd>().transpose() << std::endl; - - LandmarkAHP lmk_2 = *(std::static_pointer_cast<LandmarkAHP>(LandmarkAHP::create(n))); - std::cout << "Pos 2 = " << lmk_2.getP()->getState().transpose() << std::endl; - std::cout << "Des 2 = " << lmk_2.getCvDescriptor().t() << std::endl; - - std::string filename; - - std::string wolf_root = _WOLF_ROOT_DIR; - std::string wolf_config = wolf_root + "/src/examples"; - std::cout << "\nWolf directory for configuration files: " << wolf_config << std::endl; - - ProblemPtr problem = Problem::create("PO", 2); - filename = wolf_config + "/map_polyline_example.yaml"; - std::cout << "Reading map from file: " << filename << std::endl; - problem->loadMap(filename); - - std::cout << "Printing map..." << std::endl; - print(*(problem->getMap())); - - filename = wolf_config + "/map_polyline_example_write.yaml"; - std::cout << "Writing map to file: " << filename << std::endl; - std::string thisfile = __FILE__; - problem->getMap()->save(filename, "Example generated by test file " + thisfile); - - std::cout << "Clearing map... " << std::endl; - problem->getMap()->getLandmarkList().clear(); - - std::cout << "Re-reading map from file: " << filename << std::endl; - problem->loadMap(filename); - - std::cout << "Printing map..." << std::endl; - print(*(problem->getMap())); - - return 0; -} diff --git a/hello_wolf/CMakeLists.txt b/demos/hello_wolf/CMakeLists.txt similarity index 100% rename from hello_wolf/CMakeLists.txt rename to demos/hello_wolf/CMakeLists.txt diff --git a/hello_wolf/capture_range_bearing.cpp b/demos/hello_wolf/capture_range_bearing.cpp similarity index 89% rename from hello_wolf/capture_range_bearing.cpp rename to demos/hello_wolf/capture_range_bearing.cpp index a2d44a101085ea0ad3aa4ae7d68af68370ea5024..9ead1c183b8b08a64f709faea5236d5dbb056231 100644 --- a/hello_wolf/capture_range_bearing.cpp +++ b/demos/hello_wolf/capture_range_bearing.cpp @@ -11,7 +11,7 @@ namespace wolf { CaptureRangeBearing::CaptureRangeBearing(const TimeStamp& _ts, const SensorBasePtr& _scanner, const Eigen::VectorXi& _ids, const Eigen::VectorXd& _ranges, const Eigen::VectorXd& _bearings) : - CaptureBase("RANGE BEARING", _ts, _scanner), + CaptureBase("CaptureRangeBearing", _ts, _scanner), ids_(_ids), ranges_(_ranges), bearings_(_bearings) diff --git a/hello_wolf/capture_range_bearing.h b/demos/hello_wolf/capture_range_bearing.h similarity index 100% rename from hello_wolf/capture_range_bearing.h rename to demos/hello_wolf/capture_range_bearing.h diff --git a/hello_wolf/factor_bearing.h b/demos/hello_wolf/factor_bearing.h similarity index 100% rename from hello_wolf/factor_bearing.h rename to demos/hello_wolf/factor_bearing.h diff --git a/hello_wolf/factor_range_bearing.h b/demos/hello_wolf/factor_range_bearing.h similarity index 100% rename from hello_wolf/factor_range_bearing.h rename to demos/hello_wolf/factor_range_bearing.h diff --git a/hello_wolf/feature_range_bearing.cpp b/demos/hello_wolf/feature_range_bearing.cpp similarity index 82% rename from hello_wolf/feature_range_bearing.cpp rename to demos/hello_wolf/feature_range_bearing.cpp index 4d47cc5539f5fcfe2cc011ea4c4e6e11d2685f90..ea584a419aa21c1d7e462824d6872f7d57bd818c 100644 --- a/hello_wolf/feature_range_bearing.cpp +++ b/demos/hello_wolf/feature_range_bearing.cpp @@ -11,7 +11,7 @@ namespace wolf { FeatureRangeBearing::FeatureRangeBearing(const Eigen::VectorXd& _measurement, const Eigen::MatrixXd& _meas_covariance) : - FeatureBase("RANGE BEARING", _measurement, _meas_covariance) + FeatureBase("FeatureRangeBearing", _measurement, _meas_covariance) { // } diff --git a/hello_wolf/feature_range_bearing.h b/demos/hello_wolf/feature_range_bearing.h similarity index 100% rename from hello_wolf/feature_range_bearing.h rename to demos/hello_wolf/feature_range_bearing.h diff --git a/hello_wolf/hello_wolf.cpp b/demos/hello_wolf/hello_wolf.cpp similarity index 98% rename from hello_wolf/hello_wolf.cpp rename to demos/hello_wolf/hello_wolf.cpp index a705a480cef464c49c0ec6b2f463ecf527c825ec..8cb2ea566e8682395cd20dbc278ac93ad41c2060 100644 --- a/hello_wolf/hello_wolf.cpp +++ b/demos/hello_wolf/hello_wolf.cpp @@ -115,7 +115,7 @@ int main() SensorBasePtr sensor_odo = problem->installSensor("SensorOdom2d", "sensor odo", Vector3d(0,0,0), intrinsics_odo); // processor odometer 2d - ProcessorParamsOdom2dPtr params_odo = std::make_shared<ProcessorParamsOdom2d>(); + ParamsProcessorOdom2dPtr params_odo = std::make_shared<ParamsProcessorOdom2d>(); params_odo->voting_active = true; params_odo->time_tolerance = 0.1; params_odo->max_time_span = 999; @@ -132,7 +132,7 @@ int main() SensorBasePtr sensor_rb = problem->installSensor("SensorRangeBearing", "sensor RB", Vector3d(1,1,0), intrinsics_rb); // processor Range and Bearing - ProcessorParamsRangeBearingPtr params_rb = std::make_shared<ProcessorParamsRangeBearing>(); + ParamsProcessorRangeBearingPtr params_rb = std::make_shared<ParamsProcessorRangeBearing>(); params_rb->voting_active = false; params_rb->time_tolerance = 0.01; ProcessorBasePtr processor_rb = problem->installProcessor("ProcessorRangeBearing", "processor RB", sensor_rb, params_rb); @@ -141,7 +141,7 @@ int main() TimeStamp t(0.0); // t : 0.0 Vector3d x(0,0,0); Matrix3d P = Matrix3d::Identity() * 0.1; - problem->setPriorFactor(x, P, t, 0.5); // KF1 : (0,0,0) + problem->setPrior(x, P, t, 0.5); // KF1 : (0,0,0) // SELF CALIBRATION =================================================== diff --git a/hello_wolf/hello_wolf_autoconf.cpp b/demos/hello_wolf/hello_wolf_autoconf.cpp similarity index 99% rename from hello_wolf/hello_wolf_autoconf.cpp rename to demos/hello_wolf/hello_wolf_autoconf.cpp index a387adfe9656523c37d025bb3a74f0f198281b3d..5ab1ad1dd20a6b03411ea5cc458bde99b2b1fca8 100644 --- a/hello_wolf/hello_wolf_autoconf.cpp +++ b/demos/hello_wolf/hello_wolf_autoconf.cpp @@ -98,7 +98,7 @@ int main() WOLF_TRACE("======== CONFIGURE PROBLEM ======="); // Config file to parse. Here is where all the problem is defined: - std::string config_file = "hello_wolf/yaml/hello_wolf_config.yaml"; + std::string config_file = "demos/hello_wolf/yaml/hello_wolf_config.yaml"; std::string wolf_path = std::string(_WOLF_ROOT_DIR); // parse file into params server: each param will be retrievable from this params server: diff --git a/hello_wolf/landmark_point_2d.cpp b/demos/hello_wolf/landmark_point_2d.cpp similarity index 80% rename from hello_wolf/landmark_point_2d.cpp rename to demos/hello_wolf/landmark_point_2d.cpp index 835c4fb04e4f7b1e5695958ca9db3cbb810c5ec5..8b2ad4c0e8a9b576f67e9d8d56e41d932abedef8 100644 --- a/hello_wolf/landmark_point_2d.cpp +++ b/demos/hello_wolf/landmark_point_2d.cpp @@ -11,7 +11,7 @@ namespace wolf { LandmarkPoint2d::LandmarkPoint2d(int _id, const Eigen::Vector2d& _xy) : - LandmarkBase("POINT 2d", std::make_shared<StateBlock>(_xy)) + LandmarkBase("LandmarkPoint2d", std::make_shared<StateBlock>(_xy)) { setId(_id); } diff --git a/hello_wolf/landmark_point_2d.h b/demos/hello_wolf/landmark_point_2d.h similarity index 100% rename from hello_wolf/landmark_point_2d.h rename to demos/hello_wolf/landmark_point_2d.h diff --git a/hello_wolf/processor_range_bearing.cpp b/demos/hello_wolf/processor_range_bearing.cpp similarity index 95% rename from hello_wolf/processor_range_bearing.cpp rename to demos/hello_wolf/processor_range_bearing.cpp index 89b3d7775e3c5b79dca8de4a0d2f6f5ad91d17e7..9510807d443da2458299fe3522fa8c5f49cf0bf5 100644 --- a/hello_wolf/processor_range_bearing.cpp +++ b/demos/hello_wolf/processor_range_bearing.cpp @@ -14,7 +14,7 @@ namespace wolf { -ProcessorRangeBearing::ProcessorRangeBearing(ProcessorParamsBasePtr _params) : +ProcessorRangeBearing::ProcessorRangeBearing(ParamsProcessorBasePtr _params) : ProcessorBase("ProcessorRangeBearing", 2, _params) { // @@ -160,10 +160,10 @@ bool ProcessorRangeBearing::storeCapture(CaptureBasePtr _cap_ptr) } /* namespace wolf */ // Register in the SensorFactory -#include "core/processor/processor_factory.h" +#include "core/processor/factory_processor.h" namespace wolf { -WOLF_REGISTER_PROCESSOR("ProcessorRangeBearing", ProcessorRangeBearing) -WOLF_REGISTER_PROCESSOR_AUTO("ProcessorRangeBearing", ProcessorRangeBearing) +WOLF_REGISTER_PROCESSOR(ProcessorRangeBearing) +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorRangeBearing) } // namespace wolf diff --git a/hello_wolf/processor_range_bearing.h b/demos/hello_wolf/processor_range_bearing.h similarity index 87% rename from hello_wolf/processor_range_bearing.h rename to demos/hello_wolf/processor_range_bearing.h index ec1d8619835f1169a192639db09d8be93087cdae..1203b217e4f07c3e02a287f63b0bace4ba46ede2 100644 --- a/hello_wolf/processor_range_bearing.h +++ b/demos/hello_wolf/processor_range_bearing.h @@ -17,23 +17,23 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsRangeBearing); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorRangeBearing); -struct ProcessorParamsRangeBearing : public ProcessorParamsBase +struct ParamsProcessorRangeBearing : public ParamsProcessorBase { // We do not need special parameters, but in case you need they should be defined here. - ProcessorParamsRangeBearing() + ParamsProcessorRangeBearing() { //DEFINED FOR COMPATIBILITY PURPOSES. TO BE REMOVED IN THE FUTURE. } - ProcessorParamsRangeBearing(std::string _unique_name, const ParamsServer& _server) : - ProcessorParamsBase(_unique_name, _server) + ParamsProcessorRangeBearing(std::string _unique_name, const ParamsServer& _server) : + ParamsProcessorBase(_unique_name, _server) { // } std::string print() const { - return "\n" + ProcessorParamsBase::print(); + return "\n" + ParamsProcessorBase::print(); } }; @@ -45,12 +45,12 @@ class ProcessorRangeBearing : public ProcessorBase public: typedef Eigen::Transform<double, 2, Eigen::Isometry> Trf; - ProcessorRangeBearing(ProcessorParamsBasePtr _params); + ProcessorRangeBearing(ParamsProcessorBasePtr _params); virtual ~ProcessorRangeBearing() {/* empty */} virtual void configure(SensorBasePtr _sensor) override; // Factory method for high level API - WOLF_PROCESSOR_CREATE(ProcessorRangeBearing, ProcessorParamsRangeBearing); + WOLF_PROCESSOR_CREATE(ProcessorRangeBearing, ParamsProcessorRangeBearing); protected: // Implementation of pure virtuals from ProcessorBase diff --git a/hello_wolf/sensor_range_bearing.cpp b/demos/hello_wolf/sensor_range_bearing.cpp similarity index 86% rename from hello_wolf/sensor_range_bearing.cpp rename to demos/hello_wolf/sensor_range_bearing.cpp index 3eea032b2ba632cf3343805446a98d0805e56f3c..54507f9ac53771523b9db8716089113686bc1ca0 100644 --- a/hello_wolf/sensor_range_bearing.cpp +++ b/demos/hello_wolf/sensor_range_bearing.cpp @@ -38,9 +38,9 @@ SensorRangeBearing::~SensorRangeBearing() } /* namespace wolf */ // Register in the SensorFactory -#include "core/sensor/sensor_factory.h" +#include "core/sensor/factory_sensor.h" namespace wolf { -WOLF_REGISTER_SENSOR("SensorRangeBearing", SensorRangeBearing) -WOLF_REGISTER_SENSOR_AUTO("SensorRangeBearing", SensorRangeBearing) +WOLF_REGISTER_SENSOR(SensorRangeBearing) +WOLF_REGISTER_SENSOR_AUTO(SensorRangeBearing) } // namespace wolf diff --git a/hello_wolf/sensor_range_bearing.h b/demos/hello_wolf/sensor_range_bearing.h similarity index 100% rename from hello_wolf/sensor_range_bearing.h rename to demos/hello_wolf/sensor_range_bearing.h diff --git a/hello_wolf/yaml/hello_wolf_config.yaml b/demos/hello_wolf/yaml/hello_wolf_config.yaml similarity index 69% rename from hello_wolf/yaml/hello_wolf_config.yaml rename to demos/hello_wolf/yaml/hello_wolf_config.yaml index b84d7776622264f96a4597ade146d64bcec86438..1077fe00cb442147b03a36ffddba5b3b37016e8d 100644 --- a/hello_wolf/yaml/hello_wolf_config.yaml +++ b/demos/hello_wolf/yaml/hello_wolf_config.yaml @@ -2,6 +2,11 @@ config: problem: + tree_manager: + type: "TreeManagerSlidingWindow" + n_key_frames: -1 + fix_first_key_frame: false + viral_remove_empty_parent: true frame_structure: "PO" # keyframes have position and orientation dimension: 2 # space is 2d prior: @@ -17,7 +22,7 @@ config: name: "sen odom" extrinsic: pose: [0,0, 0] - follow: "hello_wolf/yaml/sensor_odom_2d.yaml" # config parameters in this file + follow: "demos/hello_wolf/yaml/sensor_odom_2d.yaml" # config parameters in this file - type: "SensorRangeBearing" plugin: "core" @@ -25,7 +30,7 @@ config: extrinsic: pose: [1,1, 0] noise_range_metres_std: 0.2 # parser only considers first appearence so the following file parsing will not overwrite this param - follow: hello_wolf/yaml/sensor_range_bearing.yaml # config parameters in this file + follow: demos/hello_wolf/yaml/sensor_range_bearing.yaml # config parameters in this file processors: @@ -33,10 +38,10 @@ config: plugin: "core" name: "prc odom" sensor_name: "sen odom" # attach processor to this sensor - follow: hello_wolf/yaml/processor_odom_2d.yaml # config parameters in this file + follow: demos/hello_wolf/yaml/processor_odom_2d.yaml # config parameters in this file - type: "ProcessorRangeBearing" plugin: "core" name: "prc rb" sensor_name: "sen rb" # attach processor to this sensor - follow: hello_wolf/yaml/processor_range_bearing.yaml # config parameters in this file + follow: demos/hello_wolf/yaml/processor_range_bearing.yaml # config parameters in this file diff --git a/hello_wolf/yaml/processor_odom_2d.yaml b/demos/hello_wolf/yaml/processor_odom_2d.yaml similarity index 92% rename from hello_wolf/yaml/processor_odom_2d.yaml rename to demos/hello_wolf/yaml/processor_odom_2d.yaml index bee82ff9ad905a72dc6c1ffd46ac6d7267ae8870..7e345ef211f52897b17267065e28feec0bf4b143 100644 --- a/hello_wolf/yaml/processor_odom_2d.yaml +++ b/demos/hello_wolf/yaml/processor_odom_2d.yaml @@ -10,3 +10,4 @@ keyframe_vote: angle_turned: 999 max_buff_length: 999 cov_det: 999 +apply_loss_function: true diff --git a/hello_wolf/yaml/processor_range_bearing.yaml b/demos/hello_wolf/yaml/processor_range_bearing.yaml similarity index 84% rename from hello_wolf/yaml/processor_range_bearing.yaml rename to demos/hello_wolf/yaml/processor_range_bearing.yaml index 61efbf8e31ee32ab9a348133a67037c5fbbdafee..3c257678c9a73eeb3b415e976b55eeddb3a79edd 100644 --- a/hello_wolf/yaml/processor_range_bearing.yaml +++ b/demos/hello_wolf/yaml/processor_range_bearing.yaml @@ -5,3 +5,5 @@ time_tolerance: 0.1 keyframe_vote: voting_active: true voting_aux_active: false + +apply_loss_function: true diff --git a/hello_wolf/yaml/sensor_odom_2d.yaml b/demos/hello_wolf/yaml/sensor_odom_2d.yaml similarity index 64% rename from hello_wolf/yaml/sensor_odom_2d.yaml rename to demos/hello_wolf/yaml/sensor_odom_2d.yaml index 3ad7204855cae5c1e8e00cfdc011ff27d2725692..65ac28219471ad65180538e526521d7866391a01 100644 --- a/hello_wolf/yaml/sensor_odom_2d.yaml +++ b/demos/hello_wolf/yaml/sensor_odom_2d.yaml @@ -1,4 +1,5 @@ -type: "SensorOdom2d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. +type: "SensorOdom2d" # This must match the KEY used in the FactorySensor. Otherwise it is an error. k_disp_to_disp: 0.1 # m^2 / m k_rot_to_rot: 0.1 # rad^2 / rad +apply_loss_function: true diff --git a/hello_wolf/yaml/sensor_range_bearing.yaml b/demos/hello_wolf/yaml/sensor_range_bearing.yaml similarity index 58% rename from hello_wolf/yaml/sensor_range_bearing.yaml rename to demos/hello_wolf/yaml/sensor_range_bearing.yaml index 40a2387a041f8a34a41c5669218dd4a4eb00c0bf..d1625337dfc0b0d323d662a727c1ac298117a455 100644 --- a/hello_wolf/yaml/sensor_range_bearing.yaml +++ b/demos/hello_wolf/yaml/sensor_range_bearing.yaml @@ -1,4 +1,5 @@ type: "SensorRangeBearing" noise_range_metres_std: 0.1 -noise_bearing_degrees_std: 0.5 +noise_bearing_degrees_std: 0.5 +apply_loss_function: true diff --git a/include/core/common/factory.h b/include/core/common/factory.h index f03cabec9a7527801464d9e4e025464a7d23f0ad..34c214bd674157eefe04433b3406918ae8e0cba0 100644 --- a/include/core/common/factory.h +++ b/include/core/common/factory.h @@ -28,8 +28,8 @@ namespace wolf * This class implements a generic factory as a singleton. * * > IMPORTANT: This template factory can be used to construct many different objects except: - * > - Objects deriving from SensorBase --> see SensorFactory - * > - Objects deriving from ProcessorBase --> see ProcessorFactory + * > - Objects deriving from SensorBase --> see FactorySensor + * > - Objects deriving from ProcessorBase --> see FactoryProcessor * > * > The reason for this is that the two cases above need a more elaborated API than the one in this template class. * @@ -86,8 +86,8 @@ namespace wolf * The first thing to know is that we have defined typedefs for the templates that we are using. For example: * * \code - * typedef Factory<ParamsSensorBase, std::string> ParamsSensorFactory; - * typedef Factory<ProcessorParamsBase, std::string> ProcessorParamsFactory; + * typedef Factory<ParamsSensorBase, std::string> FactoryParamsSensor; + * typedef Factory<ParamsProcessorBase, std::string> FactoryParamsProcessor; * typedef Factory<LandmarkBase, YAML::Node> LandmarkFactory; * \endcode * @@ -145,7 +145,7 @@ namespace wolf * For example, in sensor_camera_yaml.cpp we find the line: * * \code - * const bool registered_camera_intr = ParamsSensorFactory::get().registerCreator("CAMERA", createParamsSensorCamera); + * const bool registered_camera_intr = FactoryParamsSensor::get().registerCreator("CAMERA", createParamsSensorCamera); * \endcode * * which is a static invocation (i.e., it is placed at global scope outside of the ParamsSensorCamera class). @@ -218,15 +218,15 @@ namespace wolf * \endcode * * ### More information - * - ParamsSensorFactory: typedef of this template to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. - * - ProcessorParamsFactory: typedef of this template to create processor params structs deriving from ProcessorParamsBase directly from YAML files. + * - FactoryParamsSensor: typedef of this template to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. + * - FactoryParamsProcessor: typedef of this template to create processor params structs deriving from ParamsProcessorBase directly from YAML files. * - LandmarkFactory: typedef of this template to create landmarks deriving from LandmarkBase directly from YAML nodes. * - Problem::loadMap() : to load a maps directly from YAML files. * - You can also check the code in the example file ````src/examples/test_map_yaml.cpp````. * * #### See also - * - SensorFactory: to create sensors - * - ProcessorFactory: to create processors. + * - FactorySensor: to create sensors + * - FactoryProcessor: to create processors. * - Problem::installSensor() : to install sensors in WOLF Problem. * - Problem::installProcessor() : to install processors in WOLF Problem. * diff --git a/include/core/common/node_base.h b/include/core/common/node_base.h index 4488ab30ec274eeb84e49b7dcd600de9a93acf5e..2a6120408718df85ebb2945c9800d71b0060b6fd 100644 --- a/include/core/common/node_base.h +++ b/include/core/common/node_base.h @@ -27,8 +27,8 @@ namespace wolf { * - "LANDMARK" * * - A unique type, which is a subcategory of the above. The list here cannot be exhaustive, but a few examples follow: - * - "SesorCamera" - * - "SesorLaser2d" + * - "SensorCamera" + * - "SensorLaser2d" * - "LandmarkPoint3d" * - "ProcessorLaser2d" * diff --git a/include/core/common/wolf.h b/include/core/common/wolf.h index 64a4741c518ecd0f75bf029aa4e3267b1e3f8c4e..ca7da8dbe679b5bf5f0b3ca8518a6cd045e0aafa 100644 --- a/include/core/common/wolf.h +++ b/include/core/common/wolf.h @@ -212,6 +212,10 @@ WOLF_PTR_TYPEDEFS(NodeBase); // Problem WOLF_PTR_TYPEDEFS(Problem); +// Tree Manager +WOLF_PTR_TYPEDEFS(TreeManagerBase); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerBase); + // Hardware WOLF_PTR_TYPEDEFS(HardwareBase); @@ -230,7 +234,7 @@ WOLF_LIST_TYPEDEFS(ProcessorBase); WOLF_PTR_TYPEDEFS(ProcessorMotion); // - - Processor params -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsBase); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorBase); // Trajectory WOLF_PTR_TYPEDEFS(TrajectoryBase); diff --git a/include/core/factor/factor_autodiff.h b/include/core/factor/factor_autodiff.h index d5e86d2f168acce03feb9085420de1c6ad901ab8..14e3660fa43bfb8c7892a4f225b5edf38592bb4d 100644 --- a/include/core/factor/factor_autodiff.h +++ b/include/core/factor/factor_autodiff.h @@ -15,7 +15,7 @@ namespace wolf { //template class FactorAutodiff -template <class FacT, unsigned int RES, unsigned int B0, unsigned int B1 = 0, unsigned int B2 = 0, unsigned int B3 = 0, unsigned int B4 = 0, unsigned int B5 = 0, unsigned int B6 = 0, unsigned int B7 = 0, unsigned int B8 = 0, unsigned int B9 = 0> +template <class FacT, unsigned int RES, unsigned int B0, unsigned int B1 = 0, unsigned int B2 = 0, unsigned int B3 = 0, unsigned int B4 = 0, unsigned int B5 = 0, unsigned int B6 = 0, unsigned int B7 = 0, unsigned int B8 = 0, unsigned int B9 = 0, unsigned int B10 = 0, unsigned int B11 = 0> class FactorAutodiff : public FactorBase { public: @@ -31,12 +31,15 @@ class FactorAutodiff : public FactorBase static const unsigned int block7Size = B7; static const unsigned int block8Size = B8; static const unsigned int block9Size = B9; - static const unsigned int n_blocks = 10; + static const unsigned int block10Size = B10; + static const unsigned int block11Size = B11; + static const unsigned int n_blocks = 12; static const std::vector<unsigned int> state_block_sizes_; typedef ceres::Jet<double, B0 + B1 + B2 + B3 + B4 + - B5 + B6 + B7 + B8 + B9> WolfJet; + B5 + B6 + B7 + B8 + B9 + + B10 + B11> WolfJet; protected: @@ -54,6 +57,8 @@ class FactorAutodiff : public FactorBase std::array<WolfJet, B7>* jets_7_; std::array<WolfJet, B8>* jets_8_; std::array<WolfJet, B9>* jets_9_; + std::array<WolfJet, B10>* jets_10_; + std::array<WolfJet, B11>* jets_11_; public: /** \brief Constructor valid for all categories (ABSOLUTE, FRAME, FEATURE, LANDMARK) @@ -75,9 +80,11 @@ class FactorAutodiff : public FactorBase StateBlockPtr _state6Ptr, StateBlockPtr _state7Ptr, StateBlockPtr _state8Ptr, - StateBlockPtr _state9Ptr) : + StateBlockPtr _state9Ptr, + StateBlockPtr _state10Ptr, + StateBlockPtr _state11Ptr) : FactorBase(_tp, _frame_other_ptr, _capture_other_ptr, _feature_other_ptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status), - state_ptrs_({_state0Ptr,_state1Ptr,_state2Ptr,_state3Ptr,_state4Ptr,_state5Ptr,_state6Ptr,_state7Ptr,_state8Ptr,_state9Ptr}), + state_ptrs_({_state0Ptr,_state1Ptr,_state2Ptr,_state3Ptr,_state4Ptr,_state5Ptr,_state6Ptr,_state7Ptr,_state8Ptr,_state9Ptr,_state10Ptr,_state11Ptr}), residuals_jets_(new std::array<WolfJet, RES>), jets_0_(new std::array<WolfJet, B0>), jets_1_(new std::array<WolfJet, B1>), @@ -88,8 +95,24 @@ class FactorAutodiff : public FactorBase jets_6_(new std::array<WolfJet, B6>), jets_7_(new std::array<WolfJet, B7>), jets_8_(new std::array<WolfJet, B8>), - jets_9_(new std::array<WolfJet, B9>) + jets_9_(new std::array<WolfJet, B9>), + jets_10_(new std::array<WolfJet, B10>), + jets_11_(new std::array<WolfJet, B11>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + assert(_state7Ptr != nullptr && "nullptr state block"); + assert(_state8Ptr != nullptr && "nullptr state block"); + assert(_state9Ptr != nullptr && "nullptr state block"); + assert(_state10Ptr != nullptr && "nullptr state block"); + assert(_state11Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -111,7 +134,11 @@ class FactorAutodiff : public FactorBase for (unsigned int i = 0; i < B8; i++) (*jets_8_)[i] = WolfJet(0, last_jet_idx++); for (unsigned int i = 0; i < B9; i++) - (*jets_9_)[i] = WolfJet(0, last_jet_idx++); + (*jets_9_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B10; i++) + (*jets_10_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B11; i++) + (*jets_11_)[i] = WolfJet(0, last_jet_idx++); } virtual ~FactorAutodiff() @@ -126,6 +153,8 @@ class FactorAutodiff : public FactorBase delete jets_7_; delete jets_8_; delete jets_9_; + delete jets_10_; + delete jets_11_; delete residuals_jets_; } @@ -154,6 +183,8 @@ class FactorAutodiff : public FactorBase parameters[7], parameters[8], parameters[9], + parameters[10], + parameters[11], residuals); } // also compute jacobians @@ -175,6 +206,8 @@ class FactorAutodiff : public FactorBase jets_7_->data(), jets_8_->data(), jets_9_->data(), + jets_10_->data(), + jets_11_->data(), residuals_jets_->data()); // fill the residual array @@ -218,6 +251,10 @@ class FactorAutodiff : public FactorBase (*jets_8_)[i].a = parameters[8][i]; for (unsigned int i = 0; i < B9; i++) (*jets_9_)[i].a = parameters[9][i]; + for (unsigned int i = 0; i < B10; i++) + (*jets_10_)[i].a = parameters[10][i]; + for (unsigned int i = 0; i < B11; i++) + (*jets_11_)[i].a = parameters[11][i]; } /** \brief Returns a vector of Jacobian matrix corresponding to each state block evaluated in the point provided in _states_ptr @@ -244,6 +281,8 @@ class FactorAutodiff : public FactorBase jets_7_->data(), jets_8_->data(), jets_9_->data(), + jets_10_->data(), + jets_11_->data(), residuals_jets_->data()); // fill the residual vector @@ -299,10 +338,577 @@ class FactorAutodiff : public FactorBase } }; + +////////////////// SPECIALIZATION 11 BLOCKS //////////////////////////////////////////////////////////////////////// + +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9,unsigned int B10> +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,0> : public FactorBase +{ + public: + + static const unsigned int residualSize = RES; + static const unsigned int block0Size = B0; + static const unsigned int block1Size = B1; + static const unsigned int block2Size = B2; + static const unsigned int block3Size = B3; + static const unsigned int block4Size = B4; + static const unsigned int block5Size = B5; + static const unsigned int block6Size = B6; + static const unsigned int block7Size = B7; + static const unsigned int block8Size = B8; + static const unsigned int block9Size = B9; + static const unsigned int block10Size = B10; + static const unsigned int block11Size = 0; + static const unsigned int n_blocks = 11; + + static const std::vector<unsigned int> state_block_sizes_; + + typedef ceres::Jet<double, B0 + B1 + B2 + B3 + B4 + + B5 + B6 + B7 + B8 + B9 + B10> WolfJet; + + protected: + + std::vector<StateBlockPtr> state_ptrs_; + + static const std::vector<unsigned int> jacobian_locations_; + std::array<WolfJet, RES>* residuals_jets_; + + std::array<WolfJet, B0>* jets_0_; + std::array<WolfJet, B1>* jets_1_; + std::array<WolfJet, B2>* jets_2_; + std::array<WolfJet, B3>* jets_3_; + std::array<WolfJet, B4>* jets_4_; + std::array<WolfJet, B5>* jets_5_; + std::array<WolfJet, B6>* jets_6_; + std::array<WolfJet, B7>* jets_7_; + std::array<WolfJet, B8>* jets_8_; + std::array<WolfJet, B9>* jets_9_; + std::array<WolfJet, B10>* jets_10_; + + public: + + FactorAutodiff(const std::string& _tp, + const FrameBasePtr& _frame_other_ptr, + const CaptureBasePtr& _capture_other_ptr, + const FeatureBasePtr& _feature_other_ptr, + const LandmarkBasePtr& _landmark_other_ptr, + const ProcessorBasePtr& _processor_ptr, + bool _apply_loss_function, + FactorStatus _status, + StateBlockPtr _state0Ptr, + StateBlockPtr _state1Ptr, + StateBlockPtr _state2Ptr, + StateBlockPtr _state3Ptr, + StateBlockPtr _state4Ptr, + StateBlockPtr _state5Ptr, + StateBlockPtr _state6Ptr, + StateBlockPtr _state7Ptr, + StateBlockPtr _state8Ptr, + StateBlockPtr _state9Ptr, + StateBlockPtr _state10Ptr) : + FactorBase(_tp, _frame_other_ptr, _capture_other_ptr, _feature_other_ptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status), + state_ptrs_({_state0Ptr,_state1Ptr,_state2Ptr,_state3Ptr,_state4Ptr,_state5Ptr,_state6Ptr,_state7Ptr,_state8Ptr,_state9Ptr,_state10Ptr}), + residuals_jets_(new std::array<WolfJet, RES>), + jets_0_(new std::array<WolfJet, B0>), + jets_1_(new std::array<WolfJet, B1>), + jets_2_(new std::array<WolfJet, B2>), + jets_3_(new std::array<WolfJet, B3>), + jets_4_(new std::array<WolfJet, B4>), + jets_5_(new std::array<WolfJet, B5>), + jets_6_(new std::array<WolfJet, B6>), + jets_7_(new std::array<WolfJet, B7>), + jets_8_(new std::array<WolfJet, B8>), + jets_9_(new std::array<WolfJet, B9>), + jets_10_(new std::array<WolfJet, B10>) + { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + assert(_state7Ptr != nullptr && "nullptr state block"); + assert(_state8Ptr != nullptr && "nullptr state block"); + assert(_state9Ptr != nullptr && "nullptr state block"); + assert(_state10Ptr != nullptr && "nullptr state block"); + + // initialize jets + unsigned int last_jet_idx = 0; + for (unsigned int i = 0; i < B0; i++) + (*jets_0_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B1; i++) + (*jets_1_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B2; i++) + (*jets_2_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B3; i++) + (*jets_3_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B4; i++) + (*jets_4_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B5; i++) + (*jets_5_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B6; i++) + (*jets_6_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B7; i++) + (*jets_7_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B8; i++) + (*jets_8_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B9; i++) + (*jets_9_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B10; i++) + (*jets_10_)[i] = WolfJet(0, last_jet_idx++); + state_ptrs_.resize(n_blocks); + } + + virtual ~FactorAutodiff() + { + delete jets_0_; + delete jets_1_; + delete jets_2_; + delete jets_3_; + delete jets_4_; + delete jets_5_; + delete jets_6_; + delete jets_7_; + delete jets_8_; + delete jets_9_; + delete jets_10_; + delete residuals_jets_; + } + + virtual JacobianMethod getJacobianMethod() const + { + return JAC_AUTO; + } + + virtual bool evaluate(double const* const* parameters, double* residuals, double** jacobians) const + { + // only residuals + if (jacobians == nullptr) + { + (*static_cast<FacT const*>(this))(parameters[0], + parameters[1], + parameters[2], + parameters[3], + parameters[4], + parameters[5], + parameters[6], + parameters[7], + parameters[8], + parameters[9], + parameters[10], + residuals); + } + // also compute jacobians + else + { + // update jets real part + std::vector<double const*> param_vec; + param_vec.assign(parameters,parameters+n_blocks); + updateJetsRealPart(param_vec); + + // call functor + (*static_cast<FacT const*>(this))(jets_0_->data(), + jets_1_->data(), + jets_2_->data(), + jets_3_->data(), + jets_4_->data(), + jets_5_->data(), + jets_6_->data(), + jets_7_->data(), + jets_8_->data(), + jets_9_->data(), + jets_10_->data(), + residuals_jets_->data()); + + // fill the residual array + for (unsigned int i = 0; i < RES; i++) + residuals[i] = (*residuals_jets_)[i].a; + + // fill the jacobian matrices + for (unsigned int i = 0; i<n_blocks; i++) + if (jacobians[i] != nullptr) + for (unsigned int row = 0; row < RES; row++) + std::copy((*residuals_jets_)[row].v.data() + jacobian_locations_.at(i), + (*residuals_jets_)[row].v.data() + jacobian_locations_.at(i) + state_block_sizes_.at(i), + jacobians[i] + row * state_block_sizes_.at(i)); + } + return true; + } + + void updateJetsRealPart(const std::vector<double const*>& parameters) const + { + // update jets real part + for (unsigned int i = 0; i < B0; i++) + (*jets_0_)[i].a = parameters[0][i]; + for (unsigned int i = 0; i < B1; i++) + (*jets_1_)[i].a = parameters[1][i]; + for (unsigned int i = 0; i < B2; i++) + (*jets_2_)[i].a = parameters[2][i]; + for (unsigned int i = 0; i < B3; i++) + (*jets_3_)[i].a = parameters[3][i]; + for (unsigned int i = 0; i < B4; i++) + (*jets_4_)[i].a = parameters[4][i]; + for (unsigned int i = 0; i < B5; i++) + (*jets_5_)[i].a = parameters[5][i]; + for (unsigned int i = 0; i < B6; i++) + (*jets_6_)[i].a = parameters[6][i]; + for (unsigned int i = 0; i < B7; i++) + (*jets_7_)[i].a = parameters[7][i]; + for (unsigned int i = 0; i < B8; i++) + (*jets_8_)[i].a = parameters[8][i]; + for (unsigned int i = 0; i < B9; i++) + (*jets_9_)[i].a = parameters[9][i]; + for (unsigned int i = 0; i < B10; i++) + (*jets_10_)[i].a = parameters[10][i]; + } + + virtual void evaluate(const std::vector<const double*>& _states_ptr, Eigen::VectorXd& residual_, std::vector<Eigen::MatrixXd>& jacobians_) const + { + assert(residual_.size() == RES); + jacobians_.clear(); + + assert(_states_ptr.size() == n_blocks); + + // update jets real part + updateJetsRealPart(_states_ptr); + + // call functor + (*static_cast<FacT const*>(this))(jets_0_->data(), + jets_1_->data(), + jets_2_->data(), + jets_3_->data(), + jets_4_->data(), + jets_5_->data(), + jets_6_->data(), + jets_7_->data(), + jets_8_->data(), + jets_9_->data(), + jets_10_->data(), + residuals_jets_->data()); + + // fill the residual vector + for (unsigned int i = 0; i < RES; i++) + residual_(i) = (*residuals_jets_)[i].a; + + // fill the jacobian matrices + for (unsigned int i = 0; i<n_blocks; i++) + { + // Create a row major Jacobian + Eigen::MatrixRowXd Ji(Eigen::MatrixRowXd::Zero(RES, state_block_sizes_[i])); + // Fill Jacobian rows from jets + if (!state_ptrs_[i]->isFixed()) + for (unsigned int row = 0; row < RES; row++) + std::copy((*residuals_jets_)[row].v.data() + jacobian_locations_.at(i), + (*residuals_jets_)[row].v.data() + jacobian_locations_.at(i) + state_block_sizes_.at(i), + Ji.data() + row * state_block_sizes_.at(i)); + // add to the Jacobians vector + jacobians_.push_back(Ji); + } + + // print jacobian matrices +// for (unsigned int i = 0; i < n_blocks; i++) +// std::cout << jacobians_[i] << std::endl << std::endl; + } + + virtual std::vector<StateBlockPtr> getStateBlockPtrVector() const + { + return state_ptrs_; + } + + virtual std::vector<unsigned int> getStateSizes() const + { + return state_block_sizes_; + } + + virtual unsigned int getSize() const + { + return RES; + } +}; + +////////////////// SPECIALIZATION 10 BLOCKS //////////////////////////////////////////////////////////////////////// + +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9> +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,0,0> : public FactorBase +{ + public: + + static const unsigned int residualSize = RES; + static const unsigned int block0Size = B0; + static const unsigned int block1Size = B1; + static const unsigned int block2Size = B2; + static const unsigned int block3Size = B3; + static const unsigned int block4Size = B4; + static const unsigned int block5Size = B5; + static const unsigned int block6Size = B6; + static const unsigned int block7Size = B7; + static const unsigned int block8Size = B8; + static const unsigned int block9Size = B9; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; + static const unsigned int n_blocks = 10; + + static const std::vector<unsigned int> state_block_sizes_; + + typedef ceres::Jet<double, B0 + B1 + B2 + B3 + B4 + + B5 + B6 + B7 + B8 + B9> WolfJet; + + protected: + + std::vector<StateBlockPtr> state_ptrs_; + + static const std::vector<unsigned int> jacobian_locations_; + std::array<WolfJet, RES>* residuals_jets_; + + std::array<WolfJet, B0>* jets_0_; + std::array<WolfJet, B1>* jets_1_; + std::array<WolfJet, B2>* jets_2_; + std::array<WolfJet, B3>* jets_3_; + std::array<WolfJet, B4>* jets_4_; + std::array<WolfJet, B5>* jets_5_; + std::array<WolfJet, B6>* jets_6_; + std::array<WolfJet, B7>* jets_7_; + std::array<WolfJet, B8>* jets_8_; + std::array<WolfJet, B9>* jets_9_; + + public: + + FactorAutodiff(const std::string& _tp, + const FrameBasePtr& _frame_other_ptr, + const CaptureBasePtr& _capture_other_ptr, + const FeatureBasePtr& _feature_other_ptr, + const LandmarkBasePtr& _landmark_other_ptr, + const ProcessorBasePtr& _processor_ptr, + bool _apply_loss_function, + FactorStatus _status, + StateBlockPtr _state0Ptr, + StateBlockPtr _state1Ptr, + StateBlockPtr _state2Ptr, + StateBlockPtr _state3Ptr, + StateBlockPtr _state4Ptr, + StateBlockPtr _state5Ptr, + StateBlockPtr _state6Ptr, + StateBlockPtr _state7Ptr, + StateBlockPtr _state8Ptr, + StateBlockPtr _state9Ptr) : + FactorBase(_tp, _frame_other_ptr, _capture_other_ptr, _feature_other_ptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status), + state_ptrs_({_state0Ptr,_state1Ptr,_state2Ptr,_state3Ptr,_state4Ptr,_state5Ptr,_state6Ptr,_state7Ptr,_state8Ptr,_state9Ptr}), + residuals_jets_(new std::array<WolfJet, RES>), + jets_0_(new std::array<WolfJet, B0>), + jets_1_(new std::array<WolfJet, B1>), + jets_2_(new std::array<WolfJet, B2>), + jets_3_(new std::array<WolfJet, B3>), + jets_4_(new std::array<WolfJet, B4>), + jets_5_(new std::array<WolfJet, B5>), + jets_6_(new std::array<WolfJet, B6>), + jets_7_(new std::array<WolfJet, B7>), + jets_8_(new std::array<WolfJet, B8>), + jets_9_(new std::array<WolfJet, B9>) + { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + assert(_state7Ptr != nullptr && "nullptr state block"); + assert(_state8Ptr != nullptr && "nullptr state block"); + assert(_state9Ptr != nullptr && "nullptr state block"); + + // initialize jets + unsigned int last_jet_idx = 0; + for (unsigned int i = 0; i < B0; i++) + (*jets_0_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B1; i++) + (*jets_1_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B2; i++) + (*jets_2_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B3; i++) + (*jets_3_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B4; i++) + (*jets_4_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B5; i++) + (*jets_5_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B6; i++) + (*jets_6_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B7; i++) + (*jets_7_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B8; i++) + (*jets_8_)[i] = WolfJet(0, last_jet_idx++); + for (unsigned int i = 0; i < B9; i++) + (*jets_9_)[i] = WolfJet(0, last_jet_idx++); + state_ptrs_.resize(n_blocks); + } + + virtual ~FactorAutodiff() + { + delete jets_0_; + delete jets_1_; + delete jets_2_; + delete jets_3_; + delete jets_4_; + delete jets_5_; + delete jets_6_; + delete jets_7_; + delete jets_8_; + delete jets_9_; + delete residuals_jets_; + } + + virtual JacobianMethod getJacobianMethod() const + { + return JAC_AUTO; + } + + virtual bool evaluate(double const* const* parameters, double* residuals, double** jacobians) const + { + // only residuals + if (jacobians == nullptr) + { + (*static_cast<FacT const*>(this))(parameters[0], + parameters[1], + parameters[2], + parameters[3], + parameters[4], + parameters[5], + parameters[6], + parameters[7], + parameters[8], + parameters[9], + residuals); + } + // also compute jacobians + else + { + // update jets real part + std::vector<double const*> param_vec; + param_vec.assign(parameters,parameters+n_blocks); + updateJetsRealPart(param_vec); + + // call functor + (*static_cast<FacT const*>(this))(jets_0_->data(), + jets_1_->data(), + jets_2_->data(), + jets_3_->data(), + jets_4_->data(), + jets_5_->data(), + jets_6_->data(), + jets_7_->data(), + jets_8_->data(), + jets_9_->data(), + residuals_jets_->data()); + + // fill the residual array + for (unsigned int i = 0; i < RES; i++) + residuals[i] = (*residuals_jets_)[i].a; + + // fill the jacobian matrices + for (unsigned int i = 0; i<n_blocks; i++) + if (jacobians[i] != nullptr) + for (unsigned int row = 0; row < RES; row++) + std::copy((*residuals_jets_)[row].v.data() + jacobian_locations_.at(i), + (*residuals_jets_)[row].v.data() + jacobian_locations_.at(i) + state_block_sizes_.at(i), + jacobians[i] + row * state_block_sizes_.at(i)); + } + return true; + } + + void updateJetsRealPart(const std::vector<double const*>& parameters) const + { + // update jets real part + for (unsigned int i = 0; i < B0; i++) + (*jets_0_)[i].a = parameters[0][i]; + for (unsigned int i = 0; i < B1; i++) + (*jets_1_)[i].a = parameters[1][i]; + for (unsigned int i = 0; i < B2; i++) + (*jets_2_)[i].a = parameters[2][i]; + for (unsigned int i = 0; i < B3; i++) + (*jets_3_)[i].a = parameters[3][i]; + for (unsigned int i = 0; i < B4; i++) + (*jets_4_)[i].a = parameters[4][i]; + for (unsigned int i = 0; i < B5; i++) + (*jets_5_)[i].a = parameters[5][i]; + for (unsigned int i = 0; i < B6; i++) + (*jets_6_)[i].a = parameters[6][i]; + for (unsigned int i = 0; i < B7; i++) + (*jets_7_)[i].a = parameters[7][i]; + for (unsigned int i = 0; i < B8; i++) + (*jets_8_)[i].a = parameters[8][i]; + for (unsigned int i = 0; i < B9; i++) + (*jets_9_)[i].a = parameters[9][i]; + } + + virtual void evaluate(const std::vector<const double*>& _states_ptr, Eigen::VectorXd& residual_, std::vector<Eigen::MatrixXd>& jacobians_) const + { + assert(residual_.size() == RES); + jacobians_.clear(); + + assert(_states_ptr.size() == n_blocks); + + // update jets real part + updateJetsRealPart(_states_ptr); + + // call functor + (*static_cast<FacT const*>(this))(jets_0_->data(), + jets_1_->data(), + jets_2_->data(), + jets_3_->data(), + jets_4_->data(), + jets_5_->data(), + jets_6_->data(), + jets_7_->data(), + jets_8_->data(), + jets_9_->data(), + residuals_jets_->data()); + + // fill the residual vector + for (unsigned int i = 0; i < RES; i++) + residual_(i) = (*residuals_jets_)[i].a; + + // fill the jacobian matrices + for (unsigned int i = 0; i<n_blocks; i++) + { + // Create a row major Jacobian + Eigen::MatrixRowXd Ji(Eigen::MatrixRowXd::Zero(RES, state_block_sizes_[i])); + // Fill Jacobian rows from jets + if (!state_ptrs_[i]->isFixed()) + for (unsigned int row = 0; row < RES; row++) + std::copy((*residuals_jets_)[row].v.data() + jacobian_locations_.at(i), + (*residuals_jets_)[row].v.data() + jacobian_locations_.at(i) + state_block_sizes_.at(i), + Ji.data() + row * state_block_sizes_.at(i)); + // add to the Jacobians vector + jacobians_.push_back(Ji); + } + + // print jacobian matrices +// for (unsigned int i = 0; i < n_blocks; i++) +// std::cout << jacobians_[i] << std::endl << std::endl; + } + + virtual std::vector<StateBlockPtr> getStateBlockPtrVector() const + { + return state_ptrs_; + } + + virtual std::vector<unsigned int> getStateSizes() const + { + return state_block_sizes_; + } + + virtual unsigned int getSize() const + { + return RES; + } +}; + ////////////////// SPECIALIZATION 9 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0,0,0> : public FactorBase { public: @@ -317,6 +923,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0> : public FactorBase static const unsigned int block7Size = B7; static const unsigned int block8Size = B8; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 9; static const std::vector<unsigned int> state_block_sizes_; @@ -373,6 +981,17 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0> : public FactorBase jets_7_(new std::array<WolfJet, B7>), jets_8_(new std::array<WolfJet, B8>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + assert(_state7Ptr != nullptr && "nullptr state block"); + assert(_state8Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -554,7 +1173,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0> : public FactorBase ////////////////// SPECIALIZATION 8 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0,0,0> : public FactorBase { public: @@ -569,6 +1188,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0> : public FactorBase static const unsigned int block7Size = B7; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 8; static const std::vector<unsigned int> state_block_sizes_; @@ -622,6 +1243,16 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0> : public FactorBase jets_6_(new std::array<WolfJet, B6>), jets_7_(new std::array<WolfJet, B7>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + assert(_state7Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -795,7 +1426,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0> : public FactorBase ////////////////// SPECIALIZATION 7 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0,0,0> : public FactorBase { public: @@ -810,6 +1441,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 7; static const std::vector<unsigned int> state_block_sizes_; @@ -860,6 +1493,15 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0> : public FactorBase jets_5_(new std::array<WolfJet, B5>), jets_6_(new std::array<WolfJet, B6>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + assert(_state6Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1025,7 +1667,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 6 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0,0,0> : public FactorBase { public: @@ -1040,6 +1682,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 6; static const std::vector<unsigned int> state_block_sizes_; @@ -1087,6 +1731,14 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0> : public FactorBase jets_4_(new std::array<WolfJet, B4>), jets_5_(new std::array<WolfJet, B5>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + assert(_state5Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1240,7 +1892,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 5 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0,0,0> : public FactorBase { public: @@ -1255,6 +1907,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 5; static const std::vector<unsigned int> state_block_sizes_; @@ -1298,6 +1952,13 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0> : public FactorBase jets_3_(new std::array<WolfJet, B3>), jets_4_(new std::array<WolfJet, B4>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + assert(_state4Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1443,7 +2104,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 4 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3> -class FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0,0,0> : public FactorBase { public: @@ -1458,6 +2119,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 4; static const std::vector<unsigned int> state_block_sizes_; @@ -1498,6 +2161,12 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0> : public FactorBase jets_2_(new std::array<WolfJet, B2>), jets_3_(new std::array<WolfJet, B3>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + assert(_state3Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1639,7 +2308,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 3 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2> -class FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0,0,0> : public FactorBase { public: @@ -1654,6 +2323,8 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 3; static const std::vector<unsigned int> state_block_sizes_; @@ -1691,6 +2362,11 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0> : public FactorBase jets_1_(new std::array<WolfJet, B1>), jets_2_(new std::array<WolfJet, B2>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + assert(_state2Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1824,7 +2500,7 @@ class FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 2 BLOCKS //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1> -class FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0,0,0> : public FactorBase { public: @@ -1839,6 +2515,8 @@ class FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 2; static const std::vector<unsigned int> state_block_sizes_; @@ -1873,6 +2551,10 @@ class FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0> : public FactorBase jets_0_(new std::array<WolfJet, B0>), jets_1_(new std::array<WolfJet, B1>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + assert(_state1Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -1998,7 +2680,7 @@ class FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0> : public FactorBase ////////////////// SPECIALIZATION 1 BLOCK //////////////////////////////////////////////////////////////////////// template <class FacT,unsigned int RES,unsigned int B0> -class FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0> : public FactorBase +class FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0,0,0> : public FactorBase { public: @@ -2013,6 +2695,8 @@ class FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0> : public FactorBase static const unsigned int block7Size = 0; static const unsigned int block8Size = 0; static const unsigned int block9Size = 0; + static const unsigned int block10Size = 0; + static const unsigned int block11Size = 0; static const unsigned int n_blocks = 1; static const std::vector<unsigned int> state_block_sizes_; @@ -2044,6 +2728,9 @@ class FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0> : public FactorBase residuals_jets_(new std::array<WolfJet, RES>), jets_0_(new std::array<WolfJet, B0>) { + // asserts for null states + assert(_state0Ptr != nullptr && "nullptr state block"); + // initialize jets unsigned int last_jet_idx = 0; for (unsigned int i = 0; i < B0; i++) @@ -2162,113 +2849,146 @@ class FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0> : public FactorBase // STATIC CONST VECTORS INITIALIZATION //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // state_block_sizes_ +// 12 BLOCKS +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9,unsigned int B10,unsigned int B11> +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11}; +// 11 BLOCKS +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9,unsigned int B10> +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10}; // 10 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8,B9}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8,B9}; // 9 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7,B8}; // 8 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6,B7}; // 7 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5,B6}; // 6 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4,B5}; // 5 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3,B4}; // 4 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2,B3}; // 3 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1,B2}; // 2 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0,B1}; // 1 BLOCK template <class FacT,unsigned int RES,unsigned int B0> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0,0,0>::state_block_sizes_ = {B0}; // jacobian_locations_ +// 12 BLOCKS +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9,unsigned int B10,unsigned int B11> +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,B11>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5, + B0+B1+B2+B3+B4+B5+B6, + B0+B1+B2+B3+B4+B5+B6+B7, + B0+B1+B2+B3+B4+B5+B6+B7+B8, + B0+B1+B2+B3+B4+B5+B6+B7+B8+B9, + B0+B1+B2+B3+B4+B5+B6+B7+B8+B9+B10}; +// 10 BLOCKS +template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9,unsigned int B10> +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,B10,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5, + B0+B1+B2+B3+B4+B5+B6, + B0+B1+B2+B3+B4+B5+B6+B7, + B0+B1+B2+B3+B4+B5+B6+B7+B8, + B0+B1+B2+B3+B4+B5+B6+B7+B8+B9}; // 10 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8,unsigned int B9> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3, - B0+B1+B2+B3+B4, - B0+B1+B2+B3+B4+B5, - B0+B1+B2+B3+B4+B5+B6, - B0+B1+B2+B3+B4+B5+B6+B7, - B0+B1+B2+B3+B4+B5+B6+B7+B8}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,B9,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5, + B0+B1+B2+B3+B4+B5+B6, + B0+B1+B2+B3+B4+B5+B6+B7, + B0+B1+B2+B3+B4+B5+B6+B7+B8}; // 9 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7,unsigned int B8> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3, - B0+B1+B2+B3+B4, - B0+B1+B2+B3+B4+B5, - B0+B1+B2+B3+B4+B5+B6, - B0+B1+B2+B3+B4+B5+B6+B7}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,B8,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5, + B0+B1+B2+B3+B4+B5+B6, + B0+B1+B2+B3+B4+B5+B6+B7}; // 8 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6,unsigned int B7> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3, - B0+B1+B2+B3+B4, - B0+B1+B2+B3+B4+B5, - B0+B1+B2+B3+B4+B5+B6}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,B7,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5, + B0+B1+B2+B3+B4+B5+B6}; // 7 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5,unsigned int B6> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3, - B0+B1+B2+B3+B4, - B0+B1+B2+B3+B4+B5}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,B6,0,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4, + B0+B1+B2+B3+B4+B5}; // 6 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4,unsigned int B5> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3, - B0+B1+B2+B3+B4}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,B5,0,0,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3, + B0+B1+B2+B3+B4}; // 5 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3,unsigned int B4> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2, - B0+B1+B2+B3}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,B4,0,0,0,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2, + B0+B1+B2+B3}; // 4 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2,unsigned int B3> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0>::jacobian_locations_ = {0, - B0, - B0+B1, - B0+B1+B2}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,B3,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1, + B0+B1+B2}; // 3 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1,unsigned int B2> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0>::jacobian_locations_ = {0, - B0, - B0+B1}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,B2,0,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0, + B0, + B0+B1}; // 2 BLOCKS template <class FacT,unsigned int RES,unsigned int B0,unsigned int B1> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0, - B0}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,B1,0,0,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0, + B0}; // 1 BLOCK template <class FacT,unsigned int RES,unsigned int B0> -const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0}; +const std::vector<unsigned int> FactorAutodiff<FacT,RES,B0,0,0,0,0,0,0,0,0,0,0,0>::jacobian_locations_ = {0}; } // namespace wolf diff --git a/include/core/factor/factor_autodiff_distance_3d.h b/include/core/factor/factor_autodiff_distance_3d.h index 8dc182d6f92ec60d7ba310ed1e7f94e27a9281fc..1ef90ba493d3d3922685f7f42ff2b14402d7a546 100644 --- a/include/core/factor/factor_autodiff_distance_3d.h +++ b/include/core/factor/factor_autodiff_distance_3d.h @@ -23,7 +23,7 @@ class FactorAutodiffDistance3d : public FactorAutodiff<FactorAutodiffDistance3d, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status) : - FactorAutodiff("DISTANCE 3d", + FactorAutodiff("FactorAutodiffDistance3d", _frm_other, nullptr, nullptr, diff --git a/include/core/factor/factor_diff_drive.h b/include/core/factor/factor_diff_drive.h index d936a99d6c1d64f29fda2c5aeca1806e0065c4d1..7b189e4424b419b655833020ff9a94c71952748e 100644 --- a/include/core/factor/factor_diff_drive.h +++ b/include/core/factor/factor_diff_drive.h @@ -14,6 +14,7 @@ #include "core/factor/factor_autodiff.h" #include "core/frame/frame_base.h" #include "core/feature/feature_motion.h" +#include "core/math/rotations.h" namespace { @@ -126,10 +127,7 @@ inline bool FactorDiffDrive::operator ()(const T* const _p1, const T* const _o1, residuals = delta_corrected - delta_predicted; // angle remapping - while (residuals(2) > T(M_PI)) - residuals(2) = residuals(2) - T(2. * M_PI); - while (residuals(2) <= T(-M_PI)) - residuals(2) = residuals(2) + T(2. * M_PI); + pi2pi(residuals(2)); // weighted residual residuals = getMeasurementSquareRootInformationUpper() * residuals; diff --git a/include/core/factor/factor_odom_2d.h b/include/core/factor/factor_odom_2d.h index e20f0f50f158b7ed04e2d09054fafee9300a6f29..1ce2a375c131cea5234a5e603cdf2808764bc4cc 100644 --- a/include/core/factor/factor_odom_2d.h +++ b/include/core/factor/factor_odom_2d.h @@ -4,6 +4,7 @@ //Wolf includes #include "core/factor/factor_autodiff.h" #include "core/frame/frame_base.h" +#include "core/math/rotations.h" //#include "ceres/jet.h" @@ -72,10 +73,7 @@ inline bool FactorOdom2d::operator ()(const T* const _p1, const T* const _o1, co // Error er = expected_measurement - getMeasurement(); - while (er(2) > T( M_PI )) - er(2) -= T( 2 * M_PI ); - while (er(2) < T( -M_PI )) - er(2) += T( 2 * M_PI ); + er(2) = pi2pi(er(2)); // Residuals res = getMeasurementSquareRootInformationUpper() * er; diff --git a/include/core/factor/factor_odom_2d_analytic.h b/include/core/factor/factor_odom_2d_analytic.h index c7eec32a1778b9f1ad69da6c3c0087e50509a904..52ea04ccd817f2a6c914d771737c284bca4ce664 100644 --- a/include/core/factor/factor_odom_2d_analytic.h +++ b/include/core/factor/factor_odom_2d_analytic.h @@ -18,7 +18,7 @@ class FactorOdom2dAnalytic : public FactorRelative2dAnalytic const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status = FAC_ACTIVE) : - FactorRelative2dAnalytic("ODOM_2d", + FactorRelative2dAnalytic("FactorOdom2dAnalytic", _ftr_ptr, _frame_ptr, _processor_ptr, diff --git a/include/core/factor/factor_odom_2d_closeloop.h b/include/core/factor/factor_odom_2d_closeloop.h index e7d35aefa48b549174d060668cbee540edb6e9e2..85a1785440a03a15a899117b619d3d07aaa3eb39 100644 --- a/include/core/factor/factor_odom_2d_closeloop.h +++ b/include/core/factor/factor_odom_2d_closeloop.h @@ -4,6 +4,7 @@ //Wolf includes #include "core/factor/factor_autodiff.h" #include "core/frame/frame_base.h" +#include "core/math/rotations.h" //#include "ceres/jet.h" @@ -71,10 +72,7 @@ inline bool FactorOdom2dCloseloop::operator ()(const T* const _p1, const T* cons // Error er = expected_measurement - getMeasurement().cast<T>(); - while (er(2) > T( M_PI )) - er(2) -= T( 2 * M_PI ); - while (er(2) < T( -M_PI )) - er(2) += T( 2 * M_PI ); + er(2)=pi2pi(er(2)); // Residuals res = getMeasurementSquareRootInformationUpper().cast<T>() * er; diff --git a/include/core/factor/factor_pose_2d.h b/include/core/factor/factor_pose_2d.h index ce63c806017117e67d18c2e79c34468e6b16a61c..f11b674e7775c78c0f0f306be69c85c832e328de 100644 --- a/include/core/factor/factor_pose_2d.h +++ b/include/core/factor/factor_pose_2d.h @@ -54,11 +54,7 @@ inline bool FactorPose2d::operator ()(const T* const _p, const T* const _o, T* _ Eigen::Matrix<T,3,1> er; er(0) = meas(0) - _p[0]; er(1) = meas(1) - _p[1]; - er(2) = meas(2) - _o[0]; - while (er[2] > T(M_PI)) - er(2) = er(2) - T(2*M_PI); - while (er(2) <= T(-M_PI)) - er(2) = er(2) + T(2*M_PI); + er(2) = pi2pi(meas(2) - _o[0]); // residual Eigen::Map<Eigen::Matrix<T,3,1>> res(_residuals); diff --git a/include/core/factor/factor_quaternion_absolute.h b/include/core/factor/factor_quaternion_absolute.h index 8b399f668a8a4763c35186a309b1cfbf76f2a86b..aca1f7f966aa33e3f970e630b984b7fe145781ed 100644 --- a/include/core/factor/factor_quaternion_absolute.h +++ b/include/core/factor/factor_quaternion_absolute.h @@ -27,7 +27,7 @@ class FactorQuaternionAbsolute: public FactorAutodiff<FactorQuaternionAbsolute,3 ProcessorBasePtr _processor_ptr, bool _apply_loss_function, FactorStatus _status = FAC_ACTIVE) : - FactorAutodiff<FactorQuaternionAbsolute,3,4>("QUATERNION ABS", + FactorAutodiff<FactorQuaternionAbsolute,3,4>("FactorQuaternionAbsolute", nullptr, nullptr, nullptr, diff --git a/include/core/factor/factor_relative_2d_analytic.h b/include/core/factor/factor_relative_2d_analytic.h index 5a67da1ff6c0e17614902ebc3195dd8124ec0ed6..2dba90bc6d4ead00634f601bf232d4471860c418 100644 --- a/include/core/factor/factor_relative_2d_analytic.h +++ b/include/core/factor/factor_relative_2d_analytic.h @@ -4,6 +4,7 @@ //Wolf includes #include "core/factor/factor_analytic.h" #include "core/landmark/landmark_base.h" +#include "core/math/rotations.h" #include <Eigen/StdVector> namespace wolf { @@ -19,11 +20,11 @@ class FactorRelative2dAnalytic : public FactorAnalytic **/ FactorRelative2dAnalytic(const std::string& _tp, const FeatureBasePtr& _ftr_ptr, - const FrameBasePtr& _frame_ptr, + const FrameBasePtr& _frame_other_ptr, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status = FAC_ACTIVE) : - FactorAnalytic(_tp, _frame_ptr, nullptr, nullptr, nullptr, _processor_ptr, _apply_loss_function, _status, _frame_ptr->getP(), _frame_ptr->getO(), _ftr_ptr->getFrame()->getP(), _ftr_ptr->getFrame()->getO()) + FactorAnalytic(_tp, _frame_other_ptr, nullptr, nullptr, nullptr, _processor_ptr, _apply_loss_function, _status, _frame_other_ptr->getP(), _frame_other_ptr->getO(), _ftr_ptr->getFrame()->getP(), _ftr_ptr->getFrame()->getO()) { // } @@ -45,11 +46,11 @@ class FactorRelative2dAnalytic : public FactorAnalytic **/ FactorRelative2dAnalytic(const std::string& _tp, const FeatureBasePtr& _ftr_ptr, - const LandmarkBasePtr& _landmark_ptr, + const LandmarkBasePtr& _landmark_other_ptr, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status = FAC_ACTIVE) : - FactorAnalytic(_tp, nullptr, nullptr, nullptr, _landmark_ptr, _processor_ptr, _apply_loss_function, _status, _ftr_ptr->getFrame()->getP(), _ftr_ptr->getFrame()->getO(), _landmark_ptr->getP(), _landmark_ptr->getO()) + FactorAnalytic(_tp, nullptr, nullptr, nullptr, _landmark_other_ptr, _processor_ptr, _apply_loss_function, _status, _ftr_ptr->getFrame()->getP(), _ftr_ptr->getFrame()->getO(), _landmark_other_ptr->getP(), _landmark_other_ptr->getO()) { // } @@ -113,10 +114,7 @@ inline Eigen::VectorXd FactorRelative2dAnalytic::evaluateResiduals( expected_measurement(2) = _st_vector[3](0) - _st_vector[1](0); // Residual residual = expected_measurement - getMeasurement(); - while (residual(2) > M_PI) - residual(2) = residual(2) - 2 * M_PI; - while (residual(2) <= -M_PI) - residual(2) = residual(2) + 2 * M_PI; + residual(2) = pi2pi(residual(2)); residual = getMeasurementSquareRootInformationUpper() * residual; return residual; } diff --git a/include/core/factor/factor_relative_pose_2d_with_extrinsics.h b/include/core/factor/factor_relative_pose_2d_with_extrinsics.h new file mode 100644 index 0000000000000000000000000000000000000000..be13135c9c7e3e0899ac2bb9043f4dd1b7b60ef2 --- /dev/null +++ b/include/core/factor/factor_relative_pose_2d_with_extrinsics.h @@ -0,0 +1,119 @@ +#ifndef FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_THETA_H_ +#define FACTOR_RELATIVE_POSE_2D_WITH_EXTRINSICS_THETA_H_ + +//Wolf includes +#include "core/factor/factor_autodiff.h" +#include "core/frame/frame_base.h" +#include "core/math/rotations.h" + +//#include "ceres/jet.h" + +namespace wolf { + +WOLF_PTR_TYPEDEFS(FactorRelativePose2dWithExtrinsics); + +//class +class FactorRelativePose2dWithExtrinsics : public FactorAutodiff<FactorRelativePose2dWithExtrinsics, 3, 2, 1, 2, 1, 2, 1> +{ + public: + FactorRelativePose2dWithExtrinsics(const FeatureBasePtr& _ftr_ptr, + const FrameBasePtr& _frame_other_ptr, + const ProcessorBasePtr& _processor_ptr, + bool _apply_loss_function, + FactorStatus _status = FAC_ACTIVE) : + FactorAutodiff<FactorRelativePose2dWithExtrinsics, 3, 2, 1, 2, 1, 2, 1>("FactorRelativePose2dWithExtrinsics", + _frame_other_ptr, nullptr, nullptr, nullptr, + _processor_ptr, + _apply_loss_function, + _status, + _frame_other_ptr->getP(), + _frame_other_ptr->getO(), + _ftr_ptr->getFrame()->getP(), + _ftr_ptr->getFrame()->getO(), + _ftr_ptr->getCapture()->getSensorP(), + _ftr_ptr->getCapture()->getSensorO()) + { + assert(_ftr_ptr->getCapture()->getSensorP() != nullptr && "No extrinsics found!"); + assert(_ftr_ptr->getCapture()->getSensorO() != nullptr && "No extrinsics found!"); + // + } + + virtual ~FactorRelativePose2dWithExtrinsics() = default; + + virtual std::string getTopology() const override + { + return std::string("MOTION"); + } + + template<typename T> + bool operator ()(const T* const _p1, const T* const _o1, const T* const _p2, const T* const _o2, const T* const _sp, const T* const _so, + T* _residuals) const; +}; + +template<typename T> +inline bool FactorRelativePose2dWithExtrinsics::operator ()(const T* const _p1, const T* const _o1, const T* const _p2, + const T* const _o2, const T* const _ps, const T* const _os, T* _residuals) const +{ + + // MAPS + Eigen::Map<Eigen::Matrix<T,3,1> > res(_residuals); + Eigen::Map<const Eigen::Matrix<T,2,1> > p1(_p1); + Eigen::Map<const Eigen::Matrix<T,2,1> > p2(_p2); + Eigen::Map<const Eigen::Matrix<T,2,1> > ps(_ps); + T o1 = _o1[0]; + T o2 = _o2[0]; + T os = _os[0]; + + Eigen::Matrix<T, 3, 1> expected_measurement; + Eigen::Matrix<T, 3, 1> er; // error + + // Expected measurement + // r1_p_r1_s1 = ps + // r2_p_r2_s2 = ps + // r1_R_s1 = R(os) + // r2_R_s2 = R(os) + // w_R_r1 = R(o1) + // w_R_r2 = R(o2) + // ---------------------------------------- + + // s1_p_s1_s2 = s1_R_r1*r1_p_s1_r1 + + // s1_R_r1*r1_R_w*w_p_r1_w + + // s1_R_r1*r1_R_w*w_p_w_r2 + + // s1_R_r1*r1_R_w*w_R_r2*r2_p_r2_s2 + + // s1_p_s1_s2 = s1_R_r1*(r1_p_s1_r1 + r1_R_w*(w_p_r1_w + w_p_w_r2 + w_R_r2*r2_p_r2_s2)) + + expected_measurement.head(2) = Eigen::Rotation2D<T>(-os)*(-ps + Eigen::Rotation2D<T>(-o1)*(-p1 + p2 + Eigen::Rotation2D<T>(o2)*ps)); + expected_measurement(2) = o2 - o1; + + // Error + er = expected_measurement - getMeasurement().cast<T>(); + er(2) = pi2pi(er(2)); + + // Residuals + res = getMeasurementSquareRootInformationUpper().cast<T>() * er; + + //////////////////////////////////////////////////////// + // print Jacobian. Uncomment this as you wish (remember to uncomment #include "ceres/jet.h" above): +// using ceres::Jet; +// Eigen::MatrixXs J(3,6); +// J.row(0) = ((Jet<Scalar, 6>)(er(0))).v; +// J.row(1) = ((Jet<Scalar, 6>)(er(1))).v; +// J.row(2) = ((Jet<Scalar, 6>)(er(2))).v; +// J.row(0) = ((Jet<Scalar, 6>)(res(0))).v; +// J.row(1) = ((Jet<Scalar, 6>)(res(1))).v; +// J.row(2) = ((Jet<Scalar, 6>)(res(2))).v; +// if (sizeof(er(0)) != sizeof(double)) +// { +// std::cout << "FactorRelativePose2dWithExtrinsics::Jacobian(c" << id() << ") = \n " << J << std::endl; +// std::cout << "FactorRelativePose2dWithExtrinsics::Weighted Jacobian(c" << id() << ") = \n " << J << std::endl; +// std::cout << "FactorRelativePose2dWithExtrinsics::Sqrt Info(c" << id() << ") = \n" << getMeasurementSquareRootInformationUpper() << std::endl; +// } + //////////////////////////////////////////////////////// + + return true; +} + +} // namespace wolf + +#endif diff --git a/include/core/math/rotations.h b/include/core/math/rotations.h index 7c2ede927a796adfd35e7dd9240e0128f1192c11..a0a86c6ee4c3ef095725a2df2230c2fdb8de751f 100644 --- a/include/core/math/rotations.h +++ b/include/core/math/rotations.h @@ -27,7 +27,7 @@ pi2pi(const T _angle) T angle = _angle; while (angle > T( M_PI )) angle -= T( 2 * M_PI ); - while (angle < T( -M_PI )) + while (angle <= T( -M_PI )) angle += T( 2 * M_PI ); return angle; diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h index 8e5d7736eb0bd79c2e77948ae1e73d8a193f4d7f..7dc2caca9fdbe5fc8527cab6814a03665b0ac89e 100644 --- a/include/core/problem/problem.h +++ b/include/core/problem/problem.h @@ -11,7 +11,7 @@ class ProcessorMotion; class StateBlock; class TimeStamp; struct ParamsSensorBase; -struct ProcessorParamsBase; +struct ParamsProcessorBase; } //wolf includes @@ -19,8 +19,8 @@ struct ProcessorParamsBase; #include "core/frame/frame_base.h" #include "core/state_block/state_block.h" #include "core/utils/params_server.h" -#include "core/sensor/sensor_factory.h" -#include "core/processor/processor_factory.h" +#include "core/sensor/factory_sensor.h" +#include "core/processor/factory_processor.h" #include "core/processor/is_motion.h" // std includes @@ -52,6 +52,7 @@ class Problem : public std::enable_shared_from_this<Problem> friend ProcessorMotion; protected: + TreeManagerBasePtr tree_manager_; HardwareBasePtr hardware_ptr_; TrajectoryBasePtr trajectory_ptr_; MapBasePtr map_ptr_; @@ -82,6 +83,10 @@ class Problem : public std::enable_shared_from_this<Problem> SizeEigen getDim() const; std::string getFrameStructure() const; + // Tree manager -------------------------------------- + void setTreeManager(TreeManagerBasePtr _gm); + TreeManagerBasePtr getTreeManager() const; + // Hardware branch ------------------------------------ HardwareBasePtr getHardware() const; @@ -100,7 +105,7 @@ class Problem : public std::enable_shared_from_this<Problem> * \param _sen_type type of sensor * \param _unique_sensor_name unique sensor name, used to identify the particular instance of the sensor * \param _extrinsics a vector of extrinsic parameters: size 2 for 2d position, 3 for 2d pose, 3 for 3d position, 7 for 3d pose. - * \param _intrinsics_filename the name of a file containing the intrinsic parameters in a format compatible with the intrinsics creator registered in ParamsSensorFactory under the key _sen_type. + * \param _intrinsics_filename the name of a file containing the intrinsic parameters in a format compatible with the intrinsics creator registered in FactoryParamsSensor under the key _sen_type. */ SensorBasePtr installSensor(const std::string& _sen_type, // const std::string& _unique_sensor_name, // @@ -128,7 +133,7 @@ class Problem : public std::enable_shared_from_this<Problem> ProcessorBasePtr installProcessor(const std::string& _prc_type, // const std::string& _unique_processor_name, // SensorBasePtr _corresponding_sensor_ptr, // - ProcessorParamsBasePtr _prc_params = nullptr); + ParamsProcessorBasePtr _prc_params = nullptr); /** \brief Factory method to install (create, and add to sensor) processors only from its properties * @@ -382,6 +387,11 @@ class Problem : public std::enable_shared_from_this<Problem> namespace wolf { +inline TreeManagerBasePtr Problem::getTreeManager() const +{ + return tree_manager_; +} + inline bool Problem::isPriorSet() const { return prior_options_ == nullptr; diff --git a/include/core/processor/processor_factory.h b/include/core/processor/factory_processor.h similarity index 74% rename from include/core/processor/processor_factory.h rename to include/core/processor/factory_processor.h index c14f3daa364678ef6f549fa04f65eddb4885e1fd..738d3558a41124377dffa39731ed1c859d09f873 100644 --- a/include/core/processor/processor_factory.h +++ b/include/core/processor/factory_processor.h @@ -1,17 +1,17 @@ /** - * \file processor_factory.h + * \file factory_processor.h * * Created on: May 4, 2016 * \author: jsola */ -#ifndef PROCESSOR_FACTORY_H_ -#define PROCESSOR_FACTORY_H_ +#ifndef FACTORY_PROCESSOR_H_ +#define FACTORY_PROCESSOR_H_ namespace wolf { class ProcessorBase; -struct ProcessorParamsBase; +struct ParamsProcessorBase; } // wolf @@ -47,17 +47,17 @@ namespace wolf * - Write a processor creator for ProcessorOdom2d (example). * * #### Accessing the Factory - * The ProcessorFactory class is a singleton: it can only exist once in your application. + * The FactoryProcessor class is a singleton: it can only exist once in your application. * To obtain an instance of it, use the static method get(), * * \code - * ProcessorFactory::get() + * FactoryProcessor::get() * \endcode * * You can then call the methods you like, e.g. to create a processor, you type: * * \code - * ProcessorFactory::get().create(...); // see below for creating processors ... + * FactoryProcessor::get().create(...); // see below for creating processors ... * \endcode * * #### Registering processor creators @@ -69,21 +69,21 @@ namespace wolf * that knows how to create your specific processor, e.g.: * * \code - * ProcessorFactory::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create); + * FactoryProcessor::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create); * \endcode * * The method ProcessorOdom2d::create() exists in the ProcessorOdom2d class as a static method. * All these ProcessorXxx::create() methods need to have exactly the same API, regardless of the processor type. - * This API includes a processor name, and a pointer to a base struct of parameters, ProcessorParamsBasePtr, + * This API includes a processor name, and a pointer to a base struct of parameters, ParamsProcessorBasePtr, * that can be derived for each derived processor. * * Here is an example of ProcessorOdom2d::create() extracted from processor_odom_2d.h: * * \code - * static ProcessorBasePtr create(const std::string& _name, ProcessorParamsBasePtr _params) + * static ProcessorBasePtr create(const std::string& _name, ParamsProcessorBasePtr _params) * { * // cast _params to good type - * ProcessorParamsOdom2d* params = (ProcessorParamsOdom2d*)_params; + * ParamsProcessorOdom2d* params = (ParamsProcessorOdom2d*)_params; * * ProcessorBasePtr prc = new ProcessorOdom2d(params); * prc->setName(_name); // pass the name to the created ProcessorOdom2d. @@ -96,7 +96,7 @@ namespace wolf * For example, in processor_odom_2d.cpp we find the line: * * \code - * const bool registered_odom_2d = ProcessorFactory::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create); + * const bool registered_odom_2d = FactoryProcessor::get().registerCreator("ProcessorOdom2d", ProcessorOdom2d::create); * \endcode * * which is a static invocation (i.e., it is placed at global scope outside of the ProcessorOdom2d class). @@ -107,7 +107,7 @@ namespace wolf * It only needs to be passed the string of the processor type. * * \code - * ProcessorFactory::get().unregisterCreator("ProcessorOdom2d"); + * FactoryProcessor::get().unregisterCreator("ProcessorOdom2d"); * \endcode * * #### Creating processors @@ -117,7 +117,7 @@ namespace wolf * To create a ProcessorOdom2d, you type: * * \code - * ProcessorFactory::get().create("ProcessorOdom2d", "main odometry", params_ptr); + * FactoryProcessor::get().create("ProcessorOdom2d", "main odometry", params_ptr); * \endcode * * #### Example 1 : using the Factories alone @@ -125,21 +125,21 @@ namespace wolf * and bind it to a SensorOdom2d: * * \code - * #include "core/sensor/sensor_odom_2d.h" // provides SensorOdom2d and SensorFactory - * #include "core/processor/processor_odom_2d.h" // provides ProcessorOdom2d and ProcessorFactory + * #include "core/sensor/sensor_odom_2d.h" // provides SensorOdom2d and FactorySensor + * #include "core/processor/processor_odom_2d.h" // provides ProcessorOdom2d and FactoryProcessor * * // Note: SensorOdom2d::create() is already registered, automatically. * // Note: ProcessorOdom2d::create() is already registered, automatically. * - * // First create the sensor (See SensorFactory for details) - * SensorBasePtr sensor_ptr = SensorFactory::get().create ( "FactorOdom2d" , "Main odometer" , extrinsics , &intrinsics ); + * // First create the sensor (See FactorySensor for details) + * SensorBasePtr sensor_ptr = FactorySensor::get().create ( "FactorOdom2d" , "Main odometer" , extrinsics , &intrinsics ); * * // To create a odometry integrator, provide a type="ODOM 2d", a name="main odometry", and a pointer to the parameters struct: * - * ProcessorParamsOdom2d params({...}); // fill in the derived struct (note: ProcessorOdom2d actually has no input params) + * ParamsProcessorOdom2d params({...}); // fill in the derived struct (note: ProcessorOdom2d actually has no input params) * * ProcessorBasePtr processor_ptr = - * ProcessorFactory::get().create ( "ProcessorOdom2d" , "main odometry" , ¶ms ); + * FactoryProcessor::get().create ( "ProcessorOdom2d" , "main odometry" , ¶ms ); * * // Bind processor to sensor * sensor_ptr->addProcessor(processor_ptr); @@ -165,43 +165,43 @@ namespace wolf * You can also check the code in the example file ````src/examples/test_wolf_factories.cpp````. */ -// ProcessorParams factory -struct ProcessorParamsBase; -typedef Factory<ProcessorParamsBase, - const std::string&> ProcessorParamsFactory; +// ParamsProcessor factory +struct ParamsProcessorBase; +typedef Factory<ParamsProcessorBase, + const std::string&> FactoryParamsProcessor; template<> -inline std::string ProcessorParamsFactory::getClass() +inline std::string FactoryParamsProcessor::getClass() { - return "ProcessorParamsFactory"; + return "FactoryParamsProcessor"; } // Processor factory typedef Factory<ProcessorBase, const std::string&, - const ProcessorParamsBasePtr> ProcessorFactory; + const ParamsProcessorBasePtr> FactoryProcessor; template<> -inline std::string ProcessorFactory::getClass() +inline std::string FactoryProcessor::getClass() { - return "ProcessorFactory"; + return "FactoryProcessor"; } -#define WOLF_REGISTER_PROCESSOR(ProcessorType, ProcessorName) \ - namespace{ const bool WOLF_UNUSED ProcessorName##Registered = \ - wolf::ProcessorFactory::get().registerCreator(ProcessorType, ProcessorName::create); } \ +#define WOLF_REGISTER_PROCESSOR(ProcessorType) \ + namespace{ const bool WOLF_UNUSED ProcessorType##Registered = \ + wolf::FactoryProcessor::get().registerCreator(#ProcessorType, ProcessorType::create); } \ typedef Factory<ProcessorBase, const std::string&, - const ParamsServer&> AutoConfProcessorFactory; + const ParamsServer&> AutoConfFactoryProcessor; template<> -inline std::string AutoConfProcessorFactory::getClass() +inline std::string AutoConfFactoryProcessor::getClass() { - return "AutoConfProcessorFactory"; + return "AutoConfFactoryProcessor"; } -#define WOLF_REGISTER_PROCESSOR_AUTO(ProcessorType, ProcessorName) \ - namespace{ const bool WOLF_UNUSED ProcessorName##AutoConfRegistered = \ - wolf::AutoConfProcessorFactory::get().registerCreator(ProcessorType, ProcessorName::create); } \ +#define WOLF_REGISTER_PROCESSOR_AUTO(ProcessorType) \ + namespace{ const bool WOLF_UNUSED ProcessorType##AutoConfRegistered = \ + wolf::AutoConfFactoryProcessor::get().registerCreator(#ProcessorType, ProcessorType::create); } \ } /* namespace wolf */ diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h index dc62abcac8375fc238f7c93617a33ccb8662d246..0d0e54eef5217c037dabbf00eb4f3b87f100e283 100644 --- a/include/core/processor/processor_base.h +++ b/include/core/processor/processor_base.h @@ -30,13 +30,13 @@ namespace wolf { * In order to use this macro, the derived processor class, ProcessorClass, * must have a constructor available with the API: * - * ProcessorClass(const ProcessorParamsClassPtr _params); + * ProcessorClass(const ParamsProcessorClassPtr _params); */ -#define WOLF_PROCESSOR_CREATE(ProcessorClass, ProcessorParamsClass) \ +#define WOLF_PROCESSOR_CREATE(ProcessorClass, ParamsProcessorClass) \ static ProcessorBasePtr create(const std::string& _unique_name, \ const ParamsServer& _server) \ { \ - auto params = std::make_shared<ProcessorParamsClass>(_unique_name, _server); \ + auto params = std::make_shared<ParamsProcessorClass>(_unique_name, _server); \ \ auto processor = std::make_shared<ProcessorClass>(params); \ \ @@ -44,9 +44,9 @@ static ProcessorBasePtr create(const std::string& _unique_name, \ return processor; \ } \ -static ProcessorBasePtr create(const std::string& _unique_name, const ProcessorParamsBasePtr _params) \ +static ProcessorBasePtr create(const std::string& _unique_name, const ParamsProcessorBasePtr _params) \ { \ - auto params = std::static_pointer_cast<ProcessorParamsClass>(_params); \ + auto params = std::static_pointer_cast<ParamsProcessorClass>(_params); \ \ auto processor = std::make_shared<ProcessorClass>(params); \ \ @@ -208,11 +208,11 @@ class BufferCapture : public Buffer<CaptureBasePtr> {}; * * Derive from this struct to create structs of processor parameters. */ -struct ProcessorParamsBase : public ParamsBase +struct ParamsProcessorBase : public ParamsBase { std::string prefix = "processor/"; - ProcessorParamsBase() = default; - ProcessorParamsBase(std::string _unique_name, const ParamsServer& _server): + ParamsProcessorBase() = default; + ParamsProcessorBase(std::string _unique_name, const ParamsServer& _server): ParamsBase(_unique_name, _server) { time_tolerance = _server.getParam<double>(prefix + _unique_name + "/time_tolerance"); @@ -221,7 +221,7 @@ struct ProcessorParamsBase : public ParamsBase apply_loss_function = _server.getParam<bool>(prefix + _unique_name + "/apply_loss_function"); } - virtual ~ProcessorParamsBase() = default; + virtual ~ParamsProcessorBase() = default; /** maximum time difference between a Keyframe time stamp and * a particular Capture of this processor to allow assigning @@ -248,7 +248,7 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce friend SensorBase; protected: unsigned int processor_id_; - ProcessorParamsBasePtr params_; + ParamsProcessorBasePtr params_; BufferPackKeyFrame buffer_pack_kf_; BufferCapture buffer_capture_; int dim_; @@ -258,7 +258,7 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce static unsigned int processor_id_count_; public: - ProcessorBase(const std::string& _type, int _dim, ProcessorParamsBasePtr _params); + ProcessorBase(const std::string& _type, int _dim, ParamsProcessorBasePtr _params); virtual ~ProcessorBase(); virtual void configure(SensorBasePtr _sensor) = 0; virtual void remove(); diff --git a/include/core/processor/processor_diff_drive.h b/include/core/processor/processor_diff_drive.h index 48d18acccc0e48f3f5f2373b0ece28e2da607f61..bcbf3f6034250a3ffd0ac3e00b73501643d1b69b 100644 --- a/include/core/processor/processor_diff_drive.h +++ b/include/core/processor/processor_diff_drive.h @@ -13,18 +13,18 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsDiffDrive); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorDiffDrive); -struct ProcessorParamsDiffDrive : public ProcessorParamsOdom2d +struct ParamsProcessorDiffDrive : public ParamsProcessorOdom2d { - ProcessorParamsDiffDrive() = default; - ProcessorParamsDiffDrive(std::string _unique_name, const wolf::ParamsServer & _server) : - ProcessorParamsOdom2d(_unique_name, _server) + ParamsProcessorDiffDrive() = default; + ParamsProcessorDiffDrive(std::string _unique_name, const wolf::ParamsServer & _server) : + ParamsProcessorOdom2d(_unique_name, _server) { } std::string print() const { - return "\n" + ProcessorParamsOdom2d::print(); + return "\n" + ParamsProcessorOdom2d::print(); } }; @@ -33,12 +33,12 @@ WOLF_PTR_TYPEDEFS(ProcessorDiffDrive); class ProcessorDiffDrive : public ProcessorOdom2d { public: - ProcessorDiffDrive(ProcessorParamsDiffDrivePtr _params_motion); + ProcessorDiffDrive(ParamsProcessorDiffDrivePtr _params_motion); virtual ~ProcessorDiffDrive(); virtual void configure(SensorBasePtr _sensor) override; // Factory method for high level API - WOLF_PROCESSOR_CREATE(ProcessorDiffDrive, ProcessorParamsDiffDrive); + WOLF_PROCESSOR_CREATE(ProcessorDiffDrive, ParamsProcessorDiffDrive); protected: // Motion integration @@ -63,7 +63,7 @@ class ProcessorDiffDrive : public ProcessorOdom2d protected: - ProcessorParamsDiffDrivePtr params_prc_diff_drv_selfcal_; + ParamsProcessorDiffDrivePtr params_prc_diff_drv_selfcal_; double radians_per_tick_; }; diff --git a/include/core/processor/processor_loopclosure.h b/include/core/processor/processor_loopclosure.h index b0720f3a47afdfd7878b23929923295964340ea5..cbd8fa378738ad55d1072d63b7a6162a169077fa 100644 --- a/include/core/processor/processor_loopclosure.h +++ b/include/core/processor/processor_loopclosure.h @@ -6,12 +6,12 @@ namespace wolf{ -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsLoopClosure); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorLoopClosure); -struct ProcessorParamsLoopClosure : public ProcessorParamsBase +struct ParamsProcessorLoopClosure : public ParamsProcessorBase { - using ProcessorParamsBase::ProcessorParamsBase; - // virtual ~ProcessorParamsLoopClosure() = default; + using ParamsProcessorBase::ParamsProcessorBase; + // virtual ~ParamsProcessorLoopClosure() = default; // add neccesery parameters for loop closure initialisation here and initialize // them in constructor @@ -46,12 +46,12 @@ class ProcessorLoopClosure : public ProcessorBase { protected: - ProcessorParamsLoopClosurePtr params_loop_closure_; + ParamsProcessorLoopClosurePtr params_loop_closure_; int _dim; public: - ProcessorLoopClosure(const std::string& _type, int _dim, ProcessorParamsLoopClosurePtr _params_loop_closure); + ProcessorLoopClosure(const std::string& _type, int _dim, ParamsProcessorLoopClosurePtr _params_loop_closure); virtual ~ProcessorLoopClosure() = default; virtual void configure(SensorBasePtr _sensor) override { }; diff --git a/include/core/processor/processor_motion.h b/include/core/processor/processor_motion.h index 402c590326567b5f4c0c564404c09b331f8ba674..69e346ac755a4db3086b878fcc0ee61cf8979811 100644 --- a/include/core/processor/processor_motion.h +++ b/include/core/processor/processor_motion.h @@ -21,9 +21,9 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsMotion); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorMotion); -struct ProcessorParamsMotion : public ProcessorParamsBase +struct ParamsProcessorMotion : public ParamsProcessorBase { double max_time_span = 0.5; unsigned int max_buff_length = 10; @@ -31,9 +31,9 @@ struct ProcessorParamsMotion : public ProcessorParamsBase double angle_turned = 0.5; double unmeasured_perturbation_std = 1e-4; - ProcessorParamsMotion() = default; - ProcessorParamsMotion(std::string _unique_name, const ParamsServer& _server): - ProcessorParamsBase(_unique_name, _server) + ParamsProcessorMotion() = default; + ParamsProcessorMotion(std::string _unique_name, const ParamsServer& _server): + ParamsProcessorBase(_unique_name, _server) { max_time_span = _server.getParam<double>(prefix + _unique_name + "/keyframe_vote/max_time_span"); max_buff_length = _server.getParam<unsigned int>(prefix + _unique_name + "/keyframe_vote/max_buff_length"); @@ -43,7 +43,7 @@ struct ProcessorParamsMotion : public ProcessorParamsBase } std::string print() const { - return "\n" + ProcessorParamsBase::print() + "\n" + return "\n" + ParamsProcessorBase::print() + "\n" + "max_time_span: " + std::to_string(max_time_span) + "\n" + "max_buff_length: " + std::to_string(max_buff_length) + "\n" + "dist_traveled: " + std::to_string(dist_traveled) + "\n" @@ -145,7 +145,7 @@ class ProcessorMotion : public ProcessorBase, public IsMotion } ProcessingStep ; protected: - ProcessorParamsMotionPtr params_motion_; + ParamsProcessorMotionPtr params_motion_; ProcessingStep processing_step_; ///< State machine controlling the processing step virtual void setProblem(ProblemPtr) override; @@ -159,7 +159,7 @@ class ProcessorMotion : public ProcessorBase, public IsMotion SizeEigen _delta_cov_size, SizeEigen _data_size, SizeEigen _calib_size, - ProcessorParamsMotionPtr _params_motion); + ParamsProcessorMotionPtr _params_motion); virtual ~ProcessorMotion(); // Instructions to the processor: diff --git a/include/core/processor/processor_odom_2d.h b/include/core/processor/processor_odom_2d.h index b03416837ec1b0a6a86a67ff0cf40fdf820b1370..a626833c99d6b5e6987fab4259f68bf466bd6570 100644 --- a/include/core/processor/processor_odom_2d.h +++ b/include/core/processor/processor_odom_2d.h @@ -17,22 +17,22 @@ namespace wolf { WOLF_PTR_TYPEDEFS(ProcessorOdom2d); -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsOdom2d); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorOdom2d); -struct ProcessorParamsOdom2d : public ProcessorParamsMotion +struct ParamsProcessorOdom2d : public ParamsProcessorMotion { double cov_det = 1.0; - ProcessorParamsOdom2d() = default; - ProcessorParamsOdom2d(std::string _unique_name, const wolf::ParamsServer & _server) : - ProcessorParamsMotion(_unique_name, _server) + ParamsProcessorOdom2d() = default; + ParamsProcessorOdom2d(std::string _unique_name, const wolf::ParamsServer & _server) : + ParamsProcessorMotion(_unique_name, _server) { cov_det = _server.getParam<double>(prefix + _unique_name + "/keyframe_vote/cov_det"); } std::string print() const { - return "\n" + ProcessorParamsMotion::print() + "\n" + return "\n" + ParamsProcessorMotion::print() + "\n" + "cov_det: " + std::to_string(cov_det) + "\n"; } }; @@ -40,12 +40,12 @@ struct ProcessorParamsOdom2d : public ProcessorParamsMotion class ProcessorOdom2d : public ProcessorMotion { public: - ProcessorOdom2d(ProcessorParamsOdom2dPtr _params); + ProcessorOdom2d(ParamsProcessorOdom2dPtr _params); virtual ~ProcessorOdom2d(); virtual void configure(SensorBasePtr _sensor) override; // Factory method for high level API - WOLF_PROCESSOR_CREATE(ProcessorOdom2d, ProcessorParamsOdom2d); + WOLF_PROCESSOR_CREATE(ProcessorOdom2d, ParamsProcessorOdom2d); virtual bool voteForKeyFrame() const override; @@ -86,7 +86,7 @@ class ProcessorOdom2d : public ProcessorMotion CaptureBasePtr _capture_origin) override; protected: - ProcessorParamsOdom2dPtr params_odom_2d_; + ParamsProcessorOdom2dPtr params_odom_2d_; }; diff --git a/include/core/processor/processor_odom_3d.h b/include/core/processor/processor_odom_3d.h index f8f849b896aad644f998c38b50e8ca198c0738c4..ca0a9619d06dbd285bb9bf8da88943286d87e0bb 100644 --- a/include/core/processor/processor_odom_3d.h +++ b/include/core/processor/processor_odom_3d.h @@ -17,19 +17,19 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsOdom3d); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorOdom3d); -struct ProcessorParamsOdom3d : public ProcessorParamsMotion +struct ParamsProcessorOdom3d : public ParamsProcessorMotion { - ProcessorParamsOdom3d() = default; - ProcessorParamsOdom3d(std::string _unique_name, const ParamsServer& _server): - ProcessorParamsMotion(_unique_name, _server) + ParamsProcessorOdom3d() = default; + ParamsProcessorOdom3d(std::string _unique_name, const ParamsServer& _server): + ParamsProcessorMotion(_unique_name, _server) { // } std::string print() const { - return "\n" + ProcessorParamsMotion::print(); + return "\n" + ParamsProcessorMotion::print(); } }; @@ -60,12 +60,12 @@ WOLF_PTR_TYPEDEFS(ProcessorOdom3d); class ProcessorOdom3d : public ProcessorMotion { public: - ProcessorOdom3d(ProcessorParamsOdom3dPtr _params); + ProcessorOdom3d(ParamsProcessorOdom3dPtr _params); virtual ~ProcessorOdom3d(); virtual void configure(SensorBasePtr _sensor) override; // Factory method for high level API - WOLF_PROCESSOR_CREATE(ProcessorOdom3d, ProcessorParamsOdom3d); + WOLF_PROCESSOR_CREATE(ProcessorOdom3d, ParamsProcessorOdom3d); public: // Motion integration @@ -107,7 +107,7 @@ class ProcessorOdom3d : public ProcessorMotion CaptureBasePtr _capture_origin) override; protected: - ProcessorParamsOdom3dPtr params_odom_3d_; + ParamsProcessorOdom3dPtr params_odom_3d_; // noise parameters (stolen from owner SensorOdom3d) double k_disp_to_disp_; // displacement variance growth per meter of linear motion diff --git a/include/core/processor/processor_tracker.h b/include/core/processor/processor_tracker.h index d7ab951643fbc2760b8d81110a9f2338a96dad36..efe8ef33837df852499491c5f524bcfed0765129 100644 --- a/include/core/processor/processor_tracker.h +++ b/include/core/processor/processor_tracker.h @@ -13,23 +13,23 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsTracker); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorTracker); -struct ProcessorParamsTracker : public ProcessorParamsBase +struct ParamsProcessorTracker : public ParamsProcessorBase { unsigned int min_features_for_keyframe; ///< minimum nbr. of features to vote for keyframe int max_new_features; ///< maximum nbr. of new features to be processed when adding a keyframe (-1: unlimited. 0: none.) - ProcessorParamsTracker() = default; - ProcessorParamsTracker(std::string _unique_name, const wolf::ParamsServer & _server): - ProcessorParamsBase(_unique_name, _server) + ParamsProcessorTracker() = default; + ParamsProcessorTracker(std::string _unique_name, const wolf::ParamsServer & _server): + ParamsProcessorBase(_unique_name, _server) { min_features_for_keyframe = _server.getParam<unsigned int>(prefix + _unique_name + "/min_features_for_keyframe"); max_new_features = _server.getParam<int>(prefix + _unique_name + "/max_new_features"); } std::string print() const { - return ProcessorParamsBase::print() + "\n" + return ParamsProcessorBase::print() + "\n" + "min_features_for_keyframe: " + std::to_string(min_features_for_keyframe) + "\n" + "max_new_features: " + std::to_string(max_new_features) + "\n"; } @@ -96,20 +96,21 @@ class ProcessorTracker : public ProcessorBase } ProcessingStep ; protected: - ProcessorParamsTrackerPtr params_tracker_; ///< parameters for the tracker + ParamsProcessorTrackerPtr params_tracker_; ///< parameters for the tracker ProcessingStep processing_step_; ///< State machine controlling the processing step CaptureBasePtr origin_ptr_; ///< Pointer to the origin of the tracker. CaptureBasePtr last_ptr_; ///< Pointer to the last tracked capture. CaptureBasePtr incoming_ptr_; ///< Pointer to the incoming capture being processed. FeatureBasePtrList new_features_last_; ///< List of new features in \b last for landmark initialization and new key-frame creation. FeatureBasePtrList new_features_incoming_; ///< list of the new features of \b last successfully tracked in \b incoming + FeatureBasePtrList known_features_last_; ///< list of the known features in previous captures successfully tracked in \b last FeatureBasePtrList known_features_incoming_; ///< list of the known features in \b last successfully tracked in \b incoming int _dim; public: ProcessorTracker(const std::string& _type, int _dim, - ProcessorParamsTrackerPtr _params_tracker); + ParamsProcessorTrackerPtr _params_tracker); virtual ~ProcessorTracker(); bool checkTimeTolerance(const TimeStamp& _ts1, const TimeStamp& _ts2); diff --git a/include/core/processor/processor_tracker_feature.h b/include/core/processor/processor_tracker_feature.h index b86e041d25e026762ea1413429b1c6e63a594fd7..4cb706c5c3de26da86f3653ef6234251bafb3f7c 100644 --- a/include/core/processor/processor_tracker_feature.h +++ b/include/core/processor/processor_tracker_feature.h @@ -18,11 +18,11 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsTrackerFeature); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorTrackerFeature); -struct ProcessorParamsTrackerFeature : public ProcessorParamsTracker +struct ParamsProcessorTrackerFeature : public ParamsProcessorTracker { - using ProcessorParamsTracker::ProcessorParamsTracker; + using ParamsProcessorTracker::ParamsProcessorTracker; }; WOLF_PTR_TYPEDEFS(ProcessorTrackerFeature); @@ -86,11 +86,11 @@ class ProcessorTrackerFeature : public ProcessorTracker */ ProcessorTrackerFeature(const std::string& _type, int _dim, - ProcessorParamsTrackerFeaturePtr _params_tracker_feature); + ParamsProcessorTrackerFeaturePtr _params_tracker_feature); virtual ~ProcessorTrackerFeature(); protected: - ProcessorParamsTrackerFeaturePtr params_tracker_feature_; + ParamsProcessorTrackerFeaturePtr params_tracker_feature_; TrackMatrix track_matrix_; FeatureMatchMap matches_last_from_incoming_; @@ -111,7 +111,7 @@ class ProcessorTrackerFeature : public ProcessorTracker * - Create the factors, of the correct type, derived from FactorBase * (through FactorAnalytic or FactorSparse). */ - virtual unsigned int processKnown(); + virtual unsigned int processKnown() override; /** \brief Track provided features in \b _capture * \param _features_in input list of features in \b last to track @@ -147,16 +147,16 @@ class ProcessorTrackerFeature : public ProcessorTracker * * WARNING! This function only votes! It does not create KeyFrames! */ - virtual bool voteForKeyFrame() const = 0; + virtual bool voteForKeyFrame() const override = 0; // We overload the advance and reset functions to update the lists of matches - void advanceDerived(); - void resetDerived(); + virtual void advanceDerived() override; + virtual void resetDerived() override; /**\brief Process new Features * */ - virtual unsigned int processNew(const int& _max_features); + virtual unsigned int processNew(const int& _max_features) override; /** \brief Detect new Features * \param _max_features maximum number of features detected (-1: unlimited. 0: none) @@ -190,7 +190,7 @@ class ProcessorTrackerFeature : public ProcessorTracker /** \brief Emplaces a new factor for each correspondence between a feature in Capture \b last and a feature in Capture \b origin */ - virtual void establishFactors(); + virtual void establishFactors() override; }; } // namespace wolf diff --git a/include/core/processor/processor_tracker_landmark.h b/include/core/processor/processor_tracker_landmark.h index 8809426f8654803fc7012068ff9d89cd1d70ea4c..b4e7f7a41ae8bbe68d53da08288b85cda87edeab 100644 --- a/include/core/processor/processor_tracker_landmark.h +++ b/include/core/processor/processor_tracker_landmark.h @@ -16,11 +16,11 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsTrackerLandmark); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorTrackerLandmark); -struct ProcessorParamsTrackerLandmark : public ProcessorParamsTracker +struct ParamsProcessorTrackerLandmark : public ParamsProcessorTracker { - using ProcessorParamsTracker::ProcessorParamsTracker; + using ParamsProcessorTracker::ParamsProcessorTracker; // }; @@ -81,12 +81,12 @@ class ProcessorTrackerLandmark : public ProcessorTracker { public: ProcessorTrackerLandmark(const std::string& _type, - ProcessorParamsTrackerLandmarkPtr _params_tracker_landmark); + ParamsProcessorTrackerLandmarkPtr _params_tracker_landmark); virtual ~ProcessorTrackerLandmark(); protected: - ProcessorParamsTrackerLandmarkPtr params_tracker_landmark_; + ParamsProcessorTrackerLandmarkPtr params_tracker_landmark_; LandmarkBasePtrList new_landmarks_; ///< List of new detected landmarks LandmarkMatchMap matches_landmark_from_incoming_; LandmarkMatchMap matches_landmark_from_last_; diff --git a/include/core/sensor/sensor_factory.h b/include/core/sensor/factory_sensor.h similarity index 79% rename from include/core/sensor/sensor_factory.h rename to include/core/sensor/factory_sensor.h index daf01499ac759d799517cdd73ab830fb6ccaf4d5..67ef5f597108f7ddc3bc264fb1c0cbc218bdba0a 100644 --- a/include/core/sensor/sensor_factory.h +++ b/include/core/sensor/factory_sensor.h @@ -1,12 +1,12 @@ /** - * \file sensor_factory.h + * \file factory_sensor.h * * Created on: Apr 25, 2016 * \author: jsola */ -#ifndef SENSOR_FACTORY_H_ -#define SENSOR_FACTORY_H_ +#ifndef FACTORY_SENSOR_H_ +#define FACTORY_SENSOR_H_ namespace wolf { @@ -47,17 +47,17 @@ namespace wolf * - Write a sensor creator for SensorCamera (example). * * #### Accessing the factory - * The SensorFactory class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application. + * The FactorySensor class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application. * To obtain an instance of it, use the static method get(), * * \code - * SensorFactory::get() + * FactorySensor::get() * \endcode * * You can then call the methods you like, e.g. to create a sensor, you type: * * \code - * SensorFactory::get().create(...); // see below for creating sensors ... + * FactorySensor::get().create(...); // see below for creating sensors ... * \endcode * * #### Registering sensor creators @@ -69,7 +69,7 @@ namespace wolf * that knows how to create your specific sensor, e.g.: * * \code - * SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * \endcode * * The method SensorCamera::create() exists in the SensorCamera class as a static method. @@ -89,7 +89,7 @@ namespace wolf * For example, in sensor_camera.cpp we find the line: * * \code - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * \endcode * * which is a static invocation (i.e., it is placed at global scope outside of the SensorCamera class). @@ -99,7 +99,7 @@ namespace wolf * The method unregisterCreator() unregisters the SensorXxx::create() method. It only needs to be passed the string of the sensor type. * * \code - * SensorFactory::get().unregisterCreator("CAMERA"); + * FactorySensor::get().unregisterCreator("CAMERA"); * \endcode * * #### Creating sensors @@ -109,15 +109,15 @@ namespace wolf * To create e.g. a SensorCamera, you type: * * \code - * SensorFactory::get().create("CAMERA", "Front-left camera", extrinsics, intrinsics_ptr); + * FactorySensor::get().create("CAMERA", "Front-left camera", extrinsics, intrinsics_ptr); * \endcode * * where ABSOLUTELY ALL input parameters are important. In particular, the sensor name "Front-left camera" will be used to identify this camera * and to assign it the appropriate processors. DO NOT USE IT WITH DUMMY PARAMETERS! * * #### See also - * - ParamsSensorFactory: to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. - * - ProcessorFactory: to create processors that will be bound to sensors. + * - FactoryParamsSensor: to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. + * - FactoryProcessor: to create processors that will be bound to sensors. * - Problem::installSensor() : to install sensors in WOLF Problem. * * #### Example 1: writing a specific sensor creator @@ -148,14 +148,14 @@ namespace wolf * Put the code either at global scope (you must define a dummy variable for this), * \code * namespace { - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * } * main () { ... } * \endcode * or inside your main(), where a direct call is possible: * \code * main () { - * SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * ... * } * \endcode @@ -164,7 +164,7 @@ namespace wolf * Put the code at the last line of the sensor_xxx.cpp file, * \code * namespace { - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * } * \endcode * Automatic registration is recommended in wolf, and implemented in the classes shipped with it. @@ -174,7 +174,7 @@ namespace wolf * We finally provide the necessary steps to create a sensor of class SensorCamera in our application: * * \code - * #include "sensor_factory.h" + * #include "factory_sensor.h" * #include "core/sensor/sensor_camera.h" // provides SensorCamera * * // Note: SensorCamera::create() is already registered, automatically. @@ -189,10 +189,10 @@ namespace wolf * // a pointer to the intrinsics struct: * * Eigen::VectorXd extrinsics_1(7); // give it some values... - * ParamsSensorCamera intrinsics_1({...}); // see ParamsSensorFactory to fill in the derived struct + * ParamsSensorCamera intrinsics_1({...}); // see FactoryParamsSensor to fill in the derived struct * * SensorBasePtr camera_1_ptr = - * SensorFactory::get().create ( "CAMERA" , "Front-left camera" , extrinsics_1 , &intrinsics_1 ); + * FactorySensor::get().create ( "CAMERA" , "Front-left camera" , extrinsics_1 , &intrinsics_1 ); * * // A second camera... with a different name! * @@ -200,7 +200,7 @@ namespace wolf * ParamsSensorCamera intrinsics_2({...}); * * SensorBasePtr camera_2_ptr = - * SensorFactory::get().create( "CAMERA" , "Front-right camera" , extrinsics_2 , &intrinsics_2 ); + * FactorySensor::get().create( "CAMERA" , "Front-right camera" , extrinsics_2 , &intrinsics_2 ); * * return 0; * } @@ -212,42 +212,42 @@ namespace wolf // ParamsSensor factory struct ParamsSensorBase; typedef Factory<ParamsSensorBase, - const std::string&> ParamsSensorFactory; + const std::string&> FactoryParamsSensor; template<> -inline std::string ParamsSensorFactory::getClass() +inline std::string FactoryParamsSensor::getClass() { - return "ParamsSensorFactory"; + return "FactoryParamsSensor"; } // Sensor factory typedef Factory<SensorBase, const std::string&, - const Eigen::VectorXd&, const ParamsSensorBasePtr> SensorFactory; + const Eigen::VectorXd&, const ParamsSensorBasePtr> FactorySensor; template<> -inline std::string SensorFactory::getClass() +inline std::string FactorySensor::getClass() { - return "SensorFactory"; + return "FactorySensor"; } -#define WOLF_REGISTER_SENSOR(SensorType, SensorName) \ - namespace{ const bool WOLF_UNUSED SensorName##Registered = \ - SensorFactory::get().registerCreator(SensorType, SensorName::create); } \ +#define WOLF_REGISTER_SENSOR(SensorType) \ + namespace{ const bool WOLF_UNUSED SensorType##Registered = \ + FactorySensor::get().registerCreator(#SensorType, SensorType::create); } \ typedef Factory<SensorBase, const std::string&, - const ParamsServer&> AutoConfSensorFactory; + const ParamsServer&> AutoConfFactorySensor; template<> -inline std::string AutoConfSensorFactory::getClass() +inline std::string AutoConfFactorySensor::getClass() { - return "AutoConfSensorFactory"; + return "AutoConfFactorySensor"; } -#define WOLF_REGISTER_SENSOR_AUTO(SensorType, SensorName) \ - namespace{ const bool WOLF_UNUSED SensorName##AutoConfRegistered = \ - AutoConfSensorFactory::get().registerCreator(SensorType, SensorName::create); } \ +#define WOLF_REGISTER_SENSOR_AUTO(SensorType) \ + namespace{ const bool WOLF_UNUSED SensorType##AutoConfRegistered = \ + AutoConfFactorySensor::get().registerCreator(#SensorType, SensorType::create); } \ } /* namespace wolf */ diff --git a/include/core/solver/solver_factory.h b/include/core/solver/factory_solver.h similarity index 83% rename from include/core/solver/solver_factory.h rename to include/core/solver/factory_solver.h index d80fe24f78ddaa91a44e7821f2dc0a55117b8dcf..b055217828d887169f8e732138b43a4f2067c62a 100644 --- a/include/core/solver/solver_factory.h +++ b/include/core/solver/factory_solver.h @@ -1,12 +1,12 @@ /** - * \file solver_factory.h + * \file factory_solver.h * * Created on: Dec 17, 2018 * \author: jcasals */ -#ifndef SOLVER_FACTORY_H_ -#define SOLVER_FACTORY_H_ +#ifndef FACTORY_SOLVER_H_ +#define FACTORY_SOLVER_H_ namespace wolf { @@ -47,17 +47,17 @@ namespace wolf * - Write a sensor creator for SensorCamera (example). * * #### Accessing the factory - * The SensorFactory class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application. + * The FactorySensor class is a <a href="http://stackoverflow.com/questions/1008019/c-singleton-design-pattern#1008289">singleton</a>: it can only exist once in your application. * To obtain an instance of it, use the static method get(), * * \code - * SensorFactory::get() + * FactorySensor::get() * \endcode * * You can then call the methods you like, e.g. to create a sensor, you type: * * \code - * SensorFactory::get().create(...); // see below for creating sensors ... + * FactorySensor::get().create(...); // see below for creating sensors ... * \endcode * * #### Registering sensor creators @@ -69,7 +69,7 @@ namespace wolf * that knows how to create your specific sensor, e.g.: * * \code - * SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * \endcode * * The method SensorCamera::create() exists in the SensorCamera class as a static method. @@ -89,7 +89,7 @@ namespace wolf * For example, in sensor_camera.cpp we find the line: * * \code - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * \endcode * * which is a static invocation (i.e., it is placed at global scope outside of the SensorCamera class). @@ -99,7 +99,7 @@ namespace wolf * The method unregisterCreator() unregisters the SensorXxx::create() method. It only needs to be passed the string of the sensor type. * * \code - * SensorFactory::get().unregisterCreator("CAMERA"); + * FactorySensor::get().unregisterCreator("CAMERA"); * \endcode * * #### Creating sensors @@ -109,15 +109,15 @@ namespace wolf * To create e.g. a SensorCamera, you type: * * \code - * SensorFactory::get().create("CAMERA", "Front-left camera", extrinsics, intrinsics_ptr); + * FactorySensor::get().create("CAMERA", "Front-left camera", extrinsics, intrinsics_ptr); * \endcode * * where ABSOLUTELY ALL input parameters are important. In particular, the sensor name "Front-left camera" will be used to identify this camera * and to assign it the appropriate processors. DO NOT USE IT WITH DUMMY PARAMETERS! * * #### See also - * - ParamsSensorFactory: to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. - * - ProcessorFactory: to create processors that will be bound to sensors. + * - FactoryParamsSensor: to create intrinsic structs deriving from ParamsSensorBase directly from YAML files. + * - FactoryProcessor: to create processors that will be bound to sensors. * - Problem::installSensor() : to install sensors in WOLF Problem. * * #### Example 1: writing a specific sensor creator @@ -148,14 +148,14 @@ namespace wolf * Put the code either at global scope (you must define a dummy variable for this), * \code * namespace { - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * } * main () { ... } * \endcode * or inside your main(), where a direct call is possible: * \code * main () { - * SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * ... * } * \endcode @@ -164,7 +164,7 @@ namespace wolf * Put the code at the last line of the sensor_xxx.cpp file, * \code * namespace { - * const bool registered_camera = SensorFactory::get().registerCreator("CAMERA", SensorCamera::create); + * const bool registered_camera = FactorySensor::get().registerCreator("CAMERA", SensorCamera::create); * } * \endcode * Automatic registration is recommended in wolf, and implemented in the classes shipped with it. @@ -174,7 +174,7 @@ namespace wolf * We finally provide the necessary steps to create a sensor of class SensorCamera in our application: * * \code - * #include "sensor_factory.h" + * #include "factory_sensor.h" * #include "sensor_camera.h" // provides SensorCamera * * // Note: SensorCamera::create() is already registered, automatically. @@ -189,10 +189,10 @@ namespace wolf * // a pointer to the intrinsics struct: * * Eigen::VectorXd extrinsics_1(7); // give it some values... - * ParamsSensorCamera intrinsics_1({...}); // see ParamsSensorFactory to fill in the derived struct + * ParamsSensorCamera intrinsics_1({...}); // see FactoryParamsSensor to fill in the derived struct * * SensorBasePtr camera_1_ptr = - * SensorFactory::get().create ( "CAMERA" , "Front-left camera" , extrinsics_1 , &intrinsics_1 ); + * FactorySensor::get().create ( "CAMERA" , "Front-left camera" , extrinsics_1 , &intrinsics_1 ); * * // A second camera... with a different name! * @@ -200,7 +200,7 @@ namespace wolf * ParamsSensorCamera intrinsics_2({...}); * * SensorBasePtr camera_2_ptr = - * SensorFactory::get().create( "CAMERA" , "Front-right camera" , extrinsics_2 , &intrinsics_2 ); + * FactorySensor::get().create( "CAMERA" , "Front-right camera" , extrinsics_2 , &intrinsics_2 ); * * return 0; * } @@ -211,17 +211,17 @@ namespace wolf typedef Factory<SolverManager, const ProblemPtr&, - const ParamsServer&> SolverFactory; + const ParamsServer&> FactorySolver; template<> -inline std::string SolverFactory::getClass() +inline std::string FactorySolver::getClass() { - return "SolverFactory"; + return "FactorySolver"; } -#define WOLF_REGISTER_SOLVER(SolverType, SolverName) \ - namespace{ const bool WOLF_UNUSED SolverName##Registered = \ - wolf::SolverFactory::get().registerCreator(SolverType, SolverName::create); } \ +#define WOLF_REGISTER_SOLVER(SolverType) \ + namespace{ const bool WOLF_UNUSED SolverType##Registered = \ + wolf::FactorySolver::get().registerCreator(#SolverType, SolverType::create); } \ } /* namespace wolf */ diff --git a/include/core/tree_manager/factory_tree_manager.h b/include/core/tree_manager/factory_tree_manager.h new file mode 100644 index 0000000000000000000000000000000000000000..91f2b9531d91bdad952760a0670ceece4240e86a --- /dev/null +++ b/include/core/tree_manager/factory_tree_manager.h @@ -0,0 +1,61 @@ +#ifndef FACTORY_TREE_MANAGER_H_ +#define FACTORY_TREE_MANAGER_H_ + +namespace wolf +{ +class TreeManagerBase; +struct ParamsTreeManagerBase; +} + +// wolf +#include "core/common/factory.h" + +// std + +namespace wolf +{ +/** \brief TreeManager factory class + * TODO + */ + +// ParamsTreeManager factory +struct ParamsTreeManagerBase; +typedef Factory<ParamsTreeManagerBase, + const std::string&> FactoryParamsTreeManager; +template<> +inline std::string FactoryParamsTreeManager::getClass() +{ + return "FactoryParamsTreeManager"; +} + +// TreeManager factory +typedef Factory<TreeManagerBase, + const std::string&, + const ParamsTreeManagerBasePtr> FactoryTreeManager; +template<> +inline std::string FactoryTreeManager::getClass() +{ + return "FactoryTreeManager"; +} + +#define WOLF_REGISTER_TREE_MANAGER(TreeManagerType) \ + namespace{ const bool WOLF_UNUSED TreeManagerType##Registered = \ + wolf::FactoryTreeManager::get().registerCreator(#TreeManagerType, TreeManagerType::create); } \ + +typedef Factory<TreeManagerBase, + const std::string&, + const ParamsServer&> AutoConfFactoryTreeManager; +template<> +inline std::string AutoConfFactoryTreeManager::getClass() +{ + return "AutoConfFactoryTreeManager"; +} + + +#define WOLF_REGISTER_TREE_MANAGER_AUTO(TreeManagerType) \ + namespace{ const bool WOLF_UNUSED TreeManagerType##AutoConfRegistered = \ + wolf::AutoConfFactoryTreeManager::get().registerCreator(#TreeManagerType, TreeManagerType::create); } \ + +} /* namespace wolf */ + +#endif /* FACTORY_TREE_MANAGER_H_ */ diff --git a/include/core/tree_manager/tree_manager_base.h b/include/core/tree_manager/tree_manager_base.h new file mode 100644 index 0000000000000000000000000000000000000000..53ef9825ab029933b8c58e497e792d4f101c0406 --- /dev/null +++ b/include/core/tree_manager/tree_manager_base.h @@ -0,0 +1,82 @@ +#ifndef INCLUDE_TREE_MANAGER_BASE_H_ +#define INCLUDE_TREE_MANAGER_BASE_H_ + +// Wolf includes +#include "core/common/wolf.h" +#include "core/common/node_base.h" +#include "core/common/params_base.h" +#include "core/problem/problem.h" + +namespace wolf +{ +/* + * Macro for defining Autoconf tree manager creator for WOLF's high level API. + * + * Place a call to this macro inside your class declaration (in the tree_manager_class.h file), + * preferably just after the constructors. + * + * In order to use this macro, the derived processor class, ProcessorClass, + * must have a constructor available with the API: + * + * TreeManagerClass(const ParamsTreeManagerPtr _params); + */ +#define WOLF_TREE_MANAGER_CREATE(TreeManagerClass, ParamsTreeManagerClass) \ +static TreeManagerBasePtr create(const std::string& _unique_name, \ + const ParamsServer& _server) \ +{ \ + auto params = std::make_shared<ParamsTreeManagerClass>(_unique_name, _server); \ + \ + auto tree_manager = std::make_shared<TreeManagerClass>(params); \ + \ + tree_manager ->setName(_unique_name); \ + \ + return tree_manager; \ +} \ +static TreeManagerBasePtr create(const std::string& _unique_name, \ + const ParamsTreeManagerBasePtr _params) \ +{ \ + auto params = std::static_pointer_cast<ParamsTreeManagerClass>(_params); \ + \ + auto tree_manager = std::make_shared<TreeManagerClass>(params); \ + \ + tree_manager ->setName(_unique_name); \ + \ + return tree_manager; \ +} \ + +struct ParamsTreeManagerBase : public ParamsBase +{ + std::string prefix = "problem/tree_manager"; + ParamsTreeManagerBase() = default; + ParamsTreeManagerBase(std::string _unique_name, const ParamsServer& _server): + ParamsBase(_unique_name, _server) + { + } + + virtual ~ParamsTreeManagerBase() = default; + + std::string print() const + { + return ParamsBase::print() + "\n"; + } +}; + +class TreeManagerBase : public NodeBase +{ + public: + TreeManagerBase(const std::string& _type, ParamsTreeManagerBasePtr _params) : + NodeBase("TREE_MANAGER", _type), + params_(_params) + {} + + virtual ~TreeManagerBase(){} + + virtual void keyFrameCallback(FrameBasePtr _key_frame) = 0; + + protected: + ParamsTreeManagerBasePtr params_; +}; + +} /* namespace wolf */ + +#endif /* INCLUDE_TREE_MANAGER_BASE_H_ */ diff --git a/include/core/tree_manager/tree_manager_sliding_window.h b/include/core/tree_manager/tree_manager_sliding_window.h new file mode 100644 index 0000000000000000000000000000000000000000..8b2deec3b4fe8de046e1dd6c65c646be1a773727 --- /dev/null +++ b/include/core/tree_manager/tree_manager_sliding_window.h @@ -0,0 +1,54 @@ +#ifndef INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_ +#define INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_ + +#include "../tree_manager/tree_manager_base.h" + +namespace wolf +{ + +WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerSlidingWindow) +WOLF_PTR_TYPEDEFS(TreeManagerSlidingWindow) + +struct ParamsTreeManagerSlidingWindow : public ParamsTreeManagerBase +{ + ParamsTreeManagerSlidingWindow() = default; + ParamsTreeManagerSlidingWindow(std::string _unique_name, const wolf::ParamsServer & _server) : + ParamsTreeManagerBase(_unique_name, _server) + { + n_key_frames = _server.getParam<unsigned int>(prefix + "/n_key_frames"); + fix_first_key_frame = _server.getParam<bool> (prefix + "/fix_first_key_frame"); + viral_remove_empty_parent = _server.getParam<bool> (prefix + "/viral_remove_empty_parent"); + } + std::string print() const + { + return "\n" + ParamsTreeManagerBase::print() + "\n" + + "n_key_frames: " + std::to_string(n_key_frames) + "\n" + + "fix_first_key_frame: " + std::to_string(fix_first_key_frame) + "\n" + + "viral_remove_empty_parent: " + std::to_string(viral_remove_empty_parent) + "\n"; + } + + unsigned int n_key_frames; + bool fix_first_key_frame; + bool viral_remove_empty_parent; +}; + +class TreeManagerSlidingWindow : public TreeManagerBase +{ + public: + TreeManagerSlidingWindow(ParamsTreeManagerSlidingWindowPtr _params) : + TreeManagerBase("TreeManagerSlidingWindow", _params), + params_sw_(_params) + {}; + WOLF_TREE_MANAGER_CREATE(TreeManagerSlidingWindow, ParamsTreeManagerSlidingWindow) + + virtual ~TreeManagerSlidingWindow(){} + + virtual void keyFrameCallback(FrameBasePtr _key_frame) override; + + protected: + ParamsTreeManagerSlidingWindowPtr params_sw_; +}; + +} /* namespace wolf */ + +#endif /* INCLUDE_TREE_MANAGER_SLIDING_WINDOW_H_ */ diff --git a/src/ceres_wrapper/ceres_manager.cpp b/src/ceres_wrapper/ceres_manager.cpp index 0d8cba6f97cb7e2c2cdf067e7ebcb65d8ac79c10..0d0c6537fedfc21dec63760d877fb56386885adf 100644 --- a/src/ceres_wrapper/ceres_manager.cpp +++ b/src/ceres_wrapper/ceres_manager.cpp @@ -515,8 +515,8 @@ const Eigen::SparseMatrixd CeresManager::computeHessian() const } // namespace wolf -#include "core/solver/solver_factory.h" +#include "core/solver/factory_solver.h" namespace wolf { - WOLF_REGISTER_SOLVER("CERES", CeresManager) + WOLF_REGISTER_SOLVER(CeresManager) } // namespace wolf diff --git a/src/factor/factor_base.cpp b/src/factor/factor_base.cpp index 72b36c519a0d8d0ce2cb7ac4748e0dfc110026d0..2b6fb54a6710fed79e8c608dafab1f7caaaab3af 100644 --- a/src/factor/factor_base.cpp +++ b/src/factor/factor_base.cpp @@ -79,7 +79,7 @@ void FactorBase::remove(bool viral_remove_empty_parent) f->remove(viral_remove_empty_parent); // remove upstream } // add factor to be removed from solver - if (getProblem() != nullptr) + if (getProblem() != nullptr and this->getStatus() == FAC_ACTIVE) getProblem()->notifyFactor(this_fac,REMOVE); // remove other: {Frame, Capture, Feature, Landmark} diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp index c0f4d310e1062c9a68ea94a0ee0b70f912cd9d15..217bfb8d4232a40af88670fac91a52b161377d32 100644 --- a/src/frame/frame_base.cpp +++ b/src/frame/frame_base.cpp @@ -12,7 +12,7 @@ namespace wolf { unsigned int FrameBase::frame_id_count_ = 0; FrameBase::FrameBase(const TimeStamp& _ts, StateBlockPtr _p_ptr, StateBlockPtr _o_ptr, StateBlockPtr _v_ptr) : - NodeBase("FRAME", "Base"), + NodeBase("FRAME", "FrameBase"), HasStateBlocks(""), trajectory_ptr_(), frame_id_(++frame_id_count_), @@ -34,7 +34,7 @@ FrameBase::FrameBase(const TimeStamp& _ts, StateBlockPtr _p_ptr, StateBlockPtr _ } FrameBase::FrameBase(const FrameType & _tp, const TimeStamp& _ts, StateBlockPtr _p_ptr, StateBlockPtr _o_ptr, StateBlockPtr _v_ptr) : - NodeBase("FRAME", "Base"), + NodeBase("FRAME", "FrameBase"), HasStateBlocks(""), trajectory_ptr_(), frame_id_(++frame_id_count_), @@ -56,7 +56,7 @@ FrameBase::FrameBase(const FrameType & _tp, const TimeStamp& _ts, StateBlockPtr } FrameBase::FrameBase(const std::string _frame_structure, const SizeEigen _dim, const FrameType & _tp, const TimeStamp& _ts, const Eigen::VectorXd& _x) : - NodeBase("FRAME", "Base"), + NodeBase("FRAME", "FrameBase"), HasStateBlocks(_frame_structure), trajectory_ptr_(), frame_id_(++frame_id_count_), diff --git a/src/hardware/hardware_base.cpp b/src/hardware/hardware_base.cpp index adda7984748ebfb2fa6e40517f0d1bedc331efd2..8995fc7830b1b540c055ee1bc6aa4ca2c01c33ed 100644 --- a/src/hardware/hardware_base.cpp +++ b/src/hardware/hardware_base.cpp @@ -4,7 +4,7 @@ namespace wolf { HardwareBase::HardwareBase() : - NodeBase("HARDWARE", "Base") + NodeBase("HARDWARE", "HardwareBase") { // std::cout << "constructed H" << std::endl; } diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp index 263f205c1724fef3569116ce31b07e63214b166e..847c01e36d9986827e8fd16a1a4ba8d32ebb9338 100644 --- a/src/problem/problem.cpp +++ b/src/problem/problem.cpp @@ -11,18 +11,19 @@ #include "core/factor/factor_base.h" #include "core/factor/factor_block_absolute.h" #include "core/factor/factor_quaternion_absolute.h" -#include "core/sensor/sensor_factory.h" -#include "core/processor/processor_factory.h" +#include "core/sensor/factory_sensor.h" +#include "core/processor/factory_processor.h" #include "core/state_block/state_block.h" #include "core/state_block/state_quaternion.h" #include "core/state_block/state_angle.h" +#include "core/tree_manager/factory_tree_manager.h" +#include "core/tree_manager/tree_manager_base.h" #include "core/utils/logging.h" #include "core/utils/params_server.h" #include "core/utils/loader.h" #include "core/utils/check_log.h" #include "core/math/covariance.h" - // IRI libs includes // C++ includes @@ -34,10 +35,12 @@ #include <vector> #include <unordered_set> + namespace wolf { Problem::Problem(const std::string& _frame_structure, SizeEigen _dim) : + tree_manager_(nullptr), hardware_ptr_(std::make_shared<HardwareBase>()), trajectory_ptr_(std::make_shared<TrajectoryBase>(_frame_structure)), map_ptr_(std::make_shared<MapBase>()), @@ -157,6 +160,12 @@ ProblemPtr Problem::autoSetup(ParamsServer &_server) procesorMap.insert(std::pair<std::string, ProcessorBasePtr>(prc["name"], problem->installProcessor(prc["type"], prc["name"], prc["sensor_name"], _server))); } + // Tree manager + std::string tree_manager_type = _server.getParam<std::string>("problem/tree_manager/type"); + WOLF_TRACE("Tree Manager Type: ", tree_manager_type); + if (tree_manager_type != "None" and tree_manager_type != "none") + problem->setTreeManager(AutoConfFactoryTreeManager::get().create(tree_manager_type, "tree manager", _server)); + // Prior std::string prior_mode = _server.getParam<std::string>("problem/prior/mode"); if (prior_mode == "nothing") @@ -191,7 +200,7 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, // const Eigen::VectorXd& _extrinsics, // ParamsSensorBasePtr _intrinsics) { - SensorBasePtr sen_ptr = SensorFactory::get().create(_sen_type, _unique_sensor_name, _extrinsics, _intrinsics); + SensorBasePtr sen_ptr = FactorySensor::get().create(_sen_type, _unique_sensor_name, _extrinsics, _intrinsics); sen_ptr->link(getHardware()); return sen_ptr; } @@ -206,7 +215,7 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, // if (_intrinsics_filename != "") { assert(file_exists(_intrinsics_filename) && "Cannot install sensor: intrinsics' YAML file does not exist."); - ParamsSensorBasePtr intr_ptr = ParamsSensorFactory::get().create(_sen_type, _intrinsics_filename); + ParamsSensorBasePtr intr_ptr = FactoryParamsSensor::get().create(_sen_type, _intrinsics_filename); return installSensor(_sen_type, _unique_sensor_name, _extrinsics, intr_ptr); } else @@ -218,7 +227,7 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, // const std::string& _unique_sensor_name, // const ParamsServer& _server) { - SensorBasePtr sen_ptr = AutoConfSensorFactory::get().create(_sen_type, _unique_sensor_name, _server); + SensorBasePtr sen_ptr = AutoConfFactorySensor::get().create(_sen_type, _unique_sensor_name, _server); sen_ptr->link(getHardware()); return sen_ptr; } @@ -226,7 +235,7 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, // ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // const std::string& _unique_processor_name, // SensorBasePtr _corresponding_sensor_ptr, // - ProcessorParamsBasePtr _prc_params) + ParamsProcessorBasePtr _prc_params) { if (_corresponding_sensor_ptr == nullptr) { @@ -235,7 +244,7 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // return ProcessorBasePtr(); } - ProcessorBasePtr prc_ptr = ProcessorFactory::get().create(_prc_type, _unique_processor_name, _prc_params); + ProcessorBasePtr prc_ptr = FactoryProcessor::get().create(_prc_type, _unique_processor_name, _prc_params); //Dimension check int prc_dim = prc_ptr->getDim(); @@ -261,7 +270,7 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // else { assert(file_exists(_params_filename) && "Cannot install processor: parameters' YAML file does not exist."); - ProcessorParamsBasePtr prc_params = ProcessorParamsFactory::get().create(_prc_type, _params_filename); + ParamsProcessorBasePtr prc_params = FactoryParamsProcessor::get().create(_prc_type, _params_filename); return installProcessor(_prc_type, _unique_processor_name, sen_ptr, prc_params); } } @@ -275,7 +284,7 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // if (sen_ptr == nullptr) throw std::runtime_error("Cannot bind processor. Reason: Sensor \"" + _corresponding_sensor_name + "\" not found. Check sensor name, it must match in sensor and processor!"); - ProcessorBasePtr prc_ptr = AutoConfProcessorFactory::get().create(_prc_type, _unique_processor_name, _server); + ProcessorBasePtr prc_ptr = AutoConfFactoryProcessor::get().create(_prc_type, _unique_processor_name, _server); //Dimension check int prc_dim = prc_ptr->getDim(); @@ -474,12 +483,22 @@ std::string Problem::getFrameStructure() const return frame_structure_; } +void Problem::setTreeManager(TreeManagerBasePtr _gm) +{ + if (tree_manager_) + tree_manager_->setProblem(nullptr); + tree_manager_ = _gm; + tree_manager_->setProblem(shared_from_this()); + +} + void Problem::addProcessorIsMotion(IsMotionPtr _processor_motion_ptr) { processor_is_motion_list_.push_back(_processor_motion_ptr); } -void Problem::clearProcessorIsMotion(IsMotionPtr proc){ +void Problem::clearProcessorIsMotion(IsMotionPtr proc) +{ auto it = std::find(processor_is_motion_list_.begin(), processor_is_motion_list_.end(), proc); if (it != processor_is_motion_list_.end()){ processor_is_motion_list_.erase(it); @@ -532,6 +551,10 @@ void Problem::keyFrameCallback(FrameBasePtr _keyframe_ptr, ProcessorBasePtr _pro " microseconds: ", duration.count()); #endif } + + // notify tree manager + if (tree_manager_) + tree_manager_->keyFrameCallback(_keyframe_ptr); } bool Problem::permitAuxFrame(ProcessorBasePtr _processor_ptr) const diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp index 8c3ba79053e98cc77e9c80c2cb6bebc64915cc91..364dc699740595f3f36a8af86e4d8ea290af585c 100644 --- a/src/processor/processor_base.cpp +++ b/src/processor/processor_base.cpp @@ -7,7 +7,7 @@ namespace wolf { unsigned int ProcessorBase::processor_id_count_ = 0; -ProcessorBase::ProcessorBase(const std::string& _type, int _dim, ProcessorParamsBasePtr _params) : +ProcessorBase::ProcessorBase(const std::string& _type, int _dim, ParamsProcessorBasePtr _params) : NodeBase("PROCESSOR", _type), processor_id_(++processor_id_count_), params_(_params), diff --git a/src/processor/processor_diff_drive.cpp b/src/processor/processor_diff_drive.cpp index d80f89ccee5cddff4aab89ec3737c5b518463e7e..1bd0ca0ef6cacb1c90d0a7cdf843593bb38ac5ab 100644 --- a/src/processor/processor_diff_drive.cpp +++ b/src/processor/processor_diff_drive.cpp @@ -16,7 +16,7 @@ namespace wolf { -ProcessorDiffDrive::ProcessorDiffDrive(const ProcessorParamsDiffDrivePtr _params) : +ProcessorDiffDrive::ProcessorDiffDrive(const ParamsProcessorDiffDrivePtr _params) : ProcessorOdom2d(_params), params_prc_diff_drv_selfcal_(_params), radians_per_tick_(0.0) // This param needs further initialization. See this->configure(sensor). @@ -173,10 +173,10 @@ FactorBasePtr ProcessorDiffDrive::emplaceFactor(FeatureBasePtr _feature, } /* namespace wolf */ -// Register in the ProcessorFactory -#include "core/processor/processor_factory.h" +// Register in the FactoryProcessor +#include "core/processor/factory_processor.h" namespace wolf { -WOLF_REGISTER_PROCESSOR("ProcessorDiffDrive", ProcessorDiffDrive); -WOLF_REGISTER_PROCESSOR_AUTO("ProcessorDiffDrive", ProcessorDiffDrive); +WOLF_REGISTER_PROCESSOR(ProcessorDiffDrive); +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorDiffDrive); } // namespace wolf diff --git a/src/processor/processor_loopclosure.cpp b/src/processor/processor_loopclosure.cpp index 3517f9e20d5bb55c40ebde25636411c5be02d9cb..9d8589a239466f2ba7bbd30473186c7dbdba52f7 100644 --- a/src/processor/processor_loopclosure.cpp +++ b/src/processor/processor_loopclosure.cpp @@ -11,7 +11,7 @@ namespace wolf { -ProcessorLoopClosure::ProcessorLoopClosure(const std::string& _type, int _dim, ProcessorParamsLoopClosurePtr _params_loop_closure): +ProcessorLoopClosure::ProcessorLoopClosure(const std::string& _type, int _dim, ParamsProcessorLoopClosurePtr _params_loop_closure): ProcessorBase(_type, _dim, _params_loop_closure), params_loop_closure_(_params_loop_closure) { diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp index b9c5182f9bbe1abd2f00ed4340b603f8233931bc..6dfb753acd6d4e2693a6c99be5e14be8239bdd06 100644 --- a/src/processor/processor_motion.cpp +++ b/src/processor/processor_motion.cpp @@ -1,3 +1,10 @@ +/** + * \file processor_motion.cpp + * + * Created on: 15/03/2016 + * \author: jsola + */ + #include "core/processor/processor_motion.h" @@ -14,7 +21,7 @@ ProcessorMotion::ProcessorMotion(const std::string& _type, SizeEigen _delta_cov_size, SizeEigen _data_size, SizeEigen _calib_size, - ProcessorParamsMotionPtr _params_motion) : + ParamsProcessorMotionPtr _params_motion) : ProcessorBase(_type, _dim, _params_motion), params_motion_(_params_motion), processing_step_(RUNNING_WITHOUT_KF), diff --git a/src/processor/processor_odom_2d.cpp b/src/processor/processor_odom_2d.cpp index 929c1ed7ceb825fdaa265a1af592fa8125832789..4a126d901eb291a9d5fc8537b5429b294bfdc025 100644 --- a/src/processor/processor_odom_2d.cpp +++ b/src/processor/processor_odom_2d.cpp @@ -5,7 +5,7 @@ namespace wolf { -ProcessorOdom2d::ProcessorOdom2d(ProcessorParamsOdom2dPtr _params) : +ProcessorOdom2d::ProcessorOdom2d(ParamsProcessorOdom2dPtr _params) : ProcessorMotion("ProcessorOdom2d", "PO", 2, 3, 3, 3, 2, 0, _params), params_odom_2d_(_params) { @@ -170,9 +170,9 @@ FeatureBasePtr ProcessorOdom2d::emplaceFeature(CaptureMotionPtr _capture_motion) } /* namespace wolf */ -// Register in the ProcessorFactory -#include "core/processor/processor_factory.h" +// Register in the FactoryProcessor +#include "core/processor/factory_processor.h" namespace wolf { -WOLF_REGISTER_PROCESSOR("ProcessorOdom2d", ProcessorOdom2d); -WOLF_REGISTER_PROCESSOR_AUTO("ProcessorOdom2d", ProcessorOdom2d); +WOLF_REGISTER_PROCESSOR(ProcessorOdom2d); +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorOdom2d); } // namespace wolf diff --git a/src/processor/processor_odom_3d.cpp b/src/processor/processor_odom_3d.cpp index 3e1268eb1d705b3a335d9c8d9389e0c9449ebba1..71c77e1e16f9cc3b5b5b76885b64cd67b891bb7b 100644 --- a/src/processor/processor_odom_3d.cpp +++ b/src/processor/processor_odom_3d.cpp @@ -2,7 +2,7 @@ namespace wolf { -ProcessorOdom3d::ProcessorOdom3d(ProcessorParamsOdom3dPtr _params) : +ProcessorOdom3d::ProcessorOdom3d(ParamsProcessorOdom3dPtr _params) : ProcessorMotion("ProcessorOdom3d", "PO", 3, 7, 7, 6, 6, 0, _params), params_odom_3d_ (_params), k_disp_to_disp_ (0), @@ -246,9 +246,9 @@ FactorBasePtr ProcessorOdom3d::emplaceFactor(FeatureBasePtr _feature_motion, Cap } -// Register in the SensorFactory -#include "core/processor/processor_factory.h" +// Register in the FactorySensor +#include "core/processor/factory_processor.h" namespace wolf { -WOLF_REGISTER_PROCESSOR("ProcessorOdom3d", ProcessorOdom3d); -WOLF_REGISTER_PROCESSOR_AUTO("ProcessorOdom3d", ProcessorOdom3d); +WOLF_REGISTER_PROCESSOR(ProcessorOdom3d); +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorOdom3d); } // namespace wolf diff --git a/src/processor/processor_tracker.cpp b/src/processor/processor_tracker.cpp index 59671c2308468052d364f3e12bff8aa4b828c625..9750daa633b6a12a95ddf8e4034a792b816104f3 100644 --- a/src/processor/processor_tracker.cpp +++ b/src/processor/processor_tracker.cpp @@ -16,7 +16,7 @@ namespace wolf ProcessorTracker::ProcessorTracker(const std::string& _type, int _dim, - ProcessorParamsTrackerPtr _params_tracker) : + ParamsProcessorTrackerPtr _params_tracker) : ProcessorBase(_type, _dim, _params_tracker), params_tracker_(_params_tracker), processing_step_(FIRST_TIME_WITHOUT_PACK), @@ -170,7 +170,7 @@ void ProcessorTracker::processCapture(CaptureBasePtr _incoming_ptr) // process processNew(params_tracker_->max_new_features); - //TODO abort KF if last_ptr_->getFeatureList().size() < params_tracker_->min_features_for_keyframe + //TODO abort KF if known_features_last_.size() < params_tracker_->min_features_for_keyframe // We create a KF // set KF on last diff --git a/src/processor/processor_tracker_feature.cpp b/src/processor/processor_tracker_feature.cpp index 211a1aba12b12ecfb10afea00041cf82e07493be..bfe2c6cd1ac780d058421d96c64e745b378c3b88 100644 --- a/src/processor/processor_tracker_feature.cpp +++ b/src/processor/processor_tracker_feature.cpp @@ -12,7 +12,7 @@ namespace wolf ProcessorTrackerFeature::ProcessorTrackerFeature(const std::string& _type, int _dim, - ProcessorParamsTrackerFeaturePtr _params_tracker_feature) : + ParamsProcessorTrackerFeaturePtr _params_tracker_feature) : ProcessorTracker(_type, _dim, _params_tracker_feature), params_tracker_feature_(_params_tracker_feature) { @@ -47,7 +47,10 @@ unsigned int ProcessorTrackerFeature::processNew(const int& _max_new_features) // fill the track matrix for (auto ftr : new_features_last_) + { + assert(std::find(known_features_last_.begin(), known_features_last_.end(), ftr) == known_features_last_.end() && "detectNewFeatures() provided a new feature that is already in known_features_last_`"); track_matrix_.newTrack(ftr); + } // Track new features from last to incoming. This will append new correspondences to matches_last_incoming trackFeatures(new_features_last_, @@ -72,21 +75,21 @@ unsigned int ProcessorTrackerFeature::processNew(const int& _max_new_features) unsigned int ProcessorTrackerFeature::processKnown() { - assert(incoming_ptr_->getFeatureList().size() == 0 - && "In ProcessorTrackerFeature::processKnown(): incoming_ptr_ feature list must be empty before processKnown()"); + //assert(incoming_ptr_->getFeatureList().size() == 0 + // && "In ProcessorTrackerFeature::processKnown(): incoming_ptr_ feature list must be empty before processKnown()"); // clear list of known features matches_last_from_incoming_.clear(); known_features_incoming_.clear(); - if (!last_ptr_ || last_ptr_->getFeatureList().empty()) + if (!last_ptr_ || known_features_last_.empty()) { WOLF_TRACE("Empty last feature list, returning..."); return 0; } // Track features from last_ptr_ to incoming_ptr_ - trackFeatures(last_ptr_->getFeatureList(), + trackFeatures(known_features_last_, incoming_ptr_, known_features_incoming_, matches_last_from_incoming_); @@ -132,6 +135,9 @@ void ProcessorTrackerFeature::advanceDerived() { // Reset here the list of correspondences. matches_last_from_incoming_.clear(); + known_features_last_ = std::move(known_features_incoming_); + //new_features_incoming should be zero! + //known_features_last_.splice(new_features_incoming_); // // remove last from track matrix in case you want to have only KF in the track matrix // track_matrix_.remove(last_ptr_); @@ -141,6 +147,8 @@ void ProcessorTrackerFeature::resetDerived() { // Reset here the list of correspondences. matches_last_from_incoming_.clear(); + known_features_last_ = std::move(known_features_incoming_); + known_features_last_.splice(known_features_last_.end(), new_features_incoming_); // Debug //for (auto const & pair_trkid_pair : track_matrix_.matches(origin_ptr_, last_ptr_)) diff --git a/src/processor/processor_tracker_landmark.cpp b/src/processor/processor_tracker_landmark.cpp index 7035dd38de2fcfb177deef2f4ed30d28fcdd92cf..0e593a917d9c7715cb16a62a43154cbd53992d58 100644 --- a/src/processor/processor_tracker_landmark.cpp +++ b/src/processor/processor_tracker_landmark.cpp @@ -14,7 +14,7 @@ namespace wolf { ProcessorTrackerLandmark::ProcessorTrackerLandmark(const std::string& _type, - ProcessorParamsTrackerLandmarkPtr _params_tracker_landmark) : + ParamsProcessorTrackerLandmarkPtr _params_tracker_landmark) : ProcessorTracker(_type, 0, _params_tracker_landmark), params_tracker_landmark_(_params_tracker_landmark) { @@ -30,6 +30,8 @@ void ProcessorTrackerLandmark::advanceDerived() { matches_landmark_from_last_ = std::move(matches_landmark_from_incoming_); new_features_last_ = std::move(new_features_incoming_); + known_features_last_ = std::move(known_features_incoming_); + known_features_last_.splice(known_features_last_.end(), new_features_incoming_); matches_landmark_from_incoming_.clear(); new_features_incoming_.clear(); @@ -40,6 +42,8 @@ void ProcessorTrackerLandmark::resetDerived() { matches_landmark_from_last_ = std::move(matches_landmark_from_incoming_); new_features_last_ = std::move(new_features_incoming_); + known_features_last_ = std::move(known_features_incoming_); + known_features_last_.splice(known_features_last_.end(), new_features_incoming_); matches_landmark_from_incoming_.clear(); new_features_incoming_.clear(); @@ -129,15 +133,17 @@ void ProcessorTrackerLandmark::emplaceNewLandmarks() void ProcessorTrackerLandmark::establishFactors() { - // Loop all features in last_ptr_ - for (auto last_feature : last_ptr_->getFeatureList()) - { - assert(matches_landmark_from_last_.count(last_feature) == 1); + // Loop all features tracked in last_ptr_ (two lists known_features_last_ and new_features_last_) + std::list<FeatureBasePtrList> both_lists{known_features_last_, new_features_last_}; + for (auto feature_list : both_lists) + for (auto last_feature : feature_list) + { + assert(matches_landmark_from_last_.count(last_feature) == 1); - FactorBasePtr fac_ptr = emplaceFactor(last_feature, matches_landmark_from_last_[last_feature]->landmark_ptr_); + FactorBasePtr fac_ptr = emplaceFactor(last_feature, matches_landmark_from_last_[last_feature]->landmark_ptr_); - assert(fac_ptr->getFeature() != nullptr && "not linked factor returned by emplaceFactor()"); - } + assert(fac_ptr->getFeature() != nullptr && "not linked factor returned by emplaceFactor()"); + } } } // namespace wolf diff --git a/src/sensor/sensor_diff_drive.cpp b/src/sensor/sensor_diff_drive.cpp index ae48fcceb261da67fa2b940aa06248b3d5006e48..03634eb0938d9ae7c6a20b5d5a5d11a201989101 100644 --- a/src/sensor/sensor_diff_drive.cpp +++ b/src/sensor/sensor_diff_drive.cpp @@ -47,10 +47,10 @@ SensorDiffDrive::~SensorDiffDrive() } /* namespace wolf */ -// Register in the SensorFactory -#include "core/sensor/sensor_factory.h" +// Register in the FactorySensor +#include "core/sensor/factory_sensor.h" namespace wolf { -WOLF_REGISTER_SENSOR("SensorDiffDrive", SensorDiffDrive); -WOLF_REGISTER_SENSOR_AUTO("SensorDiffDrive", SensorDiffDrive); +WOLF_REGISTER_SENSOR(SensorDiffDrive); +WOLF_REGISTER_SENSOR_AUTO(SensorDiffDrive); } // namespace wolf diff --git a/src/sensor/sensor_odom_2d.cpp b/src/sensor/sensor_odom_2d.cpp index 57af930f6724980d49209aaf1ece6b6762556adc..ec7a3b54d3f8163f44276bf8120cb482a3a2fdd7 100644 --- a/src/sensor/sensor_odom_2d.cpp +++ b/src/sensor/sensor_odom_2d.cpp @@ -36,9 +36,9 @@ double SensorOdom2d::getRotVarToRotNoiseFactor() const } -// Register in the SensorFactory -#include "core/sensor/sensor_factory.h" +// Register in the FactorySensor +#include "core/sensor/factory_sensor.h" namespace wolf { -WOLF_REGISTER_SENSOR("SensorOdom2d", SensorOdom2d); -WOLF_REGISTER_SENSOR_AUTO("SensorOdom2d", SensorOdom2d); +WOLF_REGISTER_SENSOR(SensorOdom2d); +WOLF_REGISTER_SENSOR_AUTO(SensorOdom2d); } // namespace wolf diff --git a/src/sensor/sensor_odom_3d.cpp b/src/sensor/sensor_odom_3d.cpp index a79995b85e11a3c248be1f19d4c69514cd6483d8..58b9b62ee9e111ce84887ba16e728a3494e40b7a 100644 --- a/src/sensor/sensor_odom_3d.cpp +++ b/src/sensor/sensor_odom_3d.cpp @@ -39,9 +39,9 @@ SensorOdom3d::~SensorOdom3d() } // namespace wolf -// Register in the SensorFactory -#include "core/sensor/sensor_factory.h" +// Register in the FactorySensor +#include "core/sensor/factory_sensor.h" namespace wolf { -WOLF_REGISTER_SENSOR("SensorOdom3d", SensorOdom3d); -WOLF_REGISTER_SENSOR_AUTO("SensorOdom3d", SensorOdom3d); +WOLF_REGISTER_SENSOR(SensorOdom3d); +WOLF_REGISTER_SENSOR_AUTO(SensorOdom3d); } diff --git a/src/trajectory/trajectory_base.cpp b/src/trajectory/trajectory_base.cpp index 428faf954d89ffc8f0d7a88b182cd04a92850c4a..7620c9fa29132561cb0324d60399da97355f7f67 100644 --- a/src/trajectory/trajectory_base.cpp +++ b/src/trajectory/trajectory_base.cpp @@ -4,7 +4,7 @@ namespace wolf { TrajectoryBase::TrajectoryBase(const std::string& _frame_structure) : - NodeBase("TRAJECTORY", "Base"), + NodeBase("TRAJECTORY", "TrajectoryBase"), frame_structure_(_frame_structure), last_key_frame_ptr_(nullptr), last_key_or_aux_frame_ptr_(nullptr) diff --git a/src/tree_manager/tree_manager_sliding_window.cpp b/src/tree_manager/tree_manager_sliding_window.cpp new file mode 100644 index 0000000000000000000000000000000000000000..5816567557bdd2ca5779615834a3f48a418bbabe --- /dev/null +++ b/src/tree_manager/tree_manager_sliding_window.cpp @@ -0,0 +1,43 @@ +#include "core/tree_manager/tree_manager_sliding_window.h" + +namespace wolf +{ + +void TreeManagerSlidingWindow::keyFrameCallback(FrameBasePtr _key_frame) +{ + int n_kf(0); + FrameBasePtr first_KF(nullptr), second_KF(nullptr); + for (auto frm : getProblem()->getTrajectory()->getFrameList()) + { + if (frm->isKey()) + { + n_kf++; + if (first_KF == nullptr) + first_KF = frm; + else if (second_KF == nullptr) + second_KF = frm; + } + } + + // remove first KF if too many KF + if (n_kf > params_sw_->n_key_frames) + { + WOLF_DEBUG("TreeManagerSlidingWindow removing first frame"); + first_KF->remove(params_sw_->viral_remove_empty_parent); + if (params_sw_->fix_first_key_frame) + { + WOLF_DEBUG("TreeManagerSlidingWindow fixing new first frame"); + second_KF->fix(); + } + } +} + +} /* namespace wolf */ + +// Register in the FactoryTreeManager +#include "core/tree_manager/factory_tree_manager.h" +namespace wolf { +WOLF_REGISTER_TREE_MANAGER(TreeManagerSlidingWindow); +WOLF_REGISTER_TREE_MANAGER_AUTO(TreeManagerSlidingWindow); +} // namespace wolf + diff --git a/src/yaml/processor_odom_3d_yaml.cpp b/src/yaml/processor_odom_3d_yaml.cpp index 1047ba5fd2482ab1f89c5a7256eb54b86f6181d6..0a0884454f126a46e169c5edc25d26b3bb04ef64 100644 --- a/src/yaml/processor_odom_3d_yaml.cpp +++ b/src/yaml/processor_odom_3d_yaml.cpp @@ -20,13 +20,13 @@ namespace wolf namespace { -static ProcessorParamsBasePtr createProcessorOdom3dParams(const std::string & _filename_dot_yaml) +static ParamsProcessorBasePtr createProcessorOdom3dParams(const std::string & _filename_dot_yaml) { YAML::Node config = YAML::LoadFile(_filename_dot_yaml); if (config["type"].as<std::string>() == "ProcessorOdom3d") { - ProcessorParamsOdom3dPtr params = std::make_shared<ProcessorParamsOdom3d>(); + ParamsProcessorOdom3dPtr params = std::make_shared<ParamsProcessorOdom3d>(); params->time_tolerance = config["time_tolerance"] .as<double>(); params->unmeasured_perturbation_std = config["unmeasured_perturbation_std"] .as<double>(); @@ -47,8 +47,8 @@ static ProcessorParamsBasePtr createProcessorOdom3dParams(const std::string & _f return nullptr; } -// Register in the SensorFactory -const bool WOLF_UNUSED registered_prc_odom_3d = ProcessorParamsFactory::get().registerCreator("ProcessorOdom3d", createProcessorOdom3dParams); +// Register in the FactorySensor +const bool WOLF_UNUSED registered_prc_odom_3d = FactoryParamsProcessor::get().registerCreator("ProcessorOdom3d", createProcessorOdom3dParams); } // namespace [unnamed] diff --git a/src/yaml/sensor_odom_2d_yaml.cpp b/src/yaml/sensor_odom_2d_yaml.cpp index d59cd4decfb77338a0b3bb4ba17c607e03f847c1..b8ef1a083111a877b5b283c13d751df88a5af20d 100644 --- a/src/yaml/sensor_odom_2d_yaml.cpp +++ b/src/yaml/sensor_odom_2d_yaml.cpp @@ -39,8 +39,8 @@ static ParamsSensorBasePtr createParamsSensorOdom2d(const std::string & _filenam return nullptr; } -// Register in the SensorFactory -const bool WOLF_UNUSED registered_odom_2d_intr = ParamsSensorFactory::get().registerCreator("SensorOdom2d", createParamsSensorOdom2d); +// Register in the FactorySensor +const bool WOLF_UNUSED registered_odom_2d_intr = FactoryParamsSensor::get().registerCreator("SensorOdom2d", createParamsSensorOdom2d); } // namespace [unnamed] diff --git a/src/yaml/sensor_odom_3d_yaml.cpp b/src/yaml/sensor_odom_3d_yaml.cpp index e437bedcbf00257068bfea07830caa9f8224e7c9..5b700eb8210b337d59f1186be90b869fe123874f 100644 --- a/src/yaml/sensor_odom_3d_yaml.cpp +++ b/src/yaml/sensor_odom_3d_yaml.cpp @@ -41,8 +41,8 @@ static ParamsSensorBasePtr createParamsSensorOdom3d(const std::string & _filenam return nullptr; } -// Register in the SensorFactory -const bool WOLF_UNUSED registered_odom_3d_intr = ParamsSensorFactory::get().registerCreator("SensorOdom3d", createParamsSensorOdom3d); +// Register in the FactorySensor +const bool WOLF_UNUSED registered_odom_3d_intr = FactoryParamsSensor::get().registerCreator("SensorOdom3d", createParamsSensorOdom3d); } // namespace [unnamed] diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index db82caf1fc34b83b2509fe7d4f3ac4d6cc9e8c82..dc7cfae429f38b83a414229f78a70b01cc5ba53f 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -149,6 +149,10 @@ target_link_libraries(gtest_track_matrix ${PROJECT_NAME}) wolf_add_gtest(gtest_trajectory gtest_trajectory.cpp) target_link_libraries(gtest_trajectory ${PROJECT_NAME}) +# TreeManager class test +wolf_add_gtest(gtest_tree_manager gtest_tree_manager.cpp) +target_link_libraries(gtest_tree_manager ${PROJECT_NAME}) + # ------- Now Derived classes ---------- IF (Ceres_FOUND) @@ -173,6 +177,10 @@ target_link_libraries(gtest_factor_block_difference ${PROJECT_NAME}) wolf_add_gtest(gtest_factor_diff_drive gtest_factor_diff_drive.cpp) target_link_libraries(gtest_factor_diff_drive ${PROJECT_NAME}) +# FactorOdom2d class test +wolf_add_gtest(gtest_factor_odom_2d gtest_factor_odom_2d.cpp) +target_link_libraries(gtest_factor_odom_2d ${PROJECT_NAME}) + # FactorOdom3d class test wolf_add_gtest(gtest_factor_odom_3d gtest_factor_odom_3d.cpp) target_link_libraries(gtest_factor_odom_3d ${PROJECT_NAME}) @@ -185,6 +193,14 @@ target_link_libraries(gtest_factor_pose_2d ${PROJECT_NAME}) wolf_add_gtest(gtest_factor_pose_3d gtest_factor_pose_3d.cpp) target_link_libraries(gtest_factor_pose_3d ${PROJECT_NAME}) +# FactorRelativePose2dWithExtrinsics class test +wolf_add_gtest(gtest_factor_relative_pose_2d_with_extrinsics gtest_factor_relative_pose_2d_with_extrinsics.cpp) +target_link_libraries(gtest_factor_relative_pose_2d_with_extrinsics ${PROJECT_NAME}) + +# FactorRelative2dAnalytic class test +wolf_add_gtest(gtest_factor_relative_2d_analytic gtest_factor_relative_2d_analytic.cpp) +target_link_libraries(gtest_factor_relative_2d_analytic ${PROJECT_NAME}) + # MakePosDef function test wolf_add_gtest(gtest_make_posdef gtest_make_posdef.cpp) target_link_libraries(gtest_make_posdef ${PROJECT_NAME}) @@ -229,6 +245,10 @@ target_link_libraries(gtest_processor_tracker_landmark_dummy ${PROJECT_NAME} dum wolf_add_gtest(gtest_sensor_diff_drive gtest_sensor_diff_drive.cpp) target_link_libraries(gtest_sensor_diff_drive ${PROJECT_NAME}) +# TreeManagerSlidingWindow class test +wolf_add_gtest(gtest_tree_manager_sliding_window gtest_tree_manager_sliding_window.cpp) +target_link_libraries(gtest_tree_manager_sliding_window ${PROJECT_NAME}) + # yaml conversions wolf_add_gtest(gtest_yaml_conversions gtest_yaml_conversions.cpp) target_link_libraries(gtest_yaml_conversions ${PROJECT_NAME}) diff --git a/test/dummy/factor_dummy_zero_1.h b/test/dummy/factor_dummy_zero_1.h new file mode 100644 index 0000000000000000000000000000000000000000..ffe372f0cb9f5671cc491f295d38ec24b305da3b --- /dev/null +++ b/test/dummy/factor_dummy_zero_1.h @@ -0,0 +1,45 @@ +#ifndef FACTOR_DUMMY_ZERO_1_H_ +#define FACTOR_DUMMY_ZERO_1_H_ + +//Wolf includes +#include "core/factor/factor_autodiff.h" + +//#include "ceres/jet.h" + +namespace wolf { + +WOLF_PTR_TYPEDEFS(FactorDummyZero1); + +//class +class FactorDummyZero1 : public FactorAutodiff<FactorDummyZero1, 1, 1> +{ + public: + FactorDummyZero1(const StateBlockPtr& _sb_ptr) : + FactorAutodiff<FactorDummyZero1, 1, 1>("FactorDummy1", + nullptr, nullptr, nullptr, nullptr, + nullptr, + false, FAC_ACTIVE, + _sb_ptr) + { + // + } + + virtual ~FactorDummyZero1() = default; + + virtual std::string getTopology() const override + { + return std::string("MOTION"); + } + + template<typename T> + bool operator ()(const T* const _st1, + T* _residuals) const + { + _residuals[0] = _st1[0]; + return true; + } +}; + +} // namespace wolf + +#endif diff --git a/test/dummy/factor_dummy_zero_12.h b/test/dummy/factor_dummy_zero_12.h new file mode 100644 index 0000000000000000000000000000000000000000..3a57aa386d20524fbbec30aa154f555af0fbb9a1 --- /dev/null +++ b/test/dummy/factor_dummy_zero_12.h @@ -0,0 +1,155 @@ +#ifndef FACTOR_DUMMY_ZERO_12_H_ +#define FACTOR_DUMMY_ZERO_12_H_ + +//Wolf includes +#include "core/factor/factor_autodiff.h" + +//#include "ceres/jet.h" + +namespace wolf { + +//class +template <unsigned int ID> +class FactorDummyZero12 : public FactorAutodiff<FactorDummyZero12<ID>, ID, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12> +{ + static const unsigned int id = ID; + public: + FactorDummyZero12(const StateBlockPtr& _sb1_ptr, + const StateBlockPtr& _sb2_ptr, + const StateBlockPtr& _sb3_ptr, + const StateBlockPtr& _sb4_ptr, + const StateBlockPtr& _sb5_ptr, + const StateBlockPtr& _sb6_ptr, + const StateBlockPtr& _sb7_ptr, + const StateBlockPtr& _sb8_ptr, + const StateBlockPtr& _sb9_ptr, + const StateBlockPtr& _sb10_ptr, + const StateBlockPtr& _sb11_ptr, + const StateBlockPtr& _sb12_ptr) : + FactorAutodiff<FactorDummyZero12<ID>, ID, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12>("FactorDummy12", + nullptr, nullptr, nullptr, nullptr, + nullptr, + false, FAC_ACTIVE, + _sb1_ptr, + _sb2_ptr, + _sb3_ptr, + _sb4_ptr, + _sb5_ptr, + _sb6_ptr, + _sb7_ptr, + _sb8_ptr, + _sb9_ptr, + _sb10_ptr, + _sb11_ptr, + _sb12_ptr) + { + assert(id > 0 && id <= 12); + } + + virtual ~FactorDummyZero12() = default; + + virtual std::string getTopology() const override + { + return std::string("MOTION"); + } + + template<typename T> + bool operator ()(const T* const _st1, + const T* const _st2, + const T* const _st3, + const T* const _st4, + const T* const _st5, + const T* const _st6, + const T* const _st7, + const T* const _st8, + const T* const _st9, + const T* const _st10, + const T* const _st11, + const T* const _st12, + T* _residuals) const + { + Eigen::Map<Eigen::Matrix<T,ID,1>> residuals(_residuals); + switch (id) + { + case 1: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st1(_st1); + residuals = st1; + break; + } + case 2: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st2(_st2); + residuals = st2; + break; + } + case 3: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st3(_st3); + residuals = st3; + break; + } + case 4: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st4(_st4); + residuals = st4; + break; + } + case 5: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st5(_st5); + residuals = st5; + break; + } + case 6: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st6(_st6); + residuals = st6; + break; + } + case 7: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st7(_st7); + residuals = st7; + break; + } + case 8: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st8(_st8); + residuals = st8; + break; + } + case 9: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st9(_st9); + residuals = st9; + break; + } + case 10: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st10(_st10); + residuals = st10; + break; + } + case 11: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st11(_st11); + residuals = st11; + break; + } + case 12: + { + Eigen::Map<const Eigen::Matrix<T,ID,1>> st12(_st12); + residuals = st12; + break; + } + default: + throw std::runtime_error("ID not found"); + } + return true; + } +}; + +} // namespace wolf + +#endif diff --git a/test/dummy/processor_tracker_feature_dummy.cpp b/test/dummy/processor_tracker_feature_dummy.cpp index 3a30e98af0e409fb0fc8604231d7bee16a0630e6..8485d267034febde4f08911108c0773fd67ab892 100644 --- a/test/dummy/processor_tracker_feature_dummy.cpp +++ b/test/dummy/processor_tracker_feature_dummy.cpp @@ -58,6 +58,7 @@ unsigned int ProcessorTrackerFeatureDummy::detectNewFeatures(const int& _max_new FeatureBasePtrList& _features_out) { unsigned int max_features = _max_new_features; + WOLF_INFO("Detecting " , _max_new_features , " new features..." ); if (max_features == -1) { @@ -70,7 +71,7 @@ unsigned int ProcessorTrackerFeatureDummy::detectNewFeatures(const int& _max_new for (unsigned int i = 0; i < max_features; i++) { FeatureBasePtr ftr = FeatureBase::emplace<FeatureBase>(_capture, - "DUMMY FEATURE", + "FeatureDummy", Eigen::Vector1d::Ones(), Eigen::MatrixXd::Ones(1, 1)); _features_out.push_back(ftr); @@ -92,26 +93,11 @@ FactorBasePtr ProcessorTrackerFeatureDummy::emplaceFactor(FeatureBasePtr _featur return FactorBase::emplace<FactorFeatureDummy>(_feature_ptr, _feature_ptr, _feature_other_ptr, shared_from_this()); } -ProcessorBasePtr ProcessorTrackerFeatureDummy::create(const std::string& _unique_name, - const ProcessorParamsBasePtr _params) -{ - auto params = std::static_pointer_cast<ProcessorParamsTrackerFeatureDummy>(_params); - - // if cast failed use default value - if (params == nullptr) - params = std::make_shared<ProcessorParamsTrackerFeatureDummy>(); - - auto prc_ptr = std::make_shared<ProcessorTrackerFeatureDummy>(params); - - prc_ptr->setName(_unique_name); - - return prc_ptr; -} - } // namespace wolf -// Register in the ProcessorFactory -#include "core/processor/processor_factory.h" +// Register in the FactoryProcessor +#include "core/processor/factory_processor.h" namespace wolf { -WOLF_REGISTER_PROCESSOR("ProcessorTrackerFeatureDummy", ProcessorTrackerFeatureDummy) +WOLF_REGISTER_PROCESSOR(ProcessorTrackerFeatureDummy) +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorTrackerFeatureDummy) } // namespace wolf diff --git a/test/dummy/processor_tracker_feature_dummy.h b/test/dummy/processor_tracker_feature_dummy.h index 3328edf08c0234d6b587680b9b215bc91a7ae43f..c6f651ea013d2fac02164e0d3ea2cb96182fb6b2 100644 --- a/test/dummy/processor_tracker_feature_dummy.h +++ b/test/dummy/processor_tracker_feature_dummy.h @@ -14,16 +14,16 @@ namespace wolf { - -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsTrackerFeatureDummy); -struct ProcessorParamsTrackerFeatureDummy : public ProcessorParamsTrackerFeature +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorTrackerFeatureDummy); + +struct ParamsProcessorTrackerFeatureDummy : public ParamsProcessorTrackerFeature { unsigned int n_tracks_lost; ///< number of tracks lost each time track is called (the first ones) - ProcessorParamsTrackerFeatureDummy() = default; - ProcessorParamsTrackerFeatureDummy(std::string _unique_name, const wolf::ParamsServer & _server): - ProcessorParamsTrackerFeature(_unique_name, _server) + ParamsProcessorTrackerFeatureDummy() = default; + ParamsProcessorTrackerFeatureDummy(std::string _unique_name, const wolf::ParamsServer & _server): + ParamsProcessorTrackerFeature(_unique_name, _server) { n_tracks_lost = _server.getParam<unsigned int>(prefix + _unique_name + "/n_tracks_lost"); } @@ -31,19 +31,23 @@ struct ProcessorParamsTrackerFeatureDummy : public ProcessorParamsTrackerFeature WOLF_PTR_TYPEDEFS(ProcessorTrackerFeatureDummy); - + //Class class ProcessorTrackerFeatureDummy : public ProcessorTrackerFeature { public: - ProcessorTrackerFeatureDummy(ProcessorParamsTrackerFeatureDummyPtr _params_tracker_feature); + ProcessorTrackerFeatureDummy(ParamsProcessorTrackerFeatureDummyPtr _params_tracker_feature); virtual ~ProcessorTrackerFeatureDummy(); + + // Factory method for high level API + WOLF_PROCESSOR_CREATE(ProcessorTrackerFeatureDummy, ParamsProcessorTrackerFeatureDummy); + virtual void configure(SensorBasePtr _sensor) { }; protected: - ProcessorParamsTrackerFeatureDummyPtr params_tracker_feature_dummy_; + ParamsProcessorTrackerFeatureDummyPtr params_tracker_feature_dummy_; /** \brief Track provided features in \b _capture * \param _features_in input list of features in \b last to track @@ -101,15 +105,9 @@ class ProcessorTrackerFeatureDummy : public ProcessorTrackerFeature * This function emplaces a factor of the appropriate type for the derived processor. */ virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr); - - public: - - static ProcessorBasePtr create(const std::string& _unique_name, - const ProcessorParamsBasePtr _params); - }; -inline ProcessorTrackerFeatureDummy::ProcessorTrackerFeatureDummy(ProcessorParamsTrackerFeatureDummyPtr _params_tracker_feature_dummy) : +inline ProcessorTrackerFeatureDummy::ProcessorTrackerFeatureDummy(ParamsProcessorTrackerFeatureDummyPtr _params_tracker_feature_dummy) : ProcessorTrackerFeature("ProcessorTrackerFeatureDummy", 0, _params_tracker_feature_dummy), params_tracker_feature_dummy_(_params_tracker_feature_dummy) { diff --git a/test/dummy/processor_tracker_landmark_dummy.cpp b/test/dummy/processor_tracker_landmark_dummy.cpp index 72fc32f9baa1ce71216e6457d63185e057bcdc40..472b21ab150a7945987d0d64d5cd171bdf9975eb 100644 --- a/test/dummy/processor_tracker_landmark_dummy.cpp +++ b/test/dummy/processor_tracker_landmark_dummy.cpp @@ -12,7 +12,7 @@ namespace wolf { -ProcessorTrackerLandmarkDummy::ProcessorTrackerLandmarkDummy(ProcessorParamsTrackerLandmarkDummyPtr _params_tracker_landmark_dummy) : +ProcessorTrackerLandmarkDummy::ProcessorTrackerLandmarkDummy(ParamsProcessorTrackerLandmarkDummyPtr _params_tracker_landmark_dummy) : ProcessorTrackerLandmark("ProcessorTrackerLandmarkDummy", _params_tracker_landmark_dummy), params_tracker_landmark_dummy_(_params_tracker_landmark_dummy) { @@ -112,4 +112,12 @@ FactorBasePtr ProcessorTrackerLandmarkDummy::emplaceFactor(FeatureBasePtr _featu return FactorBase::emplace<FactorLandmarkDummy>(_feature_ptr, _feature_ptr, _landmark_ptr, shared_from_this()); } -} //namespace wolf +} // namespace wolf + +// Register in the FactoryProcessor +#include "core/processor/factory_processor.h" +namespace wolf { +WOLF_REGISTER_PROCESSOR(ProcessorTrackerLandmarkDummy) +WOLF_REGISTER_PROCESSOR_AUTO(ProcessorTrackerLandmarkDummy) +} // namespace wolf + diff --git a/test/dummy/processor_tracker_landmark_dummy.h b/test/dummy/processor_tracker_landmark_dummy.h index a9531c8db7a0372636c1d0cb605c21c38aec8446..b9485b3378e7644aa9206213dc3466fd41b83340 100644 --- a/test/dummy/processor_tracker_landmark_dummy.h +++ b/test/dummy/processor_tracker_landmark_dummy.h @@ -13,15 +13,15 @@ namespace wolf { -WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsTrackerLandmarkDummy); +WOLF_STRUCT_PTR_TYPEDEFS(ParamsProcessorTrackerLandmarkDummy); -struct ProcessorParamsTrackerLandmarkDummy : public ProcessorParamsTrackerLandmark +struct ParamsProcessorTrackerLandmarkDummy : public ParamsProcessorTrackerLandmark { unsigned int n_landmarks_lost; ///< number of landmarks lost each time findLandmarks is called (the last ones) - ProcessorParamsTrackerLandmarkDummy() = default; - ProcessorParamsTrackerLandmarkDummy(std::string _unique_name, const wolf::ParamsServer & _server): - ProcessorParamsTrackerLandmark(_unique_name, _server) + ParamsProcessorTrackerLandmarkDummy() = default; + ParamsProcessorTrackerLandmarkDummy(std::string _unique_name, const wolf::ParamsServer & _server): + ParamsProcessorTrackerLandmark(_unique_name, _server) { n_landmarks_lost = _server.getParam<unsigned int>(prefix + _unique_name + "/n_landmarks_lost"); } @@ -32,13 +32,17 @@ WOLF_PTR_TYPEDEFS(ProcessorTrackerLandmarkDummy); class ProcessorTrackerLandmarkDummy : public ProcessorTrackerLandmark { public: - ProcessorTrackerLandmarkDummy(ProcessorParamsTrackerLandmarkDummyPtr _params_tracker_landmark_dummy); + ProcessorTrackerLandmarkDummy(ParamsProcessorTrackerLandmarkDummyPtr _params_tracker_landmark_dummy); virtual ~ProcessorTrackerLandmarkDummy(); + + // Factory method for high level API + WOLF_PROCESSOR_CREATE(ProcessorTrackerLandmarkDummy, ParamsProcessorTrackerLandmarkDummy); + virtual void configure(SensorBasePtr _sensor) { }; protected: - ProcessorParamsTrackerLandmarkDummyPtr params_tracker_landmark_dummy_; + ParamsProcessorTrackerLandmarkDummyPtr params_tracker_landmark_dummy_; /** \brief Find provided landmarks as features in the provided capture * \param _landmarks_in input list of landmarks to be found diff --git a/test/dummy/tree_manager_dummy.h b/test/dummy/tree_manager_dummy.h new file mode 100644 index 0000000000000000000000000000000000000000..ce8e6379ece21e6a5422445b183f0576a88cc720 --- /dev/null +++ b/test/dummy/tree_manager_dummy.h @@ -0,0 +1,61 @@ +#ifndef INCLUDE_TREE_MANAGER_DUMMY_H_ +#define INCLUDE_TREE_MANAGER_DUMMY_H_ + +#include "core/tree_manager/tree_manager_base.h" + +namespace wolf +{ + +WOLF_STRUCT_PTR_TYPEDEFS(ParamsTreeManagerDummy) +struct ParamsTreeManagerDummy : public ParamsTreeManagerBase +{ + ParamsTreeManagerDummy() = default; + ParamsTreeManagerDummy(std::string _unique_name, const ParamsServer& _server): + ParamsTreeManagerBase(_unique_name, _server) + { + toy_param = _server.getParam<double>(prefix + "/toy_param"); + } + + virtual ~ParamsTreeManagerDummy() = default; + + bool toy_param; + + std::string print() const + { + return ParamsTreeManagerBase::print() + "\n" + + "toy_param: " + std::to_string(toy_param) + "\n"; + } +}; + +WOLF_PTR_TYPEDEFS(TreeManagerDummy) + +class TreeManagerDummy : public TreeManagerBase +{ + public: + TreeManagerDummy(ParamsTreeManagerBasePtr _params) : + TreeManagerBase("TreeManagerDummy", _params), + n_KF_(0) + {}; + WOLF_TREE_MANAGER_CREATE(TreeManagerDummy, ParamsTreeManagerBase) + + virtual ~TreeManagerDummy(){} + + virtual void keyFrameCallback(FrameBasePtr _KF) override + { + n_KF_++; + }; + + int n_KF_; +}; + +} /* namespace wolf */ + +// Register in the FactoryTreeManager +#include "core/tree_manager/factory_tree_manager.h" +namespace wolf { +WOLF_REGISTER_TREE_MANAGER(TreeManagerDummy) +WOLF_REGISTER_TREE_MANAGER_AUTO(TreeManagerDummy) + +} /* namespace wolf */ + +#endif /* INCLUDE_TREE_MANAGER_DUMMY_H_ */ diff --git a/test/gtest_emplace.cpp b/test/gtest_emplace.cpp index e60531daf9ab855e03b074384452d8e61c78d52a..457d41fe43f1adb01345065130f416f8ec785185 100644 --- a/test/gtest_emplace.cpp +++ b/test/gtest_emplace.cpp @@ -51,13 +51,13 @@ TEST(Emplace, Processor) ProblemPtr P = Problem::create("PO", 2); auto sen = SensorBase::emplace<SensorBase>(P->getHardware(), "Dummy", nullptr, nullptr, nullptr, 2, false); - auto prc = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen, std::make_shared<ProcessorParamsOdom2d>()); + auto prc = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen, std::make_shared<ParamsProcessorOdom2d>()); ASSERT_EQ(P, P->getHardware()->getSensorList().front()->getProcessorList().front()->getSensor()->getProblem()); ASSERT_EQ(sen, sen->getProcessorList().front()->getSensor()); ASSERT_EQ(prc, sen->getProcessorList().front()); SensorBasePtr sen2 = SensorBase::emplace<SensorBase>(P->getHardware(), "Dummy", nullptr, nullptr, nullptr, 2, false); - ProcessorOdom2dPtr prc2 = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen2, std::make_shared<ProcessorParamsOdom2d>()); + ProcessorOdom2dPtr prc2 = ProcessorOdom2d::emplace<ProcessorOdom2d>(sen2, std::make_shared<ParamsProcessorOdom2d>()); ASSERT_EQ(sen2, sen2->getProcessorList().front()->getSensor()); ASSERT_EQ(prc2, sen2->getProcessorList().front()); } diff --git a/test/gtest_factor_autodiff.cpp b/test/gtest_factor_autodiff.cpp index 993908461d6b37cae1b24d8701a3612d4dc9c432..b2b28b32d89412e3afbd2f3466946bed6cc1932b 100644 --- a/test/gtest_factor_autodiff.cpp +++ b/test/gtest_factor_autodiff.cpp @@ -13,11 +13,340 @@ #include "core/factor/factor_odom_2d.h" #include "core/factor/factor_odom_2d_analytic.h" #include "core/factor/factor_autodiff.h" +#include "dummy/factor_dummy_zero_1.h" +#include "dummy/factor_dummy_zero_12.h" using namespace wolf; using namespace Eigen; -TEST(CaptureAutodiff, ConstructorOdom2d) + +TEST(FactorAutodiff, AutodiffDummy1) +{ + StateBlockPtr sb = std::make_shared<StateBlock>(Eigen::Vector1d::Random()); + + auto fac = std::make_shared<FactorDummyZero1>(sb); + + // COMPUTE JACOBIANS + std::vector<const double*> states_ptr({sb->getStateData()}); + + std::vector<Eigen::MatrixXd> J; + Eigen::VectorXd residuals(fac->getSize()); + fac->evaluate(states_ptr, residuals, J); + + ASSERT_MATRIX_APPROX(J[0], Eigen::Matrix1d::Ones(), wolf::Constants::EPS); +} + +TEST(FactorAutodiff, AutodiffDummy12) +{ + StateBlockPtr sb1 = std::make_shared<StateBlock>(Eigen::Vector1d::Random()); + StateBlockPtr sb2 = std::make_shared<StateBlock>(Eigen::Vector2d::Random()); + StateBlockPtr sb3 = std::make_shared<StateBlock>(Eigen::Vector3d::Random()); + StateBlockPtr sb4 = std::make_shared<StateBlock>(Eigen::Vector4d::Random()); + StateBlockPtr sb5 = std::make_shared<StateBlock>(Eigen::Vector5d::Random()); + StateBlockPtr sb6 = std::make_shared<StateBlock>(Eigen::Vector6d::Random()); + StateBlockPtr sb7 = std::make_shared<StateBlock>(Eigen::Vector7d::Random()); + StateBlockPtr sb8 = std::make_shared<StateBlock>(Eigen::Vector8d::Random()); + StateBlockPtr sb9 = std::make_shared<StateBlock>(Eigen::Vector9d::Random()); + StateBlockPtr sb10 = std::make_shared<StateBlock>(Eigen::Vector10d::Random()); + StateBlockPtr sb11 = std::make_shared<StateBlock>(Eigen::VectorXd::Random(11)); + StateBlockPtr sb12 = std::make_shared<StateBlock>(Eigen::VectorXd::Random(12)); + + std::vector<const double*> states_ptr({sb1->getStateData(),sb2->getStateData(),sb3->getStateData(),sb4->getStateData(),sb5->getStateData(),sb6->getStateData(),sb7->getStateData(),sb8->getStateData(),sb9->getStateData(),sb10->getStateData(),sb11->getStateData(),sb12->getStateData()}); + std::vector<Eigen::MatrixXd> J; + Eigen::VectorXd residuals; + unsigned int i; + FactorBasePtr fac = nullptr; + + // 1 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<1>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 2 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<2>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 3 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<3>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 4 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<4>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 5 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<5>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 6 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<6>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 7 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<7>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 8 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<8>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 9 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<9>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 10 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<10>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 11 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<11>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } + + // 12 ------------------------------------------------------------------------ + fac = std::make_shared<FactorDummyZero12<12>>(sb1,sb2,sb3,sb4,sb5,sb6,sb7,sb8,sb9,sb10,sb11,sb12); + i = fac->getSize(); + + // Jacobian + J.clear(); + residuals.resize(i); + fac->evaluate(states_ptr, residuals, J); + + std::cout << "i = " << i << std::endl; + for (unsigned int j = 0; j < 12; j++) + { + std::cout << "j = " << j << std::endl; + std::cout << "Jacobian size: " << J[j].rows() << " " << J[j].cols() << std::endl; + if (j == i-1) + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Identity(i,i), wolf::Constants::EPS); + } + else + { + ASSERT_MATRIX_APPROX(J[j], Eigen::MatrixXd::Zero(i,j+1), wolf::Constants::EPS); + } + } +} + +TEST(FactorAutodiff, EmplaceOdom2d) { FrameBasePtr fr1_ptr(std::make_shared<FrameBase>(TimeStamp(0), std::make_shared<StateBlock>(2), std::make_shared<StateBlock>(1))); FrameBasePtr fr2_ptr(std::make_shared<FrameBase>(TimeStamp(0), std::make_shared<StateBlock>(2), std::make_shared<StateBlock>(1))); @@ -44,7 +373,7 @@ TEST(CaptureAutodiff, ConstructorOdom2d) ASSERT_TRUE(factor_ptr->getFrameOther()); } -TEST(CaptureAutodiff, ResidualOdom2d) +TEST(FactorAutodiff, ResidualOdom2d) { Eigen::Vector3d f1_pose, f2_pose; f1_pose << 2,1,M_PI; @@ -88,7 +417,7 @@ TEST(CaptureAutodiff, ResidualOdom2d) ASSERT_TRUE(residuals.minCoeff() > -1e-9); } -TEST(CaptureAutodiff, JacobianOdom2d) +TEST(FactorAutodiff, JacobianOdom2d) { Eigen::Vector3d f1_pose, f2_pose; f1_pose << 2,1,M_PI; @@ -166,7 +495,7 @@ TEST(CaptureAutodiff, JacobianOdom2d) // std::cout << "analytic J " << 3 << ":\n" << J3 << std::endl; } -TEST(CaptureAutodiff, AutodiffVsAnalytic) +TEST(FactorAutodiff, AutodiffVsAnalytic) { Eigen::Vector3d f1_pose, f2_pose; f1_pose << 2,1,M_PI; diff --git a/test/gtest_factor_block_difference.cpp b/test/gtest_factor_block_difference.cpp index cded07e0a3d882710f6b42e16a9460afb5e77611..594eb169754b47fb3304536742ea445051e4da85 100644 --- a/test/gtest_factor_block_difference.cpp +++ b/test/gtest_factor_block_difference.cpp @@ -66,6 +66,15 @@ class FixtureFactorBlockDifference : public testing::Test virtual void TearDown() override {} }; +TEST_F(FixtureFactorBlockDifference, CheckFactorType) +{ + // Feat_->setMeasurement() + FactorBlockDifferencePtr Fac = FactorBase::emplace<FactorBlockDifference>( + Feat_, KF0_->getP(), KF1_->getP() + ); + ASSERT_EQ(Fac->getType(), "FactorBlockDifference"); +} + TEST_F(FixtureFactorBlockDifference, EqualP) { diff --git a/test/gtest_factor_diff_drive.cpp b/test/gtest_factor_diff_drive.cpp index 0c88c19c7a719754f82abb964a2f8818aaeacb35..72f8d2529751a2ae634d93203120d5a14e766490 100644 --- a/test/gtest_factor_diff_drive.cpp +++ b/test/gtest_factor_diff_drive.cpp @@ -25,7 +25,7 @@ class ProcessorDiffDrivePublic : public ProcessorDiffDrive { using Base = ProcessorDiffDrive; public: - ProcessorDiffDrivePublic(ProcessorParamsDiffDrivePtr _params_motion) : + ProcessorDiffDrivePublic(ParamsProcessorDiffDrivePtr _params_motion) : ProcessorDiffDrive(_params_motion) { // @@ -99,7 +99,7 @@ class ProcessorDiffDrivePublic : public ProcessorDiffDrive return Base::emplaceFactor(_feature_motion, _capture_origin); } - ProcessorParamsDiffDrivePtr getParams() + ParamsProcessorDiffDrivePtr getParams() { return params_prc_diff_drv_selfcal_; } @@ -121,7 +121,7 @@ class FactorDiffDriveTest : public testing::Test TrajectoryBasePtr trajectory; ParamsSensorDiffDrivePtr intr; SensorDiffDrivePtr sensor; - ProcessorParamsDiffDrivePtr params; + ParamsProcessorDiffDrivePtr params; ProcessorDiffDrivePublicPtr processor; FrameBasePtr F0, F1; CaptureMotionPtr C0, C1; @@ -154,7 +154,7 @@ class FactorDiffDriveTest : public testing::Test calib = sensor->getIntrinsic()->getState(); // params and processor - params = std::make_shared<ProcessorParamsDiffDrive>(); + params = std::make_shared<ParamsProcessorDiffDrive>(); params->angle_turned = 1; params->dist_traveled = 2; params->max_buff_length = 3; @@ -432,7 +432,7 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics_gt) Vector3d calib_gt(1,1,1); // params and processor - ProcessorParamsDiffDrivePtr params = std::make_shared<ProcessorParamsDiffDrive>(); + ParamsProcessorDiffDrivePtr params = std::make_shared<ParamsProcessorDiffDrive>(); params->angle_turned = 99; params->dist_traveled = 99; params->max_buff_length = 99; @@ -568,7 +568,7 @@ TEST(FactorDiffDrive, preintegrate_and_solve_sensor_intrinsics) Vector3d calib_gt(1.0, 1.0, 1.0); // ground truth calib // params and processor - ProcessorParamsDiffDrivePtr params = std::make_shared<ProcessorParamsDiffDrive>(); + ParamsProcessorDiffDrivePtr params = std::make_shared<ParamsProcessorDiffDrive>(); params->angle_turned = 99; params->dist_traveled = 99; params->max_buff_length = 99; diff --git a/test/gtest_factor_odom_2d.cpp b/test/gtest_factor_odom_2d.cpp new file mode 100644 index 0000000000000000000000000000000000000000..76d559a767f962ef7e82c41bffdded012dd4d04e --- /dev/null +++ b/test/gtest_factor_odom_2d.cpp @@ -0,0 +1,109 @@ +#include "core/utils/utils_gtest.h" + +#include "core/factor/factor_odom_2d.h" +#include "core/capture/capture_odom_2d.h" +#include "core/math/rotations.h" + +#include "core/ceres_wrapper/ceres_manager.h" + +using namespace Eigen; +using namespace wolf; +using std::cout; +using std::endl; + +// Input odometry data and covariance +Matrix3d data_cov = 0.1*Matrix3d::Identity(); + +// Problem and solver +ProblemPtr problem_ptr = Problem::create("PO", 2); +CeresManager ceres_mgr(problem_ptr); + +// Two frames +FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(0)); +FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(1)); + +// Capture, feature and factor from frm1 to frm0 +auto cap1 = CaptureBase::emplace<CaptureOdom2d>(frm1, 1, nullptr, Vector3d::Zero(), data_cov); +auto fea1 = FeatureBase::emplace<FeatureBase>(cap1, "FeatureOdom2d", Vector3d::Zero(), data_cov); +auto fac1 = FactorBase::emplace<FactorOdom2d>(fea1, fea1, frm0, nullptr, false); // create and add + +TEST(FactorOdom2d, check_tree) +{ + ASSERT_TRUE(problem_ptr->check(0)); +} + +TEST(FactorOdom2d, fix_0_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // x1 groundtruth + Vector3d x1; + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * delta.head<2>(); + x1(2) = pi2pi(x0(2) + delta(2)); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + + // Fix frm0, perturb frm1 + frm0->fix(); + frm1->unfix(); + frm1->perturb(5); + + // solve for frm1 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm1->getState(), x1, 1e-6); + } +} + +TEST(FactorOdom2d, fix_1_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // x1 groundtruth + Vector3d x1; + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * delta.head<2>(); + x1(2) = pi2pi(x0(2) + delta(2)); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + + // Fix frm1, perturb frm0 + frm1->fix(); + frm0->unfix(); + frm0->perturb(5); + + // solve for frm0 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm0->getState(), x0, 1e-6); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_factor_relative_2d_analytic.cpp b/test/gtest_factor_relative_2d_analytic.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd8e2296c887aeb7ce6a07579eec939964d29a92 --- /dev/null +++ b/test/gtest_factor_relative_2d_analytic.cpp @@ -0,0 +1,109 @@ +#include "core/utils/utils_gtest.h" + +#include "core/factor/factor_relative_2d_analytic.h" +#include "core/capture/capture_odom_2d.h" +#include "core/math/rotations.h" + +#include "core/ceres_wrapper/ceres_manager.h" + +using namespace Eigen; +using namespace wolf; +using std::cout; +using std::endl; + +// Input odometry data and covariance +Matrix3d data_cov = 0.1*Matrix3d::Identity(); + +// Problem and solver +ProblemPtr problem_ptr = Problem::create("PO", 2); +CeresManager ceres_mgr(problem_ptr); + +// Two frames +FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(0)); +FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(1)); + +// Capture, feature and factor from frm1 to frm0 +auto cap1 = CaptureBase::emplace<CaptureOdom2d>(frm1, 1, nullptr, Vector3d::Zero(), data_cov); +auto fea1 = FeatureBase::emplace<FeatureBase>(cap1, "FeatureOdom2d", Vector3d::Zero(), data_cov); +auto fac1 = FactorBase::emplace<FactorRelative2dAnalytic>(fea1, "odom2d", fea1, frm0, nullptr, false); // create and add + +TEST(FactorRelative2dAnalytic, check_tree) +{ + ASSERT_TRUE(problem_ptr->check(0)); +} + +TEST(FactorRelative2dAnalytic, fix_0_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // x1 groundtruth + Vector3d x1; + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * delta.head<2>(); + x1(2) = pi2pi(x0(2) + delta(2)); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + + // Fix frm0, perturb frm1 + frm0->fix(); + frm1->unfix(); + frm1->perturb(5); + + // solve for frm1 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm1->getState(), x1, 1e-6); + } +} + +TEST(FactorRelative2dAnalytic, fix_1_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // x1 groundtruth + Vector3d x1; + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * delta.head<2>(); + x1(2) = pi2pi(x0(2) + delta(2)); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + + // Fix frm1, perturb frm0 + frm1->fix(); + frm0->unfix(); + frm0->perturb(5); + + // solve for frm0 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm0->getState(), x0, 1e-6); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_factor_relative_pose_2d_with_extrinsics.cpp b/test/gtest_factor_relative_pose_2d_with_extrinsics.cpp new file mode 100644 index 0000000000000000000000000000000000000000..32cff2bd79a00fdcf18850c5f871493584e27865 --- /dev/null +++ b/test/gtest_factor_relative_pose_2d_with_extrinsics.cpp @@ -0,0 +1,219 @@ +#include "core/utils/utils_gtest.h" + +#include "core/factor/factor_relative_pose_2d_with_extrinsics.h" +#include "core/capture/capture_odom_2d.h" +#include "core/sensor/sensor_odom_2d.h" +#include "core/processor/processor_odom_2d.h" +#include "core/math/rotations.h" + +#include "core/ceres_wrapper/ceres_manager.h" + +using namespace Eigen; +using namespace wolf; +using std::cout; +using std::endl; + +std::string wolf_root = _WOLF_ROOT_DIR; + +// Input odometry data and covariance +Matrix3d data_cov = 0.1*Matrix3d::Identity(); + +// Problem and solver +ProblemPtr problem_ptr = Problem::create("PO", 2); +CeresManager ceres_mgr(problem_ptr); + +// Sensor +auto sensor_odom2d = problem_ptr->installSensor("SensorOdom2d", "odom", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml"); +auto processor_odom2d = problem_ptr->installProcessor("ProcessorOdom2d", "odom", sensor_odom2d, std::make_shared<ParamsProcessorOdom2d>()); + +// Two frames +FrameBasePtr frm0 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(0)); +FrameBasePtr frm1 = problem_ptr->emplaceFrame(KEY, Vector3d::Zero(), TimeStamp(1)); + +// Capture, feature and factor from frm1 to frm0 +auto cap1 = CaptureBase::emplace<CaptureOdom2d>(frm1, 1, sensor_odom2d, Vector3d::Zero(), data_cov); +auto fea1 = FeatureBase::emplace<FeatureBase>(cap1, "FeatureOdom2d", Vector3d::Zero(), data_cov); +auto fac1 = FactorBase::emplace<FactorRelativePose2dWithExtrinsics>(fea1, fea1, frm0, processor_odom2d, false); // create and add + +TEST(FactorRelativePose2dWithExtrinsics, check_tree) +{ + ASSERT_TRUE(problem_ptr->check(0)); +} + +TEST(FactorRelativePose2dWithExtrinsics, fix_0_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // Random extrinsics + Vector3d xs = Vector3d::Random(); + pi2pi(xs(2)); + + // x1 groundtruth + Vector3d x1; + x1(2) = pi2pi(x0(2) + delta(2)); + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * (xs.head<2>() + Rotation2Dd(xs(2)) * delta.head<2>()) - Rotation2Dd(x1(2)) * xs.head<2>(); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + sensor_odom2d->setState(xs); + + // Perturb frm1, fix the rest + frm0->fix(); + frm1->unfix(); + sensor_odom2d->getP()->fix(); + sensor_odom2d->getO()->fix(); + frm1->perturb(5); + + // solve for frm1 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm1->getState(), x1, 1e-6); + } +} + +TEST(FactorRelativePose2dWithExtrinsics, fix_1_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // Random extrinsics + Vector3d xs = Vector3d::Random(); + pi2pi(xs(2)); + + // x1 groundtruth + Vector3d x1; + x1(2) = pi2pi(x0(2) + delta(2)); + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * (xs.head<2>() + Rotation2Dd(xs(2)) * delta.head<2>()) - Rotation2Dd(x1(2)) * xs.head<2>(); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + sensor_odom2d->setState(xs); + + // Perturb frm0, fix the rest + frm1->fix(); + frm0->unfix(); + sensor_odom2d->getP()->fix(); + sensor_odom2d->getO()->fix(); + frm0->perturb(5); + + // solve for frm0 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(frm0->getState(), x0, 1e-6); + } +} + +TEST(FactorRelativePose2dWithExtrinsics, extrinsics_p_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // Random extrinsics + Vector3d xs = Vector3d::Random(); + pi2pi(xs(2)); + + // x1 groundtruth + Vector3d x1; + x1(2) = pi2pi(x0(2) + delta(2)); + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * (xs.head<2>() + Rotation2Dd(xs(2)) * delta.head<2>()) - Rotation2Dd(x1(2)) * xs.head<2>(); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + sensor_odom2d->setState(xs); + + // Perturb sensor P, fix the rest + frm1->fix(); + frm0->fix(); + sensor_odom2d->getP()->unfix(); + sensor_odom2d->getO()->fix(); + sensor_odom2d->getP()->perturb(1); + + // solve for frm0 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(sensor_odom2d->getState(), xs, 1e-6); + } +} + +TEST(FactorRelativePose2dWithExtrinsics, extrinsics_o_solve) +{ + for (int i = 0; i < 1e3; i++) + { + // Random delta + Vector3d delta = Vector3d::Random() * 10; + pi2pi(delta(2)); + + // Random initial pose + Vector3d x0 = Vector3d::Random() * 10; + pi2pi(x0(2)); + + // Random extrinsics + Vector3d xs = Vector3d::Random(); + pi2pi(xs(2)); + + // x1 groundtruth + Vector3d x1; + x1(2) = pi2pi(x0(2) + delta(2)); + x1.head<2>() = x0.head<2>() + Rotation2Dd(x0(2)) * (xs.head<2>() + Rotation2Dd(xs(2)) * delta.head<2>()) - Rotation2Dd(x1(2)) * xs.head<2>(); + + // Set states and measurement + frm0->setState(x0); + frm1->setState(x1); + cap1->setData(delta); + fea1->setMeasurement(delta); + sensor_odom2d->setState(xs); + + //std::cout << "Sensor O: " << sensor_odom2d->getO()->getState().transpose() << std::endl; + + // Perturb sensor O, fix the rest + frm1->fix(); + frm0->fix(); + sensor_odom2d->getP()->fix(); + sensor_odom2d->getO()->unfix(); + sensor_odom2d->getO()->perturb(.2); + + //std::cout << "Sensor O (perturbed): " << sensor_odom2d->getO()->getState().transpose() << std::endl; + + // solve for frm0 + std::string report = ceres_mgr.solve(SolverManager::ReportVerbosity::BRIEF); + + ASSERT_POSE2d_APPROX(sensor_odom2d->getState(), xs, 1e-6); + } +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_frame_base.cpp b/test/gtest_frame_base.cpp index 77fa1ace2c4bf876b0c318fe79dc476688e92af0..90ba45c62add57f2f5d222579810d39f69b0cf6b 100644 --- a/test/gtest_frame_base.cpp +++ b/test/gtest_frame_base.cpp @@ -72,7 +72,7 @@ TEST(FrameBase, LinksToTree) auto F1 = FrameBase::emplace<FrameBase>(T, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto F2 = FrameBase::emplace<FrameBase>(T, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto C = CaptureBase::emplace<CaptureMotion>(F1, "CaptureMotion", 1, S, Vector3d::Zero(), 3, 3, nullptr); - auto p = ProcessorBase::emplace<ProcessorOdom2d>(S, std::make_shared<ProcessorParamsOdom2d>()); + auto p = ProcessorBase::emplace<ProcessorOdom2d>(S, std::make_shared<ParamsProcessorOdom2d>()); auto f = FeatureBase::emplace<FeatureBase>(C, "f", Vector1d(1), Matrix<double,1,1>::Identity()*.01); auto c = FactorBase::emplace<FactorOdom2d>(f, f, F2, p, false); diff --git a/test/gtest_odom_2d.cpp b/test/gtest_odom_2d.cpp index a17ea2d4dc50b36dcab596fcb5a970f56e4b5c1d..93b1ed685f976e09dd467305e7d2c2472fc37617 100644 --- a/test/gtest_odom_2d.cpp +++ b/test/gtest_odom_2d.cpp @@ -197,7 +197,7 @@ TEST(Odom2d, VoteForKfAndSolve) // Create Wolf tree nodes ProblemPtr problem = Problem::create("PO", 2); SensorBasePtr sensor_odom2d = problem->installSensor("SensorOdom2d", "odom", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml"); - ProcessorParamsOdom2dPtr params(std::make_shared<ProcessorParamsOdom2d>()); + ParamsProcessorOdom2dPtr params(std::make_shared<ParamsProcessorOdom2d>()); params->voting_active = true; params->dist_traveled = 100; params->angle_turned = data(1)*2.5; // force KF at every third process() @@ -338,7 +338,7 @@ TEST(Odom2d, KF_callback) // Create Wolf tree nodes ProblemPtr problem = Problem::create("PO", 2); SensorBasePtr sensor_odom2d = problem->installSensor("SensorOdom2d", "odom", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml"); - ProcessorParamsOdom2dPtr params(std::make_shared<ProcessorParamsOdom2d>()); + ParamsProcessorOdom2dPtr params(std::make_shared<ParamsProcessorOdom2d>()); params->dist_traveled = 100; params->angle_turned = 6.28; params->max_time_span = 100; diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp index 794d2aebaabdbe02214f2dde17bdf8118437985c..bf878e87c1cb5a277225ac20be11fce7f1b12c5d 100644 --- a/test/gtest_problem.cpp +++ b/test/gtest_problem.cpp @@ -31,11 +31,8 @@ using namespace wolf; using namespace Eigen; -// Register in the ProcessorFactory -#include "core/processor/processor_factory.h" -namespace wolf { -WOLF_REGISTER_PROCESSOR("TRACKER FEATURE DUMMY", ProcessorTrackerFeatureDummy) -} // namespace wolf +// Register in the FactoryProcessor +#include "core/processor/factory_processor.h" WOLF_PTR_TYPEDEFS(DummySolverManager); @@ -104,7 +101,7 @@ TEST(Problem, Processor) auto Sm = SensorBase::emplace<SensorOdom3d>(P->getHardware(), (Eigen::Vector7d()<<0,0,0, 0,0,0,1).finished(), ParamsSensorOdom3d()); // add motion processor - auto Pm = ProcessorBase::emplace<ProcessorOdom3d>(Sm, std::make_shared<ProcessorParamsOdom3d>()); + auto Pm = ProcessorBase::emplace<ProcessorOdom3d>(Sm, std::make_shared<ParamsProcessorOdom3d>()); // check motion processor IS NOT by emplace ASSERT_EQ(P->getProcessorIsMotion(), Pm); @@ -330,7 +327,7 @@ TEST(Problem, Covariances) // SensorBasePtr St = P->installSensor ("SensorOdom2d", "other odometer", xs2d, wolf_root + "/test/yaml/sensor_odom_2d.yaml"); SensorBasePtr St = P->installSensor ("SensorOdom3d", "other odometer", xs3d, wolf_root + "/test/yaml/sensor_odom_3d.yaml"); - ProcessorParamsTrackerFeaturePtr params = std::make_shared<ProcessorParamsTrackerFeature>(); + ParamsProcessorTrackerFeaturePtr params = std::make_shared<ParamsProcessorTrackerFeature>(); params->time_tolerance = 0.1; params->max_new_features = 5; params->min_features_for_keyframe = 10; diff --git a/test/gtest_processor_base.cpp b/test/gtest_processor_base.cpp index 96db133bba8e3efa62e6dd68fc0c1331d24623fd..4ac7acf50f3fc066901858db2b34843c58634af3 100644 --- a/test/gtest_processor_base.cpp +++ b/test/gtest_processor_base.cpp @@ -23,14 +23,6 @@ using namespace wolf; using namespace Eigen; - -// Register in the ProcessorFactory -#include "core/processor/processor_factory.h" -namespace wolf { -WOLF_REGISTER_PROCESSOR("TRACKER FEATURE DUMMY", ProcessorTrackerFeatureDummy) -} // namespace wolf - - TEST(ProcessorBase, IsMotion) { using namespace wolf; @@ -57,7 +49,7 @@ TEST(ProcessorBase, IsMotion) // Install odometer (sensor and processor) SensorBasePtr sens_odo = problem->installSensor("SensorOdom2d", "odometer", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml"); - ProcessorParamsOdom2dPtr proc_odo_params = make_shared<ProcessorParamsOdom2d>(); + ParamsProcessorOdom2dPtr proc_odo_params = make_shared<ParamsProcessorOdom2d>(); proc_odo_params->time_tolerance = dt/2; ProcessorBasePtr proc_odo = problem->installProcessor("ProcessorOdom2d", "odom processor", sens_odo, proc_odo_params); @@ -84,15 +76,17 @@ TEST(ProcessorBase, KeyFrameCallback) // Install tracker (sensor and processor) auto sens_trk = SensorBase::emplace<SensorBase>(problem->getHardware(), - "SensorOdom2d", + "SensorTrackerDummy", std::make_shared<StateBlock>(Eigen::VectorXd::Zero(2)), std::make_shared<StateBlock>(Eigen::VectorXd::Zero(1)), std::make_shared<StateBlock>(Eigen::VectorXd::Zero(2)), 2); - auto proc_trk = problem->installProcessor("ProcessorTrackerFeatureDummy", "dummy", sens_trk); + auto proc_trk_params = make_shared<ParamsProcessorTrackerFeatureDummy>(); + proc_trk_params->time_tolerance = dt/2; + auto proc_trk = problem->installProcessor("ProcessorTrackerFeatureDummy", "dummy", sens_trk, proc_trk_params); // Install odometer (sensor and processor) SensorBasePtr sens_odo = problem->installSensor("SensorOdom2d", "odometer", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml"); - ProcessorParamsOdom2dPtr proc_odo_params = make_shared<ProcessorParamsOdom2d>(); + ParamsProcessorOdom2dPtr proc_odo_params = make_shared<ParamsProcessorOdom2d>(); proc_odo_params->time_tolerance = dt/2; ProcessorBasePtr proc_odo = problem->installProcessor("ProcessorOdom2d", "odom processor", sens_odo, proc_odo_params); @@ -143,4 +137,3 @@ int main(int argc, char **argv) testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); } - diff --git a/test/gtest_processor_diff_drive.cpp b/test/gtest_processor_diff_drive.cpp index bcabf20437590cda0472777cd0e0b4e21bb381a3..92d985bfdd05576be50f862de33f13df5056eb23 100644 --- a/test/gtest_processor_diff_drive.cpp +++ b/test/gtest_processor_diff_drive.cpp @@ -20,7 +20,7 @@ class ProcessorDiffDrivePublic : public ProcessorDiffDrive { using Base = ProcessorDiffDrive; public: - ProcessorDiffDrivePublic(ProcessorParamsDiffDrivePtr _params_motion) : + ProcessorDiffDrivePublic(ParamsProcessorDiffDrivePtr _params_motion) : ProcessorDiffDrive(_params_motion) { // @@ -94,7 +94,7 @@ class ProcessorDiffDrivePublic : public ProcessorDiffDrive return Base::emplaceFactor(_feature_motion, _capture_origin); } - ProcessorParamsDiffDrivePtr getParams() + ParamsProcessorDiffDrivePtr getParams() { return params_prc_diff_drv_selfcal_; } @@ -111,7 +111,7 @@ class ProcessorDiffDriveTest : public testing::Test public: ParamsSensorDiffDrivePtr intr; SensorDiffDrivePtr sensor; - ProcessorParamsDiffDrivePtr params; + ParamsProcessorDiffDrivePtr params; ProcessorDiffDrivePublicPtr processor; ProblemPtr problem; @@ -129,7 +129,7 @@ class ProcessorDiffDriveTest : public testing::Test sensor = std::static_pointer_cast<SensorDiffDrive>(problem->installSensor("SensorDiffDrive", "sensor diff drive", extr, intr)); // params and processor - params = std::make_shared<ProcessorParamsDiffDrive>(); + params = std::make_shared<ParamsProcessorDiffDrive>(); params->voting_active = true; params->angle_turned = 1; params->dist_traveled = 2; @@ -145,7 +145,7 @@ class ProcessorDiffDriveTest : public testing::Test TEST(ProcessorDiffDrive, constructor) { - auto params = std::make_shared<ProcessorParamsDiffDrive>(); + auto params = std::make_shared<ParamsProcessorDiffDrive>(); ASSERT_NE(params, nullptr); @@ -164,7 +164,7 @@ TEST(ProcessorDiffDrive, create) auto sen = std::make_shared<SensorDiffDrive>(extr, intr); // params - auto params = std::make_shared<ProcessorParamsDiffDrive>(); + auto params = std::make_shared<ParamsProcessorDiffDrive>(); // processor auto prc_base = ProcessorDiffDrive::create("prc", params); diff --git a/test/gtest_processor_loopclosure.cpp b/test/gtest_processor_loopclosure.cpp index 5fb84268d1c376955e8cb2c7a6ed4edbb7536c11..5d5bb796004cb66a817a5fb546eee22da35e0ba5 100644 --- a/test/gtest_processor_loopclosure.cpp +++ b/test/gtest_processor_loopclosure.cpp @@ -23,7 +23,7 @@ private: bool* factor_created; public: - ProcessorLoopClosureDummy(ProcessorParamsLoopClosurePtr _params_loop_closure, bool& factor_created): + ProcessorLoopClosureDummy(ParamsProcessorLoopClosurePtr _params_loop_closure, bool& factor_created): ProcessorLoopClosure("LOOP CLOSURE DUMMY", 0, _params_loop_closure), factor_created(&factor_created){}; std::pair<FrameBasePtr,CaptureBasePtr> public_selectPairKC(){ return selectPairKC();}; @@ -71,7 +71,7 @@ TEST(ProcessorLoopClosure, installProcessor) std::make_shared<StateBlock>(Eigen::VectorXd::Zero(2)), std::make_shared<StateBlock>(Eigen::VectorXd::Zero(1)), std::make_shared<StateBlock>(Eigen::VectorXd::Zero(2)), 2); - ProcessorParamsLoopClosurePtr params = std::make_shared<ProcessorParamsLoopClosure>(); + ParamsProcessorLoopClosurePtr params = std::make_shared<ParamsProcessorLoopClosure>(); auto proc_lc = ProcessorBase::emplace<ProcessorLoopClosureDummy>(sens_lc, params, factor_created); std::cout << "sensor & processor created and added to wolf problem" << std::endl; diff --git a/test/gtest_processor_motion.cpp b/test/gtest_processor_motion.cpp index 4e449f781ba1c8091806fa7634d8b3c87bd4ff1e..8b80be06846217ed28016b1c827b31aa5c81dfb7 100644 --- a/test/gtest_processor_motion.cpp +++ b/test/gtest_processor_motion.cpp @@ -21,7 +21,7 @@ using std::static_pointer_cast; class ProcessorOdom2dPublic : public ProcessorOdom2d { public: - ProcessorOdom2dPublic(ProcessorParamsOdom2dPtr params) : ProcessorOdom2d(params) + ProcessorOdom2dPublic(ParamsProcessorOdom2dPtr params) : ProcessorOdom2d(params) { // } @@ -52,7 +52,7 @@ class ProcessorMotion_test : public testing::Test{ Matrix2d data_cov; // ProcessorMotion_test() : -// ProcessorOdom2d(std::make_shared<ProcessorParamsOdom2d>()), +// ProcessorOdom2d(std::make_shared<ParamsProcessorOdom2d>()), // dt(0) // { } @@ -63,7 +63,7 @@ class ProcessorMotion_test : public testing::Test{ dt = 1.0; problem = Problem::create("PO", 2); sensor = static_pointer_cast<SensorOdom2d>(problem->installSensor("SensorOdom2d", "odom", Vector3d(0,0,0), wolf_root + "/test/yaml/sensor_odom_2d.yaml")); - ProcessorParamsOdom2dPtr params(std::make_shared<ProcessorParamsOdom2d>()); + ParamsProcessorOdom2dPtr params(std::make_shared<ParamsProcessorOdom2d>()); params->time_tolerance = 0.25; params->dist_traveled = 100; params->angle_turned = 6.28; diff --git a/test/gtest_processor_odom_3d.cpp b/test/gtest_processor_odom_3d.cpp index 24e5e875ea0b5775747c7325239884a586f0a0c4..4a94d3e1b88d1afc89ef80a39b9fad1baa67a1f7 100644 --- a/test/gtest_processor_odom_3d.cpp +++ b/test/gtest_processor_odom_3d.cpp @@ -52,7 +52,7 @@ class ProcessorOdom3dTest : public ProcessorOdom3d double& dvar_min() {return min_disp_var_;} double& rvar_min() {return min_rot_var_;} }; -ProcessorOdom3dTest::ProcessorOdom3dTest() : ProcessorOdom3d(std::make_shared<ProcessorParamsOdom3d>()) +ProcessorOdom3dTest::ProcessorOdom3dTest() : ProcessorOdom3d(std::make_shared<ParamsProcessorOdom3d>()) { dvar_min() = 0.5; rvar_min() = 0.25; diff --git a/test/gtest_processor_tracker_feature_dummy.cpp b/test/gtest_processor_tracker_feature_dummy.cpp index e42943aeca2ef0f7359c226f20a16200da6cfdc6..604cd09b4f20ed68e1c44273f85a93c8c1a88c1a 100644 --- a/test/gtest_processor_tracker_feature_dummy.cpp +++ b/test/gtest_processor_tracker_feature_dummy.cpp @@ -1,7 +1,7 @@ // wolf includes #include "core/utils/utils_gtest.h" -#include "core/sensor/sensor_factory.h" +#include "core/sensor/factory_sensor.h" #include "dummy/processor_tracker_feature_dummy.h" #include "core/capture/capture_void.h" @@ -15,7 +15,7 @@ class ProcessorTrackerFeatureDummyDummy : public ProcessorTrackerFeatureDummy { public: - ProcessorTrackerFeatureDummyDummy(ProcessorParamsTrackerFeatureDummyPtr& _params) : + ProcessorTrackerFeatureDummyDummy(ParamsProcessorTrackerFeatureDummyPtr& _params) : ProcessorTrackerFeatureDummy(_params){} void setLast(CaptureBasePtr _last_ptr){ last_ptr_ = _last_ptr; } @@ -71,7 +71,7 @@ class ProcessorTrackerFeatureDummyTest : public testing::Test public: ProblemPtr problem; SensorBasePtr sensor; - ProcessorParamsTrackerFeatureDummyPtr params; + ParamsProcessorTrackerFeatureDummyPtr params; ProcessorTrackerFeatureDummyDummyPtr processor; virtual ~ProcessorTrackerFeatureDummyTest(){} @@ -85,7 +85,7 @@ class ProcessorTrackerFeatureDummyTest : public testing::Test sensor = problem->installSensor("SensorOdom2d", "auxiliar sensor", (Eigen::Vector3d() << 0,0,0).finished(), std::make_shared<ParamsSensorBase>()); // Install processor - params = std::make_shared<ProcessorParamsTrackerFeatureDummy>(); + params = std::make_shared<ParamsProcessorTrackerFeatureDummy>(); params->max_new_features = 10; params->min_features_for_keyframe = 7; params->time_tolerance = 0.25; diff --git a/test/gtest_processor_tracker_landmark_dummy.cpp b/test/gtest_processor_tracker_landmark_dummy.cpp index a75ba7ffb962509468343f66e894a1b527610c04..8963211c45c292341d3754e83579f8bf9738a752 100644 --- a/test/gtest_processor_tracker_landmark_dummy.cpp +++ b/test/gtest_processor_tracker_landmark_dummy.cpp @@ -1,7 +1,7 @@ // wolf includes #include "core/utils/utils_gtest.h" -#include "core/sensor/sensor_factory.h" +#include "core/sensor/factory_sensor.h" #include "dummy/processor_tracker_landmark_dummy.h" #include "core/capture/capture_void.h" @@ -15,7 +15,7 @@ class ProcessorTrackerLandmarkDummyDummy : public ProcessorTrackerLandmarkDummy { public: - ProcessorTrackerLandmarkDummyDummy(ProcessorParamsTrackerLandmarkDummyPtr& _params) : + ProcessorTrackerLandmarkDummyDummy(ParamsProcessorTrackerLandmarkDummyPtr& _params) : ProcessorTrackerLandmarkDummy(_params){} void setLast(CaptureBasePtr _last_ptr){ last_ptr_ = _last_ptr; } @@ -89,7 +89,7 @@ class ProcessorTrackerLandmarkDummyTest : public testing::Test public: ProblemPtr problem; SensorBasePtr sensor; - ProcessorParamsTrackerLandmarkDummyPtr params; + ParamsProcessorTrackerLandmarkDummyPtr params; ProcessorTrackerLandmarkDummyDummyPtr processor; virtual ~ProcessorTrackerLandmarkDummyTest(){} @@ -103,7 +103,7 @@ class ProcessorTrackerLandmarkDummyTest : public testing::Test sensor = problem->installSensor("SensorOdom2d", "auxiliar sensor", (Eigen::Vector3d() << 0,0,0).finished(), std::make_shared<ParamsSensorBase>()); // Install processor - params = std::make_shared<ProcessorParamsTrackerLandmarkDummy>(); + params = std::make_shared<ParamsProcessorTrackerLandmarkDummy>(); params->max_new_features = 10; params->min_features_for_keyframe = 7; params->time_tolerance = 0.25; diff --git a/test/gtest_tree_manager.cpp b/test/gtest_tree_manager.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4f609da767afb85bbc6cc818906524612aff3ded --- /dev/null +++ b/test/gtest_tree_manager.cpp @@ -0,0 +1,107 @@ +#include "core/utils/utils_gtest.h" +#include "core/utils/logging.h" + +#include "core/problem/problem.h" +#include "dummy/tree_manager_dummy.h" +#include "core/yaml/parser_yaml.h" + +using namespace wolf; +using namespace Eigen; + +std::string wolf_root = _WOLF_ROOT_DIR; + +TEST(TreeManager, make_shared) +{ + ProblemPtr P = Problem::create("PO", 2); + + auto ParamsGM = std::make_shared<ParamsTreeManagerBase>(); + + auto GM = std::make_shared<TreeManagerDummy>(ParamsGM); + + P->setTreeManager(GM); + + ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0); + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManager, createParams) +{ + ProblemPtr P = Problem::create("PO", 2); + + auto ParamsGM = std::make_shared<ParamsTreeManagerBase>(); + + auto GM = TreeManagerDummy::create("tree_manager", ParamsGM); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(GM) != nullptr); + + P->setTreeManager(GM); + + ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0); + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManager, createParamServer) +{ + ProblemPtr P = Problem::create("PO", 2); + + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager1.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + auto GM = TreeManagerDummy::create("tree_manager", server); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(GM) != nullptr); + + P->setTreeManager(GM); + + ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 0); + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManager, autoConf) +{ + + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager1.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + ProblemPtr P = Problem::autoSetup(server); + P->applyPriorOptions(0); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerDummy>(P->getTreeManager()) != nullptr); + ASSERT_EQ(std::static_pointer_cast<TreeManagerDummy>(P->getTreeManager())->n_KF_, 1); // prior KF +} + +TEST(TreeManager, autoConfNone) +{ + + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager2.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + ProblemPtr P = Problem::autoSetup(server); + P->applyPriorOptions(0); + + ASSERT_TRUE(P->getTreeManager() == nullptr); // params_tree_manager2.yaml problem/tree_manager/type: None +} + +TEST(TreeManager, keyFrameCallback) +{ + ProblemPtr P = Problem::create("PO", 3); + + auto ParamsGM = std::make_shared<ParamsTreeManagerBase>(); + + auto GM = std::make_shared<TreeManagerDummy>(ParamsGM); + + P->setTreeManager(GM); + + ASSERT_EQ(GM->n_KF_, 0); + + auto F0 = P->emplaceFrame("PO", 3, KEY, VectorXd(7), TimeStamp(0.0)); + P->keyFrameCallback(F0, nullptr, 0); + + ASSERT_EQ(GM->n_KF_, 1); +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/gtest_tree_manager_sliding_window.cpp b/test/gtest_tree_manager_sliding_window.cpp new file mode 100644 index 0000000000000000000000000000000000000000..4cf8cf524ef114f357919661a3aee62a65e34234 --- /dev/null +++ b/test/gtest_tree_manager_sliding_window.cpp @@ -0,0 +1,269 @@ +#include "core/utils/utils_gtest.h" +#include "core/utils/logging.h" + +#include "core/problem/problem.h" +#include "core/tree_manager/tree_manager_sliding_window.h" +#include "core/yaml/parser_yaml.h" +#include "core/capture/capture_void.h" +#include "core/feature/feature_base.h" +#include "core/factor/factor_odom_3d.h" +#include "core/factor/factor_pose_3d.h" + +using namespace wolf; +using namespace Eigen; + +std::string wolf_root = _WOLF_ROOT_DIR; + +TEST(TreeManagerSlidingWindow, make_shared) +{ + ProblemPtr P = Problem::create("PO", 2); + + auto ParamsGM = std::make_shared<ParamsTreeManagerSlidingWindow>(); + + auto GM = std::make_shared<TreeManagerSlidingWindow>(ParamsGM); + + P->setTreeManager(GM); + + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManagerSlidingWindow, createParams) +{ + ProblemPtr P = Problem::create("PO", 2); + + auto ParamsGM = std::make_shared<ParamsTreeManagerSlidingWindow>(); + + auto GM = TreeManagerSlidingWindow::create("tree_manager", ParamsGM); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(GM) != nullptr); + + P->setTreeManager(GM); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr); + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManagerSlidingWindow, createParamServer) +{ + ProblemPtr P = Problem::create("PO", 2); + + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + auto GM = TreeManagerSlidingWindow::create("tree_manager", server); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(GM) != nullptr); + + P->setTreeManager(GM); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr); + ASSERT_EQ(P->getTreeManager(), GM); +} + +TEST(TreeManagerSlidingWindow, autoConf) +{ + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + ProblemPtr P = Problem::autoSetup(server); + + ASSERT_TRUE(std::dynamic_pointer_cast<TreeManagerSlidingWindow>(P->getTreeManager()) != nullptr); +} + +TEST(TreeManagerSlidingWindow, slidingWindowFixViral) +{ + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window1.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + ProblemPtr P = Problem::autoSetup(server); + P->applyPriorOptions(0); + + // FRAME 1 ---------------------------------------------------------- + auto F1 = P->getTrajectory()->getLastKeyFrame(); + ASSERT_TRUE(F1 != nullptr); + + Vector7d state = F1->getState(); + Vector7d zero_disp(state); + Matrix6d cov = Matrix6d::Identity(); + + // FRAME 2 ---------------------------------------------------------- + auto F2 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(2)); + P->keyFrameCallback(F2, nullptr, 0); + + // absolute factor + auto C2 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr); + auto f2 = FeatureBase::emplace<FeatureBase>(C2, "absolute", state, cov); + auto c2 = FactorBase::emplace<FactorPose3d>(f2, f2, nullptr, false); + // displacement + auto C12 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr); + auto f12 = FeatureBase::emplace<FeatureBase>(C12, "odom", zero_disp, cov); + auto c12 = FactorBase::emplace<FactorOdom3d>(f12, f12, F1, nullptr, false); + + // Check no frame removed + ASSERT_FALSE(F1->isRemoving()); + + // FRAME 3 ---------------------------------------------------------- + auto F3 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(3)); + P->keyFrameCallback(F3, nullptr, 0); + + // absolute factor + auto C3 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr); + auto f3 = FeatureBase::emplace<FeatureBase>(C3, "absolute", state, cov); + auto c3 = FactorBase::emplace<FactorPose3d>(f3, f3, nullptr, false); + // displacement + auto C23 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr); + auto f23 = FeatureBase::emplace<FeatureBase>(C23, "odom", zero_disp, cov); + auto c23 = FactorBase::emplace<FactorOdom3d>(f23, f23, F2, nullptr, false); + + // Check no frame removed + ASSERT_FALSE(F1->isRemoving()); + + // FRAME 4 ---------------------------------------------------------- + auto F4 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(4)); + P->keyFrameCallback(F4, nullptr, 0); + + // absolute factor + auto C4 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr); + auto f4 = FeatureBase::emplace<FeatureBase>(C4, "absolute", state, cov); + auto c4 = FactorBase::emplace<FactorPose3d>(f4, f4, nullptr, false); + // displacement + auto C34 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr); + auto f34 = FeatureBase::emplace<FeatureBase>(C34, "odom", zero_disp, cov); + auto c34 = FactorBase::emplace<FactorOdom3d>(f34, f34, F3, nullptr, false); + + // Checks + ASSERT_TRUE(F1->isRemoving()); + ASSERT_TRUE(c12->isRemoving()); + ASSERT_TRUE(C12->isRemoving()); //Virally removed + ASSERT_TRUE(f12->isRemoving()); //Virally removed + ASSERT_TRUE(F2->isFixed()); //Fixed + + // FRAME 5 ---------------------------------------------------------- + auto F5 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(5)); + P->keyFrameCallback(F5, nullptr, 0); + + // absolute factor + auto C5 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr); + auto f5 = FeatureBase::emplace<FeatureBase>(C5, "absolute", state, cov); + auto c5 = FactorBase::emplace<FactorPose3d>(f5, f5, nullptr, false); + // displacement + auto C45 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr); + auto f45 = FeatureBase::emplace<FeatureBase>(C45, "odom", zero_disp, cov); + auto c45 = FactorBase::emplace<FactorOdom3d>(f45, f45, F4, nullptr, false); + + // Checks + ASSERT_TRUE(F1->isRemoving()); + ASSERT_TRUE(c12->isRemoving()); + ASSERT_TRUE(C12->isRemoving()); //Virally removed + ASSERT_TRUE(f12->isRemoving()); //Virally removed + ASSERT_TRUE(F2->isRemoving()); + ASSERT_TRUE(c2->isRemoving()); + ASSERT_TRUE(C2->isRemoving()); //Virally removed + ASSERT_TRUE(f2->isRemoving()); //Virally removed + ASSERT_TRUE(c23->isRemoving()); + ASSERT_TRUE(C23->isRemoving()); //Virally removed + ASSERT_TRUE(f23->isRemoving()); //Virally removed + ASSERT_TRUE(F3->isFixed()); //Fixed +} + +TEST(TreeManagerSlidingWindow, slidingWindowNoFixNoViral) +{ + ParserYAML parser = ParserYAML("test/yaml/params_tree_manager_sliding_window2.yaml", wolf_root); + ParamsServer server = ParamsServer(parser.getParams()); + + ProblemPtr P = Problem::autoSetup(server); + P->applyPriorOptions(0); + + // FRAME 1 (prior) ---------------------------------------------------------- + auto F1 = P->getTrajectory()->getLastKeyFrame(); + ASSERT_TRUE(F1 != nullptr); + + Vector7d state = F1->getState(); + Vector7d zero_disp(state); + Matrix6d cov = Matrix6d::Identity(); + + // FRAME 2 ---------------------------------------------------------- + auto F2 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(2)); + P->keyFrameCallback(F2, nullptr, 0); + + // absolute factor + auto C2 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr); + auto f2 = FeatureBase::emplace<FeatureBase>(C2, "absolute", state, cov); + auto c2 = FactorBase::emplace<FactorPose3d>(f2, f2, nullptr, false); + // displacement + auto C12 = CaptureBase::emplace<CaptureVoid>(F2, TimeStamp(2), nullptr); + auto f12 = FeatureBase::emplace<FeatureBase>(C12, "odom", zero_disp, cov); + auto c12 = FactorBase::emplace<FactorOdom3d>(f12, f12, F1, nullptr, false); + + // Check no frame removed + ASSERT_FALSE(F1->isRemoving()); + + // FRAME 3 ---------------------------------------------------------- + auto F3 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(3)); + P->keyFrameCallback(F3, nullptr, 0); + + // absolute factor + auto C3 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr); + auto f3 = FeatureBase::emplace<FeatureBase>(C3, "absolute", state, cov); + auto c3 = FactorBase::emplace<FactorPose3d>(f3, f3, nullptr, false); + // displacement + auto C23 = CaptureBase::emplace<CaptureVoid>(F3, TimeStamp(3), nullptr); + auto f23 = FeatureBase::emplace<FeatureBase>(C23, "odom", zero_disp, cov); + auto c23 = FactorBase::emplace<FactorOdom3d>(f23, f23, F2, nullptr, false); + + // Check no frame removed + ASSERT_FALSE(F1->isRemoving()); + + // FRAME 4 ---------------------------------------------------------- + auto F4 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(4)); + P->keyFrameCallback(F4, nullptr, 0); + + // absolute factor + auto C4 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr); + auto f4 = FeatureBase::emplace<FeatureBase>(C4, "absolute", state, cov); + auto c4 = FactorBase::emplace<FactorPose3d>(f4, f4, nullptr, false); + // displacement + auto C34 = CaptureBase::emplace<CaptureVoid>(F4, TimeStamp(4), nullptr); + auto f34 = FeatureBase::emplace<FeatureBase>(C34, "odom", zero_disp, cov); + auto c34 = FactorBase::emplace<FactorOdom3d>(f34, f34, F3, nullptr, false); + + // Checks + ASSERT_TRUE(F1->isRemoving()); + ASSERT_TRUE(c12->isRemoving()); + ASSERT_FALSE(C12->isRemoving()); //Not virally removed + ASSERT_FALSE(f12->isRemoving()); //Not virally removed + ASSERT_FALSE(F2->isFixed()); //Not fixed + + // FRAME 5 ---------------------------------------------------------- + auto F5 = P->emplaceFrame("PO", 3, KEY, state, TimeStamp(5)); + P->keyFrameCallback(F5, nullptr, 0); + + // absolute factor + auto C5 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr); + auto f5 = FeatureBase::emplace<FeatureBase>(C5, "absolute", state, cov); + auto c5 = FactorBase::emplace<FactorPose3d>(f5, f5, nullptr, false); + // displacement + auto C45 = CaptureBase::emplace<CaptureVoid>(F5, TimeStamp(5), nullptr); + auto f45 = FeatureBase::emplace<FeatureBase>(C45, "odom", zero_disp, cov); + auto c45 = FactorBase::emplace<FactorOdom3d>(f45, f45, F4, nullptr, false); + + // Checks + ASSERT_TRUE(F1->isRemoving()); + ASSERT_TRUE(c12->isRemoving()); + ASSERT_TRUE(C12->isRemoving()); + ASSERT_TRUE(f12->isRemoving()); + ASSERT_TRUE(F2->isRemoving()); + ASSERT_TRUE(c2->isRemoving()); + ASSERT_TRUE(C2->isRemoving()); + ASSERT_TRUE(f2->isRemoving()); + ASSERT_TRUE(c23->isRemoving()); + ASSERT_FALSE(C23->isRemoving()); //Not virally removed + ASSERT_FALSE(f23->isRemoving()); //Not virally removed + ASSERT_FALSE(F3->isFixed()); //Not fixed +} + +int main(int argc, char **argv) +{ + testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/test/yaml/params_tree_manager1.yaml b/test/yaml/params_tree_manager1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..085015b89c62f913f7bbf6ab3d6241ddde132dff --- /dev/null +++ b/test/yaml/params_tree_manager1.yaml @@ -0,0 +1,41 @@ +config: + problem: + frame_structure: "POV" + dimension: 3 + prior: + mode: "factor" + state: [0,0,0,0,0,0,1,0,0,0] + cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1] + time_tolerance: 0.1 + tree_manager: + type: "TreeManagerDummy" + toy_param: 0 + sensors: + - + type: "SensorOdom3d" + name: "odom" + plugin: "core" + k_disp_to_disp: 0.1 + k_disp_to_rot: 0.1 + k_rot_to_rot: 0.1 + min_disp_var: 0.1 + min_rot_var: 0.1 + extrinsic: + pose: [1,2,3,0,0,0,1] + processors: + - + type: "ProcessorOdom3d" + name: "my_proc_odom3d" + sensor_name: "odom" + plugin: "core" + apply_loss_function: false + time_tolerance: 0.01 # seconds + keyframe_vote: + voting_active: false + voting_aux_active: false + max_time_span: 0.2 # seconds + max_buff_length: 10 # motion deltas + dist_traveled: 0.5 # meters + angle_turned: 0.1 # radians (1 rad approx 57 deg, approx 60 deg) + + unmeasured_perturbation_std: 0.00111 \ No newline at end of file diff --git a/test/yaml/params_tree_manager2.yaml b/test/yaml/params_tree_manager2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..80b5af47ac509b0746ffb8f66775d87742e1e927 --- /dev/null +++ b/test/yaml/params_tree_manager2.yaml @@ -0,0 +1,40 @@ +config: + problem: + frame_structure: "POV" + dimension: 3 + prior: + mode: "factor" + state: [0,0,0,0,0,0,1,0,0,0] + cov: [[9,9],.1,0,0,0,0,0,0,0,0, 0,.1,0,0,0,0,0,0,0, 0,0,.1,0,0,0,0,0,0, 0,0,0,.1,0,0,0,0,0, 0,0,0,0,.1,0,0,0,0, 0,0,0,0,0,.1,0,0,0, 0,0,0,0,0,0,.1,0,0, 0,0,0,0,0,0,0,.1,0, 0,0,0,0,0,0,0,0,.1] + time_tolerance: 0.1 + tree_manager: + type: "None" + sensors: + - + type: "SensorOdom3d" + name: "odom" + plugin: "core" + k_disp_to_disp: 0.1 + k_disp_to_rot: 0.1 + k_rot_to_rot: 0.1 + min_disp_var: 0.1 + min_rot_var: 0.1 + extrinsic: + pose: [1,2,3,0,0,0,1] + processors: + - + type: "ProcessorOdom3d" + name: "my_proc_odom3d" + sensor_name: "odom" + plugin: "core" + apply_loss_function: false + time_tolerance: 0.01 # seconds + keyframe_vote: + voting_active: false + voting_aux_active: false + max_time_span: 0.2 # seconds + max_buff_length: 10 # motion deltas + dist_traveled: 0.5 # meters + angle_turned: 0.1 # radians (1 rad approx 57 deg, approx 60 deg) + + unmeasured_perturbation_std: 0.00111 \ No newline at end of file diff --git a/test/yaml/params_tree_manager_sliding_window1.yaml b/test/yaml/params_tree_manager_sliding_window1.yaml new file mode 100644 index 0000000000000000000000000000000000000000..3a0f421c5c0048125d0a8afa742e873f79e703f6 --- /dev/null +++ b/test/yaml/params_tree_manager_sliding_window1.yaml @@ -0,0 +1,43 @@ +config: + problem: + frame_structure: "PO" + dimension: 3 + prior: + mode: "factor" + state: [0,0,0,0,0,0,1] + cov: [[6,6],.1,0,0,0,0,0, 0,.1,0,0,0,0, 0,0,.1,0,0,0, 0,0,0,.1,0,0, 0,0,0,0,.1,0, 0,0,0,0,0,.1] + time_tolerance: 0.1 + tree_manager: + type: "TreeManagerSlidingWindow" + n_key_frames: 3 + fix_first_key_frame: true + viral_remove_empty_parent: true + sensors: + - + type: "SensorOdom3d" + name: "odom" + plugin: "core" + k_disp_to_disp: 0.1 + k_disp_to_rot: 0.1 + k_rot_to_rot: 0.1 + min_disp_var: 0.1 + min_rot_var: 0.1 + extrinsic: + pose: [1,2,3,0,0,0,1] + processors: + - + type: "ProcessorOdom3d" + name: "my_proc_odom3d" + sensor_name: "odom" + plugin: "core" + apply_loss_function: false + time_tolerance: 0.01 # seconds + keyframe_vote: + voting_active: false + voting_aux_active: false + max_time_span: 0.2 # seconds + max_buff_length: 10 # motion deltas + dist_traveled: 0.5 # meters + angle_turned: 0.1 # radians (1 rad approx 57 deg, approx 60 deg) + + unmeasured_perturbation_std: 0.00111 \ No newline at end of file diff --git a/test/yaml/params_tree_manager_sliding_window2.yaml b/test/yaml/params_tree_manager_sliding_window2.yaml new file mode 100644 index 0000000000000000000000000000000000000000..894dadf651dfe18919881ca44a296f3df447246a --- /dev/null +++ b/test/yaml/params_tree_manager_sliding_window2.yaml @@ -0,0 +1,43 @@ +config: + problem: + frame_structure: "PO" + dimension: 3 + prior: + mode: "factor" + state: [0,0,0,0,0,0,1] + cov: [[6,6],.1,0,0,0,0,0, 0,.1,0,0,0,0, 0,0,.1,0,0,0, 0,0,0,.1,0,0, 0,0,0,0,.1,0, 0,0,0,0,0,.1] + time_tolerance: 0.1 + tree_manager: + type: "TreeManagerSlidingWindow" + n_key_frames: 3 + fix_first_key_frame: false + viral_remove_empty_parent: false + sensors: + - + type: "SensorOdom3d" + name: "odom" + plugin: "core" + k_disp_to_disp: 0.1 + k_disp_to_rot: 0.1 + k_rot_to_rot: 0.1 + min_disp_var: 0.1 + min_rot_var: 0.1 + extrinsic: + pose: [1,2,3,0,0,0,1] + processors: + - + type: "ProcessorOdom3d" + name: "my_proc_odom3d" + sensor_name: "odom" + plugin: "core" + apply_loss_function: false + time_tolerance: 0.01 # seconds + keyframe_vote: + voting_active: false + voting_aux_active: false + max_time_span: 0.2 # seconds + max_buff_length: 10 # motion deltas + dist_traveled: 0.5 # meters + angle_turned: 0.1 # radians (1 rad approx 57 deg, approx 60 deg) + + unmeasured_perturbation_std: 0.00111 \ No newline at end of file diff --git a/test/yaml/processor_odom_3d.yaml b/test/yaml/processor_odom_3d.yaml index 65b00b967a1b3c1ed870f979479db930caf78b5e..672421b5d074b7fd627bf955a879e3f10a3544e0 100644 --- a/test/yaml/processor_odom_3d.yaml +++ b/test/yaml/processor_odom_3d.yaml @@ -1,4 +1,4 @@ -type: "ProcessorOdom3d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. +type: "ProcessorOdom3d" # This must match the KEY used in the FactorySensor. Otherwise it is an error. time_tolerance: 0.01 # seconds diff --git a/test/yaml/sensor_odom_2d.yaml b/test/yaml/sensor_odom_2d.yaml index 0841d40b310d90064de6131e32ccaee189ab104c..2d26af901956a324988ac86a67a78dacb5ae8a67 100644 --- a/test/yaml/sensor_odom_2d.yaml +++ b/test/yaml/sensor_odom_2d.yaml @@ -1,4 +1,4 @@ -type: "SensorOdom2d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. +type: "SensorOdom2d" # This must match the KEY used in the FactorySensor. Otherwise it is an error. k_disp_to_disp: 0.02 # m^2 / m k_rot_to_rot: 0.01 # rad^2 / rad diff --git a/test/yaml/sensor_odom_3d.yaml b/test/yaml/sensor_odom_3d.yaml index 58db1c088fbc80339a78ba815fddbaf69674d3b6..8eb2b235011cb3cfe4f35b1f73da6344991af0da 100644 --- a/test/yaml/sensor_odom_3d.yaml +++ b/test/yaml/sensor_odom_3d.yaml @@ -1,4 +1,4 @@ -type: "SensorOdom3d" # This must match the KEY used in the SensorFactory. Otherwise it is an error. +type: "SensorOdom3d" # This must match the KEY used in the FactorySensor. Otherwise it is an error. k_disp_to_disp: 0.02 # m^2 / m k_disp_to_rot: 0.02 # rad^2 / m