diff --git a/CMakeLists.txt b/CMakeLists.txt index 6e2dbbe0a63578c80e3f9716a416ccae852fe46f..62fbdb69c8e112d70e2f6d9540e6f37db0a757a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -124,6 +124,7 @@ SET(HDRS_CAPTURE SET(HDRS_COMMON include/${PROJECT_NAME}/common/factory.h include/${PROJECT_NAME}/common/node_base.h + include/${PROJECT_NAME}/common/node_state_blocks.h include/${PROJECT_NAME}/common/time_stamp.h include/${PROJECT_NAME}/common/wolf.h include/${PROJECT_NAME}/common/params_base.h @@ -182,7 +183,6 @@ SET(HDRS_MAP ) SET(HDRS_PROBLEM include/${PROJECT_NAME}/problem/problem.h - # include/${PROJECT_NAME}/problem/prior_problem.h ) SET(HDRS_PROCESSOR include/${PROJECT_NAME}/processor/factory_processor.h @@ -218,7 +218,6 @@ SET(HDRS_SOLVER SET(HDRS_STATE_BLOCK include/${PROJECT_NAME}/state_block/composite.h include/${PROJECT_NAME}/state_block/factory_state_block.h - include/${PROJECT_NAME}/state_block/has_state_blocks.h include/${PROJECT_NAME}/state_block/local_parametrization_angle.h include/${PROJECT_NAME}/state_block/local_parametrization_base.h include/${PROJECT_NAME}/state_block/local_parametrization_homogeneous.h @@ -265,6 +264,7 @@ SET(SRCS_CAPTURE ) SET(SRCS_COMMON src/common/node_base.cpp + src/common/node_state_blocks.cpp src/common/time_stamp.cpp ) SET(SRCS_FACTOR @@ -319,7 +319,6 @@ SET(SRCS_SOLVER src/solver/solver_manager.cpp ) SET(SRCS_STATE_BLOCK - src/state_block/has_state_blocks.cpp src/state_block/local_parametrization_base.cpp src/state_block/local_parametrization_homogeneous.cpp src/state_block/local_parametrization_quaternion.cpp diff --git a/include/core/capture/capture_base.h b/include/core/capture/capture_base.h index 31092a82461e49d01d1f74853955046e9cc73c46..c53e6f98869161efc08b536467c9d72fbe17fd62 100644 --- a/include/core/capture/capture_base.h +++ b/include/core/capture/capture_base.h @@ -29,16 +29,15 @@ class FeatureBase; //Wolf includes #include "core/common/wolf.h" -#include "core/common/node_base.h" +#include "core/common/node_state_blocks.h" #include "core/common/time_stamp.h" -#include "core/state_block/has_state_blocks.h" //std includes namespace wolf{ //class CaptureBase -class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_shared_from_this<CaptureBase> +class CaptureBase : public NodeStateBlocks, public std::enable_shared_from_this<CaptureBase> { friend FeatureBase; friend FactorBase; @@ -47,7 +46,6 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s private: FrameBaseWPtr frame_ptr_; FeatureBasePtrList feature_list_; - FactorBasePtrList constrained_by_list_; SensorBaseWPtr sensor_ptr_; ///< Pointer to sensor static unsigned int capture_id_count_; @@ -66,8 +64,9 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s StateBlockPtr _o_ptr = nullptr, StateBlockPtr _intr_ptr = nullptr); - ~CaptureBase() override; - virtual void remove(bool viral_remove_empty_parent=false); + ~CaptureBase() override = default; + void remove(bool viral_remove_parent_without_children=false) override; + bool hasChildren() const override; // Type virtual bool isMotion() const { return false; } @@ -89,26 +88,11 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s FeatureBasePtrList getFeatureList(); bool hasFeature(const FeatureBaseConstPtr &_feature) const; - FactorBaseConstPtrList getFactorList() const; - FactorBasePtrList getFactorList(); - void getFactorList(FactorBaseConstPtrList& _fac_list) const; - void getFactorList(FactorBasePtrList& _fac_list); - SensorBaseConstPtr getSensor() const; SensorBasePtr getSensor(); 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; - FactorBaseConstPtrList getConstrainedByList() const; - FactorBasePtrList getConstrainedByList(); - bool isConstrainedBy(const FactorBaseConstPtr &_factor) const; - // State blocks StateBlockConstPtr getStateBlock(const char& _key) const; StateBlockPtr getStateBlock(const char& _key); @@ -119,8 +103,6 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s StateBlockConstPtr getSensorIntrinsic() const; StateBlockPtr getSensorIntrinsic(); - bool getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const; - void fix() override; void unfix() override; @@ -235,24 +217,6 @@ inline FeatureBasePtrList CaptureBase::getFeatureList() return feature_list_; } -inline unsigned int CaptureBase::getHits() const -{ - return constrained_by_list_.size(); -} - -inline FactorBaseConstPtrList CaptureBase::getConstrainedByList() const -{ - FactorBaseConstPtrList list_const; - for (auto&& obj_ptr : constrained_by_list_) - list_const.push_back(obj_ptr); - return list_const; -} - -inline FactorBasePtrList CaptureBase::getConstrainedByList() -{ - return constrained_by_list_; -} - inline TimeStamp CaptureBase::getTimeStamp() const { return time_stamp_; diff --git a/include/core/common/node_base.h b/include/core/common/node_base.h index 31ae60e6c388ac9113db10ea2dfe33718b709cae..febc63cd81cbac43370bc5701d7e92b628724175 100644 --- a/include/core/common/node_base.h +++ b/include/core/common/node_base.h @@ -101,6 +101,7 @@ class NodeBase std::string getType() const; std::string getName() const; bool isRemoving() const; + virtual bool hasChildren() const = 0; void setType(const std::string& _type); void setName(const std::string& _name); diff --git a/include/core/common/node_state_blocks.h b/include/core/common/node_state_blocks.h new file mode 100644 index 0000000000000000000000000000000000000000..43992e3faf4846772280b5e8e801571ae33b3ce2 --- /dev/null +++ b/include/core/common/node_state_blocks.h @@ -0,0 +1,502 @@ +//--------LICENSE_START-------- +// +// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informà tica Industrial, CSIC-UPC. +// Authors: Joan Solà Ortega (jsola@iri.upc.edu) +// All rights reserved. +// +// This file is part of WOLF +// WOLF is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +//--------LICENSE_END-------- +#pragma once + +#include "core/common/wolf.h" +#include "core/common/node_base.h" +#include "core/state_block/vector_composite.h" +#include "core/state_block/spec_composite.h" + +#include <map> + +namespace wolf +{ +WOLF_PTR_TYPEDEFS(NodeStateBlocks) + +class NodeStateBlocks : public NodeBase +{ + friend Problem; + friend FactorBase; + + public: + NodeStateBlocks(const std::string& _category, const std::string& _type); + NodeStateBlocks(const std::string& _category, const std::string& _type, const SpecStateComposite& _specs); + NodeStateBlocks(const std::string& _category, + const std::string& _type, + const TypeComposite& _types, + const VectorComposite& _vectors); + virtual ~NodeStateBlocks(); + + StateKeys getKeys() const + { + return state_block_composite_.getKeys(); + } + SpecStateComposite getSpecs() const; + bool has(const char& _sb_key) const + { + return state_block_composite_.has(_sb_key); + } + bool has(const std::string& _keys) const + { + return state_block_composite_.has(_keys); + } + + std::map<char, StateBlockConstPtr> getStateBlockMap() const; + std::map<char, StateBlockPtr> getStateBlockMap(); + std::vector<StateBlockConstPtr> getStateBlockVec() const; + std::vector<StateBlockPtr> getStateBlockVec(); + + // Some typical shortcuts -- not all should be coded here, see notes below. + StateBlockConstPtr getP() const; + StateBlockConstPtr getO() const; + StateBlockPtr getP(); + StateBlockPtr getO(); + + // These act on all state blocks. Per-block action must be done through state_block.fix() or through extended API + // in derived classes of this. + virtual void fix(); + virtual void unfix(); + virtual bool isFixed() const; + + virtual StateBlockPtr addStateBlock(const char& _sb_key, const StateBlockPtr& _sb, ProblemPtr _problem); + virtual unsigned int removeStateBlock(const char& _sb_key); + bool hasStateBlock(const StateBlockConstPtr& _sb) const; + bool setStateBlock(const char _sb_key, const StateBlockPtr& _sb); + bool stateBlockKey(const StateBlockConstPtr& _sb, char& _key) const; + StateBlockConstPtr getStateBlock(const char& _sb_key) const; + StateBlockPtr getStateBlock(const char& _sb_key); + + // Emplace derived state blocks (angle, quaternion, etc). + template <typename SB, typename... Args> + std::shared_ptr<SB> emplaceStateBlock(const char& _sb_key, + ProblemPtr _problem, + Args&&... _args_of_derived_state_block_constructor); + + // Register/remove state blocks to/from wolf::Problem + void setProblem(ProblemPtr _problem) override; + virtual void remove(bool viral_remove_parent_without_children = false); + bool hasChildren() const override; + + // Factors + private: + FactorBasePtr addFactor(FactorBasePtr _co_ptr); + void removeFactor(FactorBasePtr _co_ptr); + + public: + FactorBaseConstPtrList getFactorList() const; + FactorBasePtrList getFactorList(); + void getFactorList(FactorBaseConstPtrList& _fac_list) const; + void getFactorList(FactorBasePtrList& _fac_list); + bool hasFactor(FactorBaseConstPtr _fac) const; + + FactorBaseConstPtr getFactorOf(ProcessorBaseConstPtr _processor_ptr) const; + FactorBasePtr getFactorOf(ProcessorBasePtr _processor_ptr); + FactorBaseConstPtr getFactorOf(ProcessorBaseConstPtr _processor_ptr, const std::string& type) const; + FactorBasePtr getFactorOf(ProcessorBasePtr _processor_ptr, const std::string& type); + + // States + VectorComposite getState(const StateKeys& _keys = "") const; + void setState(const VectorComposite& _state, const bool _notify = true); + void setState(const Eigen::VectorXd& _state, + const StateKeys& _keys, + const std::list<SizeEigen>& _sizes, + const bool _notify = true); + void setState(const Eigen::VectorXd& _state, const StateKeys& _keys, const bool _notify = true); + void setState(const StateKeys& _keys, const std::list<VectorXd>& _vectors, const bool _notify = true); + + VectorXd getStateVector(const StateKeys& _keys) const; + unsigned int getSize(const StateKeys& _keys = "") const; + unsigned int getLocalSize(const StateKeys& _keys = "") const; + + // Covariance + bool getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const; + + /** + * \brief perturb all states states with random noise + * following an uniform distribution in [ -amplitude, amplitude ] + */ + void perturb(double amplitude = 0.01); + + protected: + // transform state + void transform(const VectorComposite& _transformation); + + void printState(bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const; + + private: + Composite<StateBlockPtr> state_block_composite_; + + FactorBasePtrList factor_sensory_list_; + std::map<char,FactorBasePtr> factor_prior_map_; +}; + +} // namespace wolf + +//////////// IMPLEMENTATION ///////////// + +#include "core/state_block/state_block.h" + +namespace wolf +{ +inline NodeStateBlocks::NodeStateBlocks(const std::string& _category, const std::string& _type) + : NodeBase(_category, _type), state_block_composite_() +{ + // +} + +inline NodeStateBlocks::~NodeStateBlocks() +{ + // +} + +inline std::map<char, StateBlockConstPtr> NodeStateBlocks::getStateBlockMap() const +{ + std::map<char, StateBlockConstPtr> map_const; + for (auto&& pair : state_block_composite_) map_const[pair.first] = pair.second; + return map_const; +} + +inline std::map<char, StateBlockPtr> NodeStateBlocks::getStateBlockMap() +{ + return state_block_composite_; +} + +inline std::vector<StateBlockConstPtr> NodeStateBlocks::getStateBlockVec() const +{ + std::vector<StateBlockConstPtr> sbv; + for (auto key : getKeys()) + { + sbv.push_back(getStateBlock(key)); + } + return sbv; +} + +inline std::vector<StateBlockPtr> NodeStateBlocks::getStateBlockVec() +{ + std::vector<StateBlockPtr> sbv; + for (auto key : getKeys()) + { + sbv.push_back(getStateBlock(key)); + } + return sbv; +} + +inline unsigned int NodeStateBlocks::removeStateBlock(const char& _sb_key) +{ + return state_block_composite_.erase(_sb_key); +} + +template <typename SB, typename... Args> +inline std::shared_ptr<SB> NodeStateBlocks::emplaceStateBlock(const char& _sb_key, + ProblemPtr _problem, + Args&&... _args_of_derived_state_block_constructor) +{ + assert(state_block_composite_.count(_sb_key) == 0 and + "Trying to add a state block with an existing type! Use setStateBlock instead."); + std::shared_ptr<SB> sb = std::make_shared<SB>(std::forward<Args>(_args_of_derived_state_block_constructor)...); + + addStateBlock(_sb_key, sb, _problem); + + return sb; +} + +inline bool NodeStateBlocks::setStateBlock(const char _sb_key, const StateBlockPtr& _sb) +{ + assert(has(_sb_key) and "Cannot set a state block out of the state keys! Use addStateBlock instead."); + assert(state_block_composite_.count(_sb_key) > 0 and + "Cannot set an inexistent state block! Use addStateBlock instead."); + state_block_composite_.at(_sb_key) = _sb; + return true; // success +} + +inline wolf::StateBlockConstPtr NodeStateBlocks::getStateBlock(const char& _sb_key) const +{ + auto it = state_block_composite_.find(_sb_key); + if (it != state_block_composite_.end()) + return it->second; + else + return nullptr; +} + +inline wolf::StateBlockPtr NodeStateBlocks::getStateBlock(const char& _sb_key) +{ + auto it = state_block_composite_.find(_sb_key); + if (it != state_block_composite_.end()) + return it->second; + else + return nullptr; +} + +inline wolf::StateBlockConstPtr NodeStateBlocks::getP() const +{ + return getStateBlock('P'); +} + +inline wolf::StateBlockPtr NodeStateBlocks::getP() +{ + return getStateBlock('P'); +} + +inline wolf::StateBlockConstPtr NodeStateBlocks::getO() const +{ + return getStateBlock('O'); +} + +inline wolf::StateBlockPtr NodeStateBlocks::getO() +{ + return getStateBlock('O'); +} + +inline void NodeStateBlocks::fix() +{ + for (auto pair_key_sbp : state_block_composite_) + if (pair_key_sbp.second != nullptr) pair_key_sbp.second->fix(); +} + +inline void NodeStateBlocks::unfix() +{ + for (auto pair_key_sbp : state_block_composite_) + if (pair_key_sbp.second != nullptr) pair_key_sbp.second->unfix(); +} + +inline bool NodeStateBlocks::isFixed() const +{ + bool fixed = true; + for (auto pair_key_sbp : state_block_composite_) + { + if (pair_key_sbp.second) fixed &= pair_key_sbp.second->isFixed(); + } + return fixed; +} + +inline void NodeStateBlocks::setState(const VectorComposite& _state, const bool _notify) +{ + for (const auto& pair_key_vec : _state) + { + const auto& key = pair_key_vec.first; + const auto& vec = pair_key_vec.second; + const auto& sb = getStateBlock(key); + if (!sb) WOLF_ERROR("Stateblock key ", key, " not in the keys"); + assert(sb and "Stateblock key not in the keys"); + + sb->setState(vec, _notify); + } +} + +inline void NodeStateBlocks::setState(const Eigen::VectorXd& _state, const StateKeys& _keys, const bool _notify) +{ + int size = getSize(_keys); + assert(_state.size() == size and "In FrameBase::setState wrong state size"); + + unsigned int index = 0; + for (const char key : _keys) + { + const auto& sb = getStateBlock(key); + assert(sb and "Stateblock key not in the keys"); + + sb->setState(_state.segment(index, sb->getSize()), + _notify); // do not notify if state block is not estimated by the solver + index += sb->getSize(); + } +} + +inline void NodeStateBlocks::setState(const Eigen::VectorXd& _state, + const StateKeys& _keys, + const std::list<SizeEigen>& _sizes, + const bool _notify) +{ + SizeEigen index = 0; + auto size_it = _sizes.begin(); + for (const auto& key : _keys) + { + const auto& sb = getStateBlock(key); + assert(sb and "Stateblock key not in the keys"); + assert(*size_it == sb->getSize() and "State block size mismatch"); + + sb->setState(_state.segment(index, *size_it), _notify); + index += *size_it; + size_it++; + } +} + +inline void NodeStateBlocks::setState(const StateKeys& _keys, const std::list<VectorXd>& _vectors, const bool _notify) +{ + auto vec_it = _vectors.begin(); + for (const auto key : _keys) + { + const auto& sb = getStateBlock(key); + assert(sb and "Stateblock key not in the keys"); + assert(vec_it->size() == sb->getSize() and "State block size mismatch"); + + sb->setState(*vec_it, _notify); + vec_it++; + } +} + +//// _keys can be either stateblock keys of the node or a subset of this keys +inline VectorXd NodeStateBlocks::getStateVector(const StateKeys& _keys) const +{ + VectorXd state(getSize(_keys)); + + unsigned int index = 0; + for (const char key : _keys) + { + const auto& sb = getStateBlock(key); + + assert(sb != nullptr and "Requested StateBlock key not in the keys"); + + state.segment(index, sb->getSize()) = sb->getState(); + index += sb->getSize(); + } + return state; +} + +inline VectorComposite NodeStateBlocks::getState(const StateKeys& _keys) const +{ + const StateKeys& keys = (_keys == "" ? getKeys() : _keys); + + VectorComposite state; + + for (const auto key : keys) + { + auto state_it = state_block_composite_.find(key); + + if (state_it != state_block_composite_.end()) state.emplace(key, state_it->second->getState()); + } + + return state; +} + +inline unsigned int NodeStateBlocks::getSize(const StateKeys& _keys) const +{ + const StateKeys& keys = (_keys == "" ? getKeys() : _keys); + + unsigned int size = 0; + for (const char key : keys) + { + const auto& sb = getStateBlock(key); + if (!sb) + { + WOLF_ERROR("Stateblock key ", key, " not in the keys"); + } + size += sb->getSize(); + } + + return size; +} + +inline bool NodeStateBlocks::hasStateBlock(const StateBlockConstPtr& _sb) const +{ + const auto& it = std::find_if(state_block_composite_.begin(), + state_block_composite_.end(), + [_sb](const std::pair<char, StateBlockPtr>& pair) { return pair.second == _sb; }); + + return it != state_block_composite_.end(); +} + +inline bool NodeStateBlocks::stateBlockKey(const StateBlockConstPtr& _sb, char& _key) const +{ + const auto& it = std::find_if(state_block_composite_.begin(), + state_block_composite_.end(), + [_sb](const std::pair<char, StateBlockPtr>& pair) { return pair.second == _sb; }); + + if (it != state_block_composite_.end()) + { + _key = it->first; + return true; + } + else + { + _key = '0'; // '0' = not found + return false; + } +} + +inline unsigned int NodeStateBlocks::getLocalSize(const StateKeys& _keys) const +{ + StateKeys keys; + if (_keys == "") + keys = getKeys(); + else + keys = _keys; + + unsigned int size = 0; + for (const char key : keys) + { + const auto& sb = getStateBlock(key); + if (!sb) + { + WOLF_ERROR("Stateblock key ", key, " not in the keys"); + } + size += sb->getLocalSize(); + } + + return size; +} + +inline FactorBasePtr NodeStateBlocks::addFactor(FactorBasePtr _fac_ptr) +{ + factor_list_.push_back(_fac_ptr); + return _fac_ptr; +} + +inline void NodeStateBlocks::removeFactor(FactorBasePtr _fac_ptr) +{ + factor_list_.remove(_fac_ptr); +} + + +inline FactorBaseConstPtrList NodeStateBlocks::getFactorList() const +{ + FactorBaseConstPtrList list_const; + for (auto&& obj_ptr : factor_list_) list_const.push_back(obj_ptr); + return list_const; +} + +inline FactorBasePtrList NodeStateBlocks::getFactorList() +{ + return factor_list_; +} + +inline void NodeStateBlocks::getFactorList(FactorBaseConstPtrList& _fac_list) const +{ + for (auto&& obj_ptr : factor_list_) _fac_list.push_back(obj_ptr); +} + +inline void NodeStateBlocks::getFactorList(FactorBasePtrList& _fac_list) +{ + _fac_list.insert(_fac_list.end(), factor_list_.begin(), factor_list_.end()); +} + +inline bool NodeStateBlocks::hasFactor(FactorBaseConstPtr _factor) const +{ + return std::find(factor_list_.begin(), + factor_list_.end(), + _factor) != factor_list_.end(); +} + +inline bool NodeStateBlocks::hasChildren() const +{ + return not factor_list_.empty(); +} + +} // namespace wolf \ No newline at end of file diff --git a/include/core/common/wolf.h b/include/core/common/wolf.h index 82f3f1ea1869bdbec0235024b98978174305f355..3d67568866ec6e0fb923312e4546a0525dd07a4e 100644 --- a/include/core/common/wolf.h +++ b/include/core/common/wolf.h @@ -226,6 +226,10 @@ struct MatrixSizeCheck // NodeBase WOLF_PTR_TYPEDEFS(NodeBase); +// NodeStateBlocks +WOLF_PTR_TYPEDEFS(NodeStateBlocks); +WOLF_LIST_TYPEDEFS(NodeStateBlocks); + // Problem WOLF_PTR_TYPEDEFS(Problem); diff --git a/include/core/factor/factor_base.h b/include/core/factor/factor_base.h index b5529a667335850a5c5dd09f0d64ab843d08d9d5..b4e58bb0862c8bbe2d5de11c0b1ae54ae62eeef9 100644 --- a/include/core/factor/factor_base.h +++ b/include/core/factor/factor_base.h @@ -76,15 +76,16 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa { friend FeatureBase; private: - FeatureBaseWPtr feature_ptr_; ///< FeatureBase pointer (upper node) ProcessorBaseWPtr processor_ptr_; ///< Processor pointer static unsigned int factor_id_count_; - FrameBaseWPtrList frame_other_list_; ///< FrameBase pointer list - CaptureBaseWPtrList capture_other_list_; ///< CaptureBase pointer list - FeatureBaseWPtrList feature_other_list_; ///< FeatureBase pointer list - LandmarkBaseWPtrList landmark_other_list_; ///< LandmarkBase pointer list + FeatureBaseWPtr feature_ptr_; ///< Feature from which the factor was created (optional) + NodeStateBlocksWPtrList node_state_blocks_list_; ///< NodeStateBlocks pointer list + FrameBaseWPtrList frame_list_; ///< FrameBase pointer list + CaptureBaseWPtrList capture_list_; ///< CaptureBase pointer list + LandmarkBaseWPtrList landmark_list_; ///< LandmarkBase pointer list + SensorBaseWPtrList sensor_list_; ///< SensorBase pointer list protected: unsigned int factor_id_; @@ -98,20 +99,37 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa void setProblem(ProblemPtr) override final; public: + /** \brief constructor from feature + **/ FactorBase(const std::string& _tp, const FactorTopology& _top, const FeatureBasePtr& _feature_ptr, - const FrameBasePtrList& _frame_other_list, - const CaptureBasePtrList& _capture_other_list, - const FeatureBasePtrList& _feature_other_list, - const LandmarkBasePtrList& _landmark_other_list, + const FrameBasePtrList& _frame_list, + const CaptureBasePtrList& _capture_list, + const LandmarkBasePtrList& _landmark_list, + const SensorBasePtrList& _sensor_list, + const ProcessorBasePtr& _processor_ptr, + bool _apply_loss_function, + FactorStatus _status = FAC_ACTIVE); + + /** \brief constructor from measurement and noise square root information upper matrix (cholesky) + **/ + FactorBase(const std::string& _tp, + const FactorTopology& _top, + const Eigen::VectorXd& _measurement, + const Eigen::MatrixXd& _measurement_sqrt_information_upper, + const FrameBasePtrList& _frame_list, + const CaptureBasePtrList& _capture_list, + const LandmarkBasePtrList& _landmark_list, + const SensorBasePtrList& _sensor_list, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status = FAC_ACTIVE); ~FactorBase() override = default; - virtual void remove(bool viral_remove_empty_parent=false); + virtual void remove(bool viral_remove_parent_without_children=false); + bool hasChildren() const override { return false;}; unsigned int id() const; @@ -181,20 +199,10 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa FeatureBaseConstPtr getFeature() const; FeatureBasePtr getFeature(); - /** \brief Returns a pointer to its capture - **/ - CaptureBaseConstPtr getCapture() const; - CaptureBasePtr getCapture(); - - /** \brief Returns a pointer to its frame - **/ - FrameBaseConstPtr getFrame() const; - FrameBasePtr getFrame(); - - /** \brief Returns a pointer to its capture's sensor - **/ - SensorBaseConstPtr getSensor() const; - SensorBasePtr getSensor(); + // /** \brief Returns a pointer to its capture's sensor + // **/ + // SensorBaseConstPtr getSensor() const; + // SensorBasePtr getSensor(); /** \brief Returns the factor residual size **/ @@ -212,40 +220,36 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa */ bool getApplyLossFunction() const; - /** \brief Returns a pointer to the first frame constrained to - **/ - FrameBaseConstPtr getFrameOther() const; - FrameBasePtr getFrameOther(); + // /** \brief Returns a pointer to the first frame constrained to + // **/ + // FrameBaseConstPtr getFrame() const; + // FrameBasePtr getFrame(); - /** \brief Returns a pointer to the first capture constrained to - **/ - CaptureBaseConstPtr getCaptureOther() const; - CaptureBasePtr getCaptureOther(); - - /** \brief Returns a pointer to the first feature constrained to - **/ - FeatureBaseConstPtr getFeatureOther() const; - FeatureBasePtr getFeatureOther(); + // /** \brief Returns a pointer to the first capture constrained to + // **/ + // CaptureBaseConstPtr getCapture() const; + // CaptureBasePtr getCapture(); - /** \brief Returns a pointer to the first landmark constrained to - **/ - LandmarkBaseConstPtr getLandmarkOther() const; - LandmarkBasePtr getLandmarkOther(); + // /** \brief Returns a pointer to the first landmark constrained to + // **/ + // LandmarkBaseConstPtr getLandmark() const; + // LandmarkBasePtr getLandmark(); // get pointer lists to other nodes - FrameBaseWPtrList getFrameOtherList() { return frame_other_list_; } - CaptureBaseWPtrList getCaptureOtherList() { return capture_other_list_; } - FeatureBaseWPtrList getFeatureOtherList() { return feature_other_list_; } - LandmarkBaseWPtrList getLandmarkOtherList() { return landmark_other_list_; } - FrameBaseConstWPtrList getFrameOtherList() const; - CaptureBaseConstWPtrList getCaptureOtherList() const; - FeatureBaseConstWPtrList getFeatureOtherList() const; - LandmarkBaseConstWPtrList getLandmarkOtherList() const; - - bool hasFrameOther(const FrameBaseConstPtr& _frm_other) const; - bool hasCaptureOther(const CaptureBaseConstPtr& _cap_other) const; - bool hasFeatureOther(const FeatureBaseConstPtr& _ftr_other) const; - bool hasLandmarkOther(const LandmarkBaseConstPtr& _lmk_other) const; + NodeStateBlocksWPtrList getNodeStateBlocksList() { return node_state_blocks_list_; } + FrameBaseWPtrList getFrameList() { return frame_list_; } + CaptureBaseWPtrList getCaptureList() { return capture_list_; } + LandmarkBaseWPtrList getLandmarkList() { return landmark_list_; } + SensorBaseWPtrList getSensorList() { return sensor_list_; } + FrameBaseConstWPtrList getFrameList() const; + CaptureBaseConstWPtrList getCaptureList() const; + LandmarkBaseConstWPtrList getLandmarkList() const; + SensorBaseConstWPtrList getSensorList() const; + + bool hasFrame(const FrameBaseConstPtr& _frm) const; + bool hasCapture(const CaptureBaseConstPtr& _cap) const; + bool hasLandmark(const LandmarkBaseConstPtr& _lmk) const; + bool hasSensor(const SensorBaseConstPtr& _sen) const; /** * @brief getProcessor @@ -277,12 +281,7 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa private: - void setFeature(const FeatureBasePtr _ft_ptr){feature_ptr_ = _ft_ptr;} - - /** - * @brief setProcessor - * @param _processor_ptr - */ + void setFeature(const FeatureBasePtr _ft_ptr); void setProcessor(const ProcessorBasePtr& _processor_ptr); }; @@ -311,16 +310,6 @@ inline unsigned int FactorBase::id() const return factor_id_; } -inline FeatureBaseConstPtr FactorBase::getFeature() const -{ - return feature_ptr_.lock(); -} - -inline FeatureBasePtr FactorBase::getFeature() -{ - return feature_ptr_.lock(); -} - inline FactorStatus FactorBase::getStatus() const { return status_; @@ -331,69 +320,65 @@ inline bool FactorBase::getApplyLossFunction() const return apply_loss_function_; } -inline FrameBaseConstPtr FactorBase::getFrameOther() const +inline FeatureBaseConstPtr FactorBase::getFeature() const { - if (frame_other_list_.empty()) return nullptr; - if (frame_other_list_.front().expired()) return nullptr; - - return frame_other_list_.front().lock(); + if (feature_ptr_.expired()) return nullptr; + return feature_ptr_.lock(); } -inline FrameBasePtr FactorBase::getFrameOther() +inline FeatureBasePtr FactorBase::getFeature() { - if (frame_other_list_.empty()) return nullptr; - if (frame_other_list_.front().expired()) return nullptr; - - return frame_other_list_.front().lock(); + if (feature_ptr_.expired()) return nullptr; + return feature_ptr_.lock(); } -inline CaptureBaseConstPtr FactorBase::getCaptureOther() const -{ - if (capture_other_list_.empty()) return nullptr; - if (capture_other_list_.front().expired()) return nullptr; +// inline FrameBaseConstPtr FactorBase::getFrame() const +// { +// if (frame_list_.empty()) return nullptr; +// if (frame_list_.front().expired()) return nullptr; - return capture_other_list_.front().lock(); -} +// return frame_list_.front().lock(); +// } -inline CaptureBasePtr FactorBase::getCaptureOther() -{ - if (capture_other_list_.empty()) return nullptr; - if (capture_other_list_.front().expired()) return nullptr; +// inline FrameBasePtr FactorBase::getFrame() +// { +// if (frame_list_.empty()) return nullptr; +// if (frame_list_.front().expired()) return nullptr; - return capture_other_list_.front().lock(); -} +// return frame_list_.front().lock(); +// } -inline FeatureBaseConstPtr FactorBase::getFeatureOther() const -{ - if (feature_other_list_.empty()) return nullptr; - if (feature_other_list_.front().expired()) return nullptr; +// inline CaptureBaseConstPtr FactorBase::getCapture() const +// { +// if (capture_list_.empty()) return nullptr; +// if (capture_list_.front().expired()) return nullptr; - return feature_other_list_.front().lock(); -} +// return capture_list_.front().lock(); +// } -inline FeatureBasePtr FactorBase::getFeatureOther() -{ - if (feature_other_list_.empty()) return nullptr; - if (feature_other_list_.front().expired()) return nullptr; +// inline CaptureBasePtr FactorBase::getCapture() +// { +// if (capture_list_.empty()) return nullptr; +// if (capture_list_.front().expired()) return nullptr; - return feature_other_list_.front().lock(); -} +// return capture_list_.front().lock(); +// } -inline LandmarkBaseConstPtr FactorBase::getLandmarkOther() const -{ - if (landmark_other_list_.empty()) return nullptr; - if (landmark_other_list_.front().expired()) return nullptr; +// inline LandmarkBaseConstPtr FactorBase::getLandmark() const +// { +// if (landmark_list_.empty()) return nullptr; +// if (landmark_list_.front().expired()) return nullptr; - return landmark_other_list_.front().lock(); -} +// return landmark_list_.front().lock(); +// } -inline LandmarkBasePtr FactorBase::getLandmarkOther() -{ - if (landmark_other_list_.empty()) return nullptr; - if (landmark_other_list_.front().expired()) return nullptr; +// inline LandmarkBasePtr FactorBase::getLandmark() +// { +// if (landmark_list_.empty()) return nullptr; +// if (landmark_list_.front().expired()) return nullptr; - return landmark_other_list_.front().lock(); -} +// return landmark_list_.front().lock(); +// } inline ProcessorBaseConstPtr FactorBase::getProcessor() const { @@ -405,6 +390,11 @@ inline ProcessorBasePtr FactorBase::getProcessor() return processor_ptr_.lock(); } +inline void FactorBase::setFeature(const FeatureBasePtr _ft_ptr) +{ + feature_ptr_ = _ft_ptr; +} + inline void FactorBase::setProcessor(const ProcessorBasePtr& _processor_ptr) { processor_ptr_ = _processor_ptr; @@ -420,34 +410,34 @@ inline const Eigen::MatrixXd& FactorBase::getMeasurementSquareRootInformationUpp return measurement_sqrt_information_upper_; } -inline FrameBaseConstWPtrList FactorBase::getFrameOtherList() const +inline FrameBaseConstWPtrList FactorBase::getFrameList() const { FrameBaseConstWPtrList list_const; - for (auto&& obj_ptr : frame_other_list_) + for (auto&& obj_ptr : frame_list_) list_const.push_back(obj_ptr); return list_const; } -inline CaptureBaseConstWPtrList FactorBase::getCaptureOtherList() const +inline CaptureBaseConstWPtrList FactorBase::getCaptureList() const { CaptureBaseConstWPtrList list_const; - for (auto&& obj_ptr : capture_other_list_) + for (auto&& obj_ptr : capture_list_) list_const.push_back(obj_ptr); return list_const; } -inline FeatureBaseConstWPtrList FactorBase::getFeatureOtherList() const +inline LandmarkBaseConstWPtrList FactorBase::getLandmarkList() const { - FeatureBaseConstWPtrList list_const; - for (auto&& obj_ptr : feature_other_list_) + LandmarkBaseConstWPtrList list_const; + for (auto&& obj_ptr : landmark_list_) list_const.push_back(obj_ptr); return list_const; } -inline LandmarkBaseConstWPtrList FactorBase::getLandmarkOtherList() const +inline SensorBaseConstWPtrList FactorBase::getSensorList() const { - LandmarkBaseConstWPtrList list_const; - for (auto&& obj_ptr : landmark_other_list_) + SensorBaseConstWPtrList list_const; + for (auto&& obj_ptr : sensor_list_) list_const.push_back(obj_ptr); return list_const; } diff --git a/include/core/feature/feature_base.h b/include/core/feature/feature_base.h index e1a4a8ee8a68af60bf322cdc75d1ded12a448b33..a90da0e49e8342382836c6abfc9f27afd615e8f7 100644 --- a/include/core/feature/feature_base.h +++ b/include/core/feature/feature_base.h @@ -38,14 +38,13 @@ namespace wolf { //class FeatureBase class FeatureBase : public NodeBase, public std::enable_shared_from_this<FeatureBase> { - friend FactorBase; friend CaptureBase; friend SensorBase; + friend FactorBase; private: CaptureBaseWPtr capture_ptr_; FactorBasePtrList factor_list_; - FactorBasePtrList constrained_by_list_; static unsigned int feature_id_count_; @@ -57,7 +56,6 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature Eigen::MatrixXd measurement_covariance_; ///< the measurement covariance matrix Eigen::MatrixXd measurement_sqrt_information_upper_; ///< the squared root information matrix Eigen::VectorXd expectation_; ///< expectation - void setProblem(ProblemPtr _problem) override final; public: @@ -78,9 +76,9 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature const Eigen::MatrixXd& _meas_uncertainty, UncertaintyType _uncertainty_type = UNCERTAINTY_IS_COVARIANCE); - ~FeatureBase() override; - virtual void remove(bool viral_remove_empty_parent=false); - + ~FeatureBase() override = default; + virtual void remove(bool viral_remove_parent_without_children=false); + bool hasChildren() const override { return false;}; // properties unsigned int id() const; @@ -127,11 +125,6 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature void getFactorList(FactorBasePtrList & _fac_list); bool hasFactor(FactorBaseConstPtr _fac) const; - unsigned int getHits() const; - FactorBaseConstPtrList getConstrainedByList() const; - FactorBasePtrList getConstrainedByList(); - bool isConstrainedBy(const FactorBaseConstPtr &_factor) const; - void link(CaptureBasePtr cap_ptr); template<typename classType, typename... T> static std::shared_ptr<classType> emplace(CaptureBasePtr _cpt_ptr, T&&... all); @@ -156,8 +149,7 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature 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); + }; } @@ -176,11 +168,6 @@ std::shared_ptr<classType> FeatureBase::emplace(CaptureBasePtr _cpt_ptr, T&&... return ftr; } -inline unsigned int FeatureBase::getHits() const -{ - return constrained_by_list_.size(); -} - inline FactorBaseConstPtrList FeatureBase::getFactorList() const { FactorBaseConstPtrList list_const; @@ -194,18 +181,6 @@ inline FactorBasePtrList FeatureBase::getFactorList() return factor_list_; } -inline FactorBaseConstPtrList FeatureBase::getConstrainedByList() const -{ - FactorBaseConstPtrList list_const; - for (auto&& obj_ptr : constrained_by_list_) - list_const.push_back(obj_ptr); - return list_const; -} - -inline FactorBasePtrList FeatureBase::getConstrainedByList() -{ - return constrained_by_list_; -} inline unsigned int FeatureBase::id() const { diff --git a/include/core/frame/frame_base.h b/include/core/frame/frame_base.h index 5ba7ef6757528a9901ceb43b0416ef2ac8f3126c..364a0fb829bbf068b6c9d6902de549486ea5e4d4 100644 --- a/include/core/frame/frame_base.h +++ b/include/core/frame/frame_base.h @@ -31,8 +31,7 @@ class StateBlock; //Wolf includes #include "core/common/wolf.h" #include "core/common/time_stamp.h" -#include "core/common/node_base.h" -#include "core/state_block/has_state_blocks.h" +#include "core/common/node_state_blocks.h" //std includes @@ -40,7 +39,7 @@ namespace wolf { //class FrameBase -class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_shared_from_this<FrameBase> +class FrameBase : public NodeStateBlocks, public std::enable_shared_from_this<FrameBase> { friend CaptureBase; friend FactorBase; @@ -48,7 +47,6 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha private: TrajectoryBaseWPtr trajectory_ptr_; CaptureBasePtrList capture_list_; - FactorBasePtrList constrained_by_list_; static unsigned int frame_id_count_; @@ -90,7 +88,7 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha const TypeComposite& _frame_types, const VectorComposite& _frame_vectors); - ~FrameBase() override; + ~FrameBase() override = default; // Add and remove from WOLF tree --------------------------------- template<typename classType, typename... T> @@ -99,7 +97,8 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha void link(TrajectoryBasePtr); void link(ProblemPtr _prb); - virtual void remove(bool viral_remove_empty_parent=false); + void remove(bool viral_remove_parent_without_children=false) override; + bool hasChildren() const override; // Frame properties ----------------------------------------------- public: @@ -119,10 +118,6 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha protected: void setProblem(ProblemPtr _problem) override final; - // States - public: - bool getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const; - // Wolf tree access --------------------------------------------------- public: @@ -138,15 +133,6 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha CaptureBasePtrList getCaptureList(); bool hasCapture(const CaptureBaseConstPtr& _capture) const; - FactorBaseConstPtrList getFactorList() const; - FactorBasePtrList getFactorList(); - void getFactorList(FactorBaseConstPtrList& _fac_list) const; - void getFactorList(FactorBasePtrList& _fac_list); - - FactorBaseConstPtrList getConstrainedByList() const; - FactorBasePtrList getConstrainedByList(); - bool isConstrainedBy(const FactorBaseConstPtr& _factor) const; - template <class C> std::shared_ptr<const C> getCaptureOfType() const; template <class C> @@ -171,15 +157,7 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha CaptureBaseConstPtrList getCapturesOf(SensorBaseConstPtr _sensor_ptr) const; CaptureBasePtrList getCapturesOf(SensorBasePtr _sensor_ptr); - - FactorBaseConstPtr getFactorOf(ProcessorBaseConstPtr _processor_ptr) const; - FactorBasePtr getFactorOf(ProcessorBasePtr _processor_ptr); - FactorBaseConstPtr getFactorOf(ProcessorBaseConstPtr _processor_ptr, const std::string& type) const; - FactorBasePtr getFactorOf(ProcessorBasePtr _processor_ptr, const std::string& type); - - unsigned int getHits() const; - // Debug and info ------------------------------------------------------- virtual void printHeader(int depth, // bool constr_by, // @@ -203,9 +181,6 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha 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 @@ -275,24 +250,6 @@ inline CaptureBasePtrList FrameBase::getCaptureList() return capture_list_; } -inline unsigned int FrameBase::getHits() const -{ - return constrained_by_list_.size(); -} - -inline FactorBaseConstPtrList FrameBase::getConstrainedByList() const -{ - FactorBaseConstPtrList list_const; - for (auto&& obj_ptr : constrained_by_list_) - list_const.push_back(obj_ptr); - return list_const; -} - -inline FactorBasePtrList FrameBase::getConstrainedByList() -{ - return constrained_by_list_; -} - inline void FrameBase::setTrajectory(TrajectoryBasePtr _trj_ptr) { trajectory_ptr_ = _trj_ptr; diff --git a/include/core/hardware/hardware_base.h b/include/core/hardware/hardware_base.h index 29d4ba6666acb5fba05c02d69067da4acbfd4ef9..69434090adad469922429cfef23ee1dad62e2473 100644 --- a/include/core/hardware/hardware_base.h +++ b/include/core/hardware/hardware_base.h @@ -44,6 +44,7 @@ class HardwareBase : public NodeBase, public std::enable_shared_from_this<Hardwa public: HardwareBase(); ~HardwareBase() override; + bool hasChildren() const override; SensorBaseConstPtrList getSensorList() const; SensorBasePtrList getSensorList(); @@ -93,4 +94,9 @@ inline SensorBasePtrList HardwareBase::getSensorList() return sensor_list_; } +inline bool HardwareBase::hasChildren() const +{ + return not sensor_list_.empty(); +} + } // namespace wolf \ No newline at end of file diff --git a/include/core/landmark/landmark_base.h b/include/core/landmark/landmark_base.h index ae001390ec1a4a6b0b2bfb84e45040567f5b7b12..4c1a6c956ab49061de22d1b894ece1ae64c45c00 100644 --- a/include/core/landmark/landmark_base.h +++ b/include/core/landmark/landmark_base.h @@ -29,9 +29,8 @@ //Wolf includes #include "core/common/wolf.h" -#include "core/common/node_base.h" +#include "core/common/node_state_blocks.h" #include "core/common/time_stamp.h" -#include "core/state_block/has_state_blocks.h" //std includes @@ -57,13 +56,12 @@ static LandmarkBasePtr create(const YAML::Node& _node) \ } \ //class LandmarkBase -class LandmarkBase : public NodeBase, public HasStateBlocks, public std::enable_shared_from_this<LandmarkBase> +class LandmarkBase : public NodeStateBlocks, public std::enable_shared_from_this<LandmarkBase> { friend FactorBase; private: MapBaseWPtr map_ptr_; - FactorBasePtrList constrained_by_list_; static unsigned int landmark_id_count_; protected: @@ -99,24 +97,16 @@ class LandmarkBase : public NodeBase, public HasStateBlocks, public std::enable_ LandmarkBase(const YAML::Node& _n); WOLF_LANDMARK_CREATE(LandmarkBase); - ~LandmarkBase() override; - virtual void remove(bool viral_remove_empty_parent=false); + ~LandmarkBase() override = default; + void remove(bool viral_remove_parent_without_children=false) override; virtual YAML::Node toYaml() const; // Properties unsigned int id() const; void setId(unsigned int _id); - // State blocks - bool getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const; - public: - unsigned int getHits() const; - FactorBaseConstPtrList getConstrainedByList() const; - FactorBasePtrList getConstrainedByList(); - bool isConstrainedBy(const FactorBaseConstPtr &_factor) const; - MapBaseConstPtr getMap() const; MapBasePtr getMap(); @@ -191,22 +181,4 @@ inline void LandmarkBase::setId(unsigned int _id) landmark_id_count_ = _id; } -inline unsigned int LandmarkBase::getHits() const -{ - return constrained_by_list_.size(); -} - -inline FactorBaseConstPtrList LandmarkBase::getConstrainedByList() const -{ - FactorBaseConstPtrList list_const; - for (auto&& obj_ptr : constrained_by_list_) - list_const.push_back(obj_ptr); - return list_const; -} - -inline FactorBasePtrList LandmarkBase::getConstrainedByList() -{ - return constrained_by_list_; -} - } // namespace wolf \ No newline at end of file diff --git a/include/core/map/map_base.h b/include/core/map/map_base.h index 764464c43ef96b01f1bf20ce18bca3f7d29c310a..66303881b9058af3e28ff94ef7ce703ebee4c80f 100644 --- a/include/core/map/map_base.h +++ b/include/core/map/map_base.h @@ -93,7 +93,8 @@ class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase> MapBase(ParamsMapBasePtr _params, const std::string& _type = "Base"); WOLF_MAP_CREATE(MapBase, ParamsMapBase); - ~MapBase() override; + ~MapBase() override = default; + bool hasChildren() const override; protected: virtual LandmarkBasePtr addLandmark(LandmarkBasePtr _landmark_ptr); diff --git a/include/core/problem/problem.h b/include/core/problem/problem.h index fb077e8e9b0bd55924e2998f426da9bb14e07a0c..88ba661e7d43707ef8f13a999c841458f284ca92 100644 --- a/include/core/problem/problem.h +++ b/include/core/problem/problem.h @@ -37,9 +37,9 @@ class Loader; //wolf includes #include "core/common/wolf.h" +#include "core/common/node_state_blocks.h" #include "core/frame/frame_base.h" #include "core/state_block/state_block.h" -#include "core/state_block/has_state_blocks.h" #include "core/state_block/spec_composite.h" #include "core/state_block/vector_composite.h" #include "core/processor/motion_provider.h" @@ -356,7 +356,7 @@ class Problem : public std::enable_shared_from_this<Problem> bool getCovarianceBlock(StateBlockConstPtr _state1, StateBlockConstPtr _state2, Eigen::MatrixXd& _cov, const int _row = 0, const int _col=0) const; bool getCovarianceBlock(std::map<StateBlockConstPtr, unsigned int> _sb_2_idx, Eigen::MatrixXd& _cov) const; bool getCovarianceBlock(StateBlockConstPtr _state, Eigen::MatrixXd& _cov, const int _row_and_col = 0) const; - bool getCovariance(HasStateBlocksConstPtr _has_states_ptr, const StateKeys& _keys, Eigen::MatrixXd& _covariance) const; + bool getCovariance(NodeStateBlocksConstPtr _has_states_ptr, const StateKeys& _keys, Eigen::MatrixXd& _covariance) const; bool getLastFrameCovariance(const StateKeys& _keys, Eigen::MatrixXd& _covariance) const; diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h index c6773d321645c134fd15e88833b177663e6bda79..f991f99037d6191356224f0937ceee0f853fa619 100644 --- a/include/core/processor/processor_base.h +++ b/include/core/processor/processor_base.h @@ -251,6 +251,7 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce ~ProcessorBase() override; virtual void configure(SensorBasePtr _sensor) = 0; virtual void remove(); + bool hasChildren() const override {return false;}; unsigned int id() const; diff --git a/include/core/sensor/sensor_base.h b/include/core/sensor/sensor_base.h index 7e141b32af1f34954994d5aeb0abd0b0fb4d8e52..c49a7f99361665a93034820a0a4172a023fd80d4 100644 --- a/include/core/sensor/sensor_base.h +++ b/include/core/sensor/sensor_base.h @@ -31,10 +31,9 @@ class StateBlock; //Wolf includes #include "core/common/wolf.h" #include "core/sensor/spec_state_sensor.h" -#include "core/common/node_base.h" +#include "core/common/node_state_blocks.h" #include "core/common/time_stamp.h" #include "core/common/params_base.h" -#include "core/state_block/has_state_blocks.h" #include "yaml-schema-cpp/yaml_schema.hpp" //std includes @@ -105,7 +104,7 @@ struct ParamsSensorBase: public ParamsBase }; WOLF_PTR_TYPEDEFS(SensorBase); -class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_shared_from_this<SensorBase> +class SensorBase : public NodeStateBlocks, public std::enable_shared_from_this<SensorBase> { friend Problem; friend ProcessorBase; @@ -176,15 +175,12 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh bool process(const CaptureBasePtr capture_ptr); // State blocks - using HasStateBlocks::addStateBlock; StateBlockPtr addStateBlock(const char& _key, const StateBlockPtr& _sb_ptr, const bool _dynamic = false); StateBlockConstPtr getStateBlockDynamic(const char& _key) const; StateBlockPtr getStateBlockDynamic(const char& _key); StateBlockConstPtr getStateBlockDynamic(const char& _key, const TimeStamp& _ts) const; StateBlockPtr getStateBlockDynamic(const char& _key, const TimeStamp& _ts); - bool getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const; - // Declare a state block as dynamic or static (with _dymanic = false) void setStateBlockDynamic(const char& _key, bool _dynamic = true); @@ -214,9 +210,6 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh FeatureBaseConstPtr getPriorFeature(char) const; FeatureBasePtr getPriorFeature(char); - protected: - virtual void registerNewStateBlocks(ProblemPtr _problem) override; - public: void fixExtrinsics(); @@ -331,7 +324,7 @@ inline CaptureBasePtr SensorBase::getLastCapture() inline StateBlockPtr SensorBase::addStateBlock(const char& _key, const StateBlockPtr& _sb_ptr, const bool _dynamic) { assert((features_prior_map_.find(_key) == features_prior_map_.end() || _sb_ptr == nullptr) && "overwriting a state block that has an absolute factor"); - HasStateBlocks::addStateBlock(_key, _sb_ptr, getProblem()); + NodeStateBlocks::addStateBlock(_key, _sb_ptr, getProblem()); setStateBlockDynamic(_key, _dynamic); return _sb_ptr; } diff --git a/include/core/trajectory/trajectory_base.h b/include/core/trajectory/trajectory_base.h index 4c16c1e0c094e9b822a547ae6fca5484ee0f13da..ed99f062652eeab40d4eaedd3fde66556f2127ec 100644 --- a/include/core/trajectory/trajectory_base.h +++ b/include/core/trajectory/trajectory_base.h @@ -48,6 +48,7 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj public: TrajectoryBase(); ~TrajectoryBase() override; + bool hasChildren() const override; // Frames SizeEigen size() const; @@ -92,6 +93,11 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj void getFactorList(FactorBasePtrList & _fac_list); }; +inline bool TrajectoryBase::hasChildren() const +{ + return not frame_list_.empty(); +} + inline FrameConstPtrMap TrajectoryBase::getFrameMap() const { FrameConstPtrMap map_const; diff --git a/include/core/tree_manager/tree_manager_sliding_window.h b/include/core/tree_manager/tree_manager_sliding_window.h index 9585cc595ee3841d09e42ddc3d57b2c346bc68c7..507e56d1d31a1cb775a9b049459967d985d2db1d 100644 --- a/include/core/tree_manager/tree_manager_sliding_window.h +++ b/include/core/tree_manager/tree_manager_sliding_window.h @@ -37,7 +37,7 @@ struct ParamsTreeManagerSlidingWindow : public ParamsTreeManagerBase { n_frames = _node_input["n_frames"] .as<unsigned int>(); n_fix_first_frames = _node_input["n_fix_first_frames"] .as<unsigned int>(); - viral_remove_empty_parent = _node_input["viral_remove_empty_parent"] .as<bool>(); + viral_remove_parent_without_children = _node_input["viral_remove_parent_without_children"] .as<bool>(); if (n_frames <= n_fix_first_frames) throw std::runtime_error("TreeManagerSlidingWindow: Wrong parameter value. 'n_fix_first_frames' should be lower than 'n_frames'!"); } @@ -46,12 +46,12 @@ struct ParamsTreeManagerSlidingWindow : public ParamsTreeManagerBase return ParamsTreeManagerBase::print() + "\n" + "n_frames: " + toString(n_frames) + "\n" + "n_fix_first_frames: " + toString(n_fix_first_frames) + "\n" - + "viral_remove_empty_parent: " + toString(viral_remove_empty_parent) + "\n"; + + "viral_remove_parent_without_children: " + toString(viral_remove_parent_without_children) + "\n"; } unsigned int n_frames; unsigned int n_fix_first_frames; - bool viral_remove_empty_parent; + bool viral_remove_parent_without_children; }; class TreeManagerSlidingWindow : public TreeManagerBase diff --git a/schema/tree_manager/TreeManagerSlidingWindow.schema b/schema/tree_manager/TreeManagerSlidingWindow.schema index 6424af1fbc002d85112fb4a96ded5d602a518d86..740dd6b0bf9754d3c8d8551fc63f06cf126744dc 100644 --- a/schema/tree_manager/TreeManagerSlidingWindow.schema +++ b/schema/tree_manager/TreeManagerSlidingWindow.schema @@ -15,7 +15,7 @@ n_fix_first_frames: _type: unsigned int _doc: Amount of frames fixed at the begining of the sliding window. -viral_remove_empty_parent: +viral_remove_parent_without_children: _mandatory: true _type: bool _doc: If the other wolf nodes (landmarks) have to be removed when removing frames. Otherwise, they will remain alive but unconstrained. diff --git a/src/capture/capture_base.cpp b/src/capture/capture_base.cpp index 6919fc4eb6bc3ef5017d38ef661b26f8848198f4..4c370cf56a484937b3a477e5121095643d127b7c 100644 --- a/src/capture/capture_base.cpp +++ b/src/capture/capture_base.cpp @@ -34,8 +34,7 @@ CaptureBase::CaptureBase(const std::string& _type, StateBlockPtr _p_ptr, StateBlockPtr _o_ptr, StateBlockPtr _intr_ptr) : - NodeBase("CAPTURE", _type), - HasStateBlocks(), + NodeStateBlocks("CAPTURE", _type), frame_ptr_(), // nullptr sensor_ptr_(_sensor_ptr), capture_id_(++capture_id_count_), @@ -78,48 +77,45 @@ CaptureBase::CaptureBase(const std::string& _type, } } -CaptureBase::~CaptureBase() -{ -} - -void CaptureBase::remove(bool viral_remove_empty_parent) +void CaptureBase::remove(bool viral_remove_parent_without_children) { /* Order of removing: * Factors are removed first, and afterwards the rest of nodes containing state blocks. * In case multi-threading, solver can be called while removing. * This order avoids SolverManager to ignore notifications (efficiency) */ - if (!is_removing_) - { - is_removing_ = true; - CaptureBasePtr this_C = shared_from_this(); // keep this alive while removing it + if (is_removing_) + return; - // SensorBase::last_capture_ - if (getSensor() and getSensor()->getLastCapture() == this_C) - getSensor()->updateLastCapture(); + is_removing_ = true; + CaptureBasePtr this_C = shared_from_this(); // keep this alive while removing it - // remove downstream - while (!constrained_by_list_.empty()) - { - constrained_by_list_.front()->remove(viral_remove_empty_parent); // remove constrained by - } - while (!feature_list_.empty()) - { - feature_list_.front()->remove(viral_remove_empty_parent); // remove downstream - } + // SensorBase::last_capture_ + if (getSensor() and getSensor()->getLastCapture() == this_C) + getSensor()->updateLastCapture(); - // Remove State Blocks - removeStateBlocks(getProblem()); + // remove downstream + while (!feature_list_.empty()) + { + feature_list_.front()->remove(viral_remove_parent_without_children); // remove downstream + } - // remove from upstream - FrameBasePtr F = frame_ptr_.lock(); - if (F) - { - F->removeCapture(this_C); - if (viral_remove_empty_parent && F->getCaptureList().empty() && F->getConstrainedByList().empty()) - F->remove(viral_remove_empty_parent); // remove upstream - } + // remove from upstream + FrameBasePtr F = frame_ptr_.lock(); + if (F) + { + F->removeCapture(this_C); + if (viral_remove_parent_without_children and not F->hasChildren()) + F->remove(viral_remove_parent_without_children); // remove upstream } + + // Remove State Blocks + NodeStateBlocks::remove(viral_remove_parent_without_children); +} + +bool CaptureBase::hasChildren() const +{ + return NodeStateBlocks::hasChildren() or not feature_list_.empty(); } bool CaptureBase::process() @@ -141,45 +137,6 @@ void CaptureBase::removeFeature(FeatureBasePtr _ft_ptr) feature_list_.remove(_ft_ptr); } -FactorBaseConstPtrList CaptureBase::getFactorList() const -{ - FactorBaseConstPtrList fac_list; - getFactorList(fac_list); - return fac_list; -} - -FactorBasePtrList CaptureBase::getFactorList() -{ - FactorBasePtrList fac_list; - getFactorList(fac_list); - return fac_list; -} - -void CaptureBase::getFactorList(FactorBaseConstPtrList& _fac_list) const -{ - for (auto f_ptr : getFeatureList()) - if (not f_ptr->isRemoving()) - f_ptr->getFactorList(_fac_list); -} - -void CaptureBase::getFactorList(FactorBasePtrList& _fac_list) -{ - for (auto f_ptr : getFeatureList()) - if (not f_ptr->isRemoving()) - f_ptr->getFactorList(_fac_list); -} - -FactorBasePtr CaptureBase::addConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.push_back(_fac_ptr); - return _fac_ptr; -} - -void CaptureBase::removeConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.remove(_fac_ptr); -} - bool CaptureBase::hasFeature(const FeatureBaseConstPtr &_feature) const { return std::find(feature_list_.begin(), @@ -187,24 +144,17 @@ bool CaptureBase::hasFeature(const FeatureBaseConstPtr &_feature) const _feature) != feature_list_.end(); } -bool CaptureBase::isConstrainedBy(const FactorBaseConstPtr &_factor) const -{ - return std::find(constrained_by_list_.begin(), - constrained_by_list_.end(), - _factor) != constrained_by_list_.end(); -} - StateBlockConstPtr CaptureBase::getStateBlock(const char& _key) const { if (getSensor() and getSensor()->has(_key)) { if (getSensor()->isStateBlockDynamic(_key)) - return HasStateBlocks::getStateBlock(_key); + return NodeStateBlocks::getStateBlock(_key); else return getSensor()->getStateBlock(_key); } else // No sensor associated, or sensor without this state block: assume sensor params are here - return HasStateBlocks::getStateBlock(_key); + return NodeStateBlocks::getStateBlock(_key); } StateBlockPtr CaptureBase::getStateBlock(const char& _key) @@ -212,27 +162,22 @@ StateBlockPtr CaptureBase::getStateBlock(const char& _key) if (getSensor() and getSensor()->has(_key)) { if (getSensor()->isStateBlockDynamic(_key)) - return HasStateBlocks::getStateBlock(_key); + return NodeStateBlocks::getStateBlock(_key); else return getSensor()->getStateBlock(_key); } else // No sensor associated, or sensor without this state block: assume sensor params are here - return HasStateBlocks::getStateBlock(_key); -} - -bool CaptureBase::getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const -{ - return getProblem()->getCovariance(shared_from_this(), _keys, _cov); + return NodeStateBlocks::getStateBlock(_key); } void CaptureBase::fix() { - HasStateBlocks::fix(); + NodeStateBlocks::fix(); } void CaptureBase::unfix() { - HasStateBlocks::unfix(); + NodeStateBlocks::unfix(); } void CaptureBase::move(FrameBasePtr _frm_ptr) @@ -270,9 +215,7 @@ void CaptureBase::unlink() if (not this->getFrame()) return; - for (auto ftr : getFeatureList()) - assert(ftr->getFactorList().empty() && " unlinking a capture with factors!"); - assert(getConstrainedByList().empty() && " unlinking a capture constrained by factors!"); + assert(getFactorList().empty() && " unlinking a capture constrained by factors!"); // unlink from frame this->getFrame()->removeCapture(shared_from_this()); @@ -286,8 +229,7 @@ void CaptureBase::setProblem(ProblemPtr _problem) assert(getFrame() && "Cannot set problem: Capture has no Frame!"); - NodeBase::setProblem(_problem); - registerNewStateBlocks(_problem); + NodeStateBlocks::setProblem(_problem); // update SensorBase::last_capture_ if (getSensor() and @@ -313,13 +255,13 @@ void CaptureBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _s _stream << " -> Sen-"; _stream << ((_depth < 3) ? " -- " + std::to_string(getFeatureList().size()) + "f" : ""); - if (_constr_by) - { - _stream << " <-- "; - for (auto cby : getConstrainedByList()) - if (cby) - _stream << "Fac" << cby->id() << " \t"; - } + // if (_constr_by) + // { + // _stream << " <-- "; + // for (auto cby : getConstrainedByList()) + // if (cby) + // _stream << "Fac" << cby->id() << " \t"; + // } _stream << std::endl; if (getStateBlockMap().size() > 0) @@ -377,37 +319,37 @@ CheckLog CaptureBase::localCheck(bool _verbose, CaptureBaseConstPtr _cap_ptr, st log.assertTrue((getProblem() == frm_ptr->getProblem()), inconsistency_explanation); - // check contrained_by - for (auto cby : getConstrainedByList()) - { - if (_verbose) - { - _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; - for (auto Cow : cby->getCaptureOtherList()) - _stream << " Cap" << Cow.lock()->id(); - _stream << std::endl; - } - - // check constrained_by pointer to this capture - inconsistency_explanation << "constrained by capture " << id() << " @ " << _cap_ptr.get() - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasCaptureOther(_cap_ptr)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) - { - if (_verbose) - { - _stream << _tabs << " " << "sb @ " << sb.get(); - if (sb) - { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - } + // // check contrained_by + // for (auto cby : getConstrainedByList()) + // { + // if (_verbose) + // { + // _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + // for (auto Cow : cby->getCaptureOtherList()) + // _stream << " Cap" << Cow.lock()->id(); + // _stream << std::endl; + // } + + // // check constrained_by pointer to this capture + // inconsistency_explanation << "constrained by capture " << id() << " @ " << _cap_ptr.get() + // << " not found among constrained-by factors\n"; + // log.assertTrue((cby->hasCaptureOther(_cap_ptr)), inconsistency_explanation); + + // for (auto sb : cby->getStateBlockPtrVector()) + // { + // if (_verbose) + // { + // _stream << _tabs << " " << "sb @ " << sb.get(); + // if (sb) + // { + // auto lp = sb->getLocalParametrization(); + // if (lp) + // _stream << " (lp @ " << lp.get() << ")"; + // } + // _stream << std::endl; + // } + // } + // } // check frame auto frm_cap = _cap_ptr->getFrame(); diff --git a/src/capture/capture_motion.cpp b/src/capture/capture_motion.cpp index d1310a3d2e8658decc19ead49d7b719b343d5ed8..1a5daac0b34e43d489d1fb17eeba10b31ce7ee10 100644 --- a/src/capture/capture_motion.cpp +++ b/src/capture/capture_motion.cpp @@ -109,12 +109,12 @@ void CaptureMotion::printHeader(int _depth, bool _constr_by, bool _metric, bool } _stream << ((_depth < 3) ? " -- " + std::to_string(getFeatureList().size()) + "f" : ""); - if (_constr_by) - { - _stream << " <-- "; - for (auto cby : getConstrainedByList()) - _stream << "Fac" << cby->id() << " \t"; - } + // if (_constr_by) + // { + // _stream << " <-- "; + // for (auto cby : getConstrainedByList()) + // _stream << "Fac" << cby->id() << " \t"; + // } _stream << std::endl; if (getStateBlockMap().size() > 0) diff --git a/src/common/node_state_blocks.cpp b/src/common/node_state_blocks.cpp new file mode 100644 index 0000000000000000000000000000000000000000..d84a3a5ba1ad8438b9fe7888aa0739694b5c3f1e --- /dev/null +++ b/src/common/node_state_blocks.cpp @@ -0,0 +1,273 @@ +//--------LICENSE_START-------- +// +// Copyright (C) 2020,2021,2022 Institut de Robòtica i Informà tica Industrial, CSIC-UPC. +// Authors: Joan Solà Ortega (jsola@iri.upc.edu) +// All rights reserved. +// +// This file is part of WOLF +// WOLF is free software: you can redistribute it and/or modify +// it under the terms of the GNU Lesser General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public License +// along with this program. If not, see <http://www.gnu.org/licenses/>. +// +//--------LICENSE_END-------- + +#include "core/common/node_state_blocks.h" +#include "core/state_block/factory_state_block.h" + +namespace wolf +{ + +NodeStateBlocks::NodeStateBlocks(const std::string& _category, const std::string& _type, const SpecStateComposite& _specs) : + NodeBase(_category, _type) +{ + for (auto spec : _specs) + { + if (spec.first == 'P' and + spec.second.getType() != "P" and + spec.second.getType() != "StatePoint2d" and + spec.second.getType() != "StatePoint3d" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'P', the state block should be of type 'P', 'StatePoint2d' or 'StatePoint3d'"); + } + if (spec.first == 'O' and + spec.second.getType() != "O" and + spec.second.getType() != "StateAngle" and + spec.second.getType() != "StateQuaternion" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'"); + } + if (spec.first == 'V' and + spec.second.getType() != "V" and + spec.second.getType() != "StateVector2d" and + spec.second.getType() != "StateVector3d" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'"); + } + addStateBlock(spec.first, FactoryStateBlock::create(spec.second.getType(), spec.second.getState(), spec.second.isFixed()), nullptr); + } +} + +NodeStateBlocks::NodeStateBlocks(const std::string& _category, const std::string& _type, const TypeComposite& _types, const VectorComposite& _vectors) : + NodeBase(_category, _type) +{ + if (not _types.has(_vectors.getKeys()) or not _vectors.has(_types.getKeys())) + { + throw std::runtime_error("NodeStateBlocks::NodeStateBlocks: provided type and vector composites don't have the same structure"); + } + + for (auto type_pair : _types) + { + auto key = type_pair.first; + auto type = type_pair.second; + auto vector = _vectors.at(key); + + if (key == 'P' and + type != "P" and + type != "StatePoint2d" and + type != "StatePoint3d" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'P', the state block should be of type 'P', 'StatePoint2d' or 'StatePoint3d'"); + } + if (key == 'O' and + type != "O" and + type != "StateAngle" and + type != "StateQuaternion" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'"); + } + if (key == 'V' and + type != "V" and + type != "StateVector2d" and + type != "StateVector3d" ) + { + throw std::runtime_error("NodeStateBlocks: in key 'O', the state block should be of type 'O', 'StateAngle' or 'StateQuaternion'"); + } + addStateBlock(key, FactoryStateBlock::create(type, vector, false), nullptr); + } +} + +void NodeStateBlocks::remove(bool viral_remove_parent_without_children) +{ + for (const char key : getKeys()) + { + auto sbp = getStateBlock(key); + if (sbp != nullptr) + { + if (getProblem()) + { + getProblem()->notifyStateBlock(sbp, REMOVE); + } + removeStateBlock(key); + } + } +} + +SpecStateComposite NodeStateBlocks::getSpecs() const +{ + SpecStateComposite specs; + for (auto && state_pair : state_block_composite_) + { + specs.emplace(state_pair.first, SpecState(state_pair.second->getType(), + state_pair.second->getState(), + state_pair.second->isFixed() ? "fix" : "initial_guess")); + } + return specs; +} + +StateBlockPtr NodeStateBlocks::addStateBlock(const char& _sb_key, const StateBlockPtr& _sb, ProblemPtr _problem) +{ + assert(state_block_composite_.count(_sb_key) == 0 and + "Trying to add a state block with an existing type! Use setStateBlock instead."); + + state_block_composite_.emplace(_sb_key, _sb); + + // conditionally register to problem + if(_problem) + _problem->notifyStateBlock(_sb, ADD); + + return _sb; +} + +void NodeStateBlocks::setProblem(ProblemPtr _problem) +{ + NodeBase::setProblem(_problem); + + // register state blocks + if (_problem != nullptr) + { + for (auto pair_key_sbp : getStateBlockMap()) + if (pair_key_sbp.second != nullptr) + _problem->notifyStateBlock(pair_key_sbp.second, ADD); + } +} + +bool NodeStateBlocks::getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const +{ + if (not this->has(_keys)) + { + WOLF_WARN("NodeStateBlocks::getCovariance does not have the keys ", _keys, ". Available keys: ", getKeys()); + return false; + } + + bool success(true); + + // resizing + SizeEigen sz = getLocalSize(); + _cov.resize(sz, sz); + + // filling covariance + int i = 0, j = 0; + for (auto key_i : _keys) + { + auto sb_i = getStateBlock(key_i); + j = 0; + for (auto key_j : _keys) + { + auto sb_j = getStateBlock(key_j); + success = success && getProblem()->getCovarianceBlock(sb_i, sb_j, _cov, i, j); + j += sb_j->getLocalSize(); + } + i += sb_i->getLocalSize(); + } + + return success; +} + +FactorBaseConstPtr NodeStateBlocks::getFactorOf(ProcessorBaseConstPtr _processor_ptr, const std::string& type) const +{ + for (auto factor_ptr : getFactorList()) + if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) + return factor_ptr; + + return nullptr; +} + +FactorBasePtr NodeStateBlocks::getFactorOf(ProcessorBasePtr _processor_ptr, const std::string& type) +{ + for (auto factor_ptr : getFactorList()) + if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) + return factor_ptr; + + return nullptr; +} + +FactorBaseConstPtr NodeStateBlocks::getFactorOf(ProcessorBaseConstPtr _processor_ptr) const +{ + for (auto factor_ptr : getFactorList()) + if (factor_ptr->getProcessor() == _processor_ptr) + return factor_ptr; + + return nullptr; +} + +FactorBasePtr NodeStateBlocks::getFactorOf(ProcessorBasePtr _processor_ptr) +{ + for (auto factor_ptr : getFactorList()) + if (factor_ptr->getProcessor() == _processor_ptr) + return factor_ptr; + + return nullptr; +} + +void NodeStateBlocks::perturb(double amplitude) +{ + for (const auto& pair_key_sb : state_block_composite_) + { + auto& sb = pair_key_sb.second; + if (!sb->isFixed()) + sb->perturb(amplitude); + } +} + +void NodeStateBlocks::transform(const VectorComposite& _transformation) +{ + for (auto& pair_key_sb : state_block_composite_) + pair_key_sb.second->transform(_transformation); +} + + +void NodeStateBlocks::printState (bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const +{ + if (_metric && _state_blocks) + { + for (auto key : getKeys()) + { + auto sb = getStateBlock(key); + if (sb) + _stream << _tabs << " " << key + << " [" << (sb->isFixed() ? "Fix" : "Est") + << "] = ( " << std::setprecision(3) << sb->getState().transpose() << " )" + << " @ " << sb << std::endl; + } + } + else if (_metric) + { + _stream << _tabs << " " << (isFixed() ? "Fix" : "Est") + << ",\t x = ( " << std::setprecision(3) << getStateVector(getKeys()).transpose() << " )" + << std::endl; + } + else if (_state_blocks) + { + _stream << _tabs << " " << "sb:"; + for (auto key : getKeys()) + { + auto sb = getStateBlock(key); + if (sb) + _stream << " " << key + << " [" << (sb->isFixed() ? "Fix" : "Est") + << "] @ " << sb; + } + _stream << std::endl; + } +} + +} diff --git a/src/factor/factor_base.cpp b/src/factor/factor_base.cpp index 9610063417bd9a283b01d90068abf51e655e2f68..d4b1079327e100d40c9e88dfe5ae597aa6076c2d 100644 --- a/src/factor/factor_base.cpp +++ b/src/factor/factor_base.cpp @@ -30,157 +30,149 @@ unsigned int FactorBase::factor_id_count_ = 0; FactorBase::FactorBase(const std::string& _tp, const FactorTopology& _top, const FeatureBasePtr& _feature_ptr, - const FrameBasePtrList& _frame_other_list, - const CaptureBasePtrList& _capture_other_list, - const FeatureBasePtrList& _feature_other_list, - const LandmarkBasePtrList& _landmark_other_list, + const FrameBasePtrList& _frame_list, + const CaptureBasePtrList& _capture_list, + const LandmarkBasePtrList& _landmark_list, + const SensorBasePtrList& _sensor_list, + const ProcessorBasePtr& _processor_ptr, + bool _apply_loss_function, + FactorStatus _status) : + FactorBase(_tp, + _top, + _feature_ptr->getMeasurement(), + _feature_ptr->getMeasurementSquareRootInformationUpper(), + _frame_list, + _capture_list, + _landmark_list, + _processor_ptr, + _apply_loss_function, + _status) +{ +} + +FactorBase::FactorBase(const std::string& _tp, + const FactorTopology& _top, + const Eigen::VectorXd& _measurement, + const Eigen::MatrixXd& _measurement_sqrt_information_upper, + const FrameBasePtrList& _frame_list, + const CaptureBasePtrList& _capture_list, + const LandmarkBasePtrList& _landmark_list, + const SensorBasePtrList& _sensor_list, const ProcessorBasePtr& _processor_ptr, bool _apply_loss_function, FactorStatus _status) : NodeBase("FACTOR", _tp), - feature_ptr_(), // will be filled in link() processor_ptr_(_processor_ptr), - frame_other_list_(), - capture_other_list_(), - feature_other_list_(), - landmark_other_list_(), + feature_ptr_(), + node_state_blocks_list_(), + frame_list_(), + capture_list_(), + landmark_list_(), + sensor_list_(), factor_id_(++factor_id_count_), topology_(_top), status_(_status), - apply_loss_function_(_apply_loss_function) + apply_loss_function_(_apply_loss_function), + measurement_(_measurement), + measurement_sqrt_information_upper_(_measurement_sqrt_information_upper) { - for (auto Fo : _frame_other_list) - frame_other_list_.push_back(Fo); - for (auto Co : _capture_other_list) - capture_other_list_.push_back(Co); - for (auto fo : _feature_other_list) - feature_other_list_.push_back(fo); - for (auto Lo : _landmark_other_list) - landmark_other_list_.push_back(Lo); - - assert(_feature_ptr && "null feature pointer when creating a factor"); - measurement_ = _feature_ptr->getMeasurement(); - measurement_sqrt_information_upper_ = _feature_ptr->getMeasurementSquareRootInformationUpper(); + for (auto Fo : _frame_list) + { + frame_list_.push_back(Fo); + node_state_blocks_list_.push_back(Fo); + } + for (auto Co : _capture_list) + { + capture_list_.push_back(Co); + node_state_blocks_list_.push_back(Co); + } + for (auto Lo : _landmark_list) + { + landmark_list_.push_back(Lo); + node_state_blocks_list_.push_back(Lo); + } + for (auto So : _sensor_list) + { + sensor_list_.push_back(So); + node_state_blocks_list_.push_back(So); + } } - -void FactorBase::remove(bool viral_remove_empty_parent) +void FactorBase::remove(bool viral_remove_parent_without_children) { /* Order of removing: * Factors are removed first, and afterwards the rest of nodes containing state blocks. * In case multi-threading, solver can be called while removing. * This order avoids SolverManager to ignore notifications (efficiency) */ - if (!is_removing_) - { - is_removing_ = true; - FactorBasePtr this_fac = shared_from_this(); // keep this alive while removing it - - // add factor to be removed from solver - if (getProblem() != nullptr and this->getStatus() == FAC_ACTIVE) - getProblem()->notifyFactor(this_fac,REMOVE); - - // remove from upstream - FeatureBasePtr f = feature_ptr_.lock(); - if (f) - { - f->removeFactor(this_fac); - if (viral_remove_empty_parent && f->getFactorList().empty() && f->getConstrainedByList().empty()) - f->remove(viral_remove_empty_parent); // remove upstream - } - - // remove other: {Frame, Capture, Feature, Landmark} - for (auto& frm_ow : frame_other_list_) - { - auto frm_o = frm_ow.lock(); - if (frm_o) - { - frm_o->removeConstrainedBy(this_fac); - if (viral_remove_empty_parent && frm_o->getConstrainedByList().empty() && frm_o->getCaptureList().empty()) - frm_o->remove(viral_remove_empty_parent); - } - } + if (is_removing_) + return; - for (auto& cap_ow : capture_other_list_) - { - auto cap_o = cap_ow.lock(); - if (cap_o) - { - cap_o->removeConstrainedBy(this_fac); - if (viral_remove_empty_parent && cap_o->getConstrainedByList().empty() && cap_o->getFeatureList().empty()) - cap_o->remove(viral_remove_empty_parent); - } - } + is_removing_ = true; + FactorBasePtr this_fac = shared_from_this(); // keep this alive while removing it - for (auto& ftr_ow : feature_other_list_) - { - auto ftr_o = ftr_ow.lock(); - if (ftr_o) - { - ftr_o->removeConstrainedBy(this_fac); - if (viral_remove_empty_parent && ftr_o->getConstrainedByList().empty() && ftr_o->getFactorList().empty()) - ftr_o->remove(viral_remove_empty_parent); - } - } + // add factor to be removed from solver + if (getProblem() != nullptr and this->getStatus() == FAC_ACTIVE) + getProblem()->notifyFactor(this_fac,REMOVE); - for (auto& lmk_ow : landmark_other_list_) + // remove from upstream + for (auto& node_states_w : node_state_blocks_list_) + { + auto node = node_states_w.lock(); + if (node) { - auto lmk_o = lmk_ow.lock(); - if (lmk_o) - { - lmk_o->removeConstrainedBy(this_fac); - if (viral_remove_empty_parent && lmk_o->getConstrainedByList().empty()) - lmk_o->remove(viral_remove_empty_parent); - } + node->removeFactor(this_fac); + if (viral_remove_parent_without_children and not node->hasChildren()) + node->remove(viral_remove_parent_without_children); } - - // std::cout << "Removed c" << id() << std::endl; } -} -CaptureBaseConstPtr FactorBase::getCapture() const -{ - auto ftr = getFeature(); - if (ftr != nullptr and not ftr->isRemoving()) - return ftr->getCapture(); - else return nullptr; + // std::cout << "Removed c" << id() << std::endl; } -CaptureBasePtr FactorBase::getCapture() -{ - auto ftr = getFeature(); - if (ftr != nullptr and not ftr->isRemoving()) - return ftr->getCapture(); - else return nullptr; -} - -FrameBaseConstPtr FactorBase::getFrame() const -{ - auto cpt = getCapture(); - if(cpt != nullptr and not cpt->isRemoving()) return cpt->getFrame(); - else return nullptr; -} - -FrameBasePtr FactorBase::getFrame() -{ - auto cpt = getCapture(); - if(cpt != nullptr and not cpt->isRemoving()) return cpt->getFrame(); - else return nullptr; -} - -SensorBaseConstPtr FactorBase::getSensor() const -{ - auto cpt = getCapture(); - if(cpt != nullptr and not cpt->isRemoving()) return cpt->getSensor(); - else return nullptr; -} - -SensorBasePtr FactorBase::getSensor() -{ - auto cpt = getCapture(); - if(cpt != nullptr and not cpt->isRemoving()) return cpt->getSensor(); - else return nullptr; -} +// CaptureBaseConstPtr FactorBase::getCapture() const +// { +// auto ftr = getFeature(); +// if (ftr != nullptr and not ftr->isRemoving()) +// return ftr->getCapture(); +// else return nullptr; +// } + +// CaptureBasePtr FactorBase::getCapture() +// { +// auto ftr = getFeature(); +// if (ftr != nullptr and not ftr->isRemoving()) +// return ftr->getCapture(); +// else return nullptr; +// } + +// FrameBaseConstPtr FactorBase::getFrame() const +// { +// auto cpt = getCapture(); +// if(cpt != nullptr and not cpt->isRemoving()) return cpt->getFrame(); +// else return nullptr; +// } + +// FrameBasePtr FactorBase::getFrame() +// { +// auto cpt = getCapture(); +// if(cpt != nullptr and not cpt->isRemoving()) return cpt->getFrame(); +// else return nullptr; +// } + +// SensorBaseConstPtr FactorBase::getSensor() const +// { +// auto cpt = getCapture(); +// if(cpt != nullptr and not cpt->isRemoving()) return cpt->getSensor(); +// else return nullptr; +// } + +// SensorBasePtr FactorBase::getSensor() +// { +// auto cpt = getCapture(); +// if(cpt != nullptr and not cpt->isRemoving()) return cpt->getSensor(); +// else return nullptr; +// } void FactorBase::setStatus(FactorStatus _status) { @@ -196,57 +188,57 @@ void FactorBase::setStatus(FactorStatus _status) status_ = _status; } -bool FactorBase::hasFrameOther(const FrameBaseConstPtr &_frm_other) const +bool FactorBase::hasFrame(const FrameBaseConstPtr &_frm) const { - auto frm_it = find_if(frame_other_list_.begin(), - frame_other_list_.end(), - [_frm_other](const FrameBaseConstWPtr &frm_ow) + auto frm_it = find_if(frame_list_.begin(), + frame_list_.end(), + [_frm](const FrameBaseConstWPtr &frm_ow) { - return frm_ow.lock() == _frm_other; + return frm_ow.lock() == _frm; }); - if (frm_it != frame_other_list_.end()) + if (frm_it != frame_list_.end()) return true; return false; } -bool FactorBase::hasCaptureOther(const CaptureBaseConstPtr &_cap_other) const +bool FactorBase::hasCapture(const CaptureBaseConstPtr &_cap) const { - auto cap_it = find_if(capture_other_list_.begin(), - capture_other_list_.end(), - [_cap_other](const CaptureBaseConstWPtr &cap_ow) + auto cap_it = find_if(capture_list_.begin(), + capture_list_.end(), + [_cap](const CaptureBaseConstWPtr &cap_ow) { - return cap_ow.lock() == _cap_other; + return cap_ow.lock() == _cap; }); - if (cap_it != capture_other_list_.end()) + if (cap_it != capture_list_.end()) return true; return false; } -bool FactorBase::hasFeatureOther(const FeatureBaseConstPtr &_ftr_other) const +bool FactorBase::hasLandmark(const LandmarkBaseConstPtr &_lmk) const { - auto ftr_it = find_if(feature_other_list_.begin(), - feature_other_list_.end(), - [_ftr_other](const FeatureBaseConstWPtr &ftr_ow) + auto lmk_it = find_if(landmark_list_.begin(), + landmark_list_.end(), + [_lmk](const LandmarkBaseConstWPtr &lmk_ow) { - return ftr_ow.lock() == _ftr_other; + return lmk_ow.lock() == _lmk; }); - if (ftr_it != feature_other_list_.end()) + if (lmk_it != landmark_list_.end()) return true; return false; } -bool FactorBase::hasLandmarkOther(const LandmarkBaseConstPtr &_lmk_other) const +bool FactorBase::hasSensor(const SensorBaseConstPtr& _sen) const { - auto lmk_it = find_if(landmark_other_list_.begin(), - landmark_other_list_.end(), - [_lmk_other](const LandmarkBaseConstWPtr &lmk_ow) + auto sen_it = find_if(sensor_list_.begin(), + sensor_list_.end(), + [_sen](const SensorBaseConstWPtr &sen_ow) { - return lmk_ow.lock() == _lmk_other; + return sen_ow.lock() == _sen; }); - if (lmk_it != landmark_other_list_.end()) + if (sen_it != sensor_list_.end()) return true; return false; @@ -272,31 +264,16 @@ void FactorBase::link(FeatureBasePtr _ftr_ptr) WOLF_WARN_COND(_ftr_ptr->getProblem() == nullptr, "ADDING FACTOR ", this->id(), " TO FEATURE ", _ftr_ptr->id(), " THAT IS NOT CONNECTED WITH PROBLEM."); this->setProblem(_ftr_ptr->getProblem()); - // constrained by - for (auto& frm_ow : frame_other_list_) + // constrained node_state_blocks + for (auto& node_w : node_state_blocks_list_) { - auto frame_other = frm_ow.lock(); - if(frame_other != nullptr) + auto node = node_w.lock(); + if(node != nullptr) { - assert(frame_other->getProblem() && "Forbidden: linking a factor with a floating frame_other."); - frame_other->addConstrainedBy(shared_from_this()); + assert(node->getProblem() && "Forbidden: linking a factor with a floating NodeStateBlocks."); + node->addFactor(shared_from_this()); } } - for (auto& cap_ow : capture_other_list_) - { - auto capture_other = cap_ow.lock(); - if(capture_other != nullptr) capture_other->addConstrainedBy(shared_from_this()); - } - for (auto& ftr_ow : feature_other_list_) - { - auto feature_other = ftr_ow.lock(); - if(feature_other != nullptr) feature_other->addConstrainedBy(shared_from_this()); - } - for (auto& lmk_ow : landmark_other_list_) - { - auto landmark_other = lmk_ow.lock(); - if(landmark_other != nullptr) landmark_other->addConstrainedBy(shared_from_this()); - } } void FactorBase::setProblem(ProblemPtr _problem) @@ -311,23 +288,16 @@ void FactorBase::setProblem(ProblemPtr _problem) void FactorBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const { - _stream << _tabs << "Fac" << id() << " " << getType() << (getStatus() == FAC_ACTIVE ? "" : " INACTIVE") << " -->"; - if ( getFrameOtherList() .empty() - && getCaptureOtherList() .empty() - && getFeatureOtherList() .empty() - && getLandmarkOtherList().empty()) - _stream << " Abs"; - - for (auto Fow : getFrameOtherList()) + _stream << _tabs << "Fac" << id() << " " << getType() << (getStatus() == FAC_ACTIVE ? "" : " INACTIVE") << " --> "; + _stream << topology_; + + for (auto Fow : getFrameList()) if (!Fow.expired()) _stream << " Frm" << Fow.lock()->id(); - for (auto Cow : getCaptureOtherList()) + for (auto Cow : getCaptureList()) if (!Cow.expired()) _stream << " Cap" << Cow.lock()->id(); - for (auto fow : getFeatureOtherList()) - if (!fow.expired()) - _stream << " Ftr" << fow.lock()->id(); - for (auto Low : getLandmarkOtherList()) + for (auto Low : getLandmarkList()) if (!Low.expired()) _stream << " Lmk" << Low.lock()->id(); _stream << std::endl; @@ -346,17 +316,8 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: if (_verbose) _stream << _tabs << "Fac" << id() << " @ " << _fac_ptr.get(); - if ( getFrameOtherList() .empty() - && getCaptureOtherList() .empty() - && getFeatureOtherList() .empty() - && getLandmarkOtherList().empty() ) // case ABSOLUTE: - { - if (_verbose) - _stream << " --> Abs."; - } - // find constrained_by pointer in constrained frame - for (auto Fow : getFrameOtherList()) + for (auto Fow : getFrameList()) { if (!Fow.expired()) { @@ -364,22 +325,22 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: if (_verbose) { _stream << " ( --> Frm" << Fo->id() << " <- "; - for (auto cby : Fo->getConstrainedByList()) + for (auto cby : Fo->getFactorList()) _stream << " Fac" << cby->id(); } // check constrained_by pointer in constrained frame - bool found = Fo->isConstrainedBy(_fac_ptr); + bool found = Fo->hasFactor(_fac_ptr); inconsistency_explanation << "The constrained Feature " << Fo->id() << " @ " << Fo << " not found among constrained-by factors\n"; log.assertTrue((found), inconsistency_explanation); } } - if (_verbose && !getFrameOtherList().empty()) + if (_verbose and not getFrameList().empty()) _stream << ")"; // find constrained_by pointer in constrained capture - for (auto Cow : getCaptureOtherList()) + for (auto Cow : getCaptureList()) { if (!Cow.expired()) { @@ -388,45 +349,22 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: if (_verbose) { _stream << " ( --> Cap" << Co->id() << " <- "; - for (auto cby : Co->getConstrainedByList()) + for (auto cby : Co->getFactorList()) _stream << " Fac" << cby->id(); } // check constrained_by pointer in constrained frame - bool found = Co->isConstrainedBy(_fac_ptr); + bool found = Co->hasFactor(_fac_ptr); inconsistency_explanation << "The constrained capture " << Co->id() << " @ " << Co << " not found among constrained-by factors\n"; log.assertTrue((found), inconsistency_explanation); } } - if (_verbose && !getCaptureOtherList().empty()) + if (_verbose and not getCaptureList().empty()) _stream << ")"; - // find constrained_by pointer in constrained feature - for (auto fow : getFeatureOtherList()) - { - if (!fow.expired()) - { - const auto& fo = fow.lock(); - if (_verbose) - { - _stream << " ( --> Ftr" << fo->id() << " <- "; - for (auto cby : fo->getConstrainedByList()) - _stream << " Fac" << cby->id(); - } - - // check constrained_by pointer in constrained feature - bool found = fo->isConstrainedBy(_fac_ptr); - inconsistency_explanation << "The constrained feature " << fo->id() << " @ " << fo - << " not found among constrained-by factors\n"; - log.assertTrue((found), inconsistency_explanation); - } - } - if (_verbose && !getFeatureOtherList().empty()) - _stream << ")"; - // find constrained_by pointer in constrained landmark - for (auto Low : getLandmarkOtherList()) + for (auto Low : getLandmarkList()) { if (Low.expired()) { @@ -435,19 +373,19 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: if (_verbose) { _stream << " ( --> Lmk" << Lo->id() << " <- "; - for (auto cby : Lo->getConstrainedByList()) + for (auto cby : Lo->getFactorList()) _stream << " Fac" << cby->id(); } // check constrained_by pointer in constrained landmark - bool found = Lo->isConstrainedBy(_fac_ptr); + bool found = Lo->hasFactor(_fac_ptr); inconsistency_explanation << "The constrained landmark " << Lo->id() << " @ " << Lo << " not found among constrained-by factors\n"; log.assertTrue((found), inconsistency_explanation); } } - if (_verbose && !getLandmarkOtherList().empty()) + if (_verbose and not getLandmarkList().empty()) _stream << ")"; if (_verbose) _stream << std::endl; @@ -520,9 +458,8 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: found = found || found_here; } - // find in constrained Frame - for (auto Fow : getFrameOtherList()) + for (auto Fow : getFrameList()) { if (!Fow.expired()) { @@ -543,7 +480,7 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: } // find in constrained Capture - for (auto Cow : getCaptureOtherList()) + for (auto Cow : getCaptureList()) { if (!Cow.expired()) { @@ -554,34 +491,8 @@ CheckLog FactorBase::localCheck(bool _verbose, FactorBaseConstPtr _fac_ptr, std: } } - // find in constrained Feature - for (auto fow : getFeatureOtherList()) - { - if (!fow.expired()) - { - const auto& fo = fow.lock(); - // find in constrained feature's Frame - auto foF = fo->getFrame(); - found_here = foF->hasStateBlock(sb); - if (found_here && _verbose) _stream << " FtrOF" << foF->id(); - found = found || found_here; - - // find in constrained feature's Capture - auto foC = fo->getCapture(); - found_here = foC->hasStateBlock(sb); - if (found_here && _verbose) _stream << " FtrOC" << foC->id(); - found = found || found_here; - - // find in constrained feature's Sensor - auto foS = fo->getCapture()->getSensor(); - found_here = foS->hasStateBlock(sb); - if (found_here && _verbose) _stream << " FtrOS" << foS->id(); - found = found || found_here; - } - } - // find in constrained landmark - for (auto Low : getLandmarkOtherList()) + for (auto Low : getLandmarkList()) { if (!Low.expired()) { diff --git a/src/feature/feature_base.cpp b/src/feature/feature_base.cpp index 777e9188ec11195cc4a6568c1b4cf44f5f7b2bac..2545e46e22ff86c73be987a65d7e656b94c761ec 100644 --- a/src/feature/feature_base.cpp +++ b/src/feature/feature_base.cpp @@ -53,41 +53,32 @@ FeatureBase::FeatureBase(const std::string& _type, const Eigen::VectorXd& _measu // std::cout << "constructed +f" << id() << std::endl; } -FeatureBase::~FeatureBase() -{ -// std::cout << "destructed -f" << id() << std::endl; -} - -void FeatureBase::remove(bool viral_remove_empty_parent) +void FeatureBase::remove(bool viral_remove_parent_without_children) { /* Order of removing: * Factors are removed first, and afterwards the rest of nodes containing state blocks. * In case multi-threading, solver can be called while removing. * This order avoids SolverManager to ignore notifications (efficiency) */ - if (!is_removing_) + if (is_removing_) + return; + + is_removing_ = true; + FeatureBasePtr this_f = shared_from_this(); // keep this alive while removing it + + // remove downstream + while (not factor_list_.empty()) + { + factor_list_.front()->remove(viral_remove_parent_without_children); // remove downstream + } + + // remove from upstream + CaptureBasePtr C = capture_ptr_.lock(); + if (C) { - is_removing_ = true; - FeatureBasePtr this_f = shared_from_this(); // keep this alive while removing it - - // remove downstream - while (!factor_list_.empty()) - { - factor_list_.front()->remove(viral_remove_empty_parent); // remove downstream - } - while (!constrained_by_list_.empty()) - { - constrained_by_list_.front()->remove(viral_remove_empty_parent); // remove constrained - } - - // remove from upstream - CaptureBasePtr C = capture_ptr_.lock(); - if (C) - { - C->removeFeature(this_f); // remove from upstream - if (viral_remove_empty_parent && C->getFeatureList().empty() && C->getConstrainedByList().empty()) - C->remove(viral_remove_empty_parent); // remove upstream - } + C->removeFeature(this_f); // remove from upstream + if (viral_remove_parent_without_children and not C->hasChildren()) + C->remove(viral_remove_parent_without_children); // remove upstream } } @@ -102,34 +93,6 @@ void FeatureBase::removeFactor(FactorBasePtr _co_ptr) factor_list_.remove(_co_ptr); } -FrameBaseConstPtr FeatureBase::getFrame() const -{ - return capture_ptr_.lock()->getFrame(); -} - -FrameBasePtr FeatureBase::getFrame() -{ - return capture_ptr_.lock()->getFrame(); -} - -FactorBasePtr FeatureBase::addConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.push_back(_fac_ptr); - return _fac_ptr; -} - -void FeatureBase::removeConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.remove(_fac_ptr); -} - -bool FeatureBase::isConstrainedBy(const FactorBaseConstPtr &_factor) const -{ - return std::find(constrained_by_list_.begin(), - constrained_by_list_.end(), - _factor) != constrained_by_list_.end(); -} - bool FeatureBase::hasFactor(FactorBaseConstPtr _factor) const { return std::find(factor_list_.begin(), @@ -139,8 +102,8 @@ bool FeatureBase::hasFactor(FactorBaseConstPtr _factor) const void FeatureBase::getFactorList(FactorBaseConstPtrList & _fac_list) const { - // FIXME? - _fac_list.insert(_fac_list.end(), factor_list_.begin(), factor_list_.end()); + for (auto&& obj_ptr : factor_list_) + _fac_list.push_back(obj_ptr); } void FeatureBase::getFactorList(FactorBasePtrList & _fac_list) @@ -148,6 +111,16 @@ void FeatureBase::getFactorList(FactorBasePtrList & _fac_list) _fac_list.insert(_fac_list.end(), factor_list_.begin(), factor_list_.end()); } +FrameBaseConstPtr FeatureBase::getFrame() const +{ + return capture_ptr_.lock()->getFrame(); +} + +FrameBasePtr FeatureBase::getFrame() +{ + return capture_ptr_.lock()->getFrame(); +} + void FeatureBase::setMeasurementCovariance(const Eigen::MatrixXd & _meas_cov) { WOLF_ASSERT_COVARIANCE_MATRIX(_meas_cov); @@ -178,13 +151,6 @@ void FeatureBase::setMeasurement(const Eigen::VectorXd& _meas) measurement_ = _meas; } -void FeatureBase::setProblem(ProblemPtr _problem) -{ - NodeBase::setProblem(_problem); - for (auto fac : factor_list_) - fac->setProblem(_problem); -} - void FeatureBase::link(CaptureBasePtr _cpt_ptr) { assert(!is_removing_ && "linking a removed feature"); @@ -203,15 +169,7 @@ void FeatureBase::link(CaptureBasePtr _cpt_ptr) } void FeatureBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const { - _stream << _tabs << "Ftr" << id() << " trk" << trackId() << " " << getType() << ((_depth < 4) ? " -- " + std::to_string(getFactorList().size()) + "fac " : ""); - if (_constr_by) - { - _stream << " <--\t"; - for (auto cby : getConstrainedByList()) - if (cby) - _stream << "Fac" << cby->id() << " \t"; - } - _stream << std::endl; + _stream << _tabs << "Ftr" << id() << " trk" << trackId() << " " << getType() << ((_depth < 4) ? " -- " + std::to_string(getFactorList().size()) + "fac " : "") << std::endl; if (_metric) _stream << _tabs << " " << "m = ( " << std::setprecision(2) << getMeasurement().transpose() << " )" << std::endl; @@ -221,10 +179,6 @@ void FeatureBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _s void FeatureBase::print(int _depth, bool _constr_by, bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const { printHeader(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs); - if (_depth >= 4) - for (auto c : getFactorList()) - if (c) - c->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } CheckLog FeatureBase::localCheck(bool _verbose, FeatureBaseConstPtr _ftr_ptr, std::ostream& _stream, std::string _tabs) const @@ -248,21 +202,21 @@ CheckLog FeatureBase::localCheck(bool _verbose, FeatureBaseConstPtr _ftr_ptr, st // check contrained_by - for (auto cby : getConstrainedByList()) - { - if (_verbose) - { - _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; - for (auto fow : cby->getFeatureOtherList()) - _stream << " Ftr" << fow.lock()->id(); - _stream << std::endl; - } - - // check constrained_by pointer to this feature - inconsistency_explanation << "constrained by Feature " << id() << " @ " << _ftr_ptr.get() - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasFeatureOther(_ftr_ptr)), inconsistency_explanation); - } + // for (auto cby : getConstrainedByList()) + // { + // if (_verbose) + // { + // _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + // for (auto fow : cby->getFeatureOtherList()) + // _stream << " Ftr" << fow.lock()->id(); + // _stream << std::endl; + // } + + // // check constrained_by pointer to this feature + // inconsistency_explanation << "constrained by Feature " << id() << " @ " << _ftr_ptr.get() + // << " not found among constrained-by factors\n"; + // log.assertTrue((cby->hasFeatureOther(_ftr_ptr)), inconsistency_explanation); + // } // Check capture auto cap_ftr = _ftr_ptr->getCapture(); @@ -274,13 +228,13 @@ CheckLog FeatureBase::localCheck(bool _verbose, FeatureBaseConstPtr _ftr_ptr, st log.assertTrue(frame_has_cap != cap_ftr_list.end(), inconsistency_explanation); // Check factors - for(auto fac : getFactorList()) - { - inconsistency_explanation << "Ftr" << id() << " @ " << _ftr_ptr - << " ---> Fac" << fac->id() << " @ " << fac - << " -X-> Ftr" << id(); - log.assertTrue((fac->getFeature() == _ftr_ptr), inconsistency_explanation); - } + // for(auto fac : getFactorList()) + // { + // inconsistency_explanation << "Ftr" << id() << " @ " << _ftr_ptr + // << " ---> Fac" << fac->id() << " @ " << fac + // << " -X-> Ftr" << id(); + // log.assertTrue((fac->getFeature() == _ftr_ptr), inconsistency_explanation); + // } return log; } @@ -290,7 +244,7 @@ bool FeatureBase::check(CheckLog& _log, NodeBaseConstPtr _node_ptr, bool _verbos auto local_log = localCheck(_verbose, ftr_ptr, _stream, _tabs); _log.compose(local_log); - for(auto f : getFactorList()) f->check(_log, f, _verbose, _stream, _tabs + " "); + // for(auto f : getFactorList()) f->check(_log, f, _verbose, _stream, _tabs + " "); return _log.is_consistent_; } diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp index 3a27fd90d3ad5cad30cc59e3a7609bdce6abbd95..6ff34d69b1f01651d11dd4993b01de1f4f308266 100644 --- a/src/frame/frame_base.cpp +++ b/src/frame/frame_base.cpp @@ -37,8 +37,7 @@ FrameBase::FrameBase(const TimeStamp& _ts, StateBlockPtr _p_ptr, StateBlockPtr _o_ptr, StateBlockPtr _v_ptr) : - NodeBase("FRAME", "FrameBase"), - HasStateBlocks(), + NodeStateBlocks("FRAME", "FrameBase"), trajectory_ptr_(), frame_id_(++frame_id_count_), time_stamp_(_ts) @@ -60,8 +59,7 @@ FrameBase::FrameBase(const TimeStamp& _ts, FrameBase::FrameBase(const TimeStamp& _ts, const SpecStateComposite& _frame_specs) : - NodeBase("FRAME", "FrameBase"), - HasStateBlocks(_frame_specs), + NodeStateBlocks("FRAME", "FrameBase",_frame_specs), trajectory_ptr_(), frame_id_(++frame_id_count_), time_stamp_(_ts) @@ -72,51 +70,46 @@ FrameBase::FrameBase(const TimeStamp& _ts, FrameBase::FrameBase(const TimeStamp& _ts, const TypeComposite& _frame_types, const VectorComposite& _frame_vectors) : - NodeBase("FRAME", "FrameBase"), - HasStateBlocks(_frame_types, _frame_vectors), + NodeStateBlocks("FRAME", "FrameBase",_frame_types, _frame_vectors), trajectory_ptr_(), frame_id_(++frame_id_count_), time_stamp_(_ts) { } - -FrameBase::~FrameBase() -{ -} - -void FrameBase::remove(bool viral_remove_empty_parent) +void FrameBase::remove(bool viral_remove_parent_without_children) { /* Order of removing: * Factors are removed first, and afterwards the rest of nodes containing state blocks. * In case multi-threading, solver can be called while removing. * This order avoids SolverManager to ignore notifications (efficiency) */ - if (!is_removing_) + if (is_removing_) + return; + + is_removing_ = true; + FrameBasePtr this_F = shared_from_this(); // keep this alive while removing it + + // remove downstream + while (!capture_list_.empty()) { - is_removing_ = true; - FrameBasePtr this_F = shared_from_this(); // keep this alive while removing it + capture_list_.front()->remove(viral_remove_parent_without_children); // remove downstream + } - // remove downstream - while (!constrained_by_list_.empty()) - { - constrained_by_list_.front()->remove(viral_remove_empty_parent); // remove constrained - } - while (!capture_list_.empty()) - { - capture_list_.front()->remove(viral_remove_empty_parent); // remove downstream - } + // remove from upstream + TrajectoryBasePtr T = trajectory_ptr_.lock(); + if (T) + { + T->removeFrame(this_F); // remove from upstream + } - // Remove Frame State Blocks - removeStateBlocks(getProblem()); + // Remove Frame State Blocks + NodeStateBlocks::remove(viral_remove_parent_without_children); +} - // remove from upstream - TrajectoryBasePtr T = trajectory_ptr_.lock(); - if (T) - { - T->removeFrame(this_F); // remove from upstream - } - } +bool FrameBase::hasChildren() const +{ + return NodeStateBlocks::hasChildren() or not capture_list_.empty(); } void FrameBase::setTimeStamp(const TimeStamp& _ts) @@ -130,11 +123,6 @@ void FrameBase::link(ProblemPtr _prb) this->link(_prb->getTrajectory()); } -bool FrameBase::getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const -{ - return getProblem()->getCovariance(shared_from_this(), _keys, _cov); -} - FrameBaseConstPtr FrameBase::getPreviousFrame(const unsigned int& i) const { assert(getTrajectory() != nullptr && "This Frame is not linked to any trajectory"); @@ -261,86 +249,6 @@ CaptureBasePtrList FrameBase::getCapturesOf(SensorBasePtr _sensor_ptr) return captures; } -FactorBaseConstPtr FrameBase::getFactorOf(ProcessorBaseConstPtr _processor_ptr, const std::string& type) const -{ - for (auto factor_ptr : getConstrainedByList()) - if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) - return factor_ptr; - - for (auto factor_ptr : getFactorList()) - if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) - return factor_ptr; - - return nullptr; -} - -FactorBasePtr FrameBase::getFactorOf(ProcessorBasePtr _processor_ptr, const std::string& type) -{ - for (auto factor_ptr : getConstrainedByList()) - if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) - return factor_ptr; - - for (auto factor_ptr : getFactorList()) - if (factor_ptr->getProcessor() == _processor_ptr && factor_ptr->getType() == type) - return factor_ptr; - - return nullptr; -} - -FactorBaseConstPtr FrameBase::getFactorOf(ProcessorBaseConstPtr _processor_ptr) const -{ - for (auto factor_ptr : getConstrainedByList()) - if (factor_ptr->getProcessor() == _processor_ptr) - return factor_ptr; - - for (auto factor_ptr : getFactorList()) - if (factor_ptr->getProcessor() == _processor_ptr) - return factor_ptr; - - return nullptr; -} - -FactorBasePtr FrameBase::getFactorOf(ProcessorBasePtr _processor_ptr) -{ - for (auto factor_ptr : getConstrainedByList()) - if (factor_ptr->getProcessor() == _processor_ptr) - return factor_ptr; - - for (auto factor_ptr : getFactorList()) - if (factor_ptr->getProcessor() == _processor_ptr) - return factor_ptr; - - return nullptr; -} - -FactorBaseConstPtrList FrameBase::getFactorList() const -{ - FactorBaseConstPtrList fac_list; - getFactorList(fac_list); - return fac_list; -} - -FactorBasePtrList FrameBase::getFactorList() -{ - FactorBasePtrList fac_list; - getFactorList(fac_list); - return fac_list; -} - -void FrameBase::getFactorList(FactorBaseConstPtrList& _fac_list) const -{ - for (auto c_ptr : getCaptureList()) - if (not c_ptr->isRemoving()) - c_ptr->getFactorList(_fac_list); -} - -void FrameBase::getFactorList(FactorBasePtrList& _fac_list) -{ - for (auto c_ptr : getCaptureList()) - if (not c_ptr->isRemoving()) - c_ptr->getFactorList(_fac_list); -} - bool FrameBase::hasCapture(const CaptureBaseConstPtr& _capture) const { return std::find(capture_list_.begin(), @@ -348,24 +256,6 @@ bool FrameBase::hasCapture(const CaptureBaseConstPtr& _capture) const _capture) != capture_list_.end(); } -FactorBasePtr FrameBase::addConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.push_back(_fac_ptr); - return _fac_ptr; -} - -void FrameBase::removeConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.remove(_fac_ptr); -} - -bool FrameBase::isConstrainedBy(const FactorBaseConstPtr &_factor) const -{ - return std::find(constrained_by_list_.begin(), - constrained_by_list_.end(), - _factor) != constrained_by_list_.end(); -} - void FrameBase::link(TrajectoryBasePtr _trj_ptr) { assert(!is_removing_ && "linking a removed frame"); @@ -388,8 +278,7 @@ void FrameBase::setProblem(ProblemPtr _problem) if (_problem == nullptr || _problem == this->getProblem()) return; - NodeBase::setProblem(_problem); - registerNewStateBlocks(_problem); + NodeStateBlocks::setProblem(_problem); for (auto cap : capture_list_) cap->setProblem(_problem); @@ -401,13 +290,13 @@ void FrameBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _sta << " " << getKeys() << " ts = " << std::setprecision(3) << getTimeStamp() << ((_depth < 2) ? " -- " + std::to_string(getCaptureList().size()) + "C " : ""); - if (_constr_by) - { - _stream << " <-- "; - for (auto cby : getConstrainedByList()) - if (cby) - _stream << "Fac" << cby->id() << " \t"; - } + // if (_constr_by) + // { + // _stream << " <-- "; + // for (auto cby : getConstrainedByList()) + // if (cby) + // _stream << "Fac" << cby->id() << " \t"; + // } _stream << std::endl; printState(_metric, _state_blocks, _stream, _tabs); @@ -463,34 +352,34 @@ CheckLog FrameBase::localCheck(bool _verbose, FrameBaseConstPtr _frm_ptr, std::o log.assertTrue((getProblem() == trajectory_problem_ptr), inconsistency_explanation); // check constrained_by - for (auto cby : getConstrainedByList()) - { - if (_verbose) - { - _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; - for (auto Fow : cby->getFrameOtherList()) - _stream << " Frm" << Fow.lock()->id() << std::endl; - - - // check constrained_by pointer to this frame - inconsistency_explanation << "constrained-by frame " << id() << " @ " << _frm_ptr - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasFrameOther(_frm_ptr)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) - { - if (_verbose) { - _stream << _tabs << " " << "sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - } - } + // for (auto cby : getConstrainedByList()) + // { + // if (_verbose) + // { + // _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + // for (auto Fow : cby->getFrameOtherList()) + // _stream << " Frm" << Fow.lock()->id() << std::endl; + + + // // check constrained_by pointer to this frame + // inconsistency_explanation << "constrained-by frame " << id() << " @ " << _frm_ptr + // << " not found among constrained-by factors\n"; + // log.assertTrue((cby->hasFrameOther(_frm_ptr)), inconsistency_explanation); + + // for (auto sb : cby->getStateBlockPtrVector()) + // { + // if (_verbose) { + // _stream << _tabs << " " << "sb @ " << sb.get(); + // if (sb) { + // auto lp = sb->getLocalParametrization(); + // if (lp) + // _stream << " (lp @ " << lp.get() << ")"; + // } + // _stream << std::endl; + // } + // } + // } + // } // Trajectory auto trj_ptr = getTrajectory(); diff --git a/src/landmark/landmark_base.cpp b/src/landmark/landmark_base.cpp index eaa9373b1efce14ed4e44f5e8b27f6cdf3c5c387..cfbe6ccc9a8996589d9193e97a711a5c40b48456 100644 --- a/src/landmark/landmark_base.cpp +++ b/src/landmark/landmark_base.cpp @@ -35,8 +35,7 @@ namespace wolf { unsigned int LandmarkBase::landmark_id_count_ = 0; LandmarkBase::LandmarkBase(const std::string& _type, StateBlockPtr _p_ptr, StateBlockPtr _o_ptr) : - NodeBase("LANDMARK", _type), - HasStateBlocks(), + NodeStateBlocks("LANDMARK", _type), map_ptr_(), landmark_id_(++landmark_id_count_) { @@ -52,57 +51,39 @@ LandmarkBase::LandmarkBase(const std::string& _type, StateBlockPtr _p_ptr, State } LandmarkBase::LandmarkBase(const std::string& _type, const YAML::Node& _n) : - NodeBase("LANDMARK", _type), - HasStateBlocks(SpecStateComposite(_n["states"])), + NodeStateBlocks("LANDMARK", _type), map_ptr_(), landmark_id_(_n["id"].as<int>()) { } LandmarkBase::LandmarkBase(const YAML::Node& _n) : - NodeBase("LANDMARK", "LandmarkBase"), - HasStateBlocks(SpecStateComposite(_n["states"])), + NodeStateBlocks("LANDMARK", _n["type"].as<std::string>(), SpecStateComposite(_n["states"])), map_ptr_(), landmark_id_(_n["id"].as<int>()) { } -LandmarkBase::~LandmarkBase() -{ - removeStateBlocks(getProblem()); -} - -void LandmarkBase::remove(bool viral_remove_empty_parent) +void LandmarkBase::remove(bool viral_remove_parent_without_children) { /* Order of removing: * Factors are removed first, and afterwards the rest of nodes containing state blocks. * In case multi-threading, solver can be called while removing. * This order avoids SolverManager to ignore notifications (efficiency) */ - if (!is_removing_) - { - is_removing_ = true; - LandmarkBasePtr this_L = shared_from_this(); // keep this alive while removing it + if (not is_removing_) + return; - // remove constrained by - while (!constrained_by_list_.empty()) - { - constrained_by_list_.front()->remove(viral_remove_empty_parent); - } + is_removing_ = true; + LandmarkBasePtr this_L = shared_from_this(); // keep this alive while removing it - // Remove State Blocks - removeStateBlocks(getProblem()); + // remove from upstream + auto M = map_ptr_.lock(); + if (M) + M->removeLandmark(this_L); - // remove from upstream - auto M = map_ptr_.lock(); - if (M) - M->removeLandmark(this_L); - } -} - -bool LandmarkBase::getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const -{ - return getProblem()->getCovariance(shared_from_this(), _keys,_cov); + // Remove State Blocks + NodeStateBlocks::remove(viral_remove_parent_without_children); } YAML::Node LandmarkBase::toYaml() const @@ -110,7 +91,7 @@ YAML::Node LandmarkBase::toYaml() const YAML::Node node; node["id"] = landmark_id_; node["type"] = node_type_; - node["states"] = HasStateBlocks::getSpecs().toYaml(); + node["states"] = NodeStateBlocks::getSpecs().toYaml(); node["transformable"] = getP()->isTransformable(); return node; } @@ -137,38 +118,19 @@ void LandmarkBase::setProblem(ProblemPtr _problem) if (_problem == nullptr || _problem == this->getProblem()) return; - NodeBase::setProblem(_problem); - registerNewStateBlocks(_problem); -} - -FactorBasePtr LandmarkBase::addConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.push_back(_fac_ptr); - return _fac_ptr; -} - -void LandmarkBase::removeConstrainedBy(FactorBasePtr _fac_ptr) -{ - constrained_by_list_.remove(_fac_ptr); -} - -bool LandmarkBase::isConstrainedBy(const FactorBaseConstPtr &_factor) const -{ - return std::find(constrained_by_list_.begin(), - constrained_by_list_.end(), - _factor) != constrained_by_list_.end(); + NodeStateBlocks::setProblem(_problem); } void LandmarkBase::printHeader(int _depth, bool _constr_by, bool _metric, bool _state_blocks, std::ostream& _stream, std::string _tabs) const { _stream << _tabs << "Lmk" << id() << " " << getType(); - if (_constr_by) - { - _stream << "\t<-- "; - for (auto cby : getConstrainedByList()) - if (cby) - _stream << "Fac" << cby->id() << " \t"; - } + // if (_constr_by) + // { + // _stream << "\t<-- "; + // for (auto cby : getConstrainedByList()) + // if (cby) + // _stream << "Fac" << cby->id() << " \t"; + // } _stream << std::endl; printState(_metric, _state_blocks, _stream, _tabs); @@ -212,39 +174,39 @@ CheckLog LandmarkBase::localCheck(bool _verbose, LandmarkBaseConstPtr _lmk_ptr, log.assertTrue((getProblem() == map_ptr->getProblem()), inconsistency_explanation); // check constrained-by factors - for (auto cby : getConstrainedByList()) - { - if (_verbose) - { - _stream << _tabs << " " << "<- Fac" << cby->id() << " ->"; - - for (auto Low : cby->getLandmarkOtherList()) - { - if (!Low.expired()) - { - auto Lo = Low.lock(); - _stream << " Lmk" << Lo->id(); - } - } - _stream << std::endl; - } - - inconsistency_explanation << "constrained-by landmark " << id() << " @ " << _lmk_ptr.get() - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasLandmarkOther(_lmk_ptr)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) { - if (_verbose) { - _stream << _tabs << " " << "sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - } + // for (auto cby : getConstrainedByList()) + // { + // if (_verbose) + // { + // _stream << _tabs << " " << "<- Fac" << cby->id() << " ->"; + + // for (auto Low : cby->getLandmarkOtherList()) + // { + // if (!Low.expired()) + // { + // auto Lo = Low.lock(); + // _stream << " Lmk" << Lo->id(); + // } + // } + // _stream << std::endl; + // } + + // inconsistency_explanation << "constrained-by landmark " << id() << " @ " << _lmk_ptr.get() + // << " not found among constrained-by factors\n"; + // log.assertTrue((cby->hasLandmarkOther(_lmk_ptr)), inconsistency_explanation); + + // for (auto sb : cby->getStateBlockPtrVector()) { + // if (_verbose) { + // _stream << _tabs << " " << "sb @ " << sb.get(); + // if (sb) { + // auto lp = sb->getLocalParametrization(); + // if (lp) + // _stream << " (lp @ " << lp.get() << ")"; + // } + // _stream << std::endl; + // } + // } + // } // check map inconsistency_explanation << "Lmk" << id() << " @ " << _lmk_ptr diff --git a/src/map/map_base.cpp b/src/map/map_base.cpp index 616b9eaa4404cbd9be34806e20509d9ace328486..c90a7fb3e9c2a81453439914722f37e8377f71d0 100644 --- a/src/map/map_base.cpp +++ b/src/map/map_base.cpp @@ -49,9 +49,9 @@ MapBase::MapBase(ParamsMapBasePtr _params, const std::string& _type) : // std::cout << "constructed M"<< std::endl; } -MapBase::~MapBase() +bool MapBase::hasChildren() const { -// std::cout << "destructed -M" << std::endl; + return not landmark_list_.empty(); } LandmarkBasePtr MapBase::addLandmark(LandmarkBasePtr _landmark_ptr) diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp index 953748504650a14f91ec12577a454c368cc5a826..f5f205d073b4ee665eb8ebb20ada136b9552958f 100644 --- a/src/problem/problem.cpp +++ b/src/problem/problem.cpp @@ -1008,7 +1008,7 @@ bool Problem::getCovarianceBlock(StateBlockConstPtr _state, Eigen::MatrixXd& _co return getCovarianceBlock(_state, _state, _cov, _row_and_col, _row_and_col); } -bool Problem::getCovariance(HasStateBlocksConstPtr _has_blocks, const StateKeys& _keys, Eigen::MatrixXd& _covariance) const +bool Problem::getCovariance(NodeStateBlocksConstPtr _has_blocks, const StateKeys& _keys, Eigen::MatrixXd& _covariance) const { if (not _has_blocks) { diff --git a/src/sensor/sensor_base.cpp b/src/sensor/sensor_base.cpp index 483c29fd4a9721a7263ec030093874151b6a5de8..3ecc6ffc9f94682113b575110f82ad92894dc999 100644 --- a/src/sensor/sensor_base.cpp +++ b/src/sensor/sensor_base.cpp @@ -35,8 +35,7 @@ SensorBase::SensorBase(const std::string& _type, const int& _dim, ParamsSensorBasePtr _params, const SpecStateSensorComposite& _priors) : - NodeBase("SENSOR", _type, _params->name), - HasStateBlocks(), + NodeStateBlocks("SENSOR", _type), hardware_ptr_(), sensor_id_(++sensor_id_count_), // simple ID factory params_(_params), @@ -45,6 +44,8 @@ SensorBase::SensorBase(const std::string& _type, last_capture_(nullptr), dim_(_dim) { + setName(_params->name); + // Iterate all keys in _priors for (auto state_pair : _priors) { @@ -78,7 +79,7 @@ SensorBase::SensorBase(const std::string& _type, SensorBase::~SensorBase() { // Remove State Blocks - removeStateBlocks(getProblem()); + NodeStateBlocks::remove(); } void SensorBase::fixExtrinsics() @@ -199,21 +200,6 @@ void SensorBase::addPriorParameter(const char& _key, const Eigen::VectorXd& _x, features_prior_map_[_key] = ftr_prior; } -void SensorBase::registerNewStateBlocks(ProblemPtr _problem) -{ - if (_problem != nullptr) - { - for (auto & pair_key_sbp : getStateBlockMap()) - { - auto key = pair_key_sbp.first; - auto sbp = pair_key_sbp.second; - - if (sbp and not isStateBlockDynamic(key)) - _problem->notifyStateBlock(sbp, ADD); - } - } -} - void SensorBase::setDriftStd(char _key, const Eigen::VectorXd & _drift_rate_std) { drift_covs_[_key] = _drift_rate_std.cwiseAbs2().asDiagonal(); @@ -365,11 +351,6 @@ StateBlockPtr SensorBase::getIntrinsic() return getStateBlockDynamic('I'); } -bool SensorBase::getCovariance(const StateKeys& _keys, Eigen::MatrixXd& _cov) const -{ - return getProblem()->getCovariance(shared_from_this(), _keys, _cov); -} - bool SensorBase::process(const CaptureBasePtr capture_ptr) { capture_ptr->setSensor(shared_from_this()); @@ -512,11 +493,9 @@ bool SensorBase::isStateBlockInCapture(const char& _key, const TimeStamp& _ts) c void SensorBase::setProblem(ProblemPtr _problem) { - NodeBase::setProblem(_problem); + NodeStateBlocks::setProblem(_problem); for (auto prc : processor_list_) prc->setProblem(_problem); - for(auto ftr_prior : features_prior_map_) - ftr_prior.second->setProblem(_problem); } void SensorBase::link(HardwareBasePtr _hw_ptr) @@ -528,7 +507,6 @@ void SensorBase::link(HardwareBasePtr _hw_ptr) this->setHardware(_hw_ptr); this->getHardware()->addSensor(shared_from_this()); this->setProblem(_hw_ptr->getProblem()); - this->registerNewStateBlocks(getProblem()); } else { diff --git a/src/tree_manager/tree_manager_sliding_window.cpp b/src/tree_manager/tree_manager_sliding_window.cpp index e7cdbb8fbbe5a3d490a3cff1c015b55c0c2fc2f1..4850cb84d944adcb853defa363660c8b594d8a67 100644 --- a/src/tree_manager/tree_manager_sliding_window.cpp +++ b/src/tree_manager/tree_manager_sliding_window.cpp @@ -55,7 +55,7 @@ void TreeManagerSlidingWindow::keyFrameCallback(FrameBasePtr _frame) if (remove_first) { WOLF_DEBUG("TreeManagerSlidingWindow removing first frame"); - getProblem()->getTrajectory()->getFirstFrame()->remove(params_sw_->viral_remove_empty_parent); + getProblem()->getTrajectory()->getFirstFrame()->remove(params_sw_->viral_remove_parent_without_children); } } diff --git a/src/tree_manager/tree_manager_sliding_window_dual_rate.cpp b/src/tree_manager/tree_manager_sliding_window_dual_rate.cpp index 6ec268ddbc1d353617de5b867dcdd0ff5f39f87a..4023e1e631e1e98935fee6dec2aec2b0d5505612 100644 --- a/src/tree_manager/tree_manager_sliding_window_dual_rate.cpp +++ b/src/tree_manager/tree_manager_sliding_window_dual_rate.cpp @@ -75,7 +75,7 @@ void TreeManagerSlidingWindowDualRate::keyFrameCallback(FrameBasePtr _frame) } // remove frame - remove_recent_frame->remove(params_swdr_->viral_remove_empty_parent); + remove_recent_frame->remove(params_swdr_->viral_remove_parent_without_children); } // Call tree manager sliding window // It will remove oldest frame if tfirst recent frame has been kept diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml index 1f24d9b0325f1ab8237ce0003f2a91a0bb3b959f..cc8f5a612c61551b9642ab6c6a4bbe0debd2426c 100644 --- a/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml +++ b/test/yaml/params_tree_manager_sliding_window_dual_rate2.yaml @@ -17,7 +17,7 @@ problem: n_frames_recent: 3 rate_old_frames: 2 n_fix_first_frames: 0 - viral_remove_empty_parent: false + viral_remove_parent_without_children: false sensors: - type: "SensorOdom3d" diff --git a/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml b/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml index f69fece0398f4b9f9b4d651828a29abcf26c8ad3..9bea8c5c4fbed78d978368fea3e5ac1776e7c200 100644 --- a/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml +++ b/test/yaml/params_tree_manager_sliding_window_dual_rate3.yaml @@ -19,7 +19,7 @@ problem: n_frames_recent: 3 rate_old_frames: 2 n_fix_first_frames: 2 - viral_remove_empty_parent: true + viral_remove_parent_without_children: true sensors: - type: "SensorOdom3d" diff --git a/test/yaml/tree_manager_sliding_window1.yaml b/test/yaml/tree_manager_sliding_window1.yaml index 48234b6c892ef024b87a19cefbe7c071ba895f33..a18d33a5a18f69827a48465e769aa38e018a7844 100644 --- a/test/yaml/tree_manager_sliding_window1.yaml +++ b/test/yaml/tree_manager_sliding_window1.yaml @@ -2,4 +2,4 @@ type: "TreeManagerSlidingWindow" plugin: "core" n_frames: 3 n_fix_first_frames: 2 -viral_remove_empty_parent: true +viral_remove_parent_without_children: true diff --git a/test/yaml/tree_manager_sliding_window2.yaml b/test/yaml/tree_manager_sliding_window2.yaml index 7f074d9e42a8f235b1620e4b6a851b54a3071a8c..bd21b0bdc6ff510c0b8ad34498eb7a9efdb0a488 100644 --- a/test/yaml/tree_manager_sliding_window2.yaml +++ b/test/yaml/tree_manager_sliding_window2.yaml @@ -2,4 +2,4 @@ type: "TreeManagerSlidingWindow" plugin: "core" n_frames: 3 n_fix_first_frames: 0 -viral_remove_empty_parent: false \ No newline at end of file +viral_remove_parent_without_children: false \ No newline at end of file diff --git a/test/yaml/tree_manager_sliding_window_dual_rate1.yaml b/test/yaml/tree_manager_sliding_window_dual_rate1.yaml index d18a4fb29a0259425c7c6ed62aad178dfa156a8f..3a69a9206e0a6d4740bbc0254bfe3fc12c3a1800 100644 --- a/test/yaml/tree_manager_sliding_window_dual_rate1.yaml +++ b/test/yaml/tree_manager_sliding_window_dual_rate1.yaml @@ -4,4 +4,4 @@ n_frames: 5 n_frames_recent: 3 rate_old_frames: 2 n_fix_first_frames: 2 -viral_remove_empty_parent: true +viral_remove_parent_without_children: true