diff --git a/CMakeLists.txt b/CMakeLists.txt index df643606ede38ae1bc66b832a40e37499c35ffe5..8d17620362c9176e48b0a5f694359f5ba4ab1b89 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -302,8 +302,6 @@ SET(SRCS_SENSOR src/sensor/sensor_base.cpp src/sensor/sensor_diff_drive.cpp src/sensor/sensor_motion_model.cpp - src/sensor/sensor_odom.cpp - src/sensor/sensor_pose.cpp ) SET(SRCS_SOLVER src/solver/solver_manager.cpp diff --git a/include/core/sensor/factory_sensor.h b/include/core/sensor/factory_sensor.h index 976097d4555649ed78315b036bd0b35d5b7637af..745b2d839759a8608072c663140589298d8c153b 100644 --- a/include/core/sensor/factory_sensor.h +++ b/include/core/sensor/factory_sensor.h @@ -210,11 +210,10 @@ namespace wolf */ typedef Factory<SensorBase, - SizeEigen, const YAML::Node&> FactorySensor; typedef Factory<SensorBase, - SizeEigen, + const std::string&, const std::string&, const std::vector<std::string>&> FactorySensorYaml; diff --git a/include/core/sensor/sensor_base.h b/include/core/sensor/sensor_base.h index cc1f5d408819c796b717349859681ce607870369..d849b3fae49bf6a150546cdda7be6eba1a5229ae 100644 --- a/include/core/sensor/sensor_base.h +++ b/include/core/sensor/sensor_base.h @@ -59,33 +59,31 @@ namespace wolf { * Also, there should be the schema file 'SensorClass.schema' containing the specifications * of the user input yaml file. */ -#define WOLF_SENSOR_CREATE(SensorClass, ParamsSensorClass) \ -static SensorBasePtr create(SizeEigen _dim, \ - const YAML::Node& _input_node) \ -{ \ - auto params = std::make_shared<ParamsSensorClass>(_input_node); \ - \ - auto priors = Priors(_input_node["states"]); \ - \ - return std::make_shared<SensorClass>(_dim, params, priors); \ -} \ -static SensorBasePtr create(SizeEigen _dim, \ - const std::string& _yaml_filepath, \ - const std::vector<std::string>& _folders_schema) \ -{ \ - auto server = yaml_schema_cpp::YamlServer(_folders_schema, _yaml_filepath); \ - \ - if (not server.applySchema(#SensorClass)) \ - { \ - WOLF_ERROR(server.getLog().str()); \ - return nullptr; \ - } \ - auto params = std::make_shared<ParamsSensorClass>(server.getNode()); \ - \ - auto priors = Priors(server.getNode()["states"]); \ - \ - return std::make_shared<SensorClass>(_dim, params, priors); \ -} \ +#define WOLF_SENSOR_CREATE(SensorClass, ParamsSensorClass) \ +static SensorBasePtr create(const YAML::Node& _input_node) \ +{ \ + auto params = std::make_shared<ParamsSensorClass>(_input_node); \ + \ + auto priors = Priors(_input_node["states"]); \ + \ + return std::make_shared<SensorClass>(params, priors); \ +} \ +static SensorBasePtr create(const std::string& _schema, \ + const std::string& _yaml_filepath, \ + const std::vector<std::string>& _folders_schema) \ +{ \ + auto server = yaml_schema_cpp::YamlServer(_folders_schema, _yaml_filepath); \ + \ + if (not server.applySchema(_schema)) \ + { \ + throw std::runtime_error(server.getLog().str()); \ + } \ + auto params = std::make_shared<ParamsSensorClass>(server.getNode()); \ + \ + auto priors = Priors(server.getNode()["states"]); \ + \ + return std::make_shared<SensorClass>(params, priors); \ +} \ /** \brief base struct for intrinsic sensor parameters * @@ -134,8 +132,10 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh protected: std::map<char, Eigen::MatrixXd> drift_covs_; // covariance of the drift of dynamic state blocks [unit²/s] + int dim_; ///< Dimension compatibility of the sensor: 2: 2D, 3: 3D, -1: both + void setProblem(ProblemPtr _problem) override final; - virtual void loadPriors(const Priors& _priors, SizeEigen _dim); + virtual void loadPriors(const Priors& _priors); public: @@ -143,19 +143,20 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh * * Constructor with parameter vector * \param _tp Type of the sensor (types defined at wolf.h) - * \param _dim Problem dimension + * \param _dim Which dimension is the sensor compatible (2: 2D, 3: 3D, -1: both) * \param _params params struct * \param _priors priors of the sensor state blocks * **/ SensorBase(const std::string& _type, - const SizeEigen& _dim, + const int& _dim, ParamsSensorBasePtr _params, const Priors& _priors); ~SensorBase() override; unsigned int id() const; + int dim() const; HardwareBaseConstPtr getHardware() const; HardwareBasePtr getHardware(); @@ -302,6 +303,11 @@ inline unsigned int SensorBase::id() const return sensor_id_; } +inline int SensorBase::dim() const +{ + return dim_; +} + inline ProcessorBaseConstPtrList SensorBase::getProcessorList() const { ProcessorBaseConstPtrList list_const; diff --git a/include/core/sensor/sensor_diff_drive.h b/include/core/sensor/sensor_diff_drive.h index 97f6e451a7ee5cb306fc8b57b9cb954e2f132f9e..c516eaf012c0783fc1d9fd091b91868ca63a80dc 100644 --- a/include/core/sensor/sensor_diff_drive.h +++ b/include/core/sensor/sensor_diff_drive.h @@ -54,14 +54,11 @@ WOLF_PTR_TYPEDEFS(SensorDiffDrive); class SensorDiffDrive : public SensorBase { public: - - - SensorDiffDrive(const SizeEigen& _dim, - ParamsSensorDiffDrivePtr _params, + SensorDiffDrive(ParamsSensorDiffDrivePtr _params, const Priors& _priors); - WOLF_SENSOR_CREATE(SensorDiffDrive, ParamsSensorDiffDrive); - ~SensorDiffDrive() override; + + ~SensorDiffDrive() override = default; ParamsSensorDiffDriveConstPtr getParams() const; ParamsSensorDiffDrivePtr getParams(); diff --git a/include/core/sensor/sensor_motion_model.h b/include/core/sensor/sensor_motion_model.h index 3b6c56effdf72ad6acaf733150d8627f9389fbc5..4d68fb6df0619e6b9a8f8989af635be37d68767e 100644 --- a/include/core/sensor/sensor_motion_model.h +++ b/include/core/sensor/sensor_motion_model.h @@ -31,8 +31,7 @@ WOLF_PTR_TYPEDEFS(SensorMotionModel); class SensorMotionModel : public SensorBase { public: - SensorMotionModel(const SizeEigen& _dim, - ParamsSensorBasePtr _params, + SensorMotionModel(ParamsSensorBasePtr _params, const Priors& _priors); WOLF_SENSOR_CREATE(SensorMotionModel, ParamsSensorBase); diff --git a/include/core/sensor/sensor_odom.h b/include/core/sensor/sensor_odom.h index 6cb43d327e62d67a92cb227d7c5507cf953c934d..1ed6e3c8799cc37469df7f80a4ded49822363c6d 100644 --- a/include/core/sensor/sensor_odom.h +++ b/include/core/sensor/sensor_odom.h @@ -59,17 +59,25 @@ struct ParamsSensorOdom : public ParamsSensorBase } }; -WOLF_PTR_TYPEDEFS(SensorOdom); +template <unsigned int DIM> class SensorOdom : public SensorBase { protected: - SizeEigen dim_; ParamsSensorOdomPtr params_odom_; public: - SensorOdom(const SizeEigen& _dim, ParamsSensorOdomPtr _params, const Priors& _priors); - WOLF_SENSOR_CREATE(SensorOdom, ParamsSensorOdom); + SensorOdom(ParamsSensorOdomPtr _params, + const Priors& _priors) : + SensorBase("SensorOdom"+toString(DIM)+"d", + DIM, + _params, + _priors), + params_odom_(_params) + { + static_assert(DIM == 2 or DIM == 3); + } + WOLF_SENSOR_CREATE(SensorOdom<DIM>, ParamsSensorOdom); ~SensorOdom() override = default; @@ -83,29 +91,92 @@ class SensorOdom : public SensorBase }; -inline double SensorOdom::getDispVarToDispNoiseFactor() const +template <unsigned int DIM> +inline double SensorOdom<DIM>::getDispVarToDispNoiseFactor() const { return params_odom_->k_disp_to_disp; } -inline double SensorOdom::getDispVarToRotNoiseFactor() const +template <unsigned int DIM> +inline double SensorOdom<DIM>::getDispVarToRotNoiseFactor() const { return params_odom_->k_disp_to_rot; } -inline double SensorOdom::getRotVarToRotNoiseFactor() const +template <unsigned int DIM> +inline double SensorOdom<DIM>::getRotVarToRotNoiseFactor() const { return params_odom_->k_rot_to_rot; } -inline double SensorOdom::getMinDispVar() const +template <unsigned int DIM> +inline double SensorOdom<DIM>::getMinDispVar() const { return params_odom_->min_disp_var; } -inline double SensorOdom::getMinRotVar() const +template <unsigned int DIM> +inline double SensorOdom<DIM>::getMinRotVar() const { return params_odom_->min_rot_var; } -} // namespace wolf \ No newline at end of file +template <unsigned int DIM> +inline Eigen::MatrixXd SensorOdom<DIM>::computeNoiseCov(const Eigen::VectorXd & _data) const +{ + double d; // displacement + double r; // rotation + + // 2D + if (DIM ==2) + { + assert(_data.size() == 2 or _data.size() == 3); + + // data = [forward_x, rotation_z] 2D + if (_data.size() == 2) + { + d = fabs(_data(0)); + r = fabs(_data(1)); + } + else + { + d = _data.head<2>().norm(); + r = fabs(_data(2)); + } + } + // 3D + else + { + assert(_data.size() == 6 or _data.size() == 7); + + d = _data.head<3>().norm(); + if (_data.size() == 6) + r = _data.tail<3>().norm(); + else + r = 2 * acos(_data(6)); // arc cos of real part of quaternion + } + + // variances + double dvar = std::max(params_odom_->min_disp_var, params_odom_->k_disp_to_disp * d); + double rvar = std::max(params_odom_->min_rot_var, params_odom_->k_disp_to_rot * d + params_odom_->k_rot_to_rot * r); + + // return + if (DIM == 2) + return (Vector2d() << dvar, rvar).finished().asDiagonal(); + else + return (Vector6d() << dvar, dvar, dvar, rvar, rvar, rvar).finished().asDiagonal(); +} + +typedef SensorOdom<2> SensorOdom2d; +typedef SensorOdom<3> SensorOdom3d; +WOLF_DECLARED_PTR_TYPEDEFS(SensorOdom2d); +WOLF_DECLARED_PTR_TYPEDEFS(SensorOdom3d); + +} /* namespace wolf */ + +// Register in the FactorySensor +#include "core/sensor/factory_sensor.h" +namespace wolf { +WOLF_REGISTER_SENSOR(SensorOdom2d); +WOLF_REGISTER_SENSOR(SensorOdom3d); +} \ No newline at end of file diff --git a/include/core/sensor/sensor_pose.h b/include/core/sensor/sensor_pose.h index c5ecbc516c730ad0ff79b9c7d9fbfd613993544f..abf7e9e1108b81b92ba3974ff6fe51a99ef24702 100644 --- a/include/core/sensor/sensor_pose.h +++ b/include/core/sensor/sensor_pose.h @@ -49,38 +49,73 @@ struct ParamsSensorPose : public ParamsSensorBase } }; -WOLF_PTR_TYPEDEFS(SensorPose); - +template <unsigned int DIM> class SensorPose : public SensorBase { protected: - SizeEigen dim_; ParamsSensorPosePtr params_pose_; public: - SensorPose(const SizeEigen& _dim, - ParamsSensorPosePtr _params, - const Priors& _priors); - - WOLF_SENSOR_CREATE(SensorPose, ParamsSensorPose); + SensorPose(ParamsSensorPosePtr _params, + const Priors& _priors) : + SensorBase("SensorPose"+toString(DIM)+"d", + DIM, + _params, + _priors), + params_pose_(_params) + { + static_assert(DIM == 2 or DIM == 3); + } + WOLF_SENSOR_CREATE(SensorPose<DIM>, ParamsSensorPose); - ~SensorPose() override; + ~SensorPose() override = default; double getStdP() const; double getStdO() const; Eigen::MatrixXd computeNoiseCov(const Eigen::VectorXd & _data) const override; - }; -inline double SensorPose::getStdP() const +template <unsigned int DIM> +inline double SensorPose<DIM>::getStdP() const { return params_pose_->std_p; } -inline double SensorPose::getStdO() const +template <unsigned int DIM> +inline double SensorPose<DIM>::getStdO() const { return params_pose_->std_o; } -} /* namespace wolf */ \ No newline at end of file +template <> +inline Eigen::MatrixXd SensorPose<2>::computeNoiseCov(const Eigen::VectorXd & _data) const +{ + return (Eigen::Vector3d() << params_pose_->std_p, + params_pose_->std_p, + params_pose_->std_o).finished().cwiseAbs2().asDiagonal(); +} +template <> +inline Eigen::MatrixXd SensorPose<3>::computeNoiseCov(const Eigen::VectorXd & _data) const +{ + return (Eigen::Vector6d() << params_pose_->std_p, + params_pose_->std_p, + params_pose_->std_p, + params_pose_->std_o, + params_pose_->std_o, + params_pose_->std_o).finished().cwiseAbs2().asDiagonal(); +} + +typedef SensorPose<2> SensorPose2d; +typedef SensorPose<3> SensorPose3d; +WOLF_DECLARED_PTR_TYPEDEFS(SensorPose2d); +WOLF_DECLARED_PTR_TYPEDEFS(SensorPose3d); + +} /* namespace wolf */ + +// Register in the FactorySensor +#include "core/sensor/factory_sensor.h" +namespace wolf { +WOLF_REGISTER_SENSOR(SensorPose2d); +WOLF_REGISTER_SENSOR(SensorPose3d); +} \ No newline at end of file diff --git a/schema/PriorModeDynamicNoiseDrift.schema b/schema/PriorModeDynamicNoiseDrift.schema deleted file mode 100644 index 4c14a56525015f0732ee83a8b7d2c88e2d44a82c..0000000000000000000000000000000000000000 --- a/schema/PriorModeDynamicNoiseDrift.schema +++ /dev/null @@ -1,26 +0,0 @@ -mode: - type: string - yaml_type: scalar - mandatory: true - options: - - "fix" - - "factor" - - "initial_guess" - doc: The prior mode can be 'factor' to add an absolute factor (requires 'noise_std'), 'fix' to set the values constant or 'initial_guess' to just set the values -dynamic: - type: bool - yaml_type: scalar - mandatory: true - doc: If the state is dynamic, i.e. it changes along time. -noise_std: - type: VectorXd - yaml_type: scalar - mandatory: false - default: [] - doc: A vector containing the stdev values of the noise of the factor, i.e. the sqrt of the diagonal elements of the covariance matrix. -drift_std: - type: VectorXd - yaml_type: scalar - mandatory: false - default: [] - doc: A vector containing the stdev values of the noise of the drift factor (only if dynamic==true), i.e. the sqrt of the diagonal elements of the covariance matrix. \ No newline at end of file diff --git a/schema/PriorO2d.schema b/schema/PriorO2d.schema index 402d0c37e6ba16513c8905cccc485edae9b52509..c5afbd8499317a4bfde12bf07a58e5fd3818a7b3 100644 --- a/schema/PriorO2d.schema +++ b/schema/PriorO2d.schema @@ -1,3 +1,4 @@ +follow: Prior.schema type: type: string yaml_type: scalar @@ -9,5 +10,4 @@ state: type: Vector1d yaml_type: scalar mandatory: true - doc: A vector containing the state values -follow: PriorModeDynamicNoiseDrift.schema \ No newline at end of file + doc: A vector containing the state values \ No newline at end of file diff --git a/schema/PriorO3d.schema b/schema/PriorO3d.schema index e7b1dd38bb1c88f297e3d831c7ca132c704888bc..c819039b271552bfdd085c782e161a6379233ba3 100644 --- a/schema/PriorO3d.schema +++ b/schema/PriorO3d.schema @@ -1,3 +1,4 @@ +follow: Prior.schema type: type: string yaml_type: scalar @@ -9,5 +10,4 @@ state: type: Vector4d yaml_type: scalar mandatory: true - doc: A vector containing the state values. It should be a quaternion (i.e. four values and normalized) -follow: PriorModeDynamicNoiseDrift.schema \ No newline at end of file + doc: A vector containing the state values. It should be a quaternion (i.e. four values and normalized) \ No newline at end of file diff --git a/schema/PriorP2d.schema b/schema/PriorP2d.schema index d8f19390fedf3e957ced97e9c63bc66a966c402c..ef333199230dfd8dc08847c1eb830b2a36f2eb99 100644 --- a/schema/PriorP2d.schema +++ b/schema/PriorP2d.schema @@ -1,3 +1,4 @@ +follow: Prior.schema type: type: string yaml_type: scalar @@ -9,5 +10,4 @@ state: type: Vector2d yaml_type: scalar mandatory: true - doc: A vector containing the state values -follow: PriorModeDynamicNoiseDrift.schema \ No newline at end of file + doc: A vector containing the state values \ No newline at end of file diff --git a/schema/PriorP3d.schema b/schema/PriorP3d.schema index d413a902908fcf31e4e9443afe65e78fbd12007e..de70f20a0ab78f2a3a0914aca916947cde5a22a6 100644 --- a/schema/PriorP3d.schema +++ b/schema/PriorP3d.schema @@ -1,3 +1,4 @@ +follow: Prior.schema type: type: string yaml_type: scalar @@ -9,5 +10,4 @@ state: type: Vector3d yaml_type: scalar mandatory: true - doc: A vector containing the state 'P' values -follow: PriorModeDynamicNoiseDrift.schema \ No newline at end of file + doc: A vector containing the state 'P' values \ No newline at end of file diff --git a/schema/sensor/SensorDiffDrive.schema b/schema/sensor/SensorDiffDrive.schema new file mode 100644 index 0000000000000000000000000000000000000000..e42352f9749376252bd19a306013ad5e0f4c4b13 --- /dev/null +++ b/schema/sensor/SensorDiffDrive.schema @@ -0,0 +1,36 @@ +follow: SensorBase.schema +ticks_per_wheel_revolution: + mandatory: true + type: double + yaml_type: scalar + doc: ratio of displacement variance to displacement, for odometry noise calculation. +ticks_std_factor: + mandatory: true + type: double + yaml_type: scalar + doc: ratio of displacement variance to rotation, for odometry noise calculation. + +states: + P: + follow: PriorP2d.schema + O: + follow: PriorO2d.schema + I: + follow: Prior.schema + type: + type: string + yaml_type: scalar + mandatory: false + default: StateParam3 + options: [StateParam3] + doc: The type of the SensorDiffDrive intrinsic parameters is StateParam3. + state: + type: Vector3d + yaml_type: scalar + mandatory: true + doc: A vector containing the intrinsic state values. 0=left wheel radius (m), 1=right wheel radius (m), 2=wheel separation (m) + + + + + diff --git a/schema/sensor/SensorOdom2d.schema b/schema/sensor/SensorOdom2d.schema index bb88b9ec536df2ebd6a52106a9ad232b1f4ff0f6..bd4574a7a812d79922c936085d803d1224305366 100644 --- a/schema/sensor/SensorOdom2d.schema +++ b/schema/sensor/SensorOdom2d.schema @@ -25,3 +25,9 @@ min_rot_var: yaml_type: scalar doc: minimum rotation variance, for odometry noise calculation. +states: + P: + follow: PriorP2d.schema + O: + follow: PriorO2d.schema + diff --git a/schema/sensor/SensorOdom3d.schema b/schema/sensor/SensorOdom3d.schema index 1c1f877db4590c5e0f700627f65e518d7f6f2baf..36bc601c940a59daed9c184bd846561051f4a07e 100644 --- a/schema/sensor/SensorOdom3d.schema +++ b/schema/sensor/SensorOdom3d.schema @@ -27,6 +27,6 @@ min_rot_var: states: P: - follow: Prior.schema + follow: PriorP3d.schema O: - follow: Prior.schema \ No newline at end of file + follow: PriorO3d.schema \ No newline at end of file diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp index 0442805fe31fa2cfdfc76622c508ca5db0a68d4d..6f1ace470ddf2bf636b8474212baa871515341a0 100644 --- a/src/problem/problem.cpp +++ b/src/problem/problem.cpp @@ -238,7 +238,7 @@ Problem::~Problem() SensorBasePtr Problem::installSensor(const YAML::Node& _sensor_node) { - SensorBasePtr sen_ptr = FactorySensor::create(_sensor_node["type"].as<std::string>(), dim_, _sensor_node); + SensorBasePtr sen_ptr = FactorySensor::create(_sensor_node["type"].as<std::string>(), _sensor_node); sen_ptr->link(getHardware()); return sen_ptr; } @@ -251,8 +251,8 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, { throw std::runtime_error("Cannot install sensor: provided params YAML file: '" + _params_yaml_filename + "' does not exist."); } - SensorBasePtr sen_ptr = FactorySensorYaml::create(_sen_type, - dim_, + SensorBasePtr sen_ptr = FactorySensorYaml::create(_sen_type, + _sen_type, _params_yaml_filename, _folders_schema); sen_ptr->link(getHardware()); diff --git a/src/processor/processor_odom_3d.cpp b/src/processor/processor_odom_3d.cpp index da78f58b3c300c93a85d761b5fd70a92caea9310..f6eb7c2d30a340d5235938ec5c1fbe000f96344a 100644 --- a/src/processor/processor_odom_3d.cpp +++ b/src/processor/processor_odom_3d.cpp @@ -39,8 +39,8 @@ ProcessorOdom3d::~ProcessorOdom3d() void ProcessorOdom3d::configure(SensorBasePtr _sensor) { - if (not std::dynamic_pointer_cast<SensorOdom>(_sensor)) - throw std::runtime_error("Configuring ProcessorOdom3d: provided sensor is null or not of type 'SensorOdom'"); + if (not std::dynamic_pointer_cast<SensorOdom3d>(_sensor)) + throw std::runtime_error("Configuring ProcessorOdom3d: provided sensor is null or not of type 'SensorOdom3d'"); } void ProcessorOdom3d::computeCurrentDelta(const Eigen::VectorXd& _data, diff --git a/src/processor/processor_pose.cpp b/src/processor/processor_pose.cpp index a9f53bf723eb77870df110a82a6cfa6d7bd0566b..1cc44ea0d3004bc025b7c38c7ce5c5b8c451ddff 100644 --- a/src/processor/processor_pose.cpp +++ b/src/processor/processor_pose.cpp @@ -44,7 +44,7 @@ void ProcessorPose::configure(SensorBasePtr _sensor) } void ProcessorPose::createFactorIfNecessary(){ - auto sensor_pose = std::static_pointer_cast<SensorPose>(getSensor()); + auto sensor_pose = std::static_pointer_cast<SensorPose3d>(getSensor()); auto kf_it_last = buffer_frame_.getContainer().end(); auto kf_it = buffer_frame_.getContainer().begin(); while (kf_it != buffer_frame_.getContainer().end()) diff --git a/src/sensor/sensor_base.cpp b/src/sensor/sensor_base.cpp index d6ad0ad51397794b095543f4a0ab14e01c4b2ad4..db7c52199433dc72922a008725d2b1785e365e58 100644 --- a/src/sensor/sensor_base.cpp +++ b/src/sensor/sensor_base.cpp @@ -33,7 +33,7 @@ namespace wolf { unsigned int SensorBase::sensor_id_count_ = 0; SensorBase::SensorBase(const std::string& _type, - const SizeEigen& _dim, + const int& _dim, ParamsSensorBasePtr _params, const Priors& _priors) : NodeBase("SENSOR", _type, _params->name), @@ -43,12 +43,11 @@ SensorBase::SensorBase(const std::string& _type, params_(_params), state_block_dynamic_(), params_prior_map_(), - last_capture_(nullptr) + last_capture_(nullptr), + dim_(_dim) { - assert(_dim == 2 or _dim == 3); - // load priors - loadPriors(_priors, _dim); + loadPriors(_priors); } SensorBase::~SensorBase() @@ -57,11 +56,8 @@ SensorBase::~SensorBase() removeStateBlocks(getProblem()); } -void SensorBase::loadPriors(const Priors& _priors, - SizeEigen _dim) +void SensorBase::loadPriors(const Priors& _priors) { - assert(_dim == 2 or _dim == 3); - // Iterate all keys in _priors for (auto state_pair : _priors) { @@ -69,18 +65,12 @@ void SensorBase::loadPriors(const Priors& _priors, auto prior = state_pair.second; // type - if (key == 'P' and _dim == 2 and prior.getType() != "P" and prior.getType() != "StatePoint2d") - throw std::runtime_error("Prior type for key P has to be 'P' or 'StatePoint2d'"); - if (key == 'P' and _dim == 3 and prior.getType() != "P" and prior.getType() != "StatePoint3d") - throw std::runtime_error("Prior type for key P has to be 'P' or 'StatePoint3d'"); - if (key == 'V' and _dim == 2 and prior.getType() != "V" and prior.getType() != "StatePoint2d") - throw std::runtime_error("Prior type for key V has to be 'V' or 'StatePoint2d'"); - if (key == 'V' and _dim == 3 and prior.getType() != "V" and prior.getType() != "StatePoint3d") - throw std::runtime_error("Prior type for key V has to be 'V' or 'StatePoint3d'"); - if (key == 'O' and _dim == 2 and prior.getType() != "O" and prior.getType() != "StateAngle") - throw std::runtime_error("Prior type for key O in 2D has to be 'O' or 'StateAngle'"); - if (key == 'O' and _dim == 3 and prior.getType() != "O" and prior.getType() != "StateQuaternion") - throw std::runtime_error("Prior type for key O in 3D has to be 'O' or 'StateQuaternion'"); + if (key == 'P' and prior.getType() != "P" and prior.getType() != "StatePoint2d" and prior.getType() != "StatePoint3d") + throw std::runtime_error("Prior type for key P has to be 'P', 'StatePoint2d' or 'StatePoint3d'"); + if (key == 'V' and prior.getType() != "V" and prior.getType() != "StateVector2d" and prior.getType() != "StateVector3d") + throw std::runtime_error("Prior type for key V has to be 'V' 'StateVector2d' or 'StateVector3d'"); + if (key == 'O' and prior.getType() != "O" and prior.getType() != "StateAngle" and prior.getType() != "StateQuaternion") + throw std::runtime_error("Prior type for key O in 3D has to be 'O', 'StateAngle' or 'StateQuaternion'"); // --- CREATE STATE BLOCK --- auto sb = FactoryStateBlock::create(prior.getType(), prior.getState(), prior.isFixed()); diff --git a/src/sensor/sensor_diff_drive.cpp b/src/sensor/sensor_diff_drive.cpp index 89151dd40e548f0e0eb8a232f74a9358cb976d5e..514769f5b94ec8934b462194e9c901b4deb64796 100644 --- a/src/sensor/sensor_diff_drive.cpp +++ b/src/sensor/sensor_diff_drive.cpp @@ -32,26 +32,13 @@ namespace wolf { -// SpecStates specs_states_diff_drive({{'I',SpecState("StateBlock", -// 3, -// "0: left wheel radius (m), 1: right wheel radius (m), 2: wheel separation (m)")}}); - -SensorDiffDrive::SensorDiffDrive(const SizeEigen& _dim, - ParamsSensorDiffDrivePtr _params, +SensorDiffDrive::SensorDiffDrive(ParamsSensorDiffDrivePtr _params, const Priors& _priors) : SensorBase("SensorDiffDrive", - _dim, + 2, _params, _priors), params_diff_drive_(_params) -{ - assert(_dim == 2 and "SensorDiffDrive only defined for 2D problems"); - - if (this->getStateBlockDynamic('I')->getState().size() != 3) - throw std::runtime_error("SensorDiffDrive in constructor, provided state for 'I' of wrong size. Is should be 3"); -} - -SensorDiffDrive::~SensorDiffDrive() { } diff --git a/src/sensor/sensor_motion_model.cpp b/src/sensor/sensor_motion_model.cpp index a3711abd5e857f7bd262caf6f6bbd34b2aba3a90..a567d2c4fe9ccaa0e8545955f3c3f8cc4c0d6a0d 100644 --- a/src/sensor/sensor_motion_model.cpp +++ b/src/sensor/sensor_motion_model.cpp @@ -23,11 +23,10 @@ namespace wolf { -SensorMotionModel::SensorMotionModel(const SizeEigen& _dim, - ParamsSensorBasePtr _params, +SensorMotionModel::SensorMotionModel(ParamsSensorBasePtr _params, const Priors& _priors) : SensorBase("SensorMotionModel", - _dim, + -1, _params, _priors) { diff --git a/src/sensor/sensor_odom.cpp b/src/sensor/sensor_odom.cpp deleted file mode 100644 index c3ac836ca19d31d17524aac9b2463d65e0a46f3b..0000000000000000000000000000000000000000 --- a/src/sensor/sensor_odom.cpp +++ /dev/null @@ -1,90 +0,0 @@ -//--------LICENSE_START-------- -// -// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -//--------LICENSE_END-------- -#include "core/sensor/sensor_odom.h" - -namespace wolf { - -SensorOdom::SensorOdom(const SizeEigen& _dim, - ParamsSensorOdomPtr _params, - const Priors& _priors) : - SensorBase("SensorOdom", - _dim, - _params, - _priors), - dim_(_dim), - params_odom_(_params) -{ -} - -Eigen::MatrixXd SensorOdom::computeNoiseCov(const Eigen::VectorXd & _data) const -{ - double d; // displacement - double r; // rotation - - // 2D - if (dim_ ==2) - { - assert(_data.size() == 2 or _data.size() == 3); - - // data = [forward_x, rotation_z] 2D - if (_data.size() == 2) - { - d = fabs(_data(0)); - r = fabs(_data(1)); - } - else - { - d = _data.head<2>().norm(); - r = fabs(_data(2)); - } - } - // 3D - else - { - assert(_data.size() == 6 or _data.size() == 7); - - d = _data.head<3>().norm(); - if (_data.size() == 6) - r = _data.tail<3>().norm(); - else - r = 2 * acos(_data(6)); // arc cos of real part of quaternion - } - - // variances - double dvar = std::max(params_odom_->min_disp_var, params_odom_->k_disp_to_disp * d); - double rvar = std::max(params_odom_->min_rot_var, params_odom_->k_disp_to_rot * d + params_odom_->k_rot_to_rot * r); - - // return - if (dim_ == 2) - return (Vector2d() << dvar, rvar).finished().asDiagonal(); - else - return (Vector6d() << dvar, dvar, dvar, rvar, rvar, rvar).finished().asDiagonal(); -} - -} - -// Register in the FactorySensor -#include "core/sensor/factory_sensor.h" -namespace wolf { -WOLF_REGISTER_SENSOR_WITH_KEY(SensorOdom2d, SensorOdom); -WOLF_REGISTER_SENSOR_WITH_KEY(SensorOdom3d, SensorOdom); -} // namespace wolf diff --git a/src/sensor/sensor_pose.cpp b/src/sensor/sensor_pose.cpp deleted file mode 100644 index 7af50dc3ebac9fc7d47e23814edc4b2f13afa000..0000000000000000000000000000000000000000 --- a/src/sensor/sensor_pose.cpp +++ /dev/null @@ -1,71 +0,0 @@ -//--------LICENSE_START-------- -// -// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informà tica Industrial, CSIC-UPC. -// Authors: Joan Solà Ortega (jsola@iri.upc.edu) -// All rights reserved. -// -// This file is part of WOLF -// WOLF is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with this program. If not, see <http://www.gnu.org/licenses/>. -// -//--------LICENSE_END-------- -/** - * \file sensor_pose.cpp - * - * Created on: Feb 18, 2020 - * \author: mfourmy - */ - -#include "core/sensor/sensor_pose.h" - -namespace wolf { - -SensorPose::SensorPose(const SizeEigen& _dim, - ParamsSensorPosePtr _params, - const Priors& _priors) : - SensorBase("SensorPose", - _dim, - _params, - _priors), - dim_(_dim), - params_pose_(_params) -{ -} - -SensorPose::~SensorPose() -{ - -} - -Eigen::MatrixXd SensorPose::computeNoiseCov(const Eigen::VectorXd & _data) const -{ - if (dim_ == 2) - return (Eigen::Vector3d() << params_pose_->std_p, - params_pose_->std_p, - params_pose_->std_o).finished().cwiseAbs2().asDiagonal(); - else - return (Eigen::Vector6d() << params_pose_->std_p, - params_pose_->std_p, - params_pose_->std_p, - params_pose_->std_o, - params_pose_->std_o, - params_pose_->std_o).finished().cwiseAbs2().asDiagonal(); -} - -} // namespace wolf - -// Register in the FactorySensor -#include "core/sensor/factory_sensor.h" -namespace wolf { -WOLF_REGISTER_SENSOR(SensorPose); -} diff --git a/src/state_block/prior.cpp b/src/state_block/prior.cpp index 781d5ebe3813caa10092b91ec59e701765c915a5..eabd2ef1835434e72032c496def94dc9b857f5e8 100644 --- a/src/state_block/prior.cpp +++ b/src/state_block/prior.cpp @@ -29,7 +29,6 @@ namespace wolf Priors::Priors(const YAML::Node& priors_node) { - WOLF_INFO("Priors..."); if (not priors_node.IsMap()) { throw std::runtime_error("Priors: constructor with a non-map yaml node"); @@ -38,7 +37,6 @@ Priors::Priors(const YAML::Node& priors_node) { this->emplace(prior_pair.first.as<char>(), Prior(prior_pair.second)); } - WOLF_INFO("Exiting priors constructor"); } Prior::Prior(const std::string& _type, @@ -54,7 +52,6 @@ Prior::Prior(const std::string& _type, Prior::Prior(const YAML::Node& prior_node) { - WOLF_INFO("Prior...\n", prior_node); type_ = prior_node["type"].as<std::string>(); state_ = prior_node["state"].as<Eigen::VectorXd>(); mode_ = prior_node["mode"].as<std::string>(); @@ -70,9 +67,7 @@ Prior::Prior(const YAML::Node& prior_node) else drift_std_ = Eigen::VectorXd(0); - WOLF_INFO("checking"); check(); - WOLF_INFO("Exiting prior constructor"); } void Prior::check() const diff --git a/test/dummy/SensorDummyPoia3d.schema b/test/dummy/SensorDummyPoia3d.schema index ac24447e53e658a3d01e3e306938bfdab99c19fc..3c54a371cade72b795c8cb9156e08c2a109de6ee 100644 --- a/test/dummy/SensorDummyPoia3d.schema +++ b/test/dummy/SensorDummyPoia3d.schema @@ -5,6 +5,7 @@ states: O: follow: PriorO3d.schema I: + follow: Prior.schema type: type: string yaml_type: scalar @@ -17,8 +18,8 @@ states: yaml_type: scalar mandatory: true doc: A vector containing the state 'I' values - follow: PriorModeDynamicNoiseDrift.schema A: + follow: Prior.schema type: type: string yaml_type: scalar @@ -31,7 +32,6 @@ states: yaml_type: scalar mandatory: true doc: A vector containing the state 'A' values - follow: PriorModeDynamicNoiseDrift.schema noise_p_std: mandatory: true type: double diff --git a/test/dummy/sensor_dummy.h b/test/dummy/sensor_dummy.h index 23ba2a36cc36d719b71c6dae13d768452119851f..5f82b090dc2327e4cda05f3d0dd07abbc4c50e85 100644 --- a/test/dummy/sensor_dummy.h +++ b/test/dummy/sensor_dummy.h @@ -51,28 +51,26 @@ struct ParamsSensorDummy : public ParamsSensorBase } }; -WOLF_PTR_TYPEDEFS(SensorDummy); - +template <unsigned int DIM> class SensorDummy : public SensorBase { private: ParamsSensorDummyPtr params_dummy_; - SizeEigen dim_; public: - SensorDummy(SizeEigen _dim, - ParamsSensorDummyPtr _params, + SensorDummy(ParamsSensorDummyPtr _params, const Priors& _priors) : - SensorBase("SensorDummy", - _dim, + SensorBase("SensorDummy"+toString(DIM)+"d", + DIM, _params, _priors), params_dummy_(_params) { + static_assert(DIM == 2 or DIM == 3); } - WOLF_SENSOR_CREATE(SensorDummy, ParamsSensorDummy); + WOLF_SENSOR_CREATE(SensorDummy<DIM>, ParamsSensorDummy); - virtual ~SensorDummy(){}; + virtual ~SensorDummy() = default; Eigen::MatrixXd computeNoiseCov(const Eigen::VectorXd & _data) const override { @@ -81,13 +79,19 @@ class SensorDummy : public SensorBase } }; -} +typedef SensorDummy<2> SensorDummy2d; +typedef SensorDummy<3> SensorDummy3d; +typedef SensorDummy<3> SensorDummyPoia3d; +WOLF_DECLARED_PTR_TYPEDEFS(SensorDummy2d); +WOLF_DECLARED_PTR_TYPEDEFS(SensorDummy3d); +WOLF_DECLARED_PTR_TYPEDEFS(SensorDummyPoia3d); + +} // namespace wolf // Register in the FactorySensor #include "core/sensor/factory_sensor.h" namespace wolf { -WOLF_REGISTER_SENSOR_WITH_KEY(SensorDummy2d, SensorDummy); -WOLF_REGISTER_SENSOR_WITH_KEY(SensorDummy3d, SensorDummy); -WOLF_REGISTER_SENSOR_WITH_KEY(SensorDummyPoia2d, SensorDummy); -WOLF_REGISTER_SENSOR_WITH_KEY(SensorDummyPoia3d, SensorDummy); -} // namespace wolf \ No newline at end of file +WOLF_REGISTER_SENSOR(SensorDummy2d); +WOLF_REGISTER_SENSOR(SensorDummy3d); +WOLF_REGISTER_SENSOR(SensorDummyPoia3d); +} \ No newline at end of file diff --git a/test/gtest_capture_base.cpp b/test/gtest_capture_base.cpp index 1e72d21aecaaf6f0de56d9baad6aeb02b50a9eae..e8823de12eda0f672114b57f16cd38e74af85337 100644 --- a/test/gtest_capture_base.cpp +++ b/test/gtest_capture_base.cpp @@ -43,7 +43,7 @@ TEST(CaptureBase, ConstructorNoSensor) TEST(CaptureBase, ConstructorWithSensor) { - SensorBasePtr S = FactorySensorYaml::create("SensorOdom2d", 2, wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + SensorBasePtr S = FactorySensorYaml::create("SensorOdom2d", "SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); CaptureBasePtr C(std::make_shared<CaptureBase>("DUMMY", 1.5, S)); // timestamp = 1.5 ASSERT_EQ(C->getTimeStamp(), 1.5); ASSERT_FALSE(C->getFrame()); @@ -53,7 +53,7 @@ TEST(CaptureBase, ConstructorWithSensor) TEST(CaptureBase, Static_sensor_params) { - SensorBasePtr S = FactorySensorYaml::create("SensorOdom2d", 2, wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + SensorBasePtr S = FactorySensorYaml::create("SensorOdom2d", "SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); CaptureBasePtr C(std::make_shared<CaptureBase>("DUMMY", 1.5, S)); // timestamp = 1.5 // query capture blocks @@ -64,7 +64,7 @@ TEST(CaptureBase, Static_sensor_params) TEST(CaptureBase, Dynamic_sensor_params) { - SensorBasePtr S = FactorySensorYaml::create("SensorDiffDrive", 2, wolf_root + "/test/yaml/sensor_diff_drive_dynamic.yaml", {wolf_root}); + SensorBasePtr S = FactorySensorYaml::create("SensorDiffDrive", "SensorDiffDrive", wolf_root + "/test/yaml/sensor_diff_drive_dynamic.yaml", {wolf_root}); StateBlockPtr p(std::make_shared<StateBlock>(2)); StateBlockPtr o(std::make_shared<StateAngle>() ); StateBlockPtr i(std::make_shared<StateBlock>(3)); @@ -96,7 +96,7 @@ TEST(CaptureBase, print) TEST(CaptureBase, process) { - SensorBasePtr S = FactorySensorYaml::create("SensorOdom", 2, wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + SensorBasePtr S = FactorySensorYaml::create("SensorOdom2d", "SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); CaptureBasePtr C(std::make_shared<CaptureBase>("DUMMY", 1.5, nullptr)); ASSERT_DEATH({C->process();},""); // No sensor in the capture should fail C->setSensor(S); diff --git a/test/gtest_frame_base.cpp b/test/gtest_frame_base.cpp index 111c8e5f60e9b7258054325981423d9503505a21..dc7ea50ecb32b1cbd40a26a446b311c282abfa9b 100644 --- a/test/gtest_frame_base.cpp +++ b/test/gtest_frame_base.cpp @@ -66,7 +66,7 @@ TEST(FrameBase, LinksBasic) ASSERT_FALSE(F->getTrajectory()); ASSERT_FALSE(F->getProblem()); - auto S = FactorySensorYaml::create("SensorOdom", 2, wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + auto S = FactorySensorYaml::create("SensorOdom2d", "SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); ASSERT_FALSE(F->getCaptureOf(S)); ASSERT_TRUE(F->getCaptureList().empty()); ASSERT_TRUE(F->getConstrainedByList().empty()); @@ -78,7 +78,7 @@ TEST(FrameBase, LinksToTree) // Problem with 2 frames and one motion factor between them ProblemPtr P = Problem::create("PO", 2); TrajectoryBasePtr T = P->getTrajectory(); - auto S = P->installSensor("SensorOdom", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + auto S = P->installSensor("SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); auto F1 = FrameBase::emplace<FrameBase>(T, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto F2 = FrameBase::emplace<FrameBase>(T, 2, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto C = CaptureBase::emplace<CaptureMotion>(F1, "CaptureMotion", 1, S, Vector3d::Zero(), nullptr); @@ -129,7 +129,7 @@ TEST(FrameBase, Frames) // Problem with 10 frames ProblemPtr P = Problem::create("PO", 2); TrajectoryBasePtr T = P->getTrajectory(); - auto S = P->installSensor("SensorOdom", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); + auto S = P->installSensor("SensorOdom2d", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root}); auto F0 = FrameBase::emplace<FrameBase>(T, 0, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto F1 = FrameBase::emplace<FrameBase>(T, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); auto F2 = FrameBase::emplace<FrameBase>(T, 2, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); diff --git a/test/gtest_prior.cpp b/test/gtest_prior.cpp index bcccda4a4f446732a8cfd3c33dcb944985559c61..b82a64b48beeeb4c29a85dfd4bc80917c59f19c0 100644 --- a/test/gtest_prior.cpp +++ b/test/gtest_prior.cpp @@ -440,7 +440,7 @@ TEST(Prior, ParamsServerWrong) std::string prefix = key + "_" + toString(dim) + "D_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : ""); WOLF_INFO("Creating prior from prefix ", prefix); - ASSERT_THROW(auto P = Prior(input_node[prefix]),std::runtime_error); + ASSERT_THROW(auto prior = Prior(input_node[prefix]),std::runtime_error); } // I @@ -454,7 +454,7 @@ TEST(Prior, ParamsServerWrong) std::string prefix = "I_" + mode + (dynamic ? "_dynamic" : "") + (drift ? "_drift" : ""); WOLF_INFO("Creating prior from prefix ", prefix); - ASSERT_THROW(auto P = Prior(input_node[prefix]),std::runtime_error); + ASSERT_THROW(auto prior = Prior(input_node[prefix]),std::runtime_error); } } diff --git a/test/gtest_processor_motion.cpp b/test/gtest_processor_motion.cpp index 9e9e278c3301e0dd6fb2b3787f82c7044c92d769..c4b37a73ff7bbfc2b613a2b137990581afce9627 100644 --- a/test/gtest_processor_motion.cpp +++ b/test/gtest_processor_motion.cpp @@ -57,7 +57,7 @@ class ProcessorMotion_test : public testing::Test{ public: double dt; ProblemPtr problem; - SensorOdomPtr sensor; + SensorOdom2dPtr sensor; ProcessorOdom2dPublicPtr processor; CaptureMotionPtr capture; Vector2d data; @@ -69,7 +69,7 @@ class ProcessorMotion_test : public testing::Test{ dt = 1.0; problem = Problem::create("PO", 2); - sensor = static_pointer_cast<SensorOdom>(problem->installSensor("SensorOdom", + sensor = static_pointer_cast<SensorOdom2d>(problem->installSensor("SensorOdom", wolf_root + "/test/yaml/sensor_odom_2d.yaml", {wolf_root})); ParamsProcessorOdom2dPtr params(std::make_shared<ParamsProcessorOdom2d>()); diff --git a/test/gtest_sensor_base.cpp b/test/gtest_sensor_base.cpp index 2607d430bd2a101783b16ea8ce34f4c218008d70..5280195fd62b8fcaf5050f34a5915321c34772a5 100644 --- a/test/gtest_sensor_base.cpp +++ b/test/gtest_sensor_base.cpp @@ -103,9 +103,9 @@ TEST(SensorBase, makeshared_priors_POfix2D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(2, params, - Priors({{'P',Prior("P", p_state_2D)}, //default "fix", not dynamic - {'O',Prior("O", o_state_2D)}})); + auto S = std::make_shared<SensorDummy2d>(params, + Priors({{'P',Prior("P", p_state_2D)}, //default "fix", not dynamic + {'O',Prior("O", o_state_2D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -123,9 +123,9 @@ TEST(SensorBase, makeshared_priors_POfix3D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D)}, //default "fix", not dynamic - {'O',Prior("O", o_state_3D)}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D)}, //default "fix", not dynamic + {'O',Prior("O", o_state_3D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -146,9 +146,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess2D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(2, params, - Priors({{'P',Prior("P", p_state_2D, "initial_guess")}, - {'O',Prior("O", o_state_2D, "initial_guess")}})); + auto S = std::make_shared<SensorDummy2d>(params, + Priors({{'P',Prior("P", p_state_2D, "initial_guess")}, + {'O',Prior("O", o_state_2D, "initial_guess")}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -169,9 +169,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess3D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D, "initial_guess")}, - {'O',Prior("O", o_state_3D, "initial_guess")}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D, "initial_guess")}, + {'O',Prior("O", o_state_3D, "initial_guess")}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -192,9 +192,9 @@ TEST(SensorBase, makeshared_priors_POfactor2D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(2, params, - Priors({{'P',Prior("P", p_state_2D, "factor", p_std_2D)}, - {'O',Prior("O", o_state_2D, "factor", o_std_2D)}})); + auto S = std::make_shared<SensorDummy2d>(params, + Priors({{'P',Prior("P", p_state_2D, "factor", p_std_2D)}, + {'O',Prior("O", o_state_2D, "factor", o_std_2D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -215,9 +215,9 @@ TEST(SensorBase, makeshared_priors_POfactor3D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D, "factor", p_std_3D)}, - {'O',Prior("O", o_state_3D, "factor", o_std_3D)}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D, "factor", p_std_3D)}, + {'O',Prior("O", o_state_3D, "factor", o_std_3D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -238,9 +238,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic2D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(2, params, - Priors({{'P',Prior("P", p_state_2D, "initial_guess", vector0, true)}, - {'O',Prior("O", o_state_2D, "initial_guess", vector0, true)}})); + auto S = std::make_shared<SensorDummy2d>(params, + Priors({{'P',Prior("P", p_state_2D, "initial_guess", vector0, true)}, + {'O',Prior("O", o_state_2D, "initial_guess", vector0, true)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -261,9 +261,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic3D) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D, "initial_guess", vector0, true)}, - {'O',Prior("O", o_state_3D, "initial_guess", vector0, true)}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D, "initial_guess", vector0, true)}, + {'O',Prior("O", o_state_3D, "initial_guess", vector0, true)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -284,9 +284,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic2D_drift) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(2, params, - Priors({{'P',Prior("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)}, - {'O',Prior("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}})); + auto S = std::make_shared<SensorDummy2d>(params, + Priors({{'P',Prior("P", p_state_2D, "initial_guess", vector0, true, p_std_2D)}, + {'O',Prior("O", o_state_2D, "initial_guess", vector0, true, o_std_2D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -307,9 +307,9 @@ TEST(SensorBase, makeshared_priors_POinitial_guess_dynamic3D_drift) params->noise_p_std = noise_p_std; params->noise_o_std = noise_o_std; - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)}, - {'O',Prior("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D, "initial_guess", vector0, true, p_std_3D)}, + {'O',Prior("O", o_state_3D, "initial_guess", vector0, true, o_std_3D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -332,11 +332,11 @@ TEST(SensorBase, makeshared_priors_POIA_mixed) VectorXd i_state_3D = VectorXd::Random(5); - auto S = std::make_shared<SensorDummy>(3, params, - Priors({{'P',Prior("P", p_state_3D, "fix", vector0, true)}, - {'O',Prior("O", o_state_3D, "factor", o_std_3D, true, o_std_3D)}, - {'I',Prior("StateBlock", i_state_3D, "initial_guess")}, - {'A',Prior("StateQuaternion", o_state_3D, "factor", o_std_3D)}})); + auto S = std::make_shared<SensorDummy3d>(params, + Priors({{'P',Prior("P", p_state_3D, "fix", vector0, true)}, + {'O',Prior("O", o_state_3D, "factor", o_std_3D, true, o_std_3D)}, + {'I',Prior("StateBlock", i_state_3D, "initial_guess")}, + {'A',Prior("StateQuaternion", o_state_3D, "factor", o_std_3D)}})); // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), noise_cov_dummy, Constants::EPS); @@ -400,7 +400,7 @@ TEST(SensorBase, factory) { ASSERT_TRUE(valid); - auto S = FactorySensor::create("SensorDummy"+toString(dim)+"d", dim, server.getNode()); + auto S = FactorySensor::create("SensorDummy"+toString(dim)+"d", server.getNode()); auto p_size = dim; auto o_size = dim == 2 ? 1 : 4; @@ -427,7 +427,7 @@ TEST(SensorBase, factory) // either is not valid (schema) or it throws an error if (valid) { - ASSERT_THROW(FactorySensor::create("SensorDummy"+toString(dim)+"d", dim, server.getNode()),std::runtime_error); + ASSERT_THROW(FactorySensor::create("SensorDummy"+toString(dim)+"d", server.getNode()),std::runtime_error); } } } @@ -439,8 +439,12 @@ TEST(SensorBase, factory) // Yaml server YamlServer server({wolf_root}, wolf_root + "/test/yaml/sensor_tests/sensor_POIA_3D.yaml"); + auto valid = server.applySchema("SensorDummyPoia3d"); + WOLF_WARN_COND(not valid, server.getLog().str()); + ASSERT_TRUE(valid); + // create sensor - auto S = FactorySensor::create("SensorDummyPoia3d", 3, server.getNode()); + auto S = FactorySensor::create("SensorDummyPoia3d", server.getNode()); WOLF_INFO("created"); // noise @@ -463,9 +467,14 @@ TEST(SensorBase, factory) // Yaml server YamlServer server({wolf_root}, wolf_root + "/test/yaml/sensor_tests/sensor_POIA_3D_wrong.yaml"); - + + auto valid = server.applySchema("SensorDummyPoia3d"); + // create sensor - ASSERT_THROW(FactorySensor::create("SensorDummyPoia3d", 3, server.getNode()),std::runtime_error); + if (valid) + { + ASSERT_THROW(FactorySensor::create("SensorDummyPoia3d", server.getNode()),std::runtime_error); + } } } @@ -498,6 +507,7 @@ TEST(SensorBase, factory_yaml) if (not dynamic and drift) continue; + std::string SensorType = "SensorDummy"+toString(dim)+"d"; std::string yaml_filepath = wolf_root + "/test/yaml/sensor_tests/" + "sensor_PO_" + @@ -509,12 +519,13 @@ TEST(SensorBase, factory_yaml) (wrong ? "_wrong" : "") + ".yaml"; - WOLF_INFO("Creating sensor from ", yaml_filepath); + WOLF_INFO("Creating sensor ", SensorType, " from ", yaml_filepath); + // CORRECT YAML if (not wrong) { - auto S = FactorySensorYaml::create("SensorDummy"+toString(dim)+"d", dim, yaml_filepath, {wolf_root}); + auto S = FactorySensorYaml::create(SensorType, SensorType, yaml_filepath, {wolf_root}); auto p_size = dim; auto o_size = dim == 2 ? 1 : 4; @@ -525,8 +536,8 @@ TEST(SensorBase, factory_yaml) // noise ASSERT_MATRIX_APPROX(S->computeNoiseCov(vector0), - noise_cov_dummy, - Constants::EPS); + noise_cov_dummy, + Constants::EPS); // factors ASSERT_EQ(S->getPriorFeatures().size(), mode == "factor" ? 2 : 0); @@ -538,7 +549,7 @@ TEST(SensorBase, factory_yaml) // INCORRECT YAML else { - ASSERT_THROW(FactorySensorYaml::create("SensorDummy"+toString(dim)+"d", dim, yaml_filepath, {wolf_root}),std::runtime_error); + ASSERT_THROW(FactorySensorYaml::create(SensorType, SensorType, yaml_filepath, {wolf_root}),std::runtime_error); } } @@ -547,8 +558,7 @@ TEST(SensorBase, factory_yaml) WOLF_INFO("Creating sensor from name sensor_POIA_3D.yaml"); // create sensor - auto S = FactorySensorYaml::create("SensorDummy3d", - 3, + auto S = FactorySensorYaml::create("SensorDummyPoia3d", "SensorDummyPoia3d", wolf_root + "/test/yaml/sensor_tests/sensor_POIA_3D.yaml", {wolf_root}); @@ -571,8 +581,7 @@ TEST(SensorBase, factory_yaml) WOLF_INFO("Creating sensor from name sensor_POIA_3D_wrong.yaml"); // create sensor - ASSERT_THROW(FactorySensorYaml::create("SensorDummyPoia3d", - 3, + ASSERT_THROW(FactorySensorYaml::create("SensorDummyPoia3d", "SensorDummyPoia3d", wolf_root + "/test/yaml/sensor_tests/sensor_POIA_3D_wrong.yaml", {wolf_root}), std::runtime_error); diff --git a/test/yaml/sensor_diff_drive_dynamic.yaml b/test/yaml/sensor_diff_drive_dynamic.yaml index e09cb6031d493d5936a7e664a563e260b86acffe..013e6af1f52471d922fc8bb23491829e3bd3b625 100644 --- a/test/yaml/sensor_diff_drive_dynamic.yaml +++ b/test/yaml/sensor_diff_drive_dynamic.yaml @@ -1,3 +1,4 @@ +name: a_cool_sensor_diff_drive_dynamic states: P: mode: fix