diff --git a/include/core/capture/capture_base.h b/include/core/capture/capture_base.h index 7864c46b9e03eb2b3609ca588d39e4ef1a06d975..f0670bfa64e6f3cacf460e22d312c8dd9e57fa80 100644 --- a/include/core/capture/capture_base.h +++ b/include/core/capture/capture_base.h @@ -19,6 +19,9 @@ namespace wolf{ //class CaptureBase class CaptureBase : public NodeBase, public std::enable_shared_from_this<CaptureBase> { + friend FeatureBase; + friend FactorBase; + private: FrameBaseWPtr frame_ptr_; FeatureBasePtrList feature_list_; @@ -57,14 +60,12 @@ class CaptureBase : public NodeBase, public std::enable_shared_from_this<Capture void setTimeStampToNow(); FrameBasePtr getFrame() const; + private: void setFrame(const FrameBasePtr _frm_ptr); - void unlinkFromFrame(){frame_ptr_.reset();} + public: virtual void setProblem(ProblemPtr _problem) final; - - FeatureBasePtr addFeature(FeatureBasePtr _ft_ptr); FeatureBasePtrList& getFeatureList(); - void addFeatureList(FeatureBasePtrList& _new_ft_list); void getFactorList(FactorBasePtrList& _fac_list); @@ -72,9 +73,12 @@ class CaptureBase : public NodeBase, public std::enable_shared_from_this<Capture virtual void setSensor(const SensorBasePtr sensor_ptr); // constrained by + private: virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); + virtual void removeConstrainedBy(FactorBasePtr _fac_ptr); + public: unsigned int getHits() const; - FactorBasePtrList& getConstrainedByList(); + const FactorBasePtrList& getConstrainedByList() const; // State blocks const std::vector<StateBlockPtr>& getStateBlockVec() const; @@ -106,6 +110,10 @@ class CaptureBase : public NodeBase, public std::enable_shared_from_this<Capture protected: SizeEigen computeCalibSize() const; + private: + FeatureBasePtr addFeature(FeatureBasePtr _ft_ptr); + void removeFeature(FeatureBasePtr _ft_ptr); + private: void updateCalibSize(); }; @@ -132,13 +140,6 @@ inline SizeEigen CaptureBase::getCalibSize() const return calib_size_; } -inline void CaptureBase::setProblem(ProblemPtr _problem) -{ - NodeBase::setProblem(_problem); - for (auto ft : feature_list_) - ft->setProblem(_problem); -} - inline void CaptureBase::updateCalibSize() { calib_size_ = computeCalibSize(); @@ -199,7 +200,7 @@ inline unsigned int CaptureBase::getHits() const return constrained_by_list_.size(); } -inline FactorBasePtrList& CaptureBase::getConstrainedByList() +inline const FactorBasePtrList& CaptureBase::getConstrainedByList() const { return constrained_by_list_; } diff --git a/include/core/factor/factor_autodiff_distance_3D.h b/include/core/factor/factor_autodiff_distance_3D.h index d4932885e58e941ad787c52a0428aa00ea6eec5e..e26c412812fd7c7e869a79c8b95085eac43ed633 100644 --- a/include/core/factor/factor_autodiff_distance_3D.h +++ b/include/core/factor/factor_autodiff_distance_3D.h @@ -34,7 +34,6 @@ class FactorAutodiffDistance3D : public FactorAutodiff<FactorAutodiffDistance3D, _feat->getFrame()->getP(), _frm_other->getP()) { - setFeature(_feat); } virtual ~FactorAutodiffDistance3D() { /* nothing */ } diff --git a/include/core/factor/factor_base.h b/include/core/factor/factor_base.h index 884f622a8c00a55d20d6cc2022cb90f2f795ec3f..fbc07e89af8850d9e4b4228817b5bbb6e5abac53 100644 --- a/include/core/factor/factor_base.h +++ b/include/core/factor/factor_base.h @@ -20,8 +20,8 @@ namespace wolf { */ typedef enum { - FAC_INACTIVE = 0, ///< Factor established with a frame (odometry). - FAC_ACTIVE = 1 ///< Factor established with absolute reference. + FAC_INACTIVE = 0, ///< Inactive factor, it is not included in the SLAM problem. + FAC_ACTIVE = 1 ///< Normal active factor, playing its role in the solution. } FactorStatus; /** \brief Enumeration of jacobian computation method @@ -45,32 +45,36 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa protected: unsigned int factor_id_; - FactorStatus status_; ///< status of factor (types defined at wolf.h) + FactorStatus status_; ///< status of factor bool apply_loss_function_; ///< flag for applying loss function to this factor - FrameBaseWPtr frame_other_ptr_; ///< FrameBase pointer (for category FAC_FRAME) + FrameBaseWPtr frame_other_ptr_; ///< FrameBase pointer CaptureBaseWPtr capture_other_ptr_; ///< CaptureBase pointer - FeatureBaseWPtr feature_other_ptr_; ///< FeatureBase pointer (for category FAC_FEATURE) - LandmarkBaseWPtr landmark_other_ptr_; ///< LandmarkBase pointer (for category FAC_LANDMARK) + FeatureBaseWPtr feature_other_ptr_; ///< FeatureBase pointer + LandmarkBaseWPtr landmark_other_ptr_; ///< LandmarkBase pointer ProcessorBaseWPtr processor_ptr_; ///< ProcessorBase pointer public: - /** \brief Constructor of category FAC_ABSOLUTE + /** \brief Constructor not involving nodes of other frames, only feature, capture and/or frame of this factor **/ FactorBase(const std::string& _tp, - bool _apply_loss_function = false, - FactorStatus _status = FAC_ACTIVE); + bool _apply_loss_function = false, + FactorStatus _status = FAC_ACTIVE); - /** \brief Constructor valid for all categories (FRAME, FEATURE, LANDMARK) + /** \brief Default constructor. + * + * IMPORTANT: "other" means "of another branch of the wolf tree". + * You should only provide a non-nullptr in frame/capture/feature_other_ptr in case of a frame/capture/feature involved in this factor + * that does not located in the same branch. **/ FactorBase(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 = nullptr, - bool _apply_loss_function = false, - FactorStatus _status = FAC_ACTIVE); + const FrameBasePtr& _frame_other_ptr, + const CaptureBasePtr& _capture_other_ptr, + const FeatureBasePtr& _feature_other_ptr, + const LandmarkBasePtr& _landmark_other_ptr, + const ProcessorBasePtr& _processor_ptr = nullptr, + bool _apply_loss_function = false, + FactorStatus _status = FAC_ACTIVE); virtual ~FactorBase() = default; @@ -113,7 +117,6 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa /** \brief Returns a pointer to the feature constrained from **/ FeatureBasePtr getFeature() const; - void setFeature(const FeatureBasePtr _ft_ptr){feature_ptr_ = _ft_ptr;} /** \brief Returns a pointer to its capture **/ @@ -135,51 +138,43 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa */ bool getApplyLossFunction(); - /** \brief Gets the apply loss function flag - */ - void setApplyLossFunction(const bool _apply); - /** \brief Returns a pointer to the frame constrained to **/ FrameBasePtr getFrameOther() const { return frame_other_ptr_.lock(); } - void setFrameOther(FrameBasePtr _frm_o) { frame_other_ptr_ = _frm_o; } - /** \brief Returns a pointer to the frame constrained to + /** \brief Returns a pointer to the capture constrained to **/ CaptureBasePtr getCaptureOther() const { return capture_other_ptr_.lock(); } - void setCaptureOther(CaptureBasePtr _cap_o) { capture_other_ptr_ = _cap_o; } /** \brief Returns a pointer to the feature constrained to **/ FeatureBasePtr getFeatureOther() const { return feature_other_ptr_.lock(); } - void setFeatureOther(FeatureBasePtr _ftr_o) { feature_other_ptr_ = _ftr_o; } /** \brief Returns a pointer to the landmark constrained to **/ LandmarkBasePtr getLandmarkOther() const { return landmark_other_ptr_.lock(); } - void setLandmarkOther(LandmarkBasePtr _lmk_o){ landmark_other_ptr_ = _lmk_o; } + public: /** * @brief getProcessor * @return */ ProcessorBasePtr getProcessor() const; + void link(FeatureBasePtr ftr); + virtual void setProblem(ProblemPtr) final; + template<typename classType, typename... T> + static std::shared_ptr<FactorBase> emplace(FeatureBasePtr _oth_ptr, T&&... all); + + private: + + void setFeature(const FeatureBasePtr _ft_ptr){feature_ptr_ = _ft_ptr;} + /** * @brief setProcessor * @param _processor_ptr */ void setProcessor(const ProcessorBasePtr& _processor_ptr); - - void link(FeatureBasePtr); - template<typename classType, typename... T> - static std::shared_ptr<FactorBase> emplace(FeatureBasePtr _oth_ptr, T&&... all); - -// protected: -// template<typename D> -// void print(const std::string& name, const Eigen::MatrixBase<D>& mat) const; // Do nothing if input Scalar type is ceres::Jet -// template<int R, int C> -// void print(const std::string& name, const Eigen::Matrix<Scalar, R, C>& mat) const; // Normal print if Scalar type is wolf::Scalar }; } @@ -194,25 +189,6 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa namespace wolf{ -//template<typename D> -//inline void FactorBase::print(const std::string& name, const Eigen::MatrixBase<D>& mat) const {} // Do nothing if input Scalar type is ceres::Jet -//template<int R, int C> -//inline void FactorBase::print(const std::string& name, const Eigen::Matrix<Scalar, R, C>& mat) const // Normal print if Scalar type is wolf::Scalar -//{ -// if (mat.cols() == 1) -// { -// WOLF_TRACE(name, ": ", mat.transpose()); -// } -// else if (mat.rows() == 1) -// { -// WOLF_TRACE(name, ": ", mat); -// } -// else -// { -// WOLF_TRACE(name, ":\n", mat); -// } -//} - template<typename classType, typename... T> std::shared_ptr<FactorBase> FactorBase::emplace(FeatureBasePtr _ftr_ptr, T&&... all) { diff --git a/include/core/feature/feature_base.h b/include/core/feature/feature_base.h index 72a2be8a46ba1f4e95b448570ac649d478a86054..2d3506fc96cea72a4db1ed6102edf60169e54682 100644 --- a/include/core/feature/feature_base.h +++ b/include/core/feature/feature_base.h @@ -18,6 +18,8 @@ namespace wolf { //class FeatureBase class FeatureBase : public NodeBase, public std::enable_shared_from_this<FeatureBase> { + friend FactorBase; + private: CaptureBaseWPtr capture_ptr_; FactorBasePtrList factor_list_; @@ -83,24 +85,30 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature FrameBasePtr getFrame() const; CaptureBasePtr getCapture() const; - void setCapture(CaptureBasePtr _cap_ptr){capture_ptr_ = _cap_ptr;} - FactorBasePtr addFactor(FactorBasePtr _co_ptr); FactorBasePtrList& getFactorList(); - virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); unsigned int getHits() const; - FactorBasePtrList& getConstrainedByList(); + const FactorBasePtrList& getConstrainedByList() const; // all factors void getFactorList(FactorBasePtrList & _fac_list); - void link(CaptureBasePtr); + void link(CaptureBasePtr cap_ptr); template<typename classType, typename... T> static std::shared_ptr<FeatureBase> emplace(CaptureBasePtr _cpt_ptr, T&&... all); - private: + + protected: + Eigen::MatrixXs computeSqrtUpper(const Eigen::MatrixXs& _M) const; + + private: + void setCapture(CaptureBasePtr _cap_ptr){capture_ptr_ = _cap_ptr;} + FactorBasePtr addFactor(FactorBasePtr _co_ptr); + void removeFactor(FactorBasePtr _co_ptr); + virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); + virtual void removeConstrainedBy(FactorBasePtr _fac_ptr); }; } @@ -124,7 +132,7 @@ inline unsigned int FeatureBase::getHits() const return constrained_by_list_.size(); } -inline FactorBasePtrList& FeatureBase::getConstrainedByList() +inline const FactorBasePtrList& FeatureBase::getConstrainedByList() const { return constrained_by_list_; } diff --git a/include/core/frame/frame_base.h b/include/core/frame/frame_base.h index 0fdb349c15db78a40fbe2b658c739c776a9b2c3d..23f3d0975565dfd2d9f123d4b78c291925bba810 100644 --- a/include/core/frame/frame_base.h +++ b/include/core/frame/frame_base.h @@ -30,6 +30,9 @@ typedef enum //class FrameBase class FrameBase : public NodeBase, public std::enable_shared_from_this<FrameBase> { + friend CaptureBase; + friend FactorBase; + private: TrajectoryBaseWPtr trajectory_ptr_; CaptureBasePtrList capture_list_; @@ -106,6 +109,7 @@ class FrameBase : public NodeBase, public std::enable_shared_from_this<FrameBase void setP(const StateBlockPtr _p_ptr); void setO(const StateBlockPtr _o_ptr); void setV(const StateBlockPtr _v_ptr); + protected: void registerNewStateBlocks(); void removeStateBlocks(); @@ -128,39 +132,33 @@ class FrameBase : public NodeBase, public std::enable_shared_from_this<FrameBase virtual void setProblem(ProblemPtr _problem) final; TrajectoryBasePtr getTrajectory() const; - void setTrajectory(TrajectoryBasePtr _trj_ptr); FrameBasePtr getPreviousFrame() const; FrameBasePtr getNextFrame() const; CaptureBasePtrList& getCaptureList(); - CaptureBasePtr addCapture(CaptureBasePtr _capt_ptr); CaptureBasePtr getCaptureOf(const SensorBasePtr _sensor_ptr); CaptureBasePtr getCaptureOf(const SensorBasePtr _sensor_ptr, const std::string& type); CaptureBasePtrList getCapturesOf(const SensorBasePtr _sensor_ptr); - void unlinkCapture(CaptureBasePtr _cap_ptr); FactorBasePtr getFactorOf(const ProcessorBasePtr _processor_ptr); FactorBasePtr getFactorOf(const ProcessorBasePtr _processor_ptr, const std::string& type); void getFactorList(FactorBasePtrList& _fac_list); - virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); unsigned int getHits() const; - FactorBasePtrList& getConstrainedByList(); + const FactorBasePtrList& getConstrainedByList() const; void link(TrajectoryBasePtr); template<typename classType, typename... T> static std::shared_ptr<FrameBase> emplace(TrajectoryBasePtr _ptr, T&&... all); - public: - static FrameBasePtr create_PO_2D (const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x = Eigen::VectorXs::Zero(3)); - static FrameBasePtr create_PO_3D (const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x = Eigen::VectorXs::Zero(7)); - static FrameBasePtr create_POV_3D(const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x = Eigen::VectorXs::Zero(10)); + private: + + CaptureBasePtr addCapture(CaptureBasePtr _capt_ptr); + void removeCapture(CaptureBasePtr _capt_ptr); + void setTrajectory(TrajectoryBasePtr _trj_ptr); + virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); + virtual void removeConstrainedBy(FactorBasePtr _fac_ptr); + }; } // namespace wolf @@ -283,14 +281,7 @@ inline unsigned int FrameBase::getHits() const return constrained_by_list_.size(); } -inline void FrameBase::setProblem(ProblemPtr _problem) -{ - NodeBase::setProblem(_problem); - for (auto cap : capture_list_) - cap->setProblem(_problem); -} - -inline FactorBasePtrList& FrameBase::getConstrainedByList() +inline const FactorBasePtrList& FrameBase::getConstrainedByList() const { return constrained_by_list_; } diff --git a/include/core/hardware/hardware_base.h b/include/core/hardware/hardware_base.h index 1b4149a6d32671492d1eee3c05e13dacb79e92fa..99a4179542d3857ed670b4dd95ac8607c1e588b5 100644 --- a/include/core/hardware/hardware_base.h +++ b/include/core/hardware/hardware_base.h @@ -16,6 +16,8 @@ namespace wolf { //class HardwareBase class HardwareBase : public NodeBase, public std::enable_shared_from_this<HardwareBase> { + friend SensorBase; + private: SensorBasePtrList sensor_list_; @@ -23,8 +25,10 @@ class HardwareBase : public NodeBase, public std::enable_shared_from_this<Hardwa HardwareBase(); virtual ~HardwareBase(); - virtual SensorBasePtr addSensor(SensorBasePtr _sensor_ptr); SensorBasePtrList& getSensorList(); + + private: + virtual SensorBasePtr addSensor(SensorBasePtr _sensor_ptr); }; } // namespace wolf diff --git a/include/core/landmark/landmark_base.h b/include/core/landmark/landmark_base.h index 373b20149b9202ca61fcfb1c1ea4d265e284f63f..57d294acfe4404cb16fc3abdcc15e5225d2053ac 100644 --- a/include/core/landmark/landmark_base.h +++ b/include/core/landmark/landmark_base.h @@ -22,6 +22,8 @@ namespace wolf { //class LandmarkBase class LandmarkBase : public NodeBase, public std::enable_shared_from_this<LandmarkBase> { + friend FactorBase; + private: MapBaseWPtr map_ptr_; FactorBasePtrList constrained_by_list_; @@ -68,12 +70,12 @@ class LandmarkBase : public NodeBase, public std::enable_shared_from_this<Landma StateBlockPtr getO() const; void setP(const StateBlockPtr _p_ptr); void setO(const StateBlockPtr _o_ptr); - virtual void registerNewStateBlocks(); Eigen::VectorXs getState() const; void getState(Eigen::VectorXs& _state) const; bool getCovariance(Eigen::MatrixXs& _cov) const; protected: + virtual void registerNewStateBlocks(); virtual void removeStateBlocks(); // Descriptor @@ -85,11 +87,9 @@ class LandmarkBase : public NodeBase, public std::enable_shared_from_this<Landma // Navigate wolf tree virtual void setProblem(ProblemPtr _problem) final; - FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); unsigned int getHits() const; - FactorBasePtrList& getConstrainedByList(); + const FactorBasePtrList& getConstrainedByList() const; - void setMap(const MapBasePtr _map_ptr); MapBasePtr getMap(); void link(MapBasePtr); template<typename classType, typename... T> @@ -100,6 +100,12 @@ class LandmarkBase : public NodeBase, public std::enable_shared_from_this<Landma * These need to be set afterwards. */ static LandmarkBasePtr create(const YAML::Node& _node); + + private: + + void setMap(const MapBasePtr _map_ptr); + virtual FactorBasePtr addConstrainedBy(FactorBasePtr _fac_ptr); + virtual void removeConstrainedBy(FactorBasePtr _fac_ptr); }; } @@ -117,10 +123,6 @@ std::shared_ptr<LandmarkBase> LandmarkBase::emplace(MapBasePtr _map_ptr, T&&... lmk->link(_map_ptr); return lmk; } -inline void LandmarkBase::setProblem(ProblemPtr _problem) -{ - NodeBase::setProblem(_problem); -} inline MapBasePtr LandmarkBase::getMap() { @@ -149,7 +151,7 @@ inline unsigned int LandmarkBase::getHits() const return constrained_by_list_.size(); } -inline FactorBasePtrList& LandmarkBase::getConstrainedByList() +inline const FactorBasePtrList& LandmarkBase::getConstrainedByList() const { return constrained_by_list_; } diff --git a/include/core/map/map_base.h b/include/core/map/map_base.h index 90ad785458a9a3a62f6882c7294945c19ceedcc8..d4d5f4fb7de8356cf53fe05283c53093842ebb6c 100644 --- a/include/core/map/map_base.h +++ b/include/core/map/map_base.h @@ -19,6 +19,8 @@ namespace wolf { //class MapBase class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase> { + friend LandmarkBase; + private: LandmarkBasePtrList landmark_list_; @@ -26,8 +28,11 @@ class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase> MapBase(); ~MapBase(); + private: virtual LandmarkBasePtr addLandmark(LandmarkBasePtr _landmark_ptr); - virtual void addLandmarkList(LandmarkBasePtrList& _landmark_list); + virtual void removeLandmark(LandmarkBasePtr _landmark_ptr); + + public: LandmarkBasePtrList& getLandmarkList(); void load(const std::string& _map_file_yaml); diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h index 935a887be9a1bbbf467335d54692204e0b6f62b0..6aca54c5d7109822c26aede36da25ecbe58e5491 100644 --- a/include/core/problem/problem.h +++ b/include/core/problem/problem.h @@ -38,6 +38,8 @@ enum Notification class Problem : public std::enable_shared_from_this<Problem> { friend SolverManager; // Enable SolverManager to acces protected functions (consumeXXXNotificationMap()) + friend ProcessorBase; + friend ProcessorMotion; protected: HardwareBasePtr hardware_ptr_; @@ -72,7 +74,6 @@ class Problem : public std::enable_shared_from_this<Problem> // Hardware branch ------------------------------------ HardwareBasePtr getHardware(); - void addSensor(SensorBasePtr _sen_ptr); /** \brief Factory method to install (create and add) sensors only from its properties * \param _sen_type type of sensor @@ -95,12 +96,12 @@ class Problem : public std::enable_shared_from_this<Problem> const std::string& _unique_sensor_name, // const Eigen::VectorXs& _extrinsics, // const std::string& _intrinsics_filename); - /** - Custom installSensor using the parameters server - */ - SensorBasePtr installSensor(const std::string& _sen_type, // - const std::string& _unique_sensor_name, - const paramsServer& _server); + /** + Custom installSensor using the parameters server + */ + SensorBasePtr installSensor(const std::string& _sen_type, // + const std::string& _unique_sensor_name, + const paramsServer& _server); /** \brief get a sensor pointer by its name * \param _sensor_name The sensor name, as it was installed with installSensor() */ @@ -134,20 +135,23 @@ class Problem : public std::enable_shared_from_this<Problem> const std::string& _corresponding_sensor_name, // const std::string& _params_filename = ""); - /** - Custom installProcessor to be used with parameters server - */ - ProcessorBasePtr installProcessor(const std::string& _prc_type, // - const std::string& _unique_processor_name, // - const std::string& _corresponding_sensor_name, // - const paramsServer& _server); - /** \brief Set the processor motion + /** + Custom installProcessor to be used with parameters server + */ + ProcessorBasePtr installProcessor(const std::string& _prc_type, // + const std::string& _unique_processor_name, // + const std::string& _corresponding_sensor_name, // + const paramsServer& _server); + protected: + /** \brief Set the processor motion * * Set the processor motion. */ void setProcessorMotion(ProcessorMotionPtr _processor_motion_ptr); ProcessorMotionPtr setProcessorMotion(const std::string& _unique_processor_name); void clearProcessorMotion(); + + public: ProcessorMotionPtr& getProcessorMotion(); // Trajectory branch ---------------------------------- @@ -268,8 +272,6 @@ class Problem : public std::enable_shared_from_this<Problem> // Map branch ----------------------------------------- MapBasePtr getMap(); - LandmarkBasePtr addLandmark(LandmarkBasePtr _lmk_ptr); - void addLandmarkList(LandmarkBasePtrList& _lmk_list); void loadMap(const std::string& _filename_dot_yaml); void saveMap(const std::string& _filename_dot_yaml, // const std::string& _map_name = "Map automatically saved by Wolf"); @@ -288,13 +290,9 @@ class Problem : public std::enable_shared_from_this<Problem> // Solver management ---------------------------------------- - /** \brief Notifies a new state block to be added to the solver manager - */ - StateBlockPtr addStateBlock(StateBlockPtr _state_ptr); - - /** \brief Notifies a state block to be removed from the solver manager + /** \brief Notifies a new/removed state block to update the solver manager */ - void removeStateBlock(StateBlockPtr _state_ptr); + StateBlockPtr notifyStateBlock(StateBlockPtr _state_ptr, Notification _notif); /** \brief Returns the size of the map of state block notification */ @@ -304,13 +302,9 @@ class Problem : public std::enable_shared_from_this<Problem> */ bool getStateBlockNotification(const StateBlockPtr& sb_ptr, Notification& notif) const; - /** \brief Notifies a new factor to be added to the solver manager - */ - FactorBasePtr addFactor(FactorBasePtr _factor_ptr); - - /** \brief Notifies a factor to be removed from the solver manager + /** \brief Notifies a new/removed factor to update the solver manager */ - void removeFactor(FactorBasePtr _factor_ptr); + FactorBasePtr notifyFactor(FactorBasePtr _factor_ptr, Notification _notif); /** \brief Returns the size of the map of factor notification */ diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h index 4ac6c161d079579783d13ae7a232c0f915a1170f..083c2c6f142dfe8df89fb18b77ae79180e2b92d4 100644 --- a/include/core/processor/processor_base.h +++ b/include/core/processor/processor_base.h @@ -266,8 +266,10 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce SensorBasePtr getSensor(); const SensorBasePtr getSensor() const; + private: void setSensor(SensorBasePtr _sen_ptr){sensor_ptr_ = _sen_ptr;} + public: virtual bool isMotion(); void setTimeTolerance(Scalar _time_tolerance); diff --git a/include/core/processor/processor_diff_drive.h b/include/core/processor/processor_diff_drive.h index 60fbf8d295e0dd519e4d5a69cf4dc52e18349811..78ef6ca50c80e653f7143ebe72e310b859d7a18f 100644 --- a/include/core/processor/processor_diff_drive.h +++ b/include/core/processor/processor_diff_drive.h @@ -93,16 +93,19 @@ protected: Motion& _second, TimeStamp& _ts) override; - virtual CaptureMotionPtr createCapture(const TimeStamp& _ts, - const SensorBasePtr& _sensor, - const VectorXs& _data, - const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) override; + virtual CaptureMotionPtr emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) override; virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature, CaptureBasePtr _capture_origin) override; - virtual FeatureBasePtr createFeature(CaptureMotionPtr _capture_motion) override; + virtual FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_motion) override; public: diff --git a/include/core/processor/processor_motion.h b/include/core/processor/processor_motion.h index d6cacdccdd701c40fb38b0db1349ab39f4580dd0..fe77c60535d7124c1c780bf6738a78743e293a1c 100644 --- a/include/core/processor/processor_motion.h +++ b/include/core/processor/processor_motion.h @@ -218,6 +218,8 @@ class ProcessorMotion : public ProcessorBase */ FrameBasePtr setOrigin(const Eigen::VectorXs& _x_origin, const TimeStamp& _ts_origin); + virtual void setProblem(ProblemPtr); + MotionBuffer& getBuffer(); const MotionBuffer& getBuffer() const; @@ -409,7 +411,7 @@ class ProcessorMotion : public ProcessorBase */ virtual Motion interpolate(const Motion& _ref1, const Motion& _ref2, const TimeStamp& _ts, Motion& _second); - /** \brief create a CaptureMotion and add it to a Frame + /** \brief emplace a CaptureMotion * \param _ts time stamp * \param _sensor Sensor that produced the Capture * \param _data a vector of motion data @@ -417,32 +419,21 @@ class ProcessorMotion : public ProcessorBase * \param _frame_own frame owning the Capture to create * \param _frame_origin frame acting as the origin of motions for the MorionBuffer of the created MotionCapture */ - CaptureMotionPtr emplaceCapture(const FrameBasePtr& _frame_own, - const SensorBasePtr& _sensor, - const TimeStamp& _ts, - const VectorXs& _data, - const MatrixXs& _data_cov, - const VectorXs& _calib, - const VectorXs& _calib_preint, - const FrameBasePtr& _frame_origin); - - virtual CaptureMotionPtr createCapture(const TimeStamp& _ts, - const SensorBasePtr& _sensor, - const VectorXs& _data, - const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) = 0; - - /** \brief create a feature corresponding to given capture and add the feature to this capture - * \param _capture_motion: the parent capture - */ - FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_own); - - /** \brief create a feature corresponding to given capture + virtual CaptureMotionPtr emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) = 0; + + /** \brief emplace a feature corresponding to given capture and add the feature to this capture * \param _capture_motion: the parent capture */ - virtual FeatureBasePtr createFeature(CaptureMotionPtr _capture_own) = 0; + virtual FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_own) = 0; - /** \brief create a factor and link it in the wolf tree + /** \brief emplace a factor and link it in the wolf tree * \param _feature_motion: the parent feature * \param _frame_origin: the frame constrained by this motion factor */ diff --git a/include/core/processor/processor_odom_2D.h b/include/core/processor/processor_odom_2D.h index fdcf820856bb061e445273a72334b20698b9564b..37d6c9ee11c6f9c518ccbcdeb01bc9fa3f2c20a5 100644 --- a/include/core/processor/processor_odom_2D.h +++ b/include/core/processor/processor_odom_2D.h @@ -73,12 +73,15 @@ class ProcessorOdom2D : public ProcessorMotion const TimeStamp& _ts, Motion& _second) override; - virtual CaptureMotionPtr createCapture(const TimeStamp& _ts, - const SensorBasePtr& _sensor, - const VectorXs& _data, - const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) override; - virtual FeatureBasePtr createFeature(CaptureMotionPtr _capture_motion) override; + virtual CaptureMotionPtr emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) override; + virtual FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_motion) override; virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature, CaptureBasePtr _capture_origin) override; diff --git a/include/core/processor/processor_odom_3D.h b/include/core/processor/processor_odom_3D.h index b5fc2dedf099e74bfbd64e7b28ca313cdd1bd412..1c70a3b3385c82116609fa47d3897ca82d89f800 100644 --- a/include/core/processor/processor_odom_3D.h +++ b/include/core/processor/processor_odom_3D.h @@ -95,14 +95,19 @@ class ProcessorOdom3D : public ProcessorMotion const TimeStamp& _ts, Motion& _second) override; bool voteForKeyFrame() override; - virtual CaptureMotionPtr createCapture(const TimeStamp& _ts, - const SensorBasePtr& _sensor, - const VectorXs& _data, - const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) override; + virtual CaptureMotionPtr emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) override; + + virtual FeatureBasePtr emplaceFeature(CaptureMotionPtr _capture_motion) override; + virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_motion, - CaptureBasePtr _capture_origin) override; - virtual FeatureBasePtr createFeature(CaptureMotionPtr _capture_motion) override; + CaptureBasePtr _capture_origin) override; protected: ProcessorParamsOdom3DPtr params_odom_3D_; diff --git a/include/core/processor/processor_tracker.h b/include/core/processor/processor_tracker.h index 9f85d65f658b1790f886ae01300c7aeb550d5c5d..17de27c05b0e210b12f46a3d43ad89d6ab8510ef 100644 --- a/include/core/processor/processor_tracker.h +++ b/include/core/processor/processor_tracker.h @@ -103,8 +103,6 @@ class ProcessorTracker : public ProcessorBase 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 - SizeStd number_of_tracks_; - public: ProcessorTracker(const std::string& _type, ProcessorParamsTrackerPtr _params_tracker); @@ -210,18 +208,9 @@ class ProcessorTracker : public ProcessorBase FeatureBasePtrList& getNewFeaturesListLast(); - const SizeStd& previousNumberOfTracks() const - { - return number_of_tracks_; - } - - SizeStd& previousNumberOfTracks() - { - return number_of_tracks_; + std::string print(){ + return this->params_tracker_->print(); } - std::string print(){ - return this->params_tracker_->print(); - } protected: diff --git a/include/core/processor/processor_tracker_feature.h b/include/core/processor/processor_tracker_feature.h index 055e2ddf87220a65289c09e20746dd4da990541d..a808a421da22a74ad417b6cdc38024f308ff59bf 100644 --- a/include/core/processor/processor_tracker_feature.h +++ b/include/core/processor/processor_tracker_feature.h @@ -113,19 +113,32 @@ class ProcessorTrackerFeature : public ProcessorTracker */ virtual unsigned int processKnown(); - /** \brief Track provided features from \b last to \b incoming - * \param _features_last_in input list of features in \b last to track - * \param _features_incoming_out returned list of features found in \b incoming + /** \brief Track provided features in \b _capture + * \param _features_in input list of features in \b last to track + * \param _capture the capture in which the _features_in should be searched + * \param _features_out returned list of features found in \b _capture * \param _feature_correspondences returned map of correspondences: _feature_correspondences[feature_out_ptr] = feature_in_ptr + * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * If you detect all the features at once in preprocess(), you should create them (`make_shared()`) and only link the + * features that are returned in _features_out (`FeatureBase::link(_capture)`). + * + * \return the number of features tracked */ - virtual unsigned int trackFeatures(const FeatureBasePtrList& _features_last_in, FeatureBasePtrList& _features_incoming_out, FeatureMatchMap& _feature_correspondences) = 0; + virtual unsigned int trackFeatures(const FeatureBasePtrList& _features_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, + FeatureMatchMap& _feature_correspondences) = 0; /** \brief Correct the drift in incoming feature by re-comparing against the corresponding feature in origin. * \param _origin_feature input feature in origin capture tracked * \param _incoming_feature input/output feature in incoming capture to be corrected * \return false if the the process discards the correspondence with origin's feature */ - virtual bool correctFeatureDrift(const FeatureBasePtr _origin_feature, const FeatureBasePtr _last_feature, FeatureBasePtr _incoming_feature) = 0; + virtual bool correctFeatureDrift(const FeatureBasePtr _origin_feature, + const FeatureBasePtr _last_feature, + FeatureBasePtr _incoming_feature) = 0; /** \brief Vote for KeyFrame generation * @@ -147,27 +160,35 @@ class ProcessorTrackerFeature : public ProcessorTracker /** \brief Detect new Features * \param _max_features maximum number of features detected (-1: unlimited. 0: none) - * \param _features_last_out The list of detected Features. + * \param _capture The capture in which the new features should be detected. + * \param _features_out The list of detected Features in _capture. * \return The number of detected Features. * * This function detects Features that do not correspond to known Features/Landmarks in the system. * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * If you detect all the features at once in preprocess(), you should create them (`make_shared()`) and only link the + * features that are returned in _features_out (`FeatureBase::link(_capture)`). + * * The function is called in ProcessorTrackerFeature::processNew() to set the member new_features_last_, * the list of newly detected features of the capture last_ptr_. */ - virtual unsigned int detectNewFeatures(const int& _max_new_features, FeatureBasePtrList& _features_last_out) = 0; + virtual unsigned int detectNewFeatures(const int& _max_new_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out) = 0; - /** \brief Create a new factor and link it to the wolf tree + /** \brief Emplaces a new factor * \param _feature_ptr pointer to the parent Feature * \param _feature_other_ptr pointer to the other feature constrained. * * Implement this method in derived classes. * - * This function creates a factor of the appropriate type for the derived processor. + * This function emplaces a factor of the appropriate type for the derived processor. */ - virtual FactorBasePtr createFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr) = 0; + virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr) = 0; - /** \brief Establish factors between features in Captures \b last and \b origin + /** \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(); }; diff --git a/include/core/processor/processor_tracker_feature_dummy.h b/include/core/processor/processor_tracker_feature_dummy.h index 150a6ffb0068b723c9f237918b81dc56116323e2..007207cecb59a4d5028bfe5f1b0e205a0b0726b8 100644 --- a/include/core/processor/processor_tracker_feature_dummy.h +++ b/include/core/processor/processor_tracker_feature_dummy.h @@ -45,12 +45,20 @@ class ProcessorTrackerFeatureDummy : public ProcessorTrackerFeature ProcessorParamsTrackerFeatureDummyPtr params_tracker_feature_dummy_; - /** \brief Track provided features from \b last to \b incoming - * \param _features_last_in input list of features in \b last to track - * \param _features_incoming_out returned list of features found in \b incoming + /** \brief Track provided features in \b _capture + * \param _features_in input list of features in \b last to track + * \param _capture the capture in which the _features_in should be searched + * \param _features_out returned list of features found in \b _capture * \param _feature_correspondences returned map of correspondences: _feature_correspondences[feature_out_ptr] = feature_in_ptr + * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * + * \return the number of features tracked */ - virtual unsigned int trackFeatures(const FeatureBasePtrList& _features_last_in, FeatureBasePtrList& _features_incoming_out, + virtual unsigned int trackFeatures(const FeatureBasePtrList& _features_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, FeatureMatchMap& _feature_correspondences); /** \brief Correct the drift in incoming feature by re-comparing against the corresponding feature in origin. @@ -71,17 +79,28 @@ class ProcessorTrackerFeatureDummy : public ProcessorTrackerFeature /** \brief Detect new Features * \param _max_features maximum number of features detected (-1: unlimited. 0: none) - * \param _features_last_out The list of detected Features. + * \param _capture The capture in which the new features should be detected. + * \param _features_out The list of detected Features in _capture. * \return The number of detected Features. * * This function detects Features that do not correspond to known Features/Landmarks in the system. * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * * The function is called in ProcessorTrackerFeature::processNew() to set the member new_features_last_, * the list of newly detected features of the capture last_ptr_. */ - virtual unsigned int detectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out); - - virtual FactorBasePtr createFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr); + virtual unsigned int detectNewFeatures(const int& _max_new_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out); + /** \brief Emplaces a new factor + * \param _feature_ptr pointer to the parent Feature + * \param _feature_other_ptr pointer to the other feature constrained. + * + * This function emplaces a factor of the appropriate type for the derived processor. + */ + virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr); public: diff --git a/include/core/processor/processor_tracker_landmark.h b/include/core/processor/processor_tracker_landmark.h index 0e7e2e0a2b7bac5161caa2d7969766a2b57f2581..c11adecc7b16a9c0c2d367200af6ee9a55d46c64 100644 --- a/include/core/processor/processor_tracker_landmark.h +++ b/include/core/processor/processor_tracker_landmark.h @@ -104,15 +104,23 @@ class ProcessorTrackerLandmark : public ProcessorTracker */ virtual unsigned int processKnown(); - /** \brief Find provided landmarks in the incoming capture - * \param _landmarks_in input list of landmarks to be found in incoming - * \param _features_incoming_out returned list of incoming features corresponding to a landmark of _landmarks_in + /** \brief Find provided landmarks as features in the provided capture + * \param _landmarks_in input list of landmarks to be found + * \param _capture the capture in which the _landmarks_in should be searched + * \param _features_out returned list of features found in \b _capture corresponding to a landmark of _landmarks_in * \param _feature_landmark_correspondences returned map of landmark correspondences: _feature_landmark_correspondences[_feature_out_ptr] = landmark_in_ptr + * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * If you detect all the features at once in preprocess(), you should create them (`make_shared()`) and only link the + * features that are returned in _features_out (`FeatureBase::link(_capture)`). + * * \return the number of landmarks found */ - virtual unsigned int findLandmarks(const LandmarkBasePtrList& _landmarks_in, - FeatureBasePtrList& _features_incoming_out, - LandmarkMatchMap& _feature_landmark_correspondences) = 0; + virtual unsigned int findLandmarks(const LandmarkBasePtrList& _landmarks_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, + LandmarkMatchMap& _feature_landmark_correspondences) = 0; /** \brief Vote for KeyFrame generation * @@ -134,35 +142,43 @@ class ProcessorTrackerLandmark : public ProcessorTracker /** \brief Detect new Features * \param _max_features maximum number of features detected (-1: unlimited. 0: none) - * \param _features_last_out The list of detected Features. + * \param _capture The capture in which the new features should be detected. + * \param _features_out The list of detected Features in _capture. * \return The number of detected Features. * - * This function detects Features that do not correspond to known Landmarks in the system. + * This function detects Features that do not correspond to known Features/Landmarks in the system. + * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * If you detect all the features at once in preprocess(), you should create them (`make_shared()`) and only link the + * features that are returned in _features_out (`FeatureBase::link(_capture)`). * * The function is called in ProcessorTrackerLandmark::processNew() to set the member new_features_last_, * the list of newly detected features of the capture last_ptr_. */ - virtual unsigned int detectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out) = 0; + virtual unsigned int detectNewFeatures(const int& _max_new_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out) = 0; - /** \brief Creates a landmark for each of new_features_last_ + /** \brief Emplaces a landmark for each new feature of new_features_last_ **/ - virtual void createNewLandmarks(); + virtual void emplaceNewLandmarks(); - /** \brief Create one landmark + /** \brief Emplaces one landmark * * Implement in derived classes to build the type of landmark you need for this tracker. */ - virtual LandmarkBasePtr createLandmark(FeatureBasePtr _feature_ptr) = 0; + virtual LandmarkBasePtr emplaceLandmark(FeatureBasePtr _feature_ptr) = 0; - /** \brief Create a new factor + /** \brief Emplaces a new factor * \param _feature_ptr pointer to the Feature to constrain * \param _landmark_ptr LandmarkBase pointer to the Landmark constrained. * * Implement this method in derived classes. */ - virtual FactorBasePtr createFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr) = 0; + virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr) = 0; - /** \brief Establish factors between features in Capture \b last and landmarks + /** \brief Emplaces a new factor for each correspondence between a feature in Capture \b last and a landmark */ virtual void establishFactors(); }; diff --git a/include/core/processor/processor_tracker_landmark_dummy.h b/include/core/processor/processor_tracker_landmark_dummy.h index 804ecc9869789b9326d0b572c210884c8f9d15b3..7dce7d14e23e77df062ff2774630767d1d2d6b48 100644 --- a/include/core/processor/processor_tracker_landmark_dummy.h +++ b/include/core/processor/processor_tracker_landmark_dummy.h @@ -40,15 +40,20 @@ class ProcessorTrackerLandmarkDummy : public ProcessorTrackerLandmark ProcessorParamsTrackerLandmarkDummyPtr params_tracker_landmark_dummy_; - //virtual void preProcess() { } - //virtual void postProcess(); - - /** \brief Find provided landmarks in the incoming capture - * \param _landmarks_in input list of landmarks to be found in incoming - * \param _features_incoming_out returned list of incoming features corresponding to a landmark of _landmarks_in + /** \brief Find provided landmarks as features in the provided capture + * \param _landmarks_in input list of landmarks to be found + * \param _capture the capture in which the _landmarks_in should be searched + * \param _features_out returned list of features found in \b _capture corresponding to a landmark of _landmarks_in * \param _feature_landmark_correspondences returned map of landmark correspondences: _feature_landmark_correspondences[_feature_out_ptr] = landmark_in_ptr + * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * + * \return the number of landmarks found */ - virtual unsigned int findLandmarks(const LandmarkBasePtrList& _landmarks_in, FeatureBasePtrList& _features_incoming_out, + virtual unsigned int findLandmarks(const LandmarkBasePtrList& _landmarks_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, LandmarkMatchMap& _feature_landmark_correspondences); /** \brief Vote for KeyFrame generation @@ -62,29 +67,35 @@ class ProcessorTrackerLandmarkDummy : public ProcessorTrackerLandmark /** \brief Detect new Features * \param _max_features maximum number of features detected (-1: unlimited. 0: none) - * \param _features_last_out The list of detected Features. + * \param _capture The capture in which the new features should be detected. + * \param _features_out The list of detected Features in _capture. * \return The number of detected Features. * * This function detects Features that do not correspond to known Features/Landmarks in the system. * + * IMPORTANT: The features in _features_out should be emplaced. Don't use `make_shared`, use `FeatureBase::emplace` instead. + * Then, they will be already linked to the _capture. + * * The function is called in ProcessorTrackerLandmark::processNew() to set the member new_features_last_, * the list of newly detected features of the capture last_ptr_. */ - virtual unsigned int detectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out); + virtual unsigned int detectNewFeatures(const int& _max_new_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out); - /** \brief Create one landmark + /** \brief Emplace one landmark * * Implement in derived classes to build the type of landmark you need for this tracker. */ - virtual LandmarkBasePtr createLandmark(FeatureBasePtr _feature_ptr); + virtual LandmarkBasePtr emplaceLandmark(FeatureBasePtr _feature_ptr); - /** \brief Create a new factor + /** \brief Emplace a new factor * \param _feature_ptr pointer to the Feature to constrain * \param _landmark_ptr LandmarkBase pointer to the Landmark constrained. * * Implement this method in derived classes. */ - virtual FactorBasePtr createFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr); + virtual FactorBasePtr emplaceFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr); }; } // namespace wolf diff --git a/include/core/processor/track_matrix.h b/include/core/processor/track_matrix.h index edc6f9092f96fe7835d80658b975eb127552a00c..2615ad411adbe9c32efea2bf543cb24657e5ed97 100644 --- a/include/core/processor/track_matrix.h +++ b/include/core/processor/track_matrix.h @@ -78,25 +78,25 @@ class TrackMatrix TrackMatrix(); virtual ~TrackMatrix(); - // tracks across all Captures - void newTrack (CaptureBasePtr _cap, FeatureBasePtr _ftr); - void add (size_t _track_id, CaptureBasePtr _cap, FeatureBasePtr _ftr); + void newTrack (FeatureBasePtr _ftr); + void add (const SizeStd& _track_id, const FeatureBasePtr& _ftr); + void add (const FeatureBasePtr& _ftr_existing, const FeatureBasePtr& _ftr_new); void remove (FeatureBasePtr _ftr); - void remove (size_t _track_id); + void remove (const SizeStd& _track_id); void remove (CaptureBasePtr _cap); SizeStd numTracks (); - SizeStd trackSize (size_t _track_id); - Track track (size_t _track_id); + SizeStd trackSize (const SizeStd& _track_id); + Track track (const SizeStd& _track_id); Snapshot snapshot (CaptureBasePtr _capture); vector<FeatureBasePtr> - trackAsVector(size_t _track_id); + trackAsVector(const SizeStd& _track_id); list<FeatureBasePtr> snapshotAsList(CaptureBasePtr _cap); TrackMatches matches (CaptureBasePtr _cap_1, CaptureBasePtr _cap_2); - FeatureBasePtr firstFeature(size_t _track_id); - FeatureBasePtr lastFeature (size_t _track_id); - FeatureBasePtr feature (size_t _track_id, CaptureBasePtr _cap); - CaptureBasePtr firstCapture(size_t _track_id); + FeatureBasePtr firstFeature(const SizeStd& _track_id); + FeatureBasePtr lastFeature (const SizeStd& _track_id); + FeatureBasePtr feature (const SizeStd& _track_id, CaptureBasePtr _cap); + CaptureBasePtr firstCapture(const SizeStd& _track_id); // tracks across captures that belong to keyframe // SizeStd numKeyframeTracks(); @@ -108,9 +108,8 @@ class TrackMatrix static SizeStd track_id_count_; - // Along track: maps of Feature pointers indexed by time stamp. // tracks across all Captures - map<size_t, Track > tracks_; // map indexed by track_Id of ( maps indexed by TimeStamp of ( features ) ) + map<SizeStd, Track > tracks_; // map indexed by track_Id of ( maps indexed by TimeStamp of ( features ) ) // // tracks across captures that belong to keyframe // map<size_t, Track > tracks_kf_; // map indexed by track_Id of ( maps indexed by TimeStamp of ( features ) ) diff --git a/include/core/sensor/sensor_base.h b/include/core/sensor/sensor_base.h index 9002ae8fe51a10c4fbb0bdbc39f4600d4e063fe1..99a227a4010dffb1bdcddc18c390b94e5dafc2e9 100644 --- a/include/core/sensor/sensor_base.h +++ b/include/core/sensor/sensor_base.h @@ -33,6 +33,9 @@ struct IntrinsicsBase: public ParamsBase class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBase> { + friend Problem; + friend ProcessorBase; + private: HardwareBaseWPtr hardware_ptr_; ProcessorBasePtrList processor_list_; @@ -99,9 +102,12 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa virtual void setProblem(ProblemPtr _problem) final; HardwareBasePtr getHardware(); + private: void setHardware(const HardwareBasePtr _hw_ptr); - ProcessorBasePtr addProcessor(ProcessorBasePtr _proc_ptr); + void removeProcessor(ProcessorBasePtr _proc_ptr); + + public: ProcessorBasePtrList& getProcessorList(); CaptureBasePtr lastKeyCapture(void); @@ -132,7 +138,12 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa void setP(const StateBlockPtr _p_ptr); void setO(const StateBlockPtr _o_ptr); void setIntrinsic(const StateBlockPtr _intr_ptr); + + protected: void removeStateBlocks(); + virtual void registerNewStateBlocks(); + + public: void fix(); void unfix(); @@ -170,8 +181,6 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa SizeEigen getCalibSize() const; Eigen::VectorXs getCalibration() const; - virtual void registerNewStateBlocks(); - bool isExtrinsicDynamic() const; bool isIntrinsicDynamic() const; bool hasCapture() const {return has_capture_;} @@ -185,6 +194,7 @@ class SensorBase : public NodeBase, public std::enable_shared_from_this<SensorBa Eigen::MatrixXs getNoiseCov(); void setExtrinsicDynamic(bool _extrinsic_dynamic); void setIntrinsicDynamic(bool _intrinsic_dynamic); + void link(HardwareBasePtr); template<typename classType, typename... T> static std::shared_ptr<SensorBase> emplace(HardwareBasePtr _hwd_ptr, T&&... all); diff --git a/include/core/trajectory/trajectory_base.h b/include/core/trajectory/trajectory_base.h index 0ee9c37d53052a3da7f193b8a4e6715592d5628b..c41bf09830811009d415a748fbdca7a918a72f72 100644 --- a/include/core/trajectory/trajectory_base.h +++ b/include/core/trajectory/trajectory_base.h @@ -20,6 +20,8 @@ namespace wolf { //class TrajectoryBase class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<TrajectoryBase> { + friend FrameBase; + private: std::list<FrameBasePtr> frame_list_; @@ -36,7 +38,6 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj std::string getFrameStructure() const; // Frames - FrameBasePtr addFrame(FrameBasePtr _frame_ptr); FrameBasePtrList& getFrameList(); const FrameBasePtrList& getFrameList() const; FrameBasePtr getLastFrame() const; @@ -47,6 +48,11 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj void sortFrame(FrameBasePtr _frm_ptr); void updateLastFrames(); + private: + FrameBasePtr addFrame(FrameBasePtr _frame_ptr); + void removeFrame(FrameBasePtr _frame_ptr); + + public: // factors void getFactorList(FactorBasePtrList & _fac_list); diff --git a/src/capture/capture_base.cpp b/src/capture/capture_base.cpp index 78904aa8baac91d47d2300454b8a77b2f1160001..5f0ce68802c19668ce77ae1317062f0609f33399 100644 --- a/src/capture/capture_base.cpp +++ b/src/capture/capture_base.cpp @@ -102,16 +102,9 @@ FeatureBasePtr CaptureBase::addFeature(FeatureBasePtr _ft_ptr) return _ft_ptr; } -void CaptureBase::addFeatureList(FeatureBasePtrList& _new_ft_list) +void CaptureBase::removeFeature(FeatureBasePtr _ft_ptr) { - for (FeatureBasePtr feature_ptr : _new_ft_list) - { - feature_ptr->setCapture(shared_from_this()); - if (getProblem() != nullptr) - feature_ptr->setProblem(getProblem()); - // feature_list_.push_back(feature_ptr); - } - feature_list_.splice(feature_list_.end(), _new_ft_list); + feature_list_.remove(_ft_ptr); } void CaptureBase::getFactorList(FactorBasePtrList& _fac_list) @@ -123,10 +116,14 @@ void CaptureBase::getFactorList(FactorBasePtrList& _fac_list) FactorBasePtr CaptureBase::addConstrainedBy(FactorBasePtr _fac_ptr) { constrained_by_list_.push_back(_fac_ptr); - _fac_ptr->setCaptureOther(shared_from_this()); return _fac_ptr; } +void CaptureBase::removeConstrainedBy(FactorBasePtr _fac_ptr) +{ + constrained_by_list_.remove(_fac_ptr); +} + StateBlockPtr CaptureBase::getStateBlock(unsigned int _i) const { if (getSensor()) @@ -165,7 +162,7 @@ void CaptureBase::removeStateBlocks() { if (getProblem() != nullptr) { - getProblem()->removeStateBlock(sbp); + getProblem()->notifyStateBlock(sbp, REMOVE); } setStateBlock(i, nullptr); } @@ -244,7 +241,7 @@ void CaptureBase::registerNewStateBlocks() { for (auto sbp : getStateBlockVec()) if (sbp != nullptr) - getProblem()->addStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,ADD); } } @@ -294,12 +291,17 @@ void CaptureBase::setCalibration(const VectorXs& _calib) void CaptureBase::link(FrameBasePtr _frm_ptr) { + assert((this->getFrame() == nullptr || !this->getFrame()->isKey()) && "linking a capture already linked to a KF"); + + // unlink from previous non-key frame + if (this->getFrame()) + this->getFrame()->removeCapture(shared_from_this()); + if(_frm_ptr) { _frm_ptr->addCapture(shared_from_this()); this->setFrame(_frm_ptr); this->setProblem(_frm_ptr->getProblem()); - this->registerNewStateBlocks(); } else { @@ -307,5 +309,17 @@ void CaptureBase::link(FrameBasePtr _frm_ptr) } } +void CaptureBase::setProblem(ProblemPtr _problem) +{ + if (_problem == nullptr || _problem == this->getProblem()) + return; + + NodeBase::setProblem(_problem); + this->registerNewStateBlocks(); + + for (auto ft : feature_list_) + ft->setProblem(_problem); +} + } // namespace wolf diff --git a/src/factor/factor_base.cpp b/src/factor/factor_base.cpp index 44e1826d0c01432018fd83366e0b54b8233a54f6..adec4caf9e8554a4b95baa11dd3dcf5846c06eae 100644 --- a/src/factor/factor_base.cpp +++ b/src/factor/factor_base.cpp @@ -7,9 +7,9 @@ namespace wolf { unsigned int FactorBase::factor_id_count_ = 0; FactorBase::FactorBase(const std::string& _tp, - bool _apply_loss_function, - FactorStatus _status) : - NodeBase("CONSTRAINT", _tp), + bool _apply_loss_function, + FactorStatus _status) : + NodeBase("FACTOR", _tp), feature_ptr_(), // nullptr factor_id_(++factor_id_count_), status_(_status), @@ -23,13 +23,14 @@ FactorBase::FactorBase(const std::string& _tp, } FactorBase::FactorBase(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) : - NodeBase("CONSTRAINT", _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) : + NodeBase("FACTOR", _tp), feature_ptr_(), factor_id_(++factor_id_count_), status_(_status), @@ -58,13 +59,13 @@ void FactorBase::remove() } // add factor to be removed from solver if (getProblem() != nullptr) - getProblem()->removeFactor(shared_from_this()); + getProblem()->notifyFactor(shared_from_this(),REMOVE); // remove other: {Frame, Capture, Feature, Landmark} FrameBasePtr frm_o = frame_other_ptr_.lock(); if (frm_o) { - frm_o->getConstrainedByList().remove(shared_from_this()); + frm_o->removeConstrainedBy(shared_from_this()); if (frm_o->getConstrainedByList().empty() && frm_o->getCaptureList().empty()) frm_o->remove(); } @@ -72,7 +73,7 @@ void FactorBase::remove() CaptureBasePtr cap_o = capture_other_ptr_.lock(); if (cap_o) { - cap_o->getConstrainedByList().remove(shared_from_this()); + cap_o->removeConstrainedBy(shared_from_this()); if (cap_o->getConstrainedByList().empty() && cap_o->getFeatureList().empty()) cap_o->remove(); } @@ -80,7 +81,7 @@ void FactorBase::remove() FeatureBasePtr ftr_o = feature_other_ptr_.lock(); if (ftr_o) { - ftr_o->getConstrainedByList().remove(shared_from_this()); + ftr_o->removeConstrainedBy(shared_from_this()); if (ftr_o->getConstrainedByList().empty() && ftr_o->getFactorList().empty()) ftr_o->remove(); } @@ -88,7 +89,7 @@ void FactorBase::remove() LandmarkBasePtr lmk_o = landmark_other_ptr_.lock(); if (lmk_o) { - lmk_o->getConstrainedByList().remove(shared_from_this()); + lmk_o->removeConstrainedBy(shared_from_this()); if (lmk_o->getConstrainedByList().empty()) lmk_o->remove(); } @@ -99,21 +100,25 @@ void FactorBase::remove() const Eigen::VectorXs& FactorBase::getMeasurement() const { + assert(getFeature() != nullptr && "calling getMeasurement before linking with a feature"); return getFeature()->getMeasurement(); } const Eigen::MatrixXs& FactorBase::getMeasurementCovariance() const { + assert(getFeature() != nullptr && "calling getMeasurementCovariance before linking with a feature"); return getFeature()->getMeasurementCovariance(); } const Eigen::MatrixXs& FactorBase::getMeasurementSquareRootInformationUpper() const { + assert(getFeature() != nullptr && "calling getMeasurementSquareRootInformationUpper before linking with a feature"); return getFeature()->getMeasurementSquareRootInformationUpper(); } CaptureBasePtr FactorBase::getCapture() const { + assert(getFeature() != nullptr && "calling getCapture before linking with a feature"); return getFeature()->getCapture(); } @@ -124,47 +129,36 @@ void FactorBase::setStatus(FactorStatus _status) else if (_status != status_) { if (_status == FAC_ACTIVE) - getProblem()->addFactor(shared_from_this()); + getProblem()->notifyFactor(shared_from_this(),ADD); else if (_status == FAC_INACTIVE) - getProblem()->removeFactor(shared_from_this()); + getProblem()->notifyFactor(shared_from_this(),REMOVE); } status_ = _status; } -void FactorBase::setApplyLossFunction(const bool _apply) -{ - if (apply_loss_function_ != _apply) - { - if (getProblem() == nullptr) - std::cout << "factor not linked with Problem, apply loss function change not notified" << std::endl; - else - { - FactorBasePtr this_c = shared_from_this(); - getProblem()->removeFactor(this_c); - getProblem()->addFactor(this_c); - } - } -} +//void FactorBase::setApplyLossFunction(const bool _apply) +//{ +// apply_loss_function_ = _apply; +//} + void FactorBase::link(FeatureBasePtr _ftr_ptr) { + assert(this->getFeature() == nullptr && "linking an already linked factor"); + if(_ftr_ptr) { _ftr_ptr->addFactor(shared_from_this()); this->setFeature(_ftr_ptr); this->setProblem(_ftr_ptr->getProblem()); // add factor to be added in solver - if (this->getProblem() != nullptr) - { - if (this->getStatus() == FAC_ACTIVE) - this->getProblem()->addFactor(shared_from_this()); - } - else - WOLF_WARN("ADDING CONSTRAINT ", this->id(), " TO FEATURE ", _ftr_ptr->id(), " NOT CONNECTED WITH PROBLEM."); + if (this->getProblem() == nullptr) + { + WOLF_WARN("ADDING FACTOR ", this->id(), " TO FEATURE ", _ftr_ptr->id(), " NOT CONNECTED WITH PROBLEM."); + } } else - { WOLF_WARN("Linking with nullptr"); - } + auto frame_other = this->frame_other_ptr_.lock(); if(frame_other != nullptr) frame_other->addConstrainedBy(shared_from_this()); auto capture_other = this->capture_other_ptr_.lock(); @@ -174,4 +168,15 @@ void FactorBase::link(FeatureBasePtr _ftr_ptr) auto landmark_other = this->landmark_other_ptr_.lock(); if(landmark_other != nullptr) landmark_other->addConstrainedBy(shared_from_this()); } + +void FactorBase::setProblem(ProblemPtr _problem) +{ + if (_problem == nullptr || _problem == this->getProblem()) + return; + + NodeBase::setProblem(_problem); + if (this->getStatus() == FAC_ACTIVE) + this->getProblem()->notifyFactor(shared_from_this(),ADD); +} + } // namespace wolf diff --git a/src/feature/feature_base.cpp b/src/feature/feature_base.cpp index dd86c7c8cb7eaa911baa731d67a413d76b3df1b4..2929eb17fc4bb44f7b6b6094c05590c62a9e6ceb 100644 --- a/src/feature/feature_base.cpp +++ b/src/feature/feature_base.cpp @@ -70,6 +70,11 @@ FactorBasePtr FeatureBase::addFactor(FactorBasePtr _co_ptr) return _co_ptr; } +void FeatureBase::removeFactor(FactorBasePtr _co_ptr) +{ + factor_list_.remove(_co_ptr); +} + FrameBasePtr FeatureBase::getFrame() const { return capture_ptr_.lock()->getFrame(); @@ -78,10 +83,14 @@ FrameBasePtr FeatureBase::getFrame() const FactorBasePtr FeatureBase::addConstrainedBy(FactorBasePtr _fac_ptr) { constrained_by_list_.push_back(_fac_ptr); - _fac_ptr->setFeatureOther(shared_from_this()); return _fac_ptr; } +void FeatureBase::removeConstrainedBy(FactorBasePtr _fac_ptr) +{ + constrained_by_list_.remove(_fac_ptr); +} + FactorBasePtrList& FeatureBase::getFactorList() { return factor_list_; @@ -148,6 +157,8 @@ Eigen::MatrixXs FeatureBase::computeSqrtUpper(const Eigen::MatrixXs & _info) con void FeatureBase::link(CaptureBasePtr _cpt_ptr) { + assert(this->getCapture() == nullptr && "linking an already linked feature"); + if(_cpt_ptr) { _cpt_ptr->addFeature(shared_from_this()); @@ -159,5 +170,4 @@ void FeatureBase::link(CaptureBasePtr _cpt_ptr) WOLF_WARN("Linking with nullptr"); } } - } // namespace wolf diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp index c8ac508f52c3f70504d3c3fe2137573e426a5fe0..0bdb038d95318698cccbd722e81c719c03d1d97b 100644 --- a/src/frame/frame_base.cpp +++ b/src/frame/frame_base.cpp @@ -135,7 +135,7 @@ void FrameBase::registerNewStateBlocks() { for (StateBlockPtr sbp : getStateBlockVec()) if (sbp != nullptr) - getProblem()->addStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,ADD); } } @@ -148,7 +148,7 @@ void FrameBase::removeStateBlocks() { if (getProblem() != nullptr) { - getProblem()->removeStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,REMOVE); } setStateBlock(i, nullptr); } @@ -343,6 +343,11 @@ CaptureBasePtr FrameBase::addCapture(CaptureBasePtr _capt_ptr) return _capt_ptr; } +void FrameBase::removeCapture(CaptureBasePtr _capt_ptr) +{ + capture_list_.remove(_capt_ptr); +} + CaptureBasePtr FrameBase::getCaptureOf(const SensorBasePtr _sensor_ptr, const std::string& type) { for (CaptureBasePtr capture_ptr : getCaptureList()) @@ -368,12 +373,6 @@ CaptureBasePtrList FrameBase::getCapturesOf(const SensorBasePtr _sensor_ptr) return captures; } -void FrameBase::unlinkCapture(CaptureBasePtr _cap_ptr) -{ - _cap_ptr->unlinkFromFrame(); - capture_list_.remove(_cap_ptr); -} - FactorBasePtr FrameBase::getFactorOf(const ProcessorBasePtr _processor_ptr, const std::string& type) { for (const FactorBasePtr& constaint_ptr : getConstrainedByList()) @@ -399,66 +398,41 @@ void FrameBase::getFactorList(FactorBasePtrList& _fac_list) FactorBasePtr FrameBase::addConstrainedBy(FactorBasePtr _fac_ptr) { constrained_by_list_.push_back(_fac_ptr); - _fac_ptr->setFrameOther(shared_from_this()); return _fac_ptr; } -FrameBasePtr FrameBase::create_PO_2D(const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x) -{ - assert(_x.size() == 3 && "Wrong state vector size. Should be 3 for 2D!"); - StateBlockPtr p_ptr ( std::make_shared<StateBlock> (_x.head <2> ( ) ) ); - StateBlockPtr o_ptr ( std::make_shared<StateAngle> ((Scalar) _x(2) ) ); - StateBlockPtr v_ptr ( nullptr ); - FrameBasePtr f ( std::make_shared<FrameBase>(_tp, _ts, p_ptr, o_ptr, v_ptr) ); - f->setType("PO 2D"); - return f; -} -FrameBasePtr FrameBase::create_PO_3D(const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x) -{ - assert(_x.size() == 7 && "Wrong state vector size. Should be 7 for 3D!"); - StateBlockPtr p_ptr ( std::make_shared<StateBlock> (_x.head <3> ( ) ) ); - StateBlockPtr o_ptr ( std::make_shared<StateQuaternion> (_x.tail <4> ( ) ) ); - StateBlockPtr v_ptr ( nullptr ); - FrameBasePtr f ( std::make_shared<FrameBase>(_tp, _ts, p_ptr, o_ptr, v_ptr) ); - f->setType("PO 3D"); - return f; -} -FrameBasePtr FrameBase::create_POV_3D(const FrameType & _tp, - const TimeStamp& _ts, - const Eigen::VectorXs& _x) -{ - assert(_x.size() == 10 && "Wrong state vector size. Should be 10 for 3D!"); - StateBlockPtr p_ptr ( std::make_shared<StateBlock> (_x.head <3> ( ) ) ); - StateBlockPtr o_ptr ( std::make_shared<StateQuaternion> (_x.segment <4> (3) ) ); - StateBlockPtr v_ptr ( std::make_shared<StateBlock> (_x.tail <3> ( ) ) ); - FrameBasePtr f ( std::make_shared<FrameBase>(_tp, _ts, p_ptr, o_ptr, v_ptr) ); - f->setType("POV 3D"); - return f; -} -void FrameBase::link(TrajectoryBasePtr _ptr) -{ - if(_ptr) +void FrameBase::removeConstrainedBy(FactorBasePtr _fac_ptr) +{ + constrained_by_list_.remove(_fac_ptr); +} + +void FrameBase::link(TrajectoryBasePtr _trj_ptr) +{ + assert(this->getTrajectory() == nullptr && "linking an already linked frame"); + + if(_trj_ptr) { - _ptr->addFrame(shared_from_this()); - this->setTrajectory(_ptr); - this->setProblem(_ptr->getProblem()); - if (this->isKey()) this->registerNewStateBlocks(); + _trj_ptr->addFrame(shared_from_this()); + this->setTrajectory(_trj_ptr); + this->setProblem(_trj_ptr->getProblem()); } else { WOLF_WARN("Linking with a nullptr"); } } -} // namespace wolf -#include "core/common/factory.h" -namespace wolf +void FrameBase::setProblem(ProblemPtr _problem) { -namespace{ const bool WOLF_UNUSED Frame_PO_2D_Registered = FrameFactory::get().registerCreator("PO 2D", FrameBase::create_PO_2D ); } -namespace{ const bool WOLF_UNUSED Frame_PO_3D_Registered = FrameFactory::get().registerCreator("PO 3D", FrameBase::create_PO_3D ); } -namespace{ const bool WOLF_UNUSED Frame_POV_3D_Registered = FrameFactory::get().registerCreator("POV 3D", FrameBase::create_POV_3D); } + if (_problem == nullptr || _problem == this->getProblem()) + return; + + NodeBase::setProblem(_problem); + if (this->isKey()) + this->registerNewStateBlocks(); + + for (auto cap : capture_list_) + cap->setProblem(_problem); +} + } // namespace wolf diff --git a/src/landmark/landmark_base.cpp b/src/landmark/landmark_base.cpp index 25dbf77343c40d83bc9a85960561fee198a4378b..cb3f7cb21d3c0172e99ee482018f48365206d15f 100644 --- a/src/landmark/landmark_base.cpp +++ b/src/landmark/landmark_base.cpp @@ -92,7 +92,7 @@ void LandmarkBase::registerNewStateBlocks() { for (auto sbp : getStateBlockVec()) if (sbp != nullptr) - getProblem()->addStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,ADD); } } @@ -110,7 +110,7 @@ void LandmarkBase::removeStateBlocks() { if (getProblem() != nullptr) { - getProblem()->removeStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,REMOVE); } setStateBlock(i, nullptr); } @@ -164,12 +164,13 @@ YAML::Node LandmarkBase::saveToYaml() const void LandmarkBase::link(MapBasePtr _map_ptr) { + assert(this->getMap() == nullptr && "linking an already linked landmark"); + if(_map_ptr) { this->setMap(_map_ptr); _map_ptr->addLandmark(shared_from_this()); this->setProblem(_map_ptr->getProblem()); - this->registerNewStateBlocks(); } else { @@ -177,13 +178,26 @@ void LandmarkBase::link(MapBasePtr _map_ptr) } } +void LandmarkBase::setProblem(ProblemPtr _problem) +{ + if (_problem == nullptr || _problem == this->getProblem()) + return; + + NodeBase::setProblem(_problem); + this->registerNewStateBlocks(); +} + FactorBasePtr LandmarkBase::addConstrainedBy(FactorBasePtr _fac_ptr) { constrained_by_list_.push_back(_fac_ptr); - _fac_ptr->setLandmarkOther(shared_from_this()); return _fac_ptr; } +void LandmarkBase::removeConstrainedBy(FactorBasePtr _fac_ptr) +{ + constrained_by_list_.remove(_fac_ptr); +} + LandmarkBasePtr LandmarkBase::create(const YAML::Node& _node) { unsigned int id = _node["id"] .as< unsigned int >(); diff --git a/src/map/map_base.cpp b/src/map/map_base.cpp index bff3d2a105ce9c4dc44050d86bb8c25b3668d739..3a3d32f8ac073ba88160995f69af8e1c150426bb 100644 --- a/src/map/map_base.cpp +++ b/src/map/map_base.cpp @@ -33,17 +33,9 @@ LandmarkBasePtr MapBase::addLandmark(LandmarkBasePtr _landmark_ptr) return _landmark_ptr; } -void MapBase::addLandmarkList(LandmarkBasePtrList& _landmark_list) +void MapBase::removeLandmark(LandmarkBasePtr _landmark_ptr) { - //TEMPORARY FIX, should be made compliant with the new emplace methodology - LandmarkBasePtrList lmk_list_copy = _landmark_list; //since _landmark_list will be empty after addDownNodeList() - for (LandmarkBasePtr landmark_ptr : lmk_list_copy) - { - landmark_ptr->setMap(shared_from_this()); - landmark_ptr->setProblem(getProblem()); - landmark_ptr->registerNewStateBlocks(); - } - landmark_list_.splice(landmark_list_.end(), _landmark_list); + landmark_list_.remove(_landmark_ptr); } void MapBase::load(const std::string& _map_file_dot_yaml) diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp index 24e38ddd14173751dc1de557223140371f5d62aa..b607d1b356e3772439e05bc62885f3bcd83a2de6 100644 --- a/src/problem/problem.cpp +++ b/src/problem/problem.cpp @@ -114,19 +114,13 @@ Problem::~Problem() // WOLF_DEBUG("destructed -P"); } -void Problem::addSensor(SensorBasePtr _sen_ptr) -{ - // getHardware()->addSensor(_sen_ptr); - _sen_ptr->link(getHardware()); -} - SensorBasePtr Problem::installSensor(const std::string& _sen_type, // const std::string& _unique_sensor_name, // const Eigen::VectorXs& _extrinsics, // IntrinsicsBasePtr _intrinsics) { SensorBasePtr sen_ptr = SensorFactory::get().create(uppercase(_sen_type), _unique_sensor_name, _extrinsics, _intrinsics); - addSensor(sen_ptr); + sen_ptr->link(getHardware()); return sen_ptr; } @@ -146,14 +140,16 @@ SensorBasePtr Problem::installSensor(const std::string& _sen_type, // return installSensor(_sen_type, _unique_sensor_name, _extrinsics, IntrinsicsBasePtr()); } - SensorBasePtr Problem::installSensor(const std::string& _sen_type, // - const std::string& _unique_sensor_name, // - const paramsServer& _server) - { - SensorBasePtr sen_ptr = AutoConfSensorFactory::get().create(uppercase(_sen_type), _unique_sensor_name, _server); - addSensor(sen_ptr); - return sen_ptr; - } + +SensorBasePtr Problem::installSensor(const std::string& _sen_type, // + const std::string& _unique_sensor_name, // + const paramsServer& _server) +{ + SensorBasePtr sen_ptr = AutoConfSensorFactory::get().create(uppercase(_sen_type), _unique_sensor_name, _server); + sen_ptr->link(getHardware()); + return sen_ptr; +} + ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // const std::string& _unique_processor_name, // SensorBasePtr _corresponding_sensor_ptr, // @@ -168,7 +164,6 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // ProcessorBasePtr prc_ptr = ProcessorFactory::get().create(uppercase(_prc_type), _unique_processor_name, _prc_params, _corresponding_sensor_ptr); prc_ptr->configure(_corresponding_sensor_ptr); - // _corresponding_sensor_ptr->addProcessor(prc_ptr); prc_ptr->link(_corresponding_sensor_ptr); // setting the origin in all processor motion if origin already setted @@ -211,7 +206,6 @@ ProcessorBasePtr Problem::installProcessor(const std::string& _prc_type, // ProcessorBasePtr prc_ptr = AutoConfProcessorFactory::get().create(uppercase(_prc_type), _unique_processor_name, _server, sen_ptr); prc_ptr->configure(sen_ptr); prc_ptr->link(sen_ptr); - // sen_ptr->addProcessor(prc_ptr); // setting the origin in all processor motion if origin already setted if (prc_ptr->isMotion() && prior_is_set_) @@ -445,57 +439,30 @@ void Problem::auxFrameCallback(FrameBasePtr _frame_ptr, ProcessorBasePtr _proces processor_motion_ptr_->keyFrameCallback(_frame_ptr, _time_tolerance); } -LandmarkBasePtr Problem::addLandmark(LandmarkBasePtr _lmk_ptr) -{ - getMap()->addLandmark(_lmk_ptr); - return _lmk_ptr; -} - -void Problem::addLandmarkList(LandmarkBasePtrList& _lmk_list) -{ - getMap()->addLandmarkList(_lmk_list); -} - -StateBlockPtr Problem::addStateBlock(StateBlockPtr _state_ptr) +StateBlockPtr Problem::notifyStateBlock(StateBlockPtr _state_ptr, Notification _noti) { std::lock_guard<std::mutex> lock(mut_state_block_notifications_); //std::cout << "Problem::addStateBlockPtr " << _state_ptr.get() << std::endl; - // Add add notification - // Check if there is already a notification for this state block - auto notification_it = state_block_notification_map_.find(_state_ptr); - if (notification_it != state_block_notification_map_.end() && notification_it->second == ADD) - { - WOLF_WARN("There is already an ADD notification of this state block"); - } - else - state_block_notification_map_[_state_ptr] = ADD; - - return _state_ptr; -} - -void Problem::removeStateBlock(StateBlockPtr _state_ptr) -{ - std::lock_guard<std::mutex> lock(mut_state_block_notifications_); - //std::cout << "Problem::removeStateBlockPtr " << _state_ptr.get() << std::endl; - // Check if there is already a notification for this state block auto notification_it = state_block_notification_map_.find(_state_ptr); + // exsiting notification for this state block if (notification_it != state_block_notification_map_.end()) { - if (notification_it->second == REMOVE) + // duplicated notification + if ( notification_it->second == _noti) { - WOLF_WARN("There is already an REMOVE notification of this state block"); + WOLF_WARN("This notification has been already notified"); } - // Remove ADD notification + // opposite notification -> cancell out eachother else - { state_block_notification_map_.erase(notification_it); - } } - // Add REMOVE notification + // Add notification else - state_block_notification_map_[_state_ptr] = REMOVE; + state_block_notification_map_[_state_ptr] = _noti; + + return _state_ptr; } bool Problem::getStateBlockNotification(const StateBlockPtr& sb_ptr, Notification& notif) const @@ -508,45 +475,31 @@ bool Problem::getStateBlockNotification(const StateBlockPtr& sb_ptr, Notificatio return true; } -FactorBasePtr Problem::addFactor(FactorBasePtr _factor_ptr) +FactorBasePtr Problem::notifyFactor(FactorBasePtr _factor_ptr, Notification _noti) { std::lock_guard<std::mutex> lock(mut_factor_notifications_); //std::cout << "Problem::addFactorPtr " << _factor_ptr->id() << std::endl; - // Add ADD notification - // Check if there is already a notification for this state block - auto notification_it = factor_notification_map_.find(_factor_ptr); - if (notification_it != factor_notification_map_.end() && notification_it->second == ADD) - { - WOLF_WARN("There is already an ADD notification of this factor"); - } - // Add ADD notification (override in case of REMOVE) - else - factor_notification_map_[_factor_ptr] = ADD; - - return _factor_ptr; -} - -void Problem::removeFactor(FactorBasePtr _factor_ptr) -{ - std::lock_guard<std::mutex> lock(mut_factor_notifications_); - //std::cout << "Problem::removeFactorPtr " << _factor_ptr->id() << std::endl; - - // Check if there is already a notification for this state block + // Check if there is already the same notification for this factor auto notification_it = factor_notification_map_.find(_factor_ptr); + // exsiting notification for this factor if (notification_it != factor_notification_map_.end()) { - if (notification_it->second == REMOVE) + // duplicated notification + if (notification_it->second == _noti) { - WOLF_WARN("There is already an REMOVE notification of this state block"); + WOLF_WARN("This notification has been already notified"); } - // Remove ADD notification + // opposite notification -> cancell out eachother else factor_notification_map_.erase(notification_it); + } - // Add REMOVE notification + // Add notification else - factor_notification_map_[_factor_ptr] = REMOVE; + factor_notification_map_[_factor_ptr] = _noti; + + return _factor_ptr; } bool Problem::getFactorNotification(const FactorBasePtr& fac_ptr, Notification& notif) const diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp index a70930c6b936ef898db10f22a01d8b8010cdc1c3..32c555dd44522ee092c34c5b3d372eeb34a0e36b 100644 --- a/src/processor/processor_base.cpp +++ b/src/processor/processor_base.cpp @@ -85,19 +85,22 @@ void ProcessorBase::remove() sen->getProcessorList().remove(this_p); } } - void ProcessorBase::link(SensorBasePtr _sen_ptr) + +void ProcessorBase::link(SensorBasePtr _sen_ptr) +{ + assert(this->getSensor() == nullptr && "linking an already linked processor"); + + if(_sen_ptr) { - if(_sen_ptr) - { - _sen_ptr->addProcessor(shared_from_this()); - this->setSensor(_sen_ptr); - this->setProblem(_sen_ptr->getProblem()); - } - else - { - WOLF_WARN("Linking with a nullptr"); - } + _sen_ptr->addProcessor(shared_from_this()); + this->setSensor(_sen_ptr); + this->setProblem(_sen_ptr->getProblem()); } + else + { + WOLF_WARN("Linking with a nullptr"); + } +} ///////////////////////////////////////////////////////////////////////////////////////// void BufferPackKeyFrame::add(const FrameBasePtr& _key_frame, const Scalar& _time_tolerance) diff --git a/src/processor/processor_diff_drive.cpp b/src/processor/processor_diff_drive.cpp index 6c508a35a1f25693e7fa350945dab18b0c020cf2..b75dd17e468012c231fd9a8c2ded3fb60fca7588 100644 --- a/src/processor/processor_diff_drive.cpp +++ b/src/processor/processor_diff_drive.cpp @@ -195,41 +195,48 @@ Motion ProcessorDiffDrive::interpolate(const Motion& _ref, } -CaptureMotionPtr ProcessorDiffDrive::createCapture(const TimeStamp& _ts, - const SensorBasePtr& _sensor, - const VectorXs& _data, - const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) +CaptureMotionPtr ProcessorDiffDrive::emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) { - - StateBlockPtr i_ptr = _sensor->isIntrinsicDynamic()? - std::make_shared<StateBlock>(3, false) : nullptr; - - return std::make_shared<CaptureWheelJointPosition>(_ts, _sensor, _data, _data_cov, - _frame_origin, nullptr, nullptr, i_ptr); + StateBlockPtr i_ptr = _sensor->isIntrinsicDynamic()? + std::make_shared<StateBlock>(3, false) : nullptr; + + auto cap_motion = std::static_pointer_cast<CaptureMotion>(CaptureBase::emplace<CaptureWheelJointPosition>(_frame_own, + _ts, + _sensor, + _data, + _data_cov, + _frame_origin, + nullptr, + nullptr, + i_ptr)); + cap_motion->setCalibration(_calib); + cap_motion->setCalibrationPreint(_calib_preint); + + return cap_motion; } FactorBasePtr ProcessorDiffDrive::emplaceFactor(FeatureBasePtr _feature, CaptureBasePtr _capture_origin) { - // FactorOdom2DPtr fac_odom = - // std::make_shared<FactorOdom2D>(_feature, _capture_origin->getFrame(), - // shared_from_this()); - auto fac_odom = FactorBase::emplace<FactorOdom2D>(_feature, _feature, _capture_origin->getFrame(), + auto fac_odom = FactorBase::emplace<FactorOdom2D>(_feature, _feature, _capture_origin->getFrame(), shared_from_this()); - // _feature->addFactor(fac_odom); - // _capture_origin->getFrame()->addConstrainedBy(fac_odom); - - return fac_odom; + return fac_odom; } -FeatureBasePtr ProcessorDiffDrive::createFeature(CaptureMotionPtr _capture_motion) +FeatureBasePtr ProcessorDiffDrive::emplaceFeature(CaptureMotionPtr _capture_motion) { - FeatureBasePtr key_feature_ptr = std::make_shared<FeatureDiffDrive>( - _capture_motion->getBuffer().get().back().delta_integr_, - _capture_motion->getBuffer().get().back().delta_integr_cov_, - _capture_motion->getBuffer().getCalibrationPreint(), - _capture_motion->getBuffer().get().back().jacobian_calib_); + FeatureBasePtr key_feature_ptr = FeatureBase::emplace<FeatureDiffDrive>(_capture_motion, + _capture_motion->getBuffer().get().back().delta_integr_, + _capture_motion->getBuffer().get().back().delta_integr_cov_, + _capture_motion->getBuffer().getCalibrationPreint(), + _capture_motion->getBuffer().get().back().jacobian_calib_); WOLF_INFO(_capture_motion->getBuffer().getCalibrationPreint()); WOLF_INFO(_capture_motion->getBuffer().get().back().jacobian_calib_); diff --git a/src/processor/processor_motion.cpp b/src/processor/processor_motion.cpp index a33fcde2cac2a04d149f759e1e1ad08c574c041e..55d2c16b52f55c68d66a8494a87b7e7c906c5b64 100644 --- a/src/processor/processor_motion.cpp +++ b/src/processor/processor_motion.cpp @@ -612,38 +612,6 @@ CaptureMotionPtr ProcessorMotion::findCaptureContainingTimeStamp(const TimeStamp return capture_motion; } -CaptureMotionPtr ProcessorMotion::emplaceCapture(const FrameBasePtr& _frame_own, - const SensorBasePtr& _sensor, - const TimeStamp& _ts, - const VectorXs& _data, - const MatrixXs& _data_cov, - const VectorXs& _calib, - const VectorXs& _calib_preint, - const FrameBasePtr& _frame_origin) -{ - CaptureMotionPtr capture = createCapture(_ts, - _sensor, - _data, - _data_cov, - _frame_origin); - - capture->setCalibration(_calib); - capture->setCalibrationPreint(_calib_preint); - - // add to wolf tree - // _frame_own->addCapture(capture); - capture->link(_frame_own); - return capture; -} - -FeatureBasePtr ProcessorMotion::emplaceFeature(CaptureMotionPtr _capture_motion) -{ - FeatureBasePtr feature = createFeature(_capture_motion); - // _capture_motion->addFeature(feature); - feature->link(_capture_motion); - return feature; -} - PackKeyFramePtr ProcessorMotion::computeProcessingStep() { if (!getProblem()->priorIsSet()) @@ -684,4 +652,20 @@ PackKeyFramePtr ProcessorMotion::computeProcessingStep() return pack; } +void ProcessorMotion::setProblem(ProblemPtr _problem) +{ + if (_problem == nullptr || _problem == this->getProblem()) + return; + + NodeBase::setProblem(_problem); + + // set the origin + if (origin_ptr_ == nullptr && this->getProblem()->getLastKeyFrame() != nullptr) + this->setOrigin(this->getProblem()->getLastKeyFrame()); + + // set the main processor motion + if (this->getProblem()->getProcessorMotion() == nullptr) + this->getProblem()->setProcessorMotion(std::static_pointer_cast<ProcessorMotion>(shared_from_this())); +}; + } diff --git a/src/processor/processor_odom_2D.cpp b/src/processor/processor_odom_2D.cpp index 9b19d4e8c4eda8db40eac71574534f3419880634..38dccacd9bf4d2d1512de442f79734b30d4c02a6 100644 --- a/src/processor/processor_odom_2D.cpp +++ b/src/processor/processor_odom_2D.cpp @@ -144,33 +144,38 @@ bool ProcessorOdom2D::voteForKeyFrame() return false; } -CaptureMotionPtr ProcessorOdom2D::createCapture(const TimeStamp& _ts, const SensorBasePtr& _sensor, - const VectorXs& _data, const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) +CaptureMotionPtr ProcessorOdom2D::emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) { - CaptureOdom2DPtr capture_odom = std::make_shared<CaptureOdom2D>(_ts, _sensor, _data, _data_cov, _frame_origin); - return capture_odom; + auto cap_motion = std::static_pointer_cast<CaptureMotion>(CaptureBase::emplace<CaptureOdom2D>(_frame_own, _ts, _sensor, _data, _data_cov, _frame_origin)); + cap_motion->setCalibration(_calib); + cap_motion->setCalibrationPreint(_calib_preint); + + return cap_motion; } FactorBasePtr ProcessorOdom2D::emplaceFactor(FeatureBasePtr _feature, CaptureBasePtr _capture_origin) { - // FactorOdom2DPtr fac_odom = std::make_shared<FactorOdom2D>(_feature, _capture_origin->getFrame(), - // shared_from_this()); auto fac_odom = FactorBase::emplace<FactorOdom2D>(_feature, _feature, _capture_origin->getFrame(), shared_from_this()); - // _feature->addFactor(fac_odom); - // _capture_origin->getFrame()->addConstrainedBy(fac_odom); return fac_odom; } -FeatureBasePtr ProcessorOdom2D::createFeature(CaptureMotionPtr _capture_motion) +FeatureBasePtr ProcessorOdom2D::emplaceFeature(CaptureMotionPtr _capture_motion) { Eigen::MatrixXs covariance = _capture_motion->getBuffer().get().back().delta_integr_cov_; makePosDef(covariance); - FeatureBasePtr key_feature_ptr = std::make_shared<FeatureBase>("ODOM 2D", - _capture_motion->getBuffer().get().back().delta_integr_, - covariance); + FeatureBasePtr key_feature_ptr = FeatureBase::emplace<FeatureBase>(_capture_motion, + "ODOM 2D", + _capture_motion->getBuffer().get().back().delta_integr_, + covariance); return key_feature_ptr; } diff --git a/src/processor/processor_odom_3D.cpp b/src/processor/processor_odom_3D.cpp index 9c29e0f89fb6dba5d4495fd3a4d2b1241812cb68..76fc35d3bc166eb30e878ab2e61b4f4fbe2950e3 100644 --- a/src/processor/processor_odom_3D.cpp +++ b/src/processor/processor_odom_3D.cpp @@ -395,33 +395,38 @@ bool ProcessorOdom3D::voteForKeyFrame() return false; } -CaptureMotionPtr ProcessorOdom3D::createCapture(const TimeStamp& _ts, const SensorBasePtr& _sensor, - const VectorXs& _data, const MatrixXs& _data_cov, - const FrameBasePtr& _frame_origin) +CaptureMotionPtr ProcessorOdom3D::emplaceCapture(const FrameBasePtr& _frame_own, + const SensorBasePtr& _sensor, + const TimeStamp& _ts, + const VectorXs& _data, + const MatrixXs& _data_cov, + const VectorXs& _calib, + const VectorXs& _calib_preint, + const FrameBasePtr& _frame_origin) { - CaptureOdom3DPtr capture_odom = std::make_shared<CaptureOdom3D>(_ts, _sensor, _data, _data_cov, _frame_origin); - return capture_odom; + auto cap_motion = std::static_pointer_cast<CaptureMotion>(CaptureBase::emplace<CaptureOdom3D>(_frame_own, _ts, _sensor, _data, _data_cov, _frame_origin)); + cap_motion->setCalibration(_calib); + cap_motion->setCalibrationPreint(_calib_preint); + + return cap_motion; +} + +FeatureBasePtr ProcessorOdom3D::emplaceFeature(CaptureMotionPtr _capture_motion) +{ + FeatureBasePtr key_feature_ptr = FeatureBase::emplace<FeatureBase>(_capture_motion, + "ODOM 3D", + _capture_motion->getBuffer().get().back().delta_integr_, + _capture_motion->getBuffer().get().back().delta_integr_cov_); + return key_feature_ptr; } FactorBasePtr ProcessorOdom3D::emplaceFactor(FeatureBasePtr _feature_motion, CaptureBasePtr _capture_origin) { - // FactorOdom3DPtr fac_odom = std::make_shared<FactorOdom3D>(_feature_motion, _capture_origin->getFrame(), - // shared_from_this()); auto fac_odom = FactorBase::emplace<FactorOdom3D>(_feature_motion, _feature_motion, _capture_origin->getFrame(), shared_from_this()); - // _feature_motion->addFactor(fac_odom); - // _capture_origin->getFrame()->addConstrainedBy(fac_odom); return fac_odom; } -FeatureBasePtr ProcessorOdom3D::createFeature(CaptureMotionPtr _capture_motion) -{ - FeatureBasePtr key_feature_ptr = std::make_shared<FeatureBase>( - "ODOM 3D", _capture_motion->getBuffer().get().back().delta_integr_, - _capture_motion->getBuffer().get().back().delta_integr_cov_); - return key_feature_ptr; -} - void ProcessorOdom3D::remap(const Eigen::VectorXs& _x1, const Eigen::VectorXs& _x2, Eigen::VectorXs& _x_out) { new (&p1_) Eigen::Map<const Eigen::Vector3s>(_x1.data()); diff --git a/src/processor/processor_tracker.cpp b/src/processor/processor_tracker.cpp index ad2c73b62f0c5a91601f59272aae2355b9b313d6..3cde80f33ac88d48ef30d56daf0a43a3ffe7c075 100644 --- a/src/processor/processor_tracker.cpp +++ b/src/processor/processor_tracker.cpp @@ -21,8 +21,7 @@ ProcessorTracker::ProcessorTracker(const std::string& _type, processing_step_(FIRST_TIME_WITHOUT_PACK), origin_ptr_(nullptr), last_ptr_(nullptr), - incoming_ptr_(nullptr), - number_of_tracks_(0) + incoming_ptr_(nullptr) { // } @@ -55,7 +54,7 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) PackKeyFramePtr pack = buffer_pack_kf_.selectPack( incoming_ptr_, params_tracker_->time_tolerance); buffer_pack_kf_.removeUpTo( pack->key_frame->getTimeStamp() ); - WOLF_DEBUG( "PT ", getName(), ": KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp().get() ); + WOLF_DEBUG( "PT ", getName(), " FIRST_TIME_WITH_PACK: KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp() ); // Append incoming to KF // pack->key_frame->addCapture(incoming_ptr_); @@ -76,6 +75,8 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) } case FIRST_TIME_WITHOUT_PACK : { + WOLF_DEBUG( "PT ", getName(), " FIRST_TIME_WITHOUT_PACK" ); + FrameBasePtr kfrm = getProblem()->emplaceFrame(KEY, incoming_ptr_->getTimeStamp()); incoming_ptr_->link(kfrm); @@ -98,10 +99,12 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) { // No-break case only for debug. Next case will be executed too. PackKeyFramePtr pack = buffer_pack_kf_.selectPack( incoming_ptr_, params_tracker_->time_tolerance); - WOLF_DEBUG( "PT ", getName(), ": KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp().get() ); + WOLF_DEBUG( "PT ", getName(), " SECOND_TIME_WITH_PACK: KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp() ); } // @suppress("No break at end of case") case SECOND_TIME_WITHOUT_PACK : { + WOLF_DEBUG( "PT ", getName(), " SECOND_TIME_WITHOUT_PACK" ); + FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp()); incoming_ptr_->link(frm); @@ -127,16 +130,14 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) PackKeyFramePtr pack = buffer_pack_kf_.selectPack( last_ptr_ , params_tracker_->time_tolerance); buffer_pack_kf_.removeUpTo( pack->key_frame->getTimeStamp() ); - WOLF_DEBUG( "PT ", getName(), ": KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp().get() ); + WOLF_DEBUG( "PT ", getName(), " RUNNING_WITH_PACK: KF" , pack->key_frame->id() , " callback unpacked with ts= " , pack->key_frame->getTimeStamp() ); processKnown(); // Capture last_ is added to the new keyframe FrameBasePtr last_old_frame = last_ptr_->getFrame(); - last_old_frame->unlinkCapture(last_ptr_); + last_ptr_->link(pack->key_frame); // automatically calling last_ptr_->unlink(); last_old_frame->remove(); - // pack->key_frame->addCapture(last_ptr_); - last_ptr_->link(pack->key_frame); // Create new frame FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp()); @@ -158,19 +159,18 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) } case RUNNING_WITHOUT_PACK : { + WOLF_DEBUG( "PT ", getName(), " RUNNING_WITHOUT_PACK" ); + processKnown(); - // eventually add more features - if (last_ptr_->getFeatureList().size() < params_tracker_->min_features_for_keyframe) + if (voteForKeyFrame() && permittedKeyFrame()) { - //WOLF_TRACE("Adding more features..."); + // process processNew(params_tracker_->max_new_features); - } - if (voteForKeyFrame() && permittedKeyFrame()) - { - // We create a KF + //TODO abort KF if last_ptr_->getFeatureList().size() < params_tracker_->min_features_for_keyframe + // We create a KF // set KF on last last_ptr_->getFrame()->setState(getProblem()->getState(last_ptr_->getTimeStamp())); last_ptr_->getFrame()->setKey(); @@ -179,9 +179,6 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) FrameBasePtr frm = getProblem()->emplaceFrame(NON_ESTIMATED, incoming_ptr_->getTimeStamp()); incoming_ptr_->link(frm); - // process - processNew(params_tracker_->max_new_features); - // Establish factors establishFactors(); @@ -245,7 +242,6 @@ void ProcessorTracker::process(CaptureBasePtr const _incoming_ptr) break; } - number_of_tracks_ = last_ptr_->getFeatureList().size(); postProcess(); } diff --git a/src/processor/processor_tracker_feature.cpp b/src/processor/processor_tracker_feature.cpp index fc923797005a5a5efd5e01c1e88473b6b595d82e..f27d3b9c1bc6f664e135b4ca6893b6a977e7d206 100644 --- a/src/processor/processor_tracker_feature.cpp +++ b/src/processor/processor_tracker_feature.cpp @@ -36,25 +36,30 @@ unsigned int ProcessorTrackerFeature::processNew(const int& _max_new_features) matches_last_from_incoming_.clear(); // Populate the last Capture with new Features. The result is in new_features_last_. - unsigned int n = detectNewFeatures(_max_new_features, new_features_last_); + unsigned int n = detectNewFeatures(_max_new_features, last_ptr_, new_features_last_); + + // check all features have been emplaced + assert(std::all_of(new_features_last_.begin(), new_features_last_.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by detectNewFeatures()"); + + // fill the track matrix for (auto ftr : new_features_last_) - track_matrix_.newTrack(last_ptr_, ftr); + track_matrix_.newTrack(ftr); // Track new features from last to incoming. This will append new correspondences to matches_last_incoming - trackFeatures(new_features_last_, new_features_incoming_, matches_last_from_incoming_); + trackFeatures(new_features_last_, incoming_ptr_, new_features_incoming_, matches_last_from_incoming_); + + // check all features have been emplaced + assert(std::all_of(new_features_incoming_.begin(), new_features_incoming_.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by trackFeatures()"); + + // fill the track matrix for (auto ftr : new_features_incoming_) { - ftr->setProblem(this->getProblem()); - SizeStd trk_id_from_last = matches_last_from_incoming_[ftr]->feature_ptr_->trackId(); - track_matrix_.add(trk_id_from_last, incoming_ptr_, ftr); + assert(matches_last_from_incoming_.count(ftr) != 0); + track_matrix_.add(matches_last_from_incoming_[ftr]->feature_ptr_, ftr); } - // Append all new Features to the incoming Captures' list of Features - incoming_ptr_->addFeatureList(new_features_incoming_); - - // Append all new Features to the last Captures' list of Features - last_ptr_->addFeatureList(new_features_last_); - // return the number of new features detected in \b last return n; } @@ -70,16 +75,23 @@ unsigned int ProcessorTrackerFeature::processKnown() known_features_incoming_.clear(); if (!last_ptr_ || last_ptr_->getFeatureList().empty()) - { return 0; - } // Track features from last_ptr_ to incoming_ptr_ - trackFeatures(last_ptr_->getFeatureList(), known_features_incoming_, matches_last_from_incoming_); - for (auto match : matches_last_from_incoming_) + trackFeatures(last_ptr_->getFeatureList(), + incoming_ptr_, + known_features_incoming_, + matches_last_from_incoming_); + + // check all features have been emplaced + assert(std::all_of(known_features_incoming_.begin(), known_features_incoming_.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by trackFeatures()"); + + // fill the track matrix + for (auto ftr : known_features_incoming_) { - SizeStd trk_id_from_last = match.second->feature_ptr_->trackId(); - track_matrix_.add(trk_id_from_last, incoming_ptr_, match.first); + assert(matches_last_from_incoming_.count(ftr) != 0); + track_matrix_.add(matches_last_from_incoming_[ftr]->feature_ptr_, ftr); } // Check/correct incoming-origin correspondences @@ -87,14 +99,10 @@ unsigned int ProcessorTrackerFeature::processKnown() { for (auto feature_in_incoming : known_features_incoming_) { - SizeStd track_id = feature_in_incoming->trackId(); + SizeStd track_id = feature_in_incoming->trackId(); FeatureBasePtr feature_in_last = track_matrix_.feature(track_id, last_ptr_); FeatureBasePtr feature_in_origin = track_matrix_.feature(track_id, origin_ptr_); - if (correctFeatureDrift(feature_in_origin, feature_in_last, feature_in_incoming)) - { - feature_in_incoming->setProblem(this->getProblem()); - } - else + if (!correctFeatureDrift(feature_in_origin, feature_in_last, feature_in_incoming)) { // Remove this feature from many places: matches_last_from_incoming_ .erase (feature_in_incoming); // remove match @@ -105,9 +113,6 @@ unsigned int ProcessorTrackerFeature::processKnown() } } - // Add to wolf tree - incoming_ptr_->addFeatureList(known_features_incoming_); - return matches_last_from_incoming_.size(); } @@ -116,10 +121,6 @@ void ProcessorTrackerFeature::advanceDerived() // Reset here the list of correspondences. matches_last_from_incoming_.clear(); - // We set problem here because we could not determine Problem from incoming capture at the time of adding the features to incoming's feature list. - for (auto ftr : incoming_ptr_->getFeatureList()) - ftr->setProblem(getProblem()); - // // remove last from track matrix in case you want to have only KF in the track matrix // track_matrix_.remove(last_ptr_); } @@ -129,17 +130,11 @@ void ProcessorTrackerFeature::resetDerived() // Reset here the list of correspondences. matches_last_from_incoming_.clear(); - // Update features according to the move above. - TrackMatches matches_origin_last = track_matrix_.matches(origin_ptr_, last_ptr_); - - for (auto const & pair_trkid_pair : matches_origin_last) - { - FeatureBasePtr feature_in_origin = pair_trkid_pair.second.first; - FeatureBasePtr feature_in_last = pair_trkid_pair.second.second; - feature_in_last->setProblem(getProblem()); // Since these features were in incoming_, they had no Problem assigned. - - WOLF_DEBUG("Matches reset: track: ", pair_trkid_pair.first, " origin: ", feature_in_origin->id(), " last: ", feature_in_last->id()); - } + // Debug + //for (auto const & pair_trkid_pair : track_matrix_.matches(origin_ptr_, last_ptr_)) + //{ + // WOLF_DEBUG("Matches reset: track: ", pair_trkid_pair.first, " origin: ", pair_trkid_pair.second.first->id(), " last: ", pair_trkid_pair.second.second->id()); + //} } void ProcessorTrackerFeature::establishFactors() @@ -155,12 +150,13 @@ void ProcessorTrackerFeature::establishFactors() FeatureBasePtr feature_in_last = pair_trkid_pair.second.second; - auto fac_ptr = createFactor(feature_in_last, feature_in_origin); - fac_ptr->link(feature_in_last); + auto fac_ptr = emplaceFactor(feature_in_last, feature_in_origin); + + assert(fac_ptr->getFeature() != nullptr && "not emplaced factor returned by emplaceFactor()"); WOLF_DEBUG( "Factor: track: " , feature_in_last->trackId(), - " origin: " , feature_in_origin->id() , - " from last: " , feature_in_last->id() ); + " origin: " , feature_in_origin->id() , + " from last: " , feature_in_last->id() ); } } diff --git a/src/processor/processor_tracker_feature_dummy.cpp b/src/processor/processor_tracker_feature_dummy.cpp index 999f8620792dd83a7e34cb295ec4cf32049568ad..48838b3cda114b17cf0ce840b16983534fb7d258 100644 --- a/src/processor/processor_tracker_feature_dummy.cpp +++ b/src/processor/processor_tracker_feature_dummy.cpp @@ -11,14 +11,15 @@ namespace wolf { -unsigned int ProcessorTrackerFeatureDummy::trackFeatures(const FeatureBasePtrList& _features_last_in, - FeatureBasePtrList& _features_incoming_out, +unsigned int ProcessorTrackerFeatureDummy::trackFeatures(const FeatureBasePtrList& _features_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, FeatureMatchMap& _feature_correspondences) { - WOLF_INFO("tracking " , _features_last_in.size() , " features..."); + WOLF_INFO("tracking " , _features_in.size() , " features..."); auto count = 0; - for (auto feat_in : _features_last_in) + for (auto feat_in : _features_in) { if (count < params_tracker_feature_dummy_->n_tracks_lost) // lose first ntrackslost tracks { @@ -27,15 +28,18 @@ unsigned int ProcessorTrackerFeatureDummy::trackFeatures(const FeatureBasePtrLis } else { - FeatureBasePtr ftr(std::make_shared<FeatureBase>("POINT IMAGE", feat_in->getMeasurement(), feat_in->getMeasurementCovariance())); - _features_incoming_out.push_back(ftr); - _feature_correspondences[_features_incoming_out.back()] = std::make_shared<FeatureMatch>(FeatureMatch({feat_in,0})); + FeatureBasePtr ftr = FeatureBase::emplace<FeatureBase>(_capture, + "FEATURE DUMMY", + feat_in->getMeasurement(), + feat_in->getMeasurementCovariance()); + _features_out.push_back(ftr); + _feature_correspondences[_features_out.back()] = std::make_shared<FeatureMatch>(FeatureMatch({feat_in,0})); WOLF_INFO("track: " , feat_in->trackId() , " last: " , feat_in->id() , " inc: " , ftr->id() , " !" ); } } - return _features_incoming_out.size(); + return _features_out.size(); } bool ProcessorTrackerFeatureDummy::voteForKeyFrame() @@ -49,42 +53,43 @@ bool ProcessorTrackerFeatureDummy::voteForKeyFrame() return incoming_ptr_->getFeatureList().size() < params_tracker_feature_->min_features_for_keyframe; } -unsigned int ProcessorTrackerFeatureDummy::detectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out) +unsigned int ProcessorTrackerFeatureDummy::detectNewFeatures(const int& _max_new_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out) { - unsigned int max_features = _max_features; + unsigned int max_features = _max_new_features; if (max_features == -1) { max_features = 10; WOLF_INFO("max_features unlimited, setting it to " , max_features); } - WOLF_INFO("Detecting " , _max_features , " new features..." ); + WOLF_INFO("Detecting " , _max_new_features , " new features..." ); // detecting new features for (unsigned int i = 0; i < max_features; i++) { - FeatureBasePtr ftr(std::make_shared<FeatureBase>("DUMMY FEATURE", - Eigen::Vector1s::Ones(), - Eigen::MatrixXs::Ones(1, 1))); - _features_incoming_out.push_back(ftr); + FeatureBasePtr ftr = FeatureBase::emplace<FeatureBase>(_capture, + "DUMMY FEATURE", + Eigen::Vector1s::Ones(), + Eigen::MatrixXs::Ones(1, 1)); + _features_out.push_back(ftr); WOLF_INFO("feature " , ftr->id() , " detected!" ); } - WOLF_INFO(_features_incoming_out.size() , " features detected!"); + WOLF_INFO(_features_out.size() , " features detected!"); - return _features_incoming_out.size(); + return _features_out.size(); } -FactorBasePtr ProcessorTrackerFeatureDummy::createFactor(FeatureBasePtr _feature_ptr, - FeatureBasePtr _feature_other_ptr) +FactorBasePtr ProcessorTrackerFeatureDummy::emplaceFactor(FeatureBasePtr _feature_ptr, + FeatureBasePtr _feature_other_ptr) { - WOLF_INFO( "creating factor: track " , _feature_other_ptr->trackId() , " last feature " , _feature_ptr->id() - , " with origin feature " , _feature_other_ptr->id() ); + WOLF_INFO( "emplacing factor: track " , _feature_other_ptr->trackId() , " last feature " , _feature_ptr->id(), + " with origin feature " , _feature_other_ptr->id() ); - auto fac = std::make_shared<FactorFeatureDummy>(_feature_ptr, _feature_other_ptr, shared_from_this()); - - return fac; + return FactorBase::emplace<FactorFeatureDummy>(_feature_ptr, _feature_ptr, _feature_other_ptr, shared_from_this()); } ProcessorBasePtr ProcessorTrackerFeatureDummy::create(const std::string& _unique_name, diff --git a/src/processor/processor_tracker_landmark.cpp b/src/processor/processor_tracker_landmark.cpp index c55b21dc981c000ccf508b82ecf1f6842a1285c0..0d7c50c2a9e6ac8a3e91009a1ed361251a4104aa 100644 --- a/src/processor/processor_tracker_landmark.cpp +++ b/src/processor/processor_tracker_landmark.cpp @@ -23,50 +23,43 @@ ProcessorTrackerLandmark::ProcessorTrackerLandmark(const std::string& _type, ProcessorTrackerLandmark::~ProcessorTrackerLandmark() { - // All is shared_ptr: no need to destruct explicitly // - // for ( auto match : matches_landmark_from_incoming_) - // { - // match.second.reset(); // : Should we just remove the entries? What about match.first? - // } - // for ( auto match : matches_landmark_from_last_) - // { - // match.second.reset(); // : Should we just remove the entries? What about match.first? - // } } void ProcessorTrackerLandmark::advanceDerived() { - for (auto match : matches_landmark_from_last_) - { - match.second.reset(); // TODO: Should we just remove the entries? What about match.first? - } matches_landmark_from_last_ = std::move(matches_landmark_from_incoming_); new_features_last_ = std::move(new_features_incoming_); + + matches_landmark_from_incoming_.clear(); + new_features_incoming_.clear(); + new_landmarks_.clear(); } void ProcessorTrackerLandmark::resetDerived() { - for (auto match : matches_landmark_from_last_) - { - match.second.reset(); // TODO: Should we just remove the entries? What about match.first? - } matches_landmark_from_last_ = std::move(matches_landmark_from_incoming_); new_features_last_ = std::move(new_features_incoming_); + + matches_landmark_from_incoming_.clear(); + new_features_incoming_.clear(); + new_landmarks_.clear(); } unsigned int ProcessorTrackerLandmark::processKnown() { - // clear matches list - matches_landmark_from_incoming_.clear(); + assert(matches_landmark_from_incoming_.empty()); // Find landmarks in incoming_ptr_ FeatureBasePtrList known_features_list_incoming; unsigned int n = findLandmarks(getProblem()->getMap()->getLandmarkList(), + incoming_ptr_, known_features_list_incoming, matches_landmark_from_incoming_); - // Append found incoming features - incoming_ptr_->addFeatureList(known_features_list_incoming); + + // check all features have been emplaced + assert(std::all_of(known_features_list_incoming.begin(), known_features_list_incoming.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by findLandmarks()"); return n; } @@ -76,54 +69,56 @@ unsigned int ProcessorTrackerLandmark::processNew(const int& _max_features) /* Rationale: A keyFrame will be created using the last Capture. * * First, we work on this Capture to detect new Features, - * eventually create Landmarks with them, - * and in such case create the new Factors feature-landmark. - * When done, we need to track these new Features to the incoming Capture. - * - * At the end, all new Features are appended to the lists of known Features in - * the last and incoming Captures. + * eventually create Landmarks with them. + * When done, we need to find these new Landmarks in the incoming Capture. */ - // clear new lists - new_features_last_.clear(); - new_features_incoming_.clear(); - new_landmarks_.clear(); + // assuming cleared new lists + assert(new_features_last_.empty()); + assert(new_features_incoming_.empty()); + assert(new_landmarks_.empty()); // We first need to populate the \b last Capture with new Features - unsigned int n = detectNewFeatures(_max_features, new_features_last_); + unsigned int n = detectNewFeatures(_max_features, + last_ptr_, + new_features_last_); + + // check all features have been emplaced + assert(std::all_of(new_features_last_.begin(), new_features_last_.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by detectNewFeatures()"); // create new landmarks with the new features discovered - createNewLandmarks(); + emplaceNewLandmarks(); // Find the new landmarks in incoming_ptr_ (if it's not nullptr) if (incoming_ptr_ != nullptr) { - findLandmarks(new_landmarks_, new_features_incoming_, matches_landmark_from_incoming_); - - // Append all new Features to the incoming Capture's list of Features - incoming_ptr_->addFeatureList(new_features_incoming_); + findLandmarks(new_landmarks_, + incoming_ptr_, + new_features_incoming_, + matches_landmark_from_incoming_); + + // check all features have been emplaced + assert(std::all_of(new_features_incoming_.begin(), new_features_incoming_.end(), [](FeatureBasePtr f){return f->getCapture() != nullptr;}) && + "any not linked feature returned by findLandmarks()"); } - // Append all new Features to the last Capture's list of Features - last_ptr_->addFeatureList(new_features_last_); - - // Append new landmarks to the map - getProblem()->addLandmarkList(new_landmarks_); - // return the number of new features detected in \b last return n; } -void ProcessorTrackerLandmark::createNewLandmarks() +void ProcessorTrackerLandmark::emplaceNewLandmarks() { - // First, make sure the list is empty and will only contain new lmks - new_landmarks_.clear(); + // assuming empty list + assert(new_landmarks_.empty()); // Create a landmark for each new feature in last Capture: for (auto new_feature_ptr : new_features_last_) { // create new landmark - LandmarkBasePtr new_lmk_ptr = createLandmark(new_feature_ptr); + LandmarkBasePtr new_lmk_ptr = emplaceLandmark(new_feature_ptr); + + assert(new_lmk_ptr->getMap() != nullptr && "not linked landmark returned by emplaceLandmark()"); new_landmarks_.push_back(new_lmk_ptr); @@ -137,13 +132,11 @@ void ProcessorTrackerLandmark::establishFactors() // Loop all features in last_ptr_ for (auto last_feature : last_ptr_->getFeatureList()) { - auto lmk = matches_landmark_from_last_[last_feature]->landmark_ptr_; - FactorBasePtr fac_ptr = createFactor(last_feature, - lmk); - if (fac_ptr != nullptr) // factor links - { - fac_ptr->link(last_feature); - } + assert(matches_landmark_from_last_.count(last_feature) == 1); + + 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()"); } } diff --git a/src/processor/processor_tracker_landmark_dummy.cpp b/src/processor/processor_tracker_landmark_dummy.cpp index 61540a8afec1b4c204e59b92fca645efde1cd4ca..422e778279f605a01fddbaa67b10baab5f4de92d 100644 --- a/src/processor/processor_tracker_landmark_dummy.cpp +++ b/src/processor/processor_tracker_landmark_dummy.cpp @@ -26,7 +26,8 @@ ProcessorTrackerLandmarkDummy::~ProcessorTrackerLandmarkDummy() } unsigned int ProcessorTrackerLandmarkDummy::findLandmarks(const LandmarkBasePtrList& _landmarks_in, - FeatureBasePtrList& _features_incoming_out, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, LandmarkMatchMap& _feature_landmark_correspondences) { std::cout << "\tProcessorTrackerLandmarkDummy::findLandmarks" << std::endl; @@ -40,10 +41,11 @@ unsigned int ProcessorTrackerLandmarkDummy::findLandmarks(const LandmarkBasePtrL { if (count < prev_found - params_tracker_landmark_dummy_->n_landmarks_lost) // lose last n_landmarks_lost landmarks { - FeatureBasePtr ftr(std::make_shared<FeatureBase>("DUMMY FEATURE", - Eigen::Vector1s::Ones(), - Eigen::MatrixXs::Ones(1, 1))); - _features_incoming_out.push_back(ftr); + FeatureBasePtr ftr = FeatureBase::emplace<FeatureBase>(_capture, + "DUMMY FEATURE", + Eigen::Vector1s::Ones(), + Eigen::MatrixXs::Ones(1, 1)); + _features_out.push_back(ftr); _feature_landmark_correspondences[ftr] = std::make_shared<LandmarkMatch>(landmark_in_ptr, 1); std::cout << "\t\tlandmark " << landmark_in_ptr->id() << " found!" << std::endl; } @@ -53,7 +55,7 @@ unsigned int ProcessorTrackerLandmarkDummy::findLandmarks(const LandmarkBasePtrL } count++; } - return _features_incoming_out.size(); + return _features_out.size(); } bool ProcessorTrackerLandmarkDummy::voteForKeyFrame() @@ -64,7 +66,9 @@ bool ProcessorTrackerLandmarkDummy::voteForKeyFrame() return vote; } -unsigned int ProcessorTrackerLandmarkDummy::detectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out) +unsigned int ProcessorTrackerLandmarkDummy::detectNewFeatures(const int& _max_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out) { std::cout << "\tProcessorTrackerLandmarkDummy::detectNewFeatures" << std::endl; @@ -80,31 +84,32 @@ unsigned int ProcessorTrackerLandmarkDummy::detectNewFeatures(const int& _max_fe // detecting new features for (unsigned int i = 0; i < max_features; i++) { - FeatureBasePtr ftr(std::make_shared<FeatureBase>("DUMMY FEATURE", - Eigen::Vector1s::Ones(), - Eigen::MatrixXs::Ones(1, 1))); - _features_incoming_out.push_back(ftr); + FeatureBasePtr ftr = FeatureBase::emplace<FeatureBase>(_capture, + "DUMMY FEATURE", + Eigen::Vector1s::Ones(), + Eigen::MatrixXs::Ones(1, 1)); + _features_out.push_back(ftr); WOLF_INFO("feature " , ftr->id() , " detected!" ); } - WOLF_INFO(_features_incoming_out.size() , " features detected!"); + WOLF_INFO(_features_out.size() , " features detected!"); - return _features_incoming_out.size(); + return _features_out.size(); } -LandmarkBasePtr ProcessorTrackerLandmarkDummy::createLandmark(FeatureBasePtr _feature_ptr) +LandmarkBasePtr ProcessorTrackerLandmarkDummy::emplaceLandmark(FeatureBasePtr _feature_ptr) { - //std::cout << "ProcessorTrackerLandmarkDummy::createLandmark" << std::endl; - return std::make_shared<LandmarkBase>("BASE", std::make_shared<StateBlock>(2), std::make_shared<StateBlock>(1)); + //std::cout << "ProcessorTrackerLandmarkDummy::emplaceLandmark" << std::endl; + return LandmarkBase::emplace<LandmarkBase>(getProblem()->getMap(), "BASE", std::make_shared<StateBlock>(2), std::make_shared<StateBlock>(1)); } -FactorBasePtr ProcessorTrackerLandmarkDummy::createFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr) +FactorBasePtr ProcessorTrackerLandmarkDummy::emplaceFactor(FeatureBasePtr _feature_ptr, LandmarkBasePtr _landmark_ptr) { - std::cout << "\tProcessorTrackerLandmarkDummy::createFactor" << std::endl; + std::cout << "\tProcessorTrackerLandmarkDummy::emplaceFactor" << std::endl; std::cout << "\t\tfeature " << _feature_ptr->id() << std::endl; std::cout << "\t\tlandmark "<< _landmark_ptr->id() << std::endl; - return std::make_shared<FactorLandmarkDummy>(_feature_ptr, _landmark_ptr, shared_from_this()); + return FactorBase::emplace<FactorLandmarkDummy>(_feature_ptr, _feature_ptr, _landmark_ptr, shared_from_this()); } } //namespace wolf diff --git a/src/processor/track_matrix.cpp b/src/processor/track_matrix.cpp index 394fa88964d46e1a0d0e1632a058a124cb4ecfdc..b6c9cd176ffe3fd7468d60710c434ff29fe8e1db 100644 --- a/src/processor/track_matrix.cpp +++ b/src/processor/track_matrix.cpp @@ -22,7 +22,7 @@ TrackMatrix::~TrackMatrix() // } -Track TrackMatrix::track(size_t _track_id) +Track TrackMatrix::track(const SizeStd& _track_id) { if (tracks_.count(_track_id) > 0) return tracks_.at(_track_id); @@ -38,24 +38,28 @@ Snapshot TrackMatrix::snapshot(CaptureBasePtr _capture) return Snapshot(); } -void TrackMatrix::newTrack(CaptureBasePtr _cap, FeatureBasePtr _ftr) +void TrackMatrix::newTrack(FeatureBasePtr _ftr) { track_id_count_ ++; - add(track_id_count_, _cap, _ftr); + add(track_id_count_, _ftr); } -void TrackMatrix::add(size_t _track_id, CaptureBasePtr _cap, FeatureBasePtr _ftr) +void TrackMatrix::add(const SizeStd& _track_id, const FeatureBasePtr& _ftr) { - assert( (_track_id > 0) && (_track_id <= track_id_count_) && "Provided track ID does not exist. Use newTrack() instead."); + assert(( tracks_.count(_track_id) != 0 || _track_id == track_id_count_) && "Provided track ID does not exist. Use newTrack() instead."); + assert( _ftr->getCapture() != nullptr && "adding a feature not linked to any capture"); _ftr->setTrackId(_track_id); - if (_cap != _ftr->getCapture()) - _ftr->setCapture(_cap); - tracks_[_track_id].emplace(_cap->getTimeStamp(), _ftr); - snapshots_[_cap].emplace(_track_id, _ftr); // will create new snapshot if _cap_id is not present + tracks_[_track_id].emplace(_ftr->getCapture()->getTimeStamp(), _ftr); + snapshots_[_ftr->getCapture()].emplace(_track_id, _ftr); // will create new snapshot if _cap_id is not present } -void TrackMatrix::remove(size_t _track_id) +void TrackMatrix::add(const FeatureBasePtr& _ftr_existing,const FeatureBasePtr& _ftr_new) +{ + add(_ftr_existing->trackId(), _ftr_new); +} + +void TrackMatrix::remove(const SizeStd& _track_id) { // Remove track features from all Snapshots if (tracks_.count(_track_id)) @@ -116,12 +120,12 @@ size_t TrackMatrix::numTracks() return tracks_.size(); } -size_t TrackMatrix::trackSize(size_t _track_id) +size_t TrackMatrix::trackSize(const SizeStd& _track_id) { return track(_track_id).size(); } -FeatureBasePtr TrackMatrix::firstFeature(size_t _track_id) +FeatureBasePtr TrackMatrix::firstFeature(const SizeStd& _track_id) { if (tracks_.count(_track_id) > 0) return tracks_.at(_track_id).begin()->second; @@ -129,7 +133,7 @@ FeatureBasePtr TrackMatrix::firstFeature(size_t _track_id) return nullptr; } -FeatureBasePtr TrackMatrix::lastFeature(size_t _track_id) +FeatureBasePtr TrackMatrix::lastFeature(const SizeStd& _track_id) { if (tracks_.count(_track_id) > 0) return tracks_.at(_track_id).rbegin()->second; @@ -137,7 +141,7 @@ FeatureBasePtr TrackMatrix::lastFeature(size_t _track_id) return nullptr; } -vector<FeatureBasePtr> TrackMatrix::trackAsVector(size_t _track_id) +vector<FeatureBasePtr> TrackMatrix::trackAsVector(const SizeStd& _track_id) { vector<FeatureBasePtr> vec; if (tracks_.count(_track_id)) @@ -182,7 +186,7 @@ TrackMatches TrackMatrix::matches(CaptureBasePtr _cap_1, CaptureBasePtr _cap_2) return pairs; } -FeatureBasePtr TrackMatrix::feature(size_t _track_id, CaptureBasePtr _cap) +FeatureBasePtr TrackMatrix::feature(const SizeStd& _track_id, CaptureBasePtr _cap) { if (snapshot(_cap).count(_track_id)) return snapshot(_cap).at(_track_id); @@ -190,7 +194,7 @@ FeatureBasePtr TrackMatrix::feature(size_t _track_id, CaptureBasePtr _cap) return nullptr; } -CaptureBasePtr TrackMatrix::firstCapture(size_t _track_id) +CaptureBasePtr TrackMatrix::firstCapture(const SizeStd& _track_id) { return firstFeature(_track_id)->getCapture(); } diff --git a/src/sensor/sensor_base.cpp b/src/sensor/sensor_base.cpp index 3ad6e39bcd7a6b44013b48c4167e5bada37e1216..1be0920fb059789e99b16f3a84d11b3a33b49699 100644 --- a/src/sensor/sensor_base.cpp +++ b/src/sensor/sensor_base.cpp @@ -75,7 +75,7 @@ void SensorBase::removeStateBlocks() { if (getProblem() != nullptr && !extrinsic_dynamic_) { - getProblem()->removeStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,REMOVE); } setStateBlockPtrStatic(i, nullptr); } @@ -171,14 +171,12 @@ void SensorBase::addPriorParameter(const unsigned int _i, const Eigen::VectorXs& params_prior_map_[_i]->remove(); // create feature - FeatureBasePtr ftr_prior = std::make_shared<FeatureBase>("ABSOLUTE",_x,_cov); + FeatureBasePtr ftr_prior = FeatureBase::emplace<FeatureBase>(nullptr, "ABSOLUTE",_x,_cov);//std::make_shared<FeatureBase>("ABSOLUTE",_x,_cov); // set feature problem ftr_prior->setProblem(getProblem()); // create & add factor absolute - // ftr_prior->addFactor(std::make_shared<FactorQuaternionAbsolute>(_sb)); - // ftr_prior->addFactor(std::make_shared<FactorBlockAbsolute>(_sb, _start_idx, _size)); if (is_quaternion) FactorBase::emplace<FactorQuaternionAbsolute>(ftr_prior, _sb); else @@ -198,13 +196,13 @@ void SensorBase::registerNewStateBlocks() { auto sbp = getStateBlockPtrStatic(i); if (sbp != nullptr) - getProblem()->addStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,ADD); } if (i >= 2 && !isIntrinsicDynamic()) { auto sbp = getStateBlockPtrStatic(i); if (sbp != nullptr) - getProblem()->addStateBlock(sbp); + getProblem()->notifyStateBlock(sbp,ADD); } } } @@ -339,6 +337,11 @@ ProcessorBasePtr SensorBase::addProcessor(ProcessorBasePtr _proc_ptr) return _proc_ptr; } +void SensorBase::removeProcessor(ProcessorBasePtr _proc_ptr) +{ + processor_list_.remove(_proc_ptr); +} + StateBlockPtr SensorBase::getStateBlock(unsigned int _i) { CaptureBasePtr cap; @@ -406,6 +409,7 @@ void SensorBase::setProblem(ProblemPtr _problem) void SensorBase::link(HardwareBasePtr _hw_ptr) { + assert(this->getHardware() == nullptr && "linking an already linked sensor"); if(_hw_ptr) { this->setHardware(_hw_ptr); diff --git a/src/solver/solver_manager.cpp b/src/solver/solver_manager.cpp index e03be2d6ce6c5a7dac729efeef040a4d312ae11e..e7fcb6f56e2934b5c47c13cd0696013e476829bd 100644 --- a/src/solver/solver_manager.cpp +++ b/src/solver/solver_manager.cpp @@ -17,7 +17,7 @@ void SolverManager::update() auto fac_notification_map = wolf_problem_->consumeFactorNotificationMap(); auto sb_notification_map = wolf_problem_->consumeStateBlockNotificationMap(); - // REMOVE CONSTRAINTS + // REMOVE FACTORS for (auto fac_notification_it = fac_notification_map.begin(); fac_notification_it != fac_notification_map.end(); /* nothing, next is handled within the for */) @@ -70,7 +70,7 @@ void SolverManager::update() sb_notification_map.erase(sb_notification_map.begin()); } - // ADD CONSTRAINTS + // ADD FACTORS while (!fac_notification_map.empty()) { assert(fac_notification_map.begin()->second == ADD && "unexpected factor notification value after all REMOVE have been processed, this should be ADD"); diff --git a/src/trajectory/trajectory_base.cpp b/src/trajectory/trajectory_base.cpp index a2395ffae0c1512ca4157fc335bd02ed62855d6a..34921e3f468a0e4960f4b305978eb33ba01109f4 100644 --- a/src/trajectory/trajectory_base.cpp +++ b/src/trajectory/trajectory_base.cpp @@ -34,6 +34,16 @@ FrameBasePtr TrajectoryBase::addFrame(FrameBasePtr _frame_ptr) return _frame_ptr; } +void TrajectoryBase::removeFrame(FrameBasePtr _frame_ptr) +{ + // add to list + frame_list_.remove(_frame_ptr); + + // update last_estimated and last_key + if (_frame_ptr->isKeyOrAux()) + updateLastFrames(); +} + void TrajectoryBase::getFactorList(FactorBasePtrList & _fac_list) { for(auto fr_ptr : getFrameList()) diff --git a/test/gtest_capture_base.cpp b/test/gtest_capture_base.cpp index 633669c7b4a5fea47832bf22ab009cb3671cad7a..15be1ff455614ce95b116e865b1666a1a728d24b 100644 --- a/test/gtest_capture_base.cpp +++ b/test/gtest_capture_base.cpp @@ -82,28 +82,6 @@ TEST(CaptureBase, addFeature) ASSERT_EQ(C->getFeatureList().front(), f); } -TEST(CaptureBase, addFeatureList) -{ - CaptureBasePtr C(std::make_shared<CaptureBase>("DUMMY", 1.2)); // timestamp = 1.2 - // FeatureBasePtr f_first = C->addFeature(std::make_shared<FeatureBase>("DUMMY", Vector2s::Zero(), Matrix2s::Identity())); - auto f_first = FeatureBase::emplace<FeatureBase>(C, "DUMMY", Vector2s::Zero(), Matrix2s::Identity()); - ASSERT_EQ(C->getFeatureList().size(), (unsigned int) 1); - - // make a list to add - std::list<FeatureBasePtr> fl; - for (int i = 0; i<3; i++) - { - fl.push_back(std::make_shared<FeatureBase>("DUMMY", Vector2s::Zero(), Matrix2s::Identity())); - } - FeatureBasePtr f_last = fl.back(); - - C->addFeatureList((fl)); - ASSERT_EQ(C->getFeatureList().size(), (unsigned int) 4); - ASSERT_EQ(fl.size(), (unsigned int) 0); // features have been moved, not copied // EDIT 02-2019: features have been copied - ASSERT_EQ(C->getFeatureList().front(), f_first); - ASSERT_EQ(C->getFeatureList().back(), f_last); -} - TEST(CaptureBase, process) { SensorBasePtr S(std::make_shared<SensorBase>("DUMMY", nullptr, nullptr, nullptr, 2)); diff --git a/test/gtest_ceres_manager.cpp b/test/gtest_ceres_manager.cpp index 28cd36ced23e26ab9921905c7227640e9bbf1134..1f508dbe5cb760e6c5360d4cab16d5f4eb378ac7 100644 --- a/test/gtest_ceres_manager.cpp +++ b/test/gtest_ceres_manager.cpp @@ -101,7 +101,7 @@ TEST(CeresManager, AddStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -124,13 +124,13 @@ TEST(CeresManager, DoubleAddStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); // add stateblock again - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -153,7 +153,7 @@ TEST(CeresManager, UpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -184,7 +184,7 @@ TEST(CeresManager, AddUpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // Fix state block sb_ptr->fix(); @@ -211,7 +211,7 @@ TEST(CeresManager, RemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -220,7 +220,7 @@ TEST(CeresManager, RemoveStateBlock) ASSERT_TRUE(ceres_manager_ptr->isStateBlockRegisteredCeresManager(sb_ptr)); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver ceres_manager_ptr->update(); @@ -243,10 +243,10 @@ TEST(CeresManager, AddRemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver ceres_manager_ptr->update(); @@ -269,13 +269,13 @@ TEST(CeresManager, RemoveUpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver ceres_manager_ptr->update(); @@ -294,16 +294,16 @@ TEST(CeresManager, DoubleRemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver ceres_manager_ptr->update(); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver manager ceres_manager_ptr->update(); @@ -346,7 +346,7 @@ TEST(CeresManager, DoubleAddFactor) FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(FactorBase::emplace<FactorPose2D>(f,f)); // add factor again - P->addFactor(c); + P->notifyFactor(c,ADD); // update solver ceres_manager_ptr->update(); @@ -374,7 +374,7 @@ TEST(CeresManager, RemoveFactor) ceres_manager_ptr->update(); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // update solver ceres_manager_ptr->update(); @@ -399,7 +399,7 @@ TEST(CeresManager, AddRemoveFactor) FactorPose2DPtr c = std::static_pointer_cast<FactorPose2D>(FactorBase::emplace<FactorPose2D>(f,f)); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); ASSERT_TRUE(P->getFactorNotificationMapSize() == 0); // add+remove = empty @@ -429,13 +429,13 @@ TEST(CeresManager, DoubleRemoveFactor) ceres_manager_ptr->update(); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // update solver ceres_manager_ptr->update(); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); ASSERT_DEATH({ // update solver @@ -463,7 +463,7 @@ TEST(CeresManager, AddStateBlockLocalParam) sb_ptr->setLocalParametrization(local_param_ptr); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -490,7 +490,7 @@ TEST(CeresManager, RemoveLocalParam) sb_ptr->setLocalParametrization(local_param_ptr); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); @@ -518,7 +518,7 @@ TEST(CeresManager, AddLocalParam) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver ceres_manager_ptr->update(); diff --git a/test/gtest_frame_base.cpp b/test/gtest_frame_base.cpp index 4f189f559920003b3a0b8a033a56cde340d997ef..f02418eb99ce6d49eeaaee923755314c85c8fcc4 100644 --- a/test/gtest_frame_base.cpp +++ b/test/gtest_frame_base.cpp @@ -133,10 +133,6 @@ TEST(FrameBase, LinksToTree) F1->setKey(); ASSERT_TRUE(F1->isKey()); ASSERT_TRUE(F1->isKeyOrAux()); - - // Unlink - F1->unlinkCapture(C); - ASSERT_TRUE(F1->getCaptureList().empty()); } #include "core/state_block/state_quaternion.h" diff --git a/test/gtest_problem.cpp b/test/gtest_problem.cpp index d36a14461c139e60be272f5f54c883e77ff35999..7570f6c1870274ac8315b57468fff1da9e7b7be5 100644 --- a/test/gtest_problem.cpp +++ b/test/gtest_problem.cpp @@ -96,12 +96,7 @@ TEST(Problem, Processor) // Sm->addProcessor(Pm); auto Pm = std::static_pointer_cast<ProcessorMotion>(ProcessorBase::emplace<ProcessorOdom3D>(Sm, std::make_shared<ProcessorParamsOdom3D>())); - // check motion processor IS NOT set by addSensor <-- using InstallProcessor it should, see test Installers - ASSERT_FALSE(P->getProcessorMotion()); - - // set processor motion - P->setProcessorMotion(Pm); - // re-check motion processor IS set by addSensor + // check motion processor IS NOT by emplace ASSERT_EQ(P->getProcessorMotion(), Pm); } diff --git a/test/gtest_processor_loopclosure.cpp b/test/gtest_processor_loopclosure.cpp index f2c99aac536fb2265ad100f00f41def2aa2abeae..a7fc6818d0b739682eb546923bab9cb40e9bef27 100644 --- a/test/gtest_processor_loopclosure.cpp +++ b/test/gtest_processor_loopclosure.cpp @@ -70,8 +70,7 @@ TEST(ProcessorLoopClosure, installProcessor) std::make_shared<StateBlock>(Eigen::VectorXs::Zero(1)), std::make_shared<StateBlock>(Eigen::VectorXs::Zero(2)), 2); ProcessorParamsLoopClosurePtr params = std::make_shared<ProcessorParamsLoopClosure>(); - ProcessorLoopClosureDummyPtr proc_lc = std::make_shared<ProcessorLoopClosureDummy>(params, factor_created); - proc_lc->link(sens_lc); + auto proc_lc = ProcessorBase::emplace<ProcessorLoopClosureDummy>(sens_lc, params, factor_created); std::cout << "sensor & processor created and added to wolf problem" << std::endl; // initialize @@ -82,7 +81,7 @@ TEST(ProcessorLoopClosure, installProcessor) // new KF t += dt; - FrameBasePtr kf = FrameBase::create_PO_2D (KEY, t, x); //KF2 + FrameBasePtr kf = problem->emplaceFrame(KEY, x, t); //KF2 proc_lc->keyFrameCallback(kf, dt/2); // new capture diff --git a/test/gtest_processor_tracker_feature_dummy.cpp b/test/gtest_processor_tracker_feature_dummy.cpp index 02e24d90b19dc6a9537ccfbb3a7434887ce6c48e..ea169fcf994feeb624f88e718e94265aa4fbdb10 100644 --- a/test/gtest_processor_tracker_feature_dummy.cpp +++ b/test/gtest_processor_tracker_feature_dummy.cpp @@ -25,13 +25,16 @@ class ProcessorTrackerFeatureDummyDummy : public ProcessorTrackerFeatureDummy unsigned int callProcessNew(const int& _max_new_features){ return this->processNew(_max_new_features); } - unsigned int callDetectNewFeatures(const int& _max_features, FeatureBasePtrList& _features_incoming_out){ return this->detectNewFeatures(_max_features, _features_incoming_out); } + unsigned int callDetectNewFeatures(const int& _max_features, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out){ return this->detectNewFeatures(_max_features, _capture, _features_out); } - unsigned int callTrackFeatures(const FeatureBasePtrList& _features_last_in, - FeatureBasePtrList& _features_incoming_out, - FeatureMatchMap& _feature_correspondences){ return this->trackFeatures(_features_last_in, _features_incoming_out, _feature_correspondences); } + unsigned int callTrackFeatures(const FeatureBasePtrList& _features_in, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, + FeatureMatchMap& _feature_correspondences){ return this->trackFeatures(_features_in, _capture, _features_out, _feature_correspondences); } - FactorBasePtr callCreateFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr){ return this->createFactor(_feature_ptr, _feature_other_ptr); } + FactorBasePtr callEmplaceFactor(FeatureBasePtr _feature_ptr, FeatureBasePtr _feature_other_ptr){ return this->emplaceFactor(_feature_ptr, _feature_other_ptr); } void callEstablishFactors(){ this->establishFactors();} @@ -48,6 +51,20 @@ class ProcessorTrackerFeatureDummyDummy : public ProcessorTrackerFeatureDummy }; }; +bool isFeatureLinked(FeatureBasePtr ftr, CaptureBasePtr cap) +{ + return ftr->getCapture() == cap && + std::find(cap->getFeatureList().begin(), cap->getFeatureList().end(), ftr) != cap->getFeatureList().end(); + +} + +bool isFactorLinked(FactorBasePtr fac, FeatureBasePtr ftr) +{ + return fac->getFeature() == ftr && + std::find(ftr->getFactorList().begin(), ftr->getFactorList().end(), fac) != ftr->getFactorList().end(); + +} + // Use the following in case you want to initialize tests with predefines variables or methods. class ProcessorTrackerFeatureDummyTest : public testing::Test { @@ -57,6 +74,8 @@ class ProcessorTrackerFeatureDummyTest : public testing::Test ProcessorParamsTrackerFeatureDummyPtr params; ProcessorTrackerFeatureDummyDummyPtr processor; + virtual ~ProcessorTrackerFeatureDummyTest(){} + virtual void SetUp() { // Wolf problem @@ -92,9 +111,14 @@ TEST_F(ProcessorTrackerFeatureDummyTest, callDetectNewFeatures) FeatureBasePtrList feat_list; // demo callDetectNewFeatures - unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, feat_list); + unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); ASSERT_EQ(n_feat, feat_list.size()); ASSERT_EQ(n_feat, params->max_new_features); + + // check the features are emplaced + ASSERT_EQ(n_feat, last_cap->getFeatureList().size()); + for (auto feat : feat_list) + ASSERT_TRUE(isFeatureLinked(feat, last_cap)); } TEST_F(ProcessorTrackerFeatureDummyTest, trackFeatures) @@ -106,7 +130,7 @@ TEST_F(ProcessorTrackerFeatureDummyTest, trackFeatures) FeatureBasePtrList feat_list; //fill feat_last list - processor->callDetectNewFeatures(params->max_new_features, feat_list); + processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); // Put a capture on incoming_ptr_ CaptureBasePtr inc_cap = std::make_shared<CaptureVoid>(1, sensor); @@ -115,9 +139,14 @@ TEST_F(ProcessorTrackerFeatureDummyTest, trackFeatures) //test trackFeatures FeatureBasePtrList feat_list_out; FeatureMatchMap feat_correspondance; - processor->callTrackFeatures(feat_list, feat_list_out, feat_correspondance); + processor->callTrackFeatures(feat_list, inc_cap, feat_list_out, feat_correspondance); ASSERT_EQ(feat_list_out.size(), feat_correspondance.size()); ASSERT_EQ(feat_list.size(), feat_list_out.size()+1); // one of each 10 tracks is lost + + // check the features are emplaced + ASSERT_EQ(inc_cap->getFeatureList().size(), feat_list_out.size()); + for (auto feat : feat_list_out) + ASSERT_TRUE(isFeatureLinked(feat, inc_cap)); } TEST_F(ProcessorTrackerFeatureDummyTest, processNew) @@ -136,6 +165,12 @@ TEST_F(ProcessorTrackerFeatureDummyTest, processNew) ASSERT_EQ(processor->getLast()->getFeatureList().size(), 10); // detected 10 features ASSERT_EQ(processor->getIncoming()->getFeatureList().size(), 9); // 1 track lost ASSERT_EQ(processor->getMatchesLastFromIncoming().size(), 9); // 1 track lost + + // check the features are emplaced + for (auto feat : last_cap->getFeatureList()) + ASSERT_TRUE(isFeatureLinked(feat, last_cap)); + for (auto feat : inc_cap->getFeatureList()) + ASSERT_TRUE(isFeatureLinked(feat, inc_cap)); } TEST_F(ProcessorTrackerFeatureDummyTest, processKnown) @@ -166,9 +201,17 @@ TEST_F(ProcessorTrackerFeatureDummyTest, processKnown) ASSERT_EQ(n_tracked_feat, 13); // 1 track lost ASSERT_EQ(processor->getIncoming()->getFeatureList().size(), 13); // 1 track lost ASSERT_EQ(processor->getMatchesLastFromIncoming().size(), 13); // 1 track lost + + // check the features are emplaced + for (auto feat : processor->getOrigin()->getFeatureList()) + ASSERT_TRUE(isFeatureLinked(feat, processor->getOrigin())); + for (auto feat : processor->getLast()->getFeatureList()) + ASSERT_TRUE(isFeatureLinked(feat, processor->getLast())); + for (auto feat : processor->getIncoming()->getFeatureList()) + ASSERT_TRUE(isFeatureLinked(feat, processor->getIncoming())); } -TEST_F(ProcessorTrackerFeatureDummyTest, createFactor) +TEST_F(ProcessorTrackerFeatureDummyTest, emplaceFactor) { FeatureBasePtr ftr(std::make_shared<FeatureBase>("DUMMY FEATURE", Eigen::Vector1s::Ones(), @@ -177,13 +220,15 @@ TEST_F(ProcessorTrackerFeatureDummyTest, createFactor) Eigen::Vector1s::Ones(), Eigen::MatrixXs::Ones(1, 1))); - FactorBasePtr fac = processor->callCreateFactor(ftr, ftr_other); - fac->link(ftr); - ASSERT_EQ(fac->getFeature(),ftr); + FactorBasePtr fac = processor->callEmplaceFactor(ftr, ftr_other); + + // check factor correctly emplaced + ASSERT_TRUE(isFactorLinked(fac, ftr)); ASSERT_EQ(fac->getFrameOther(),nullptr); ASSERT_EQ(fac->getCaptureOther(),nullptr); ASSERT_EQ(fac->getFeatureOther(),ftr_other); ASSERT_EQ(fac->getLandmarkOther(),nullptr); + ASSERT_TRUE(std::find(ftr_other->getConstrainedByList().begin(),ftr_other->getConstrainedByList().end(), fac) != ftr_other->getConstrainedByList().end()); } TEST_F(ProcessorTrackerFeatureDummyTest, establishFactors) @@ -244,6 +289,7 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process) ASSERT_TRUE(problem->getTrajectory()->getLastKeyFrame() != nullptr); ASSERT_EQ(problem->getTrajectory()->getLastKeyFrame()->id(), cap1->getFrame()->id()); + ASSERT_TRUE(problem->check(0)); //2ND TIME WOLF_DEBUG("Second time..."); @@ -252,6 +298,7 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process) ASSERT_EQ(processor->getOrigin()->getFeatureList().size(), params->max_new_features); ASSERT_EQ(processor->getLast()->getFeatureList().size(), params->max_new_features-1); + ASSERT_TRUE(problem->check(0)); //3RD TIME WOLF_DEBUG("Third time..."); @@ -259,6 +306,7 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process) cap3->process(); ASSERT_EQ(processor->getLast()->getFeatureList().size(), params->max_new_features-2); + ASSERT_TRUE(problem->check(0)); //4TH TIME WOLF_DEBUG("Forth time..."); @@ -266,6 +314,7 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process) cap4->process(); ASSERT_EQ(processor->getLast()->getFeatureList().size(), params->max_new_features-3); + ASSERT_TRUE(problem->check(0)); //5TH TIME -> KF in cap4 (tracked features < 7 (params->min_features_for_keyframe)) WOLF_DEBUG("Fifth time..."); @@ -274,11 +323,13 @@ TEST_F(ProcessorTrackerFeatureDummyTest, process) ASSERT_TRUE(cap4->getFrame()->isKey()); ASSERT_EQ(problem->getTrajectory()->getLastKeyFrame()->id(), cap4->getFrame()->id()); + ASSERT_TRUE(problem->check(0)); // check factors WOLF_DEBUG("checking factors..."); TrackMatrix track_matrix = processor->getTrackMatrix(); ASSERT_EQ(cap4->getFeatureList().size(), params->min_features_for_keyframe + params->max_new_features); + ASSERT_TRUE(problem->check(0)); unsigned int n_factors0 = 0; unsigned int n_factors4 = 0; for (auto feat : cap4->getFeatureList()) diff --git a/test/gtest_processor_tracker_landmark_dummy.cpp b/test/gtest_processor_tracker_landmark_dummy.cpp index a5f3f5945b13320516d713ab30f535383f273d55..8ed266881c29e43a29836eac706ec0dd9c96f19e 100644 --- a/test/gtest_processor_tracker_landmark_dummy.cpp +++ b/test/gtest_processor_tracker_landmark_dummy.cpp @@ -26,19 +26,23 @@ class ProcessorTrackerLandmarkDummyDummy : public ProcessorTrackerLandmarkDummy unsigned int callProcessNew(const int& _max_new_features){ return this->processNew(_max_new_features); } unsigned int callDetectNewFeatures(const int& _max_features, - FeatureBasePtrList& _features_incoming_out){ return this->detectNewFeatures(_max_features, - _features_incoming_out); } + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out){ return this->detectNewFeatures(_max_features, + _capture, + _features_out); } unsigned int callFindLandmarks(const LandmarkBasePtrList& _landmarks_in, - FeatureBasePtrList& _features_incoming_out, + const CaptureBasePtr& _capture, + FeatureBasePtrList& _features_out, LandmarkMatchMap& _feature_landmark_correspondences){ return this->findLandmarks(_landmarks_in, - _features_incoming_out, + _capture, + _features_out, _feature_landmark_correspondences); } - LandmarkBasePtr callCreateLandmark(FeatureBasePtr _feature_ptr){ return this->createLandmark(_feature_ptr); } - void callCreateNewLandmarks(){ this->createNewLandmarks(); } - FactorBasePtr callCreateFactor(FeatureBasePtr _feature_ptr, - LandmarkBasePtr _landmark_ptr){ return this->createFactor(_feature_ptr, + LandmarkBasePtr callEmplaceLandmark(FeatureBasePtr _feature_ptr){ return this->emplaceLandmark(_feature_ptr); } + void callEmplaceNewLandmarks(){ this->emplaceNewLandmarks(); } + FactorBasePtr callEmplaceFactor(FeatureBasePtr _feature_ptr, + LandmarkBasePtr _landmark_ptr){ return this->emplaceFactor(_feature_ptr, _landmark_ptr); } void callEstablishFactors(){ this->establishFactors();} @@ -58,6 +62,27 @@ class ProcessorTrackerLandmarkDummyDummy : public ProcessorTrackerLandmarkDummy }; }; +bool isFeatureLinked(FeatureBasePtr ftr, CaptureBasePtr cap) +{ + return ftr->getCapture() == cap && + std::find(cap->getFeatureList().begin(), cap->getFeatureList().end(), ftr) != cap->getFeatureList().end(); + +} + +bool isFactorLinked(FactorBasePtr fac, FeatureBasePtr ftr) +{ + return fac->getFeature() == ftr && + std::find(ftr->getFactorList().begin(), ftr->getFactorList().end(), fac) != ftr->getFactorList().end(); + +} + +bool isLandmarkLinked(LandmarkBasePtr lmk, MapBasePtr map) +{ + return lmk->getMap() == map && + std::find(map->getLandmarkList().begin(), map->getLandmarkList().end(), lmk) != map->getLandmarkList().end(); + +} + // Use the following in case you want to initialize tests with predefines variables or methods. class ProcessorTrackerLandmarkDummyTest : public testing::Test { @@ -67,6 +92,8 @@ class ProcessorTrackerLandmarkDummyTest : public testing::Test ProcessorParamsTrackerLandmarkDummyPtr params; ProcessorTrackerLandmarkDummyDummyPtr processor; + virtual ~ProcessorTrackerLandmarkDummyTest(){} + virtual void SetUp() { // Wolf problem @@ -102,12 +129,17 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, detectNewFeatures) FeatureBasePtrList feat_list; // demo callDetectNewFeatures - unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, feat_list); + unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); ASSERT_EQ(n_feat, feat_list.size()); // detected 10 features ASSERT_EQ(n_feat, params->max_new_features); // detected 10 features + + // check the features are emplaced + ASSERT_EQ(n_feat, last_cap->getFeatureList().size()); + for (auto feat : feat_list) + ASSERT_TRUE(isFeatureLinked(feat, last_cap)); } -TEST_F(ProcessorTrackerLandmarkDummyTest, createLandmark) +TEST_F(ProcessorTrackerLandmarkDummyTest, emplaceLandmark) { // Put a capture on last_ptr_ CaptureBasePtr last_cap = std::make_shared<CaptureVoid>(0, sensor); @@ -116,19 +148,18 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, createLandmark) FeatureBasePtrList feat_list; // demo callDetectNewFeatures - unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, feat_list); - ASSERT_EQ(n_feat, feat_list.size()); // detected 10 features - ASSERT_EQ(n_feat, params->max_new_features); // detected 10 features + unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); for (auto ftr : feat_list) { - auto lmk = processor->callCreateLandmark(ftr); - lmk->link(problem->getMap()); + auto lmk = processor->callEmplaceLandmark(ftr); + // check that it is correctly emplaced + ASSERT_TRUE(isLandmarkLinked(lmk,problem->getMap())); } - ASSERT_EQ(problem->getMap()->getLandmarkList().size(),n_feat); // created 10 landmarks + ASSERT_EQ(problem->getMap()->getLandmarkList().size(),n_feat); // emplaced 10 landmarks } -TEST_F(ProcessorTrackerLandmarkDummyTest, createNewLandmarks) +TEST_F(ProcessorTrackerLandmarkDummyTest, emplaceNewLandmarks) { // Put a capture on last_ptr_ CaptureBasePtr last_cap = std::make_shared<CaptureVoid>(0, sensor); @@ -137,14 +168,16 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, createNewLandmarks) FeatureBasePtrList feat_list; // test detectNewFeatures - unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, feat_list); - ASSERT_EQ(n_feat, feat_list.size()); // detected 10 features - ASSERT_EQ(n_feat, params->max_new_features); // detected 10 features + unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); // test createNewLandmarks processor->setNewFeaturesLast(feat_list); - processor->callCreateNewLandmarks(); - ASSERT_EQ(processor->getNewLandmarks().size(),n_feat); // created 10 landmarks + processor->callEmplaceNewLandmarks(); + ASSERT_EQ(processor->getNewLandmarks().size(),n_feat); // emplaced 10 landmarks + + // check that it is correctly emplaced + for (auto lmk : processor->getNewLandmarks()) + ASSERT_TRUE(isLandmarkLinked(lmk,problem->getMap())); } TEST_F(ProcessorTrackerLandmarkDummyTest, findLandmarks) @@ -156,22 +189,26 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, findLandmarks) FeatureBasePtrList feat_list; // test detectNewFeatures - unsigned int n_feat = processor->callDetectNewFeatures(params->max_new_features, feat_list); - ASSERT_EQ(n_feat, feat_list.size()); // detected 10 features - ASSERT_EQ(n_feat, params->max_new_features); // detected 10 features + processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); // test createNewLandmarks processor->setNewFeaturesLast(feat_list); - processor->callCreateNewLandmarks(); + processor->callEmplaceNewLandmarks(); LandmarkBasePtrList new_landmarks = processor->getNewLandmarks(); - ASSERT_EQ(new_landmarks.size(),n_feat); // created 10 landmarks //test findLandmarks LandmarkMatchMap feature_landmark_correspondences; FeatureBasePtrList feat_found; - processor->callFindLandmarks(new_landmarks, feat_found, feature_landmark_correspondences); + + CaptureBasePtr inc_cap = std::make_shared<CaptureVoid>(0, sensor); + processor->setInc(inc_cap); + + processor->callFindLandmarks(new_landmarks, inc_cap, feat_found, feature_landmark_correspondences); ASSERT_EQ(feature_landmark_correspondences.size(), feat_found.size()); ASSERT_EQ(feat_list.size(), feat_found.size()+1); // one of each 10 tracks is lost + + for (auto feat : feat_found) + ASSERT_TRUE(isFeatureLinked(feat, inc_cap)); } TEST_F(ProcessorTrackerLandmarkDummyTest, processNew) @@ -184,7 +221,7 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, processNew) CaptureBasePtr inc_cap = std::make_shared<CaptureVoid>(1, sensor); processor->setInc(inc_cap); - auto n_new_feat = processor->callProcessNew(10); // detect 10 features + auto n_new_feat = processor->callProcessNew(10); // detect 10 features in last, create landmarks, find landmarks in incoming ASSERT_EQ(n_new_feat, 10); // detected 10 features ASSERT_EQ(processor->getLast()->getFeatureList().size(), 10); // detected 10 features @@ -196,14 +233,15 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, processNew) TEST_F(ProcessorTrackerLandmarkDummyTest, processKnown) { + // Put a capture on last_ptr_ + CaptureBasePtr last_cap = std::make_shared<CaptureVoid>(0, sensor); + processor->setLast(last_cap); + // create 10 landmarks and link them to map FeatureBasePtrList feat_list; - processor->callDetectNewFeatures(params->max_new_features, feat_list); - for (auto ftr : feat_list) - { - auto lmk = processor->callCreateLandmark(ftr); - lmk->link(problem->getMap()); - } + processor->callDetectNewFeatures(params->max_new_features, last_cap, feat_list); + processor->setNewFeaturesLast(feat_list); + processor->callEmplaceNewLandmarks(); ASSERT_EQ(problem->getMap()->getLandmarkList().size(),10); // created 10 landmarks // Put a capture on incoming_ptr_ @@ -217,7 +255,7 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, processKnown) ASSERT_EQ(processor->getMatchesLandmarkFromIncoming().size(), 9); // 1 of each 10 landmarks is not found } -TEST_F(ProcessorTrackerLandmarkDummyTest, createFactor) +TEST_F(ProcessorTrackerLandmarkDummyTest, emplaceFactor) { FeatureBasePtr ftr(std::make_shared<FeatureBase>("DUMMY FEATURE", Eigen::Vector1s::Ones(), @@ -226,8 +264,7 @@ TEST_F(ProcessorTrackerLandmarkDummyTest, createFactor) std::make_shared<StateBlock>(1), std::make_shared<StateBlock>(1))); - FactorBasePtr fac = processor->callCreateFactor(ftr, lmk); - fac->link(ftr); + FactorBasePtr fac = processor->callEmplaceFactor(ftr, lmk); ASSERT_EQ(fac->getFeature(),ftr); ASSERT_EQ(fac->getFrameOther(),nullptr); ASSERT_EQ(fac->getCaptureOther(),nullptr); diff --git a/test/gtest_solver_manager.cpp b/test/gtest_solver_manager.cpp index 815817a6eac6faabf045a438819d09ae2d2529be..de653851d9de3aa625421088b4fb076e9b586afb 100644 --- a/test/gtest_solver_manager.cpp +++ b/test/gtest_solver_manager.cpp @@ -126,7 +126,7 @@ TEST(SolverManager, AddStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver solver_manager_ptr->update(); @@ -145,13 +145,13 @@ TEST(SolverManager, DoubleAddStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver solver_manager_ptr->update(); // add stateblock again - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver solver_manager_ptr->update(); @@ -170,7 +170,7 @@ TEST(SolverManager, UpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // check flags ASSERT_FALSE(sb_ptr->stateUpdated()); @@ -218,7 +218,7 @@ TEST(SolverManager, AddUpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // check flags ASSERT_FALSE(sb_ptr->stateUpdated()); @@ -256,7 +256,7 @@ TEST(SolverManager, AddUpdateLocalParamStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // check flags ASSERT_FALSE(sb_ptr->stateUpdated()); @@ -308,7 +308,7 @@ TEST(SolverManager, AddLocalParamRemoveLocalParamStateBlock) ASSERT_TRUE(sb_ptr->localParamUpdated()); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver manager solver_manager_ptr->update(); @@ -346,13 +346,13 @@ TEST(SolverManager, RemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver solver_manager_ptr->update(); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver solver_manager_ptr->update(); @@ -371,10 +371,10 @@ TEST(SolverManager, AddRemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver solver_manager_ptr->update(); @@ -393,10 +393,10 @@ TEST(SolverManager, RemoveUpdateStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add state_block - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver solver_manager_ptr->update(); @@ -412,16 +412,16 @@ TEST(SolverManager, DoubleRemoveStateBlock) StateBlockPtr sb_ptr = std::make_shared<StateBlock>(state); // add stateblock - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver solver_manager_ptr->update(); // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); // update solver manager solver_manager_ptr->update(); @@ -450,7 +450,7 @@ TEST(SolverManager, AddUpdatedStateBlock) // == When an ADD is notified: a ADD notification should be stored == // add state_block - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); Notification notif; ASSERT_EQ(P->getStateBlockNotificationMapSize(),1); @@ -465,35 +465,44 @@ TEST(SolverManager, AddUpdatedStateBlock) // Fix --> FLAG sb_ptr->unfix(); + // Check flag has been set true + ASSERT_TRUE(sb_ptr->fixUpdated()); ASSERT_EQ(P->getStateBlockNotificationMapSize(),1); // No new notifications (fix and set state are flags in sb) // == consume empties the notification map == solver_manager_ptr->update(); // it calls P->consumeStateBlockNotificationMap(); ASSERT_EQ(P->getStateBlockNotificationMapSize(),0); + // Check flags have been reset + ASSERT_FALSE(sb_ptr->fixUpdated()); + ASSERT_FALSE(sb_ptr->stateUpdated()); // == When an REMOVE is notified: a REMOVE notification should be stored == // remove state_block - P->removeStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,REMOVE); ASSERT_EQ(P->getStateBlockNotificationMapSize(),1); ASSERT_TRUE(P->getStateBlockNotification(sb_ptr, notif)); ASSERT_EQ(notif, REMOVE); - // == ADD + REMOVE: notification map should be empty == - P->addStateBlock(sb_ptr); - P->removeStateBlock(sb_ptr); - ASSERT_TRUE(P->getStateBlockNotificationMapSize() == 0); + // == REMOVE + ADD: notification map should be empty == + P->notifyStateBlock(sb_ptr,ADD); + ASSERT_EQ(P->getStateBlockNotificationMapSize(),0); // == UPDATES should clear the list of notifications == // add state_block - P->addStateBlock(sb_ptr); + P->notifyStateBlock(sb_ptr,ADD); // update solver solver_manager_ptr->update(); ASSERT_EQ(P->getStateBlockNotificationMapSize(),0); // After solver_manager->update, notifications should be empty + + // == ADD + REMOVE: notification map should be empty == + P->notifyStateBlock(sb_ptr,ADD); + P->notifyStateBlock(sb_ptr,REMOVE); + ASSERT_EQ(P->getStateBlockNotificationMapSize(),0); } TEST(SolverManager, AddFactor) @@ -542,7 +551,7 @@ TEST(SolverManager, RemoveFactor) solver_manager_ptr->update(); // add factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // notification Notification notif; @@ -578,7 +587,7 @@ TEST(SolverManager, AddRemoveFactor) ASSERT_EQ(notif, ADD); // add factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // notification ASSERT_EQ(P->getFactorNotificationMapSize(), 0); // ADD+REMOVE cancels out @@ -611,13 +620,13 @@ TEST(SolverManager, DoubleRemoveFactor) solver_manager_ptr->update(); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // update solver solver_manager_ptr->update(); // remove factor - P->removeFactor(c); + P->notifyFactor(c,REMOVE); // update solver solver_manager_ptr->update(); diff --git a/test/gtest_track_matrix.cpp b/test/gtest_track_matrix.cpp index f2f08e8c2241624b8914fd0eb6dc2ebbf93bab2d..8d7cafc5f699abc2f0fa9d275f57d5b4b3677821 100644 --- a/test/gtest_track_matrix.cpp +++ b/test/gtest_track_matrix.cpp @@ -25,23 +25,29 @@ class TrackMatrixTest : public testing::Test virtual void SetUp() { - F0 = std::make_shared<FrameBase>(0.0, nullptr); - F1 = std::make_shared<FrameBase>(1.0, nullptr); - F2 = std::make_shared<FrameBase>(2.0, nullptr); - F3 = std::make_shared<FrameBase>(3.0, nullptr); - F4 = std::make_shared<FrameBase>(4.0, nullptr); - - C0 = std::make_shared<CaptureBase>("BASE", 0.0); - C1 = std::make_shared<CaptureBase>("BASE", 1.0); - C2 = std::make_shared<CaptureBase>("BASE", 2.0); - C3 = std::make_shared<CaptureBase>("BASE", 3.0); - C4 = std::make_shared<CaptureBase>("BASE", 4.0); - - f0 = std::make_shared<FeatureBase>("BASE", m, m_cov); - f1 = std::make_shared<FeatureBase>("BASE", m, m_cov); - f2 = std::make_shared<FeatureBase>("BASE", m, m_cov); - f3 = std::make_shared<FeatureBase>("BASE", m, m_cov); - f4 = std::make_shared<FeatureBase>("BASE", m, m_cov); + // unlinked captures + // Some warnings will be thrown "linking with nullptr" for emplacing without providing frame pointer + C0 = CaptureBase::emplace<CaptureBase>(nullptr, "BASE", 0.0); + C1 = CaptureBase::emplace<CaptureBase>(nullptr, "BASE", 1.0); + C2 = CaptureBase::emplace<CaptureBase>(nullptr, "BASE", 2.0); + C3 = CaptureBase::emplace<CaptureBase>(nullptr, "BASE", 3.0); + C4 = CaptureBase::emplace<CaptureBase>(nullptr, "BASE", 4.0); + + // unlinked frames + // Some warnings will be thrown "linking with nullptr" for emplacing without providing frame pointer + F0 = FrameBase::emplace<FrameBase>(nullptr, 0.0, nullptr); + F1 = FrameBase::emplace<FrameBase>(nullptr, 1.0, nullptr); + F2 = FrameBase::emplace<FrameBase>(nullptr, 2.0, nullptr); + F3 = FrameBase::emplace<FrameBase>(nullptr, 3.0, nullptr); + F4 = FrameBase::emplace<FrameBase>(nullptr, 4.0, nullptr); + + // unlinked features + // Some warnings will be thrown "linking with nullptr" for emplacing without providing capture pointer + f0 = FeatureBase::emplace<FeatureBase>(nullptr, "BASE", m, m_cov); + f1 = FeatureBase::emplace<FeatureBase>(nullptr, "BASE", m, m_cov); + f2 = FeatureBase::emplace<FeatureBase>(nullptr, "BASE", m, m_cov); + f3 = FeatureBase::emplace<FeatureBase>(nullptr, "BASE", m, m_cov); + f4 = FeatureBase::emplace<FeatureBase>(nullptr, "BASE", m, m_cov); // F0 and F4 are keyframes F0->setKey(); @@ -58,26 +64,35 @@ class TrackMatrixTest : public testing::Test TEST_F(TrackMatrixTest, newTrack) { - track_matrix.newTrack(C0, f0); + f0->link(C0); + f1->link(C1); + f2->link(C1); + f3->link(C1); + + track_matrix.newTrack(f0); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); - track_matrix.newTrack(C0, f1); + track_matrix.newTrack(f1); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2); - track_matrix.newTrack(C1, f2); + track_matrix.newTrack(f2); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 3); - track_matrix.newTrack(C1, f3); + track_matrix.newTrack(f3); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 4); } TEST_F(TrackMatrixTest, add) { - track_matrix.newTrack(C0, f0); + f0->link(C0); + f1->link(C1); + f2->link(C2); + + track_matrix.newTrack(f0); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); - track_matrix.add(f0->trackId(), C1, f1); - /* KC0 C1 C2 snapshots + track_matrix.add(f0->trackId(), f1); + /* KC0 C1 snapshots * * f0---f1 trk 0 */ @@ -85,7 +100,33 @@ TEST_F(TrackMatrixTest, add) ASSERT_EQ(f1->trackId(), f0->trackId()); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); - track_matrix.add(f0->trackId(), C2, f2); + track_matrix.add(f0->trackId(), f2); + /* KC0 C1 C2 snapshots + * + * f0---f1---f2 trk 0 + */ + ASSERT_EQ(track_matrix.trackSize(f2->trackId()), (unsigned int) 3); + ASSERT_EQ(f2->trackId(), f0->trackId()); +} + +TEST_F(TrackMatrixTest, add2) +{ + f0->link(C0); + f1->link(C1); + f2->link(C2); + f3->link(C1); + + track_matrix.newTrack(f0); + + track_matrix.add(f0, f1); + /* KC0 C1 snapshots + * + * f0---f1 trk 0 + */ + ASSERT_EQ(track_matrix.trackSize(f1->trackId()), (unsigned int) 2); + ASSERT_EQ(f1->trackId(), f0->trackId()); + + track_matrix.add(f1, f2); /* KC0 C1 C2 snapshots * * f0---f1---f2 trk 0 @@ -94,13 +135,12 @@ TEST_F(TrackMatrixTest, add) ASSERT_EQ(f2->trackId(), f0->trackId()); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); - track_matrix.add(f0->trackId(), C2, f2); + track_matrix.newTrack(f3); /* KC0 C1 C2 snapshots * * f0---f1---f2 trk 0 * f3 trk 1 */ - track_matrix.add(1, C1, f3); ASSERT_EQ(track_matrix.trackSize(f3->trackId()), (unsigned int) 1); ASSERT_NE(f3->trackId(), f0->trackId()); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 2); @@ -108,8 +148,12 @@ TEST_F(TrackMatrixTest, add) TEST_F(TrackMatrixTest, numTracks) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); /* C0 C1 C2 snapshots * @@ -118,16 +162,20 @@ TEST_F(TrackMatrixTest, numTracks) ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); - track_matrix.add(f0->trackId(), C0, f2); + track_matrix.add(f0->trackId(), f2); ASSERT_EQ(track_matrix.numTracks(), (unsigned int) 1); } TEST_F(TrackMatrixTest, trackSize) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -149,9 +197,13 @@ TEST_F(TrackMatrixTest, first_last_Feature) * f2 trk 1 */ - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C1, f2); + f0->link(C0); + f1->link(C1); + f2->link(C1); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); ASSERT_EQ(track_matrix.firstFeature(f0->trackId()), f0); ASSERT_EQ(track_matrix.lastFeature (f0->trackId()), f1); @@ -162,9 +214,13 @@ TEST_F(TrackMatrixTest, first_last_Feature) TEST_F(TrackMatrixTest, remove_ftr) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -207,9 +263,13 @@ TEST_F(TrackMatrixTest, remove_ftr) TEST_F(TrackMatrixTest, remove_trk) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -230,9 +290,13 @@ TEST_F(TrackMatrixTest, remove_trk) TEST_F(TrackMatrixTest, remove_snapshot) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -257,9 +321,13 @@ TEST_F(TrackMatrixTest, remove_snapshot) TEST_F(TrackMatrixTest, track) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -281,9 +349,13 @@ TEST_F(TrackMatrixTest, track) TEST_F(TrackMatrixTest, snapshot) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -305,9 +377,13 @@ TEST_F(TrackMatrixTest, snapshot) TEST_F(TrackMatrixTest, trackAsVector) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -325,9 +401,13 @@ TEST_F(TrackMatrixTest, trackAsVector) TEST_F(TrackMatrixTest, snapshotAsList) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.newTrack(C0, f2); + f0->link(C0); + f1->link(C1); + f2->link(C0); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.newTrack(f2); /* C0 C1 C2 snapshots * @@ -345,11 +425,17 @@ TEST_F(TrackMatrixTest, snapshotAsList) TEST_F(TrackMatrixTest, matches) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.add(f0->trackId(), C2, f2); - track_matrix.newTrack(C0, f3); - track_matrix.add(f3->trackId(), C1, f4); + f0->link(C0); + f1->link(C1); + f2->link(C2); + f3->link(C0); + f4->link(C1); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.add(f0->trackId(), f2); + track_matrix.newTrack(f3); + track_matrix.add(f3->trackId(), f4); /* C0 C1 C2 C3 snapshots * @@ -371,11 +457,17 @@ TEST_F(TrackMatrixTest, matches) TEST_F(TrackMatrixTest, trackAtKeyframes) { - track_matrix.newTrack(C0, f0); - track_matrix.add(f0->trackId(), C1, f1); - track_matrix.add(f0->trackId(), C2, f2); - track_matrix.add(f0->trackId(), C4, f4); - track_matrix.newTrack(C1, f3); + f0->link(C0); + f1->link(C1); + f2->link(C2); + f3->link(C1); + f4->link(C4); + + track_matrix.newTrack(f0); + track_matrix.add(f0->trackId(), f1); + track_matrix.add(f0->trackId(), f2); + track_matrix.add(f0->trackId(), f4); + track_matrix.newTrack(f3); /* KC0 C1 C2 C3 KC4 snapshots * * f0---f1---f2--------f4 trk 0 diff --git a/test/gtest_trajectory.cpp b/test/gtest_trajectory.cpp index 2edffe94d62ca65ce10bce645eeb5d08d685676f..d31cb98496a85cc82a1436dd1ef8043809a89488 100644 --- a/test/gtest_trajectory.cpp +++ b/test/gtest_trajectory.cpp @@ -57,14 +57,10 @@ TEST(TrajectoryBase, ClosestKeyFrame) // 1 2 3 4 time stamps // --+-----+-----+-----+---> time - FrameBasePtr F1 = std::make_shared<FrameBase>(KEY, 1, nullptr, nullptr); - FrameBasePtr F2 = std::make_shared<FrameBase>(KEY, 2, nullptr, nullptr); - FrameBasePtr F3 = std::make_shared<FrameBase>(AUXILIARY, 3, nullptr, nullptr); - FrameBasePtr F4 = std::make_shared<FrameBase>(NON_ESTIMATED, 4, nullptr, nullptr); - T->addFrame(F1); - T->addFrame(F2); - T->addFrame(F3); - T->addFrame(F4); + FrameBasePtr F1 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 1); + FrameBasePtr F2 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 2); + FrameBasePtr F3 = P->emplaceFrame(AUXILIARY, Eigen::Vector3s::Zero(), 3); + FrameBasePtr F4 = P->emplaceFrame(NON_ESTIMATED, Eigen::Vector3s::Zero(), 4); FrameBasePtr KF; // closest key-frame queried @@ -98,9 +94,9 @@ TEST(TrajectoryBase, ClosestKeyOrAuxFrame) // 1 2 3 time stamps // --+-----+-----+---> time - FrameBasePtr F1 = FrameBase::emplace<FrameBase>(T, KEY, 1, nullptr, nullptr); - FrameBasePtr F2 = FrameBase::emplace<FrameBase>(T, AUXILIARY, 2, nullptr, nullptr); - FrameBasePtr F3 = FrameBase::emplace<FrameBase>(T, NON_ESTIMATED, 3, nullptr, nullptr); + FrameBasePtr F1 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 1); + FrameBasePtr F2 = P->emplaceFrame(AUXILIARY, Eigen::Vector3s::Zero(), 2); + FrameBasePtr F3 = P->emplaceFrame(NON_ESTIMATED, Eigen::Vector3s::Zero(), 3); FrameBasePtr KF; // closest key-frame queried @@ -134,30 +130,24 @@ TEST(TrajectoryBase, Add_Remove_Frame) // 1 2 3 time stamps // --+-----+-----+---> time - FrameBasePtr F1 = std::make_shared<FrameBase>(KEY, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed - FrameBasePtr F2 = std::make_shared<FrameBase>(KEY, 2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not - FrameBasePtr F3 = std::make_shared<FrameBase>(NON_ESTIMATED, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame - - // FrameBasePtr f1 = FrameBase::emplace<FrameBase>(T, KEY_FRAME, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed - // FrameBasePtr f2 = FrameBase::emplace<FrameBase>(T, KEY_FRAME, 2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not - // FrameBasePtr f3 = FrameBase::emplace<FrameBase>(T, NON_KEY_FRAME, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame - std::cout << __LINE__ << std::endl; - // add frames and keyframes - F1->link(T); + // add F1 + FrameBasePtr F1 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 1); // 2 non-fixed if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getFrameList(). size(), (SizeStd) 1); ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 2); std::cout << __LINE__ << std::endl; - F2->link(T); + // add F2 + FrameBasePtr F2 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 2); // 1 fixed, 1 not if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getFrameList(). size(), (SizeStd) 2); ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 4); std::cout << __LINE__ << std::endl; - F3->link(T); + // add F3 + FrameBasePtr F3 = P->emplaceFrame(NON_ESTIMATED, Eigen::Vector3s::Zero(), 3); if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getFrameList(). size(), (SizeStd) 3); ASSERT_EQ(P->getStateBlockNotificationMapSize(), (SizeStd) 4); @@ -212,24 +202,20 @@ TEST(TrajectoryBase, KeyFramesAreSorted) // 1 2 3 time stamps // --+-----+-----+---> time - FrameBasePtr F1 = std::make_shared<FrameBase>(KEY, 1, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // 2 non-fixed - FrameBasePtr F2 = std::make_shared<FrameBase>(KEY, 2, make_shared<StateBlock>(2), make_shared<StateBlock>(1, true)); // 1 fixed, 1 not - FrameBasePtr F3 = std::make_shared<FrameBase>(NON_ESTIMATED, 3, make_shared<StateBlock>(2), make_shared<StateBlock>(1)); // non-key-frame - // add frames and keyframes in random order --> keyframes must be sorted after that - F2->link(T); + FrameBasePtr F2 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 2); if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getLastFrame() ->id(), F2->id()); ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id()); ASSERT_EQ(T->getLastKeyFrame() ->id(), F2->id()); - F3->link(T); + FrameBasePtr F3 = P->emplaceFrame(NON_ESTIMATED, Eigen::Vector3s::Zero(), 3); // non-key-frame if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getLastFrame() ->id(), F3->id()); ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id()); ASSERT_EQ(T->getLastKeyFrame() ->id(), F2->id()); - F1->link(T); + FrameBasePtr F1 = P->emplaceFrame(KEY, Eigen::Vector3s::Zero(), 1); if (debug) P->print(2,0,0,0); ASSERT_EQ(T->getLastFrame() ->id(), F3->id()); ASSERT_EQ(T->getLastKeyOrAuxFrame()->id(), F2->id());