diff --git a/include/core/capture/capture_base.h b/include/core/capture/capture_base.h index 7eb1a10b19fe6ffcc169468c6feb69dd33aed69c..8811ed06d459893a6b738812361f008e0a30efa2 100644 --- a/include/core/capture/capture_base.h +++ b/include/core/capture/capture_base.h @@ -116,6 +116,9 @@ class CaptureBase : public NodeBase, public HasStateBlocks, public std::enable_s std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, CaptureBasePtr _cap_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + protected: virtual SizeEigen computeCalibSize() const; diff --git a/include/core/common/node_base.h b/include/core/common/node_base.h index 2a6120408718df85ebb2945c9800d71b0060b6fd..dcd7d37176c2eb4c36aea7c8b342aa064b43a896 100644 --- a/include/core/common/node_base.h +++ b/include/core/common/node_base.h @@ -3,6 +3,7 @@ // Wolf includes #include "core/common/wolf.h" +#include "core/utils/check_log.h" namespace wolf { diff --git a/include/core/factor/factor_base.h b/include/core/factor/factor_base.h index aa0164605fc80ddd0b48915a3b75e6c69c6a1b8b..6436100b70dc72d24e5332c693792ae11f567330 100644 --- a/include/core/factor/factor_base.h +++ b/include/core/factor/factor_base.h @@ -220,6 +220,9 @@ class FactorBase : public NodeBase, public std::enable_shared_from_this<FactorBa std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, FactorBasePtr _fac_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + private: void setFeature(const FeatureBasePtr _ft_ptr){feature_ptr_ = _ft_ptr;} diff --git a/include/core/feature/feature_base.h b/include/core/feature/feature_base.h index 83e343c0c3f25aaeb0219289e143bfa8f7733fae..da1f68b8400cb94f87d1cc5ee460fbf8440b7bee 100644 --- a/include/core/feature/feature_base.h +++ b/include/core/feature/feature_base.h @@ -119,6 +119,9 @@ class FeatureBase : public NodeBase, public std::enable_shared_from_this<Feature std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, FeatureBasePtr _feature_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + private: void setCapture(CaptureBasePtr _cap_ptr){capture_ptr_ = _cap_ptr;} FactorBasePtr addFactor(FactorBasePtr _co_ptr); diff --git a/include/core/frame/frame_base.h b/include/core/frame/frame_base.h index 32b582b04f15da321b6dd7710fda60ac9e882cac..e43dd50dc7e0161bbe16830e760145a914c277fa 100644 --- a/include/core/frame/frame_base.h +++ b/include/core/frame/frame_base.h @@ -144,6 +144,10 @@ class FrameBase : public NodeBase, public HasStateBlocks, public std::enable_sha bool state_blocks, std::ostream& stream = std::cout, std::string _tabs = "") const; + + virtual CheckLog localCheck(bool _verbose, FrameBasePtr _frm_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + private: CaptureBasePtr addCapture(CaptureBasePtr _capt_ptr); diff --git a/include/core/hardware/hardware_base.h b/include/core/hardware/hardware_base.h index 3c29221acb417b3d0e13fb764207e2ae05e67190..fba575b0b8ea55a15b8bbe4972d0bc12984ae62b 100644 --- a/include/core/hardware/hardware_base.h +++ b/include/core/hardware/hardware_base.h @@ -40,6 +40,9 @@ class HardwareBase : public NodeBase, public std::enable_shared_from_this<Hardwa std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, HardwareBasePtr _hwd_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + private: virtual SensorBasePtr addSensor(SensorBasePtr _sensor_ptr); }; diff --git a/include/core/landmark/landmark_base.h b/include/core/landmark/landmark_base.h index 15b423c3b398230697f066fead211569ee1a36d2..3d177d79c972b1e072fb86d5d7790e686cd387ff 100644 --- a/include/core/landmark/landmark_base.h +++ b/include/core/landmark/landmark_base.h @@ -99,6 +99,9 @@ class LandmarkBase : public NodeBase, public HasStateBlocks, public std::enable_ std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, LandmarkBasePtr _lmk_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; + private: void setMap(const MapBasePtr _map_ptr); diff --git a/include/core/map/map_base.h b/include/core/map/map_base.h index 75a00a97c1a7026e51604ecca877f5b0e639f056..e609298014d8b68ca9e686a877ea80b041b34214 100644 --- a/include/core/map/map_base.h +++ b/include/core/map/map_base.h @@ -50,6 +50,9 @@ class MapBase : public NodeBase, public std::enable_shared_from_this<MapBase> bool state_blocks, std::ostream& stream = std::cout, std::string _tabs = "") const; + + virtual CheckLog localCheck(bool _verbose, MapBasePtr _map_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; private: std::string dateTimeNow(); }; diff --git a/include/core/processor/processor_base.h b/include/core/processor/processor_base.h index b12d92f10a430810150040fe9277346d2f63c620..4182e762db050a3f36e714d453b73fb63568f5bc 100644 --- a/include/core/processor/processor_base.h +++ b/include/core/processor/processor_base.h @@ -377,6 +377,9 @@ class ProcessorBase : public NodeBase, public std::enable_shared_from_this<Proce bool state_blocks, std::ostream& stream = std::cout, std::string _tabs = "") const; + + virtual CheckLog localCheck(bool _verbose, ProcessorBasePtr _prc_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; }; inline bool ProcessorBase::isVotingActive() const diff --git a/include/core/sensor/sensor_base.h b/include/core/sensor/sensor_base.h index 2bf9d2bbc902622e984a88471b62782115088fec..e1be8095b90f395477ea72ed0302520fb0ae4bbb 100644 --- a/include/core/sensor/sensor_base.h +++ b/include/core/sensor/sensor_base.h @@ -255,6 +255,8 @@ class SensorBase : public NodeBase, public HasStateBlocks, public std::enable_sh std::ostream& stream = std::cout, std::string _tabs = "") const; + virtual CheckLog localCheck(bool _verbose, SensorBasePtr _sen_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; void link(HardwareBasePtr); template<typename classType, typename... T> diff --git a/include/core/trajectory/trajectory_base.h b/include/core/trajectory/trajectory_base.h index 8d6e69e41d741bd70bdc6e212df2490ecbc4b62c..f2153401cea96f3af77f360a55453200c16a7877 100644 --- a/include/core/trajectory/trajectory_base.h +++ b/include/core/trajectory/trajectory_base.h @@ -59,6 +59,9 @@ class TrajectoryBase : public NodeBase, public std::enable_shared_from_this<Traj bool state_blocks, std::ostream& stream = std::cout, std::string _tabs = "") const; + + virtual CheckLog localCheck(bool _verbose, TrajectoryBasePtr _trj_ptr, std::ostream& _stream, std::string _tabs = "") const; + bool check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs = "") const; private: FrameBasePtr addFrame(FrameBasePtr _frame_ptr); void removeFrame(FrameBasePtr _frame_ptr); diff --git a/src/capture/capture_base.cpp b/src/capture/capture_base.cpp index 65a78728260a755e3b9ddbc370d7d8bc623a3160..79c40b7604f4edbfb5c0cae8605493e63eada692 100644 --- a/src/capture/capture_base.cpp +++ b/src/capture/capture_base.cpp @@ -344,4 +344,105 @@ void CaptureBase::print(int _depth, bool _constr_by, bool _metric, bool _state_b for (auto f : getFeatureList()) f->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog CaptureBase::localCheck(bool _verbose, CaptureBasePtr _cap_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) + { + _stream << _tabs << "Cap" << id() << " @ " << _cap_ptr.get() << " -> Sen"; + if (getSensor()) _stream << getSensor()->id(); + else _stream << "-"; + _stream << std::endl; + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Frm" << getFrame()->id() << " @ " << getFrame().get() << std::endl; + } + for (auto pair: getStateBlockMap()) + { + auto sb = pair.second; + + // check for valid state block + inconsistency_explanation << "Capture " << id() << " @ " << _cap_ptr.get() << " has State block pointer " + << sb.get() << " = 0 \n"; + log.assertTrue((sb.get() != 0), inconsistency_explanation); + + if (_verbose) + { + _stream << _tabs << " " << pair.first << " sb @ " << sb.get(); + if (sb) { + auto lp = sb->getLocalParametrization(); + if (lp) + _stream << " (lp @ " << lp.get() << ")"; + } + _stream << std::endl; + } + } + + auto frm_ptr = getFrame(); + // check problem and frame pointers + inconsistency_explanation << "Capture problem pointer " << getProblem().get() + << " different from frame problem pointer " << frm_ptr->getProblem().get() << "\n"; + log.assertTrue((getProblem() == frm_ptr->getProblem()), inconsistency_explanation); + + + // check contrained_by + for (const auto& cby : getConstrainedByList()) + { + if (_verbose) + { + _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + for (const 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; + } + } + } + + auto frm_cap = _cap_ptr->getFrame(); + inconsistency_explanation << "Cap" << id() << " @ " << _cap_ptr + << " ---> Frm" << frm_cap->id() << " @ " << frm_cap + << " -X-> Frm" << id(); + auto frm_cap_list = frm_cap->getCaptureList(); + auto frame_has_cap = std::find_if(frm_cap_list.begin(), frm_cap_list.end(), [&_cap_ptr](CaptureBasePtr cap){ return cap == _cap_ptr;}); + log.assertTrue(frame_has_cap != frm_cap_list.end(), inconsistency_explanation); + + for(auto f : getFeatureList()) + { + inconsistency_explanation << "Cap " << id() << " @ " << _cap_ptr + << " ---> Ftr" << f->id() << " @ " << f + << " -X-> Cap" << id(); + log.assertTrue((f->getCapture() == _cap_ptr), inconsistency_explanation); + } + return log; +} +bool CaptureBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto sen_ptr = std::static_pointer_cast<CaptureBase>(_node_ptr); + auto local_log = localCheck(_verbose, sen_ptr, _stream, _tabs); + _log.compose(local_log); + + for(auto f : getFeatureList()) f->check(_log, f, _verbose, _stream, _tabs + " "); + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/factor/factor_base.cpp b/src/factor/factor_base.cpp index ee45aa68570db221c37b2d686c26aab948d6f40e..f85054ef85efb67e019d1720fb5c364b1774a4fc 100644 --- a/src/factor/factor_base.cpp +++ b/src/factor/factor_base.cpp @@ -336,4 +336,284 @@ void FactorBase::print(int _depth, bool _constr_by, bool _metric, bool _state_bl { printHeader(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs); } + +CheckLog FactorBase::localCheck(bool _verbose, FactorBasePtr _fac_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + 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 (const auto& Fow : getFrameOtherList()) + { + if (!Fow.expired()) + { + const auto& Fo = Fow.lock(); + if (_verbose) + { + _stream << " ( --> Frm" << Fo->id() << " <- "; + for (auto cby : Fo->getConstrainedByList()) + _stream << " Fac" << cby->id(); + } + + // check constrained_by pointer in constrained frame + 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 && !getFrameOtherList().empty()) + _stream << ")"; + // find constrained_by pointer in constrained capture + for (const auto& Cow : getCaptureOtherList()) + { + if (!Cow.expired()) + { + const auto& Co = Cow.lock(); + + if (_verbose) + { + _stream << " ( --> Cap" << Co->id() << " <- "; + for (auto cby : Co->getConstrainedByList()) + _stream << " Fac" << cby->id(); + } + + // check constrained_by pointer in constrained frame + bool found = Co->isConstrainedBy(_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()) + _stream << ")"; + // find constrained_by pointer in constrained feature + for (const 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 (const auto& Low : getLandmarkOtherList()) + { + if (Low.expired()) + { + const auto& Lo = Low.lock(); + + if (_verbose) + { + _stream << " ( --> Lmk" << Lo->id() << " <- "; + for (auto cby : Lo->getConstrainedByList()) + _stream << " Fac" << cby->id(); + } + + // check constrained_by pointer in constrained landmark + bool found = Lo->isConstrainedBy(_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()) + _stream << ")"; + if (_verbose) + _stream << std::endl; + //Check Problem and feature ptrs + if (_verbose) + { + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Ftr" << getFeature()->id() << " @ " << getFeature().get() << std::endl; + } + auto ftr_ptr = getFeature(); + // check problem and feature pointers + inconsistency_explanation << "The factor " << id() << " @ " << _fac_ptr.get() << " problem ptr " << getProblem().get() + << " is different from Feature's problem ptr " << ftr_ptr->getProblem().get() << "\n"; + log.assertTrue((getProblem() == ftr_ptr->getProblem()), inconsistency_explanation); + + + inconsistency_explanation << "Fac" << id() << " @ " << _fac_ptr + << " ---> Ftr" << ftr_ptr->id() << " @ " << ftr_ptr + << " -X-> Fac" << id(); + auto ftr_fac_list = ftr_ptr->getFactorList(); + auto ftr_has_fac = std::find_if(ftr_fac_list.begin(), ftr_fac_list.end(), [&_fac_ptr](FactorBasePtr fac){ return fac == _fac_ptr;}); + log.assertTrue(ftr_has_fac!= ftr_fac_list.end(), inconsistency_explanation); + + // find state block pointers in all constrained nodes + SensorBasePtr S = getSensor(); // get own sensor to check sb + FrameBasePtr F = getFrame(); + CaptureBasePtr C = getCapture(); + + for (auto sb : getStateBlockPtrVector()) + { + bool found = false; + if (_verbose) + { + _stream << _tabs << " " << "sb @ " << sb.get(); + if (sb) + { + auto lp = sb->getLocalParametrization(); + if (lp) + _stream << " (lp @ " << lp.get() << ")"; + } + } + bool found_here; + + // find in own Frame + found_here = F->hasStateBlock(sb); + if (found_here && _verbose) _stream << " Frm" << F->id(); + found = found || found_here; + + // find in own Capture + found_here = C->hasStateBlock(sb); + if (found_here && _verbose) _stream << " Cap" << C->id(); + found = found || found_here; + + // Find in other Captures of the own Frame + if (!found_here) + for (auto FC : F->getCaptureList()) + { + found_here = FC->hasStateBlock(sb); + if (found_here && _verbose) _stream << " Frm" << F->id() << ".Cap" << FC->id(); + found = found || found_here; + } + + // find in own Sensor + if (S) + { + found_here = S->hasStateBlock(sb); + if (found_here && _verbose) _stream << " Sen" << S->id(); + found = found || found_here; + } + + + // find in constrained Frame + for (const auto& Fow : getFrameOtherList()) + { + if (!Fow.expired()) + { + const auto& Fo = Fow.lock(); + found_here = Fo->hasStateBlock(sb); + if (found_here && _verbose) _stream << " FrmO" << Fo->id(); + found = found || found_here; + + // find in feature other's captures + for (auto FoC : Fo->getCaptureList()) + { + found_here = FoC->hasStateBlock(sb); + if (found_here && _verbose) _stream << " FrmO" << Fo->id() << ".C" << FoC->id(); + found = found || found_here; + } + + } + } + + // find in constrained Capture + for (const auto& Cow : getCaptureOtherList()) + { + if (!Cow.expired()) + { + const auto& Co = Cow.lock(); + found_here = Co->hasStateBlock(sb); + if (found_here && _verbose) _stream << " CapO" << Co->id(); + found = found || found_here; + } + } + + // find in constrained Feature + for (const 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 (const auto& Low : getLandmarkOtherList()) + { + if (!Low.expired()) + { + const auto& Lo = Low.lock(); + found_here = Lo->hasStateBlock(sb); + if (found_here && _verbose) _stream << " LmkO" << Lo->id(); + found = found || found_here; + } + } + + if (_verbose) + { + if (found) + _stream << " found"; + else + _stream << " NOT FOUND !"; + _stream << std::endl; + } + + // check that the state block has been found somewhere + inconsistency_explanation << "The stateblock " << sb << " has not been found (is floating!)"; + log.assertTrue((found), inconsistency_explanation); + + inconsistency_explanation << "The stateblock " << sb << " of factor " << id() << " @ " << _fac_ptr << " is null\n"; + log.assertTrue((sb.get() != nullptr), inconsistency_explanation); + } + return log; +} + +bool FactorBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto fac_ptr = std::static_pointer_cast<FactorBase>(_node_ptr); + auto local_log = localCheck(_verbose, fac_ptr, _stream, _tabs); + _log.compose(local_log); + + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/feature/feature_base.cpp b/src/feature/feature_base.cpp index d3aa372b7ecdae23e6d09382f12e7fd22ff7df58..0acccaf7a9fb9404e76ac9c5b142ed0839a9405c 100644 --- a/src/feature/feature_base.cpp +++ b/src/feature/feature_base.cpp @@ -188,4 +188,70 @@ void FeatureBase::print(int _depth, bool _constr_by, bool _metric, bool _state_b for (auto c : getFactorList()) c->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog FeatureBase::localCheck(bool _verbose, FeatureBasePtr _ftr_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) + { + _stream << _tabs << "Ftr" << id() << " @ " << _ftr_ptr.get() << std::endl; + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Cap" << getCapture()->id() << " @ " << getCapture().get() + << std::endl; + } + + auto cap_ptr = getCapture(); + // check problem and capture pointers + inconsistency_explanation << "Feature frame problem pointer " << getProblem().get() + << " different from Capture problem pointer " << cap_ptr->getProblem().get() << "\n"; + log.assertTrue((getProblem() == cap_ptr->getProblem()), inconsistency_explanation); + + + // check contrained_by + for (auto cby : getConstrainedByList()) + { + if (_verbose) + { + _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + for (const 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); + + } + + auto cap_ftr = _ftr_ptr->getCapture(); + inconsistency_explanation << "Ftr" << id() << " @ " << _ftr_ptr + << " ---> Cap" << cap_ftr->id() << " @ " << cap_ftr + << " -X-> Ftr" << id(); + auto cap_ftr_list = cap_ftr->getFeatureList(); + auto frame_has_cap = std::find_if(cap_ftr_list.begin(), cap_ftr_list.end(), [&_ftr_ptr](FeatureBasePtr ftr){ return ftr == _ftr_ptr;}); + log.assertTrue(frame_has_cap != cap_ftr_list.end(), 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; +} +bool FeatureBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto ftr_ptr = std::static_pointer_cast<FeatureBase>(_node_ptr); + auto local_log = localCheck(_verbose, ftr_ptr, _stream, _tabs); + _log.compose(local_log); + + for(auto f : getFactorList()) f->check(_log, f, _verbose, _stream, _tabs + " "); + + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/frame/frame_base.cpp b/src/frame/frame_base.cpp index a36417929bab661538736d837b016683c9597792..bca65f5a4bb2e7b11e0e48fd54013f265dd8db95 100644 --- a/src/frame/frame_base.cpp +++ b/src/frame/frame_base.cpp @@ -403,4 +403,107 @@ void FrameBase::print(int _depth, bool _constr_by, bool _metric, bool _state_blo for (auto C : getCaptureList()) C->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog FrameBase::localCheck(bool _verbose, FrameBasePtr _frm_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) { + _stream << _tabs << (isKeyOrAux() ? (isKey() ? "KFrm" : "EFrm") : "Frm") + << id() << " @ " << _frm_ptr.get() << std::endl; + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Trj @ " << getTrajectory().get() << std::endl; + } + for (const auto &pair: getStateBlockMap()) { + + auto sb = pair.second; + + // check for valid state block + inconsistency_explanation << "Frame " << id() << " @ "<< _frm_ptr.get() + << " has State block pointer " << sb.get() + << " = 0 \n"; + log.assertTrue((sb.get() != 0), inconsistency_explanation); + + if (_verbose) { + _stream << _tabs << " " << pair.first << " sb @ " << sb.get(); + if (sb) { + auto lp = sb->getLocalParametrization(); + if (lp) + _stream << " (lp @ " << lp.get() << ")"; + } + _stream << std::endl; + } + } + + // check problem pointer + auto trajectory_ptr = getTrajectory(); + auto trajectory_problem_ptr = trajectory_ptr->getProblem(); + inconsistency_explanation << "Frame problem pointer " << getProblem().get() + << " different from Trajectory problem pointer " << trajectory_problem_ptr.get() << "\n"; + log.assertTrue((getProblem() == trajectory_problem_ptr), inconsistency_explanation); + + // // check trajectory pointer + // inconsistency_explanation << "Frame trajectory pointer is " << getTrajectory() + // << " but trajectory pointer is" << trajectory_ptr << "\n"; + // log.assertTrue((getTrajectory() == T, inconsistency_explanation); + + // check constrained_by + for (auto cby : getConstrainedByList()) + { + if (_verbose) + { + _stream << _tabs << " " << "<- Fac" << cby->id() << " -> "; + for (const 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"; + auto F = std::static_pointer_cast<FrameBase>(_frm_ptr); + log.assertTrue((cby->hasFrameOther(F)), 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; + } + } + } + } + + auto trj_ptr = getTrajectory(); + inconsistency_explanation << "Frm" << id() << " @ " << _frm_ptr + << " ---> Trj" << " @ " << trj_ptr + << " -X-> Frm" << id(); + auto trj_frm_list = trj_ptr->getFrameList(); + auto trj_has_frm = std::find_if(trj_frm_list.begin(), trj_frm_list.end(), [&_frm_ptr](FrameBasePtr frm){ return frm == _frm_ptr;}); + log.assertTrue(trj_has_frm != trj_frm_list.end(), inconsistency_explanation); + + for(auto C : getCaptureList()) + { + inconsistency_explanation << "Frm " << id() << " @ " << _frm_ptr + << " ---> Cap" << C->id() << " @ " << C + << " -X-> Frm" << id(); + log.assertTrue((C->getFrame() == _frm_ptr), inconsistency_explanation); + } + return log; +} + +bool FrameBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto frm_ptr = std::static_pointer_cast<FrameBase>(_node_ptr); + auto local_log = localCheck(_verbose, frm_ptr, _stream, _tabs); + _log.compose(local_log); + for(auto C : getCaptureList()) C->check(_log, C, _verbose, _stream, _tabs + " "); + + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/hardware/hardware_base.cpp b/src/hardware/hardware_base.cpp index 788f644c00298bfb7d7108271a2159475bc70334..72f07b8e216e6ca830ec9021dbb7ca1144d09860 100644 --- a/src/hardware/hardware_base.cpp +++ b/src/hardware/hardware_base.cpp @@ -32,4 +32,29 @@ void HardwareBase::print(int _depth, bool _constr_by, bool _metric, bool _state_ for (auto S : getSensorList()) S->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog HardwareBase::localCheck(bool _verbose, HardwareBasePtr _hwd_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + if (_verbose) + { + _stream << _tabs << "Hrw @ " << _hwd_ptr.get() << std::endl; + } + + // check pointer to Problem + inconsistency_explanation << "Hwd->getProblem() [" << getProblem().get() + << "] -> " << " Prb->getHardware() [" << getProblem()->getHardware().get() << "] -> Hwd [" << _hwd_ptr.get() << "] Mismatch!\n"; + log.assertTrue((_hwd_ptr->getProblem()->getHardware().get() == _hwd_ptr.get()), inconsistency_explanation); + return log; +} +bool HardwareBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto hwd_ptr = std::static_pointer_cast<HardwareBase>(_node_ptr); + auto local_log = localCheck(_verbose, hwd_ptr, _stream, _tabs); + _log.compose(local_log); + for (auto S : getSensorList()) + S->check(_log, S, _verbose, _stream, _tabs + " "); + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/landmark/landmark_base.cpp b/src/landmark/landmark_base.cpp index 56cf45857c880907415709525784ba50b85118fe..9f2552615dc76f2c631b3007578da62bcfbea462 100644 --- a/src/landmark/landmark_base.cpp +++ b/src/landmark/landmark_base.cpp @@ -219,6 +219,90 @@ LandmarkBasePtr LandmarkBase::create(const YAML::Node& _node) return lmk; } +CheckLog LandmarkBase::localCheck(bool _verbose, LandmarkBasePtr _lmk_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) + { + _stream << _tabs << "Lmk" << id() << " @ " << _lmk_ptr.get() << std::endl; + _stream << _tabs << " -> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " -> Map @ " << getMap().get() << std::endl; + for (const auto& pair : getStateBlockMap()) + { + auto sb = pair.second; + _stream << _tabs << " " << pair.first << " sb @ " << sb.get(); + if (sb) + { + auto lp = sb->getLocalParametrization(); + if (lp) + _stream << " (lp @ " << lp.get() << ")"; + } + _stream << std::endl; + } + } + + auto map_ptr = getMap(); + // check problem and map pointers + inconsistency_explanation << "Landmarks' problem ptr " + << getProblem().get() << " different from Map's problem ptr " + << map_ptr->getProblem().get() << "\n"; + + log.assertTrue((getProblem() == map_ptr->getProblem()), inconsistency_explanation); + + for (auto cby : getConstrainedByList()) + { + if (_verbose) + { + _stream << _tabs << " " << "<- Fac" << cby->id() << " ->"; + + for (const auto& Low : cby->getLandmarkOtherList()) + { + if (!Low.expired()) + { + const auto& Lo = Low.lock(); + _stream << " Lmk" << Lo->id(); + } + } + _stream << std::endl; + } + + // check constrained-by factors + 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; + } + } + } + + inconsistency_explanation << "Lmk" << id() << " @ " << _lmk_ptr + << " ---> Map" << map_ptr + << " -X-> Lmk" << id(); + auto map_lmk_list = map_ptr->getLandmarkList(); + auto map_has_lmk = std::find_if(map_lmk_list.begin(), map_lmk_list.end(), [&_lmk_ptr](LandmarkBasePtr lmk){ return lmk == _lmk_ptr;}); + log.assertTrue(map_has_lmk != map_lmk_list.end(), inconsistency_explanation); + + return log; +} +bool LandmarkBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto lmk_ptr = std::static_pointer_cast<LandmarkBase>(_node_ptr); + auto local_log = localCheck(_verbose, lmk_ptr, _stream, _tabs); + _log.compose(local_log); + + return _log.is_consistent_; +} // Register landmark creator namespace { diff --git a/src/map/map_base.cpp b/src/map/map_base.cpp index 73efc29d7497f9e7c3fa434cc62cfef611ff9277..4c13360effa052b61b189042a95d2ec92bedfa4d 100644 --- a/src/map/map_base.cpp +++ b/src/map/map_base.cpp @@ -101,4 +101,28 @@ void MapBase::print(int _depth, bool _constr_by, bool _metric, bool _state_block for (auto L : getLandmarkList()) L->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog MapBase::localCheck(bool _verbose, MapBasePtr _map_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) + _stream << _tabs << "Map @ " << _map_ptr.get() << std::endl; + + // check pointer to Problem + inconsistency_explanation << "Map->getProblem() [" << getProblem().get() + << "] -> " << " Prb->getMap() [" << getProblem()->getMap().get() << "] -> Map [" << _map_ptr.get() << "] Mismatch!\n"; + log.assertTrue((_map_ptr->getProblem()->getMap().get() == _map_ptr.get()), inconsistency_explanation); + return log; +} +bool MapBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto map_ptr = std::static_pointer_cast<MapBase>(_node_ptr); + auto local_log = localCheck(_verbose, map_ptr, _stream, _tabs); + _log.compose(local_log); + for (auto L : getLandmarkList()) + L->check(_log, L, _verbose, _stream, _tabs + " "); + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/problem/problem.cpp b/src/problem/problem.cpp index f2d41a420415f8b0f9fb3ac9f6b5e286036c1160..58112a40d249aaadaad330dbf9ae08fe05263e85 100644 --- a/src/problem/problem.cpp +++ b/src/problem/problem.cpp @@ -1067,6 +1067,8 @@ bool Problem::check(bool _verbose, std::ostream& _stream) const CheckLog log(true, ""); log.explanation_ = "## WOLF::problem inconsistencies list \n ---------------------------------- \n"; + std::string tabs = ""; + if (_verbose) _stream << std::endl; if (_verbose) _stream << "Wolf tree integrity ---------------------" << std::endl; auto P = shared_from_this(); @@ -1078,624 +1080,19 @@ bool Problem::check(bool _verbose, std::ostream& _stream) const // HARDWARE branch // ------------------------ auto H = hardware_ptr_; - if (_verbose) - { - _stream << "Hrw @ " << H.get() << std::endl; - } - - // check pointer to Problem - std::stringstream inconsistency_explanation; - inconsistency_explanation << "Hardware problem pointer is " << H->getProblem().get() - << " but problem pointer is " << P.get() << "\n"; - log.assertTrue((H->getProblem() == P), inconsistency_explanation); - - - // Sensors ======================================================================================= - for (auto S : H->getSensorList()) - { - if (_verbose) - { - _stream << " Sen" << S->id() << " @ " << S.get() << std::endl; - _stream << " -> Prb @ " << S->getProblem().get() << std::endl; - _stream << " -> Hrw @ " << S->getHardware().get() << std::endl; - for (auto pair: S->getStateBlockMap()) - { - auto sb = pair.second; - _stream << " " << pair.first << " sb @ " << sb.get(); - if (sb) - { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - - // check problem and hardware pointers - inconsistency_explanation << "Sensor problem pointer is " << S->getProblem().get() - << " but problem pointer is " << P.get() << "\n"; - log.assertTrue((S->getProblem() == P), inconsistency_explanation); - - - inconsistency_explanation << "Sensor hardware pointer is " << S->getHardware() - << " but hardware pointer is " << H << "\n"; - log.assertTrue((S->getHardware() == H), inconsistency_explanation); - - - // Processors ======================================================================================= - for (auto p : S->getProcessorList()) - { - if (_verbose) - { - _stream << " Prc" << p->id() << " @ " << p.get() << " -> Sen" << p->getSensor()->id() << std::endl; - _stream << " -> Prb @ " << p->getProblem().get() << std::endl; - _stream << " -> Sen" << p->getSensor()->id() << " @ " << p->getSensor().get() << std::endl; - } - - // check problem and sensor pointers - inconsistency_explanation << "Processor problem pointer is " << p->getProblem().get() - << " but problem pointer is " << P.get() << "\n"; - log.assertTrue((p->getProblem() == P), inconsistency_explanation); - - - inconsistency_explanation << "Processor sensor pointer is " << p->getSensor() - << " but sensor pointer is " << P.get() << "\n"; - log.assertTrue((p->getProblem() == P), inconsistency_explanation); - - } - } + H->check(log, H, _verbose, _stream, tabs); // ------------------------ // TRAJECTORY branch // ------------------------ auto T = trajectory_ptr_; - if (_verbose) - { - _stream << "Trj @ " << T.get() << std::endl; - } - - // check pointer to Problem - inconsistency_explanation << "Trajectory problem pointer is " << T->getProblem().get() - << " but problem pointer is" << P.get() << "\n"; - log.assertTrue((T->getProblem() == P), inconsistency_explanation); - - - // Frames ======================================================================================= - for (auto F : T->getFrameList()) - { - if (_verbose) { - _stream << (F->isKeyOrAux() ? (F->isKey() ? " KFrm" : " EFrm") : " Frm") - << F->id() << " @ " << F.get() << std::endl; - _stream << " -> Prb @ " << F->getProblem().get() << std::endl; - _stream << " -> Trj @ " << F->getTrajectory().get() << std::endl; - } - for (const auto &pair: F->getStateBlockMap()) { - - auto sb = pair.second; - - // check for valid state block - inconsistency_explanation << "Frame " << F->id() << " @ "<< F.get() - << " has State block pointer " << sb.get() - << " = 0 \n"; - log.assertTrue((sb.get() != 0), inconsistency_explanation); - - if (_verbose) { - _stream << " "<< pair.first << " sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - - // check problem pointer - inconsistency_explanation << "Frame problem pointer is " << F->getProblem().get() - << " but problem pointer is" << P.get() << "\n"; - log.assertTrue((F->getProblem() == P), inconsistency_explanation); - - // check trajectory pointer - inconsistency_explanation << "Frame trajectory pointer is " << F->getTrajectory() - << " but trajectory pointer is" << T << "\n"; - log.assertTrue((F->getTrajectory() == T), inconsistency_explanation); - - - // check constrained_by - for (auto cby : F->getConstrainedByList()) - { - if (_verbose) - { - _stream << " <- Fac" << cby->id() << " -> "; - for (const auto& Fow : cby->getFrameOtherList()) - _stream << " F" << Fow.lock()->id() << std::endl; - } - - // check constrained_by pointer to this frame - inconsistency_explanation << "constrained-by frame " << F->id() << " @ " << F - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasFrameOther(F)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) - { - - if (_verbose) { - _stream << " sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - } - - // Captures ======================================================================================= - for (auto C : F->getCaptureList()) - { - if (_verbose) - { - _stream << " Cap" << C->id() << " @ " << C.get() << " -> Sen"; - if (C->getSensor()) _stream << C->getSensor()->id(); - else _stream << "-"; - _stream << std::endl; - _stream << " -> Prb @ " << C->getProblem().get() << std::endl; - _stream << " -> Frm" << C->getFrame()->id() << " @ " << C->getFrame().get() << std::endl; - } - for (auto pair: C->getStateBlockMap()) - { - auto sb = pair.second; - - // check for valid state block - inconsistency_explanation << "Capture " << C->id() << " @ " << C.get() << " has State block pointer " - << sb.get() << " = 0 \n"; - log.assertTrue((sb.get() != 0), inconsistency_explanation); - - if (_verbose) - { - _stream << " " << pair.first << " sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - - // check problem and frame pointers - inconsistency_explanation << "Capture problem pointer is " << C->getProblem().get() - << " but problem pointer is" << P.get() << "\n"; - log.assertTrue((C->getProblem() == P), inconsistency_explanation); + T->check(log, T, _verbose, _stream, tabs); - - inconsistency_explanation << "Capture frame pointer is " << C->getFrame() - << " but frame pointer is" << F << "\n"; - log.assertTrue((C->getFrame() == F), inconsistency_explanation); - - - // check contrained_by - for (const auto& cby : C->getConstrainedByList()) - { - if (_verbose) - { - _stream << " <- Fac" << cby->id() << " -> "; - for (const auto& Cow : cby->getCaptureOtherList()) - _stream << " Cap" << Cow.lock()->id(); - _stream << std::endl; - } - - // check constrained_by pointer to this capture - inconsistency_explanation << "constrained by capture " << C->id() << " @ " << C - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasCaptureOther(C)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) - { - if (_verbose) - { - _stream << " sb @ " << sb.get(); - if (sb) - { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - - } - - // Features ======================================================================================= - for (auto f : C->getFeatureList()) - { - if (_verbose) - { - _stream << " Ftr" << f->id() << " @ " << f.get() << std::endl; - _stream << " -> Prb @ " << f->getProblem().get() << std::endl; - _stream << " -> Cap" << f->getCapture()->id() << " @ " << f->getCapture().get() - << std::endl; - } - - // check problem and capture pointers - inconsistency_explanation << "Feature frame pointer is " << f->getProblem().get() - << " but problem pointer is" << P.get() << "\n"; - log.assertTrue((f->getProblem() == P), inconsistency_explanation); - - - inconsistency_explanation << "Feature capture pointer is " << f->getCapture() - << " but capture pointer is" << C << "\n"; - log.assertTrue((f->getCapture() == C), inconsistency_explanation); - - - // check contrained_by - for (auto cby : f->getConstrainedByList()) - { - if (_verbose) - { - _stream << " <- Fac" << cby->id() << " -> "; - for (const auto& fow : cby->getFeatureOtherList()) - _stream << " Ftr" << fow.lock()->id(); - _stream << std::endl; - } - - // check constrained_by pointer to this feature - inconsistency_explanation << "constrained by Feature " << f->id() << " @ " << f - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasFeatureOther(f)), inconsistency_explanation); - - } - - // Factors ======================================================================================= - for (auto c : f->getFactorList()) - { - if (_verbose) - _stream << " Fac" << c->id() << " @ " << c.get(); - - if ( c->getFrameOtherList() .empty() - && c->getCaptureOtherList() .empty() - && c->getFeatureOtherList() .empty() - && c->getLandmarkOtherList().empty() ) // case ABSOLUTE: - { - if (_verbose) - _stream << " --> Abs."; - } - - // find constrained_by pointer in constrained frame - for (const auto& Fow : c->getFrameOtherList()) - { - if (!Fow.expired()) - { - const auto& Fo = Fow.lock(); - if (_verbose) - { - _stream << " ( --> Frm" << Fo->id() << " <- "; - for (auto cby : Fo->getConstrainedByList()) - _stream << " Fac" << cby->id(); - } - - // check constrained_by pointer in constrained frame - bool found = Fo->isConstrainedBy(c); - inconsistency_explanation << "The constrained Feature " << Fo->id() << " @ " << Fo - << " not found among constrained-by factors\n"; - log.assertTrue((found), inconsistency_explanation); - - } - } - if (_verbose && !c->getFrameOtherList().empty()) - _stream << ")"; - - // find constrained_by pointer in constrained capture - for (const auto& Cow : c->getCaptureOtherList()) - { - if (!Cow.expired()) - { - const auto& Co = Cow.lock(); - - if (_verbose) - { - _stream << " ( --> Cap" << Co->id() << " <- "; - for (auto cby : Co->getConstrainedByList()) - _stream << " Fac" << cby->id(); - } - - // check constrained_by pointer in constrained frame - bool found = Co->isConstrainedBy(c); - inconsistency_explanation << "The constrained capture " << Co->id() << " @ " << Co - << " not found among constrained-by factors\n"; - log.assertTrue((found), inconsistency_explanation); - - } - } - if (_verbose && !c->getCaptureOtherList().empty()) - _stream << ")"; - - // find constrained_by pointer in constrained feature - for (const auto& fow : c->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(c); - inconsistency_explanation << "The constrained feature " << fo->id() << " @ " << fo - << " not found among constrained-by factors\n"; - log.assertTrue((found), inconsistency_explanation); - } - } - if (_verbose && !c->getFeatureOtherList().empty()) - _stream << ")"; - - // find constrained_by pointer in constrained landmark - for (const auto& Low : c->getLandmarkOtherList()) - { - if (Low.expired()) - { - const auto& Lo = Low.lock(); - - if (_verbose) - { - _stream << " ( --> Lmk" << Lo->id() << " <- "; - for (auto cby : Lo->getConstrainedByList()) - _stream << " Fac" << cby->id(); - } - - // check constrained_by pointer in constrained landmark - bool found = Lo->isConstrainedBy(c); - inconsistency_explanation << "The constrained landmark " << Lo->id() << " @ " << Lo - << " not found among constrained-by factors\n"; - log.assertTrue((found), inconsistency_explanation); - - } - } - if (_verbose && !c->getLandmarkOtherList().empty()) - _stream << ")"; - - if (_verbose) - _stream << std::endl; - - if (_verbose) - { - _stream << " -> Prb @ " << c->getProblem().get() << std::endl; - _stream << " -> Ftr" << c->getFeature()->id() << " @ " << c->getFeature().get() << std::endl; - } - - // check problem and feature pointers - inconsistency_explanation << "The factor " << c->id() << " @ " << c << " has problem ptr " << c->getProblem().get() - << " but problem ptr is " << P.get() << "\n"; - log.assertTrue((c->getProblem() == P), inconsistency_explanation); - - - inconsistency_explanation << "The factor " << c->id() << " @ " << c << " has feature ptr " << c->getFeature() - << " but it should have " << f << "\n"; - log.assertTrue((c->getProblem() == P), inconsistency_explanation); - - - // find state block pointers in all constrained nodes - SensorBasePtr S = c->getFeature()->getCapture()->getSensor(); // get own sensor to check sb - for (auto sb : c->getStateBlockPtrVector()) - { - bool found = false; - if (_verbose) - { - _stream << " sb @ " << sb.get(); - if (sb) - { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - } - bool found_here; - - // find in own Frame - found_here = F->hasStateBlock(sb); - if (found_here && _verbose) _stream << " Frm" << F->id(); - found = found || found_here; - - // find in own Capture - found_here = C->hasStateBlock(sb); - if (found_here && _verbose) _stream << " Cap" << C->id(); - found = found || found_here; - - // Find in other Captures of the own Frame - if (!found_here) - for (auto FC : F->getCaptureList()) - { - found_here = FC->hasStateBlock(sb); - if (found_here && _verbose) _stream << " Frm" << F->id() << ".Cap" << FC->id(); - found = found || found_here; - } - - // find in own Sensor - if (S) - { - found_here = S->hasStateBlock(sb); - if (found_here && _verbose) _stream << " Sen" << S->id(); - found = found || found_here; - } - - - // find in constrained Frame - for (const auto& Fow : c->getFrameOtherList()) - { - if (!Fow.expired()) - { - const auto& Fo = Fow.lock(); - found_here = Fo->hasStateBlock(sb); - if (found_here && _verbose) _stream << " FrmO" << Fo->id(); - found = found || found_here; - - // find in feature other's captures - for (auto FoC : Fo->getCaptureList()) - { - found_here = FoC->hasStateBlock(sb); - if (found_here && _verbose) _stream << " FrmO" << Fo->id() << ".C" << FoC->id(); - found = found || found_here; - } - - } - } - - // find in constrained Capture - for (const auto& Cow : c->getCaptureOtherList()) - { - if (!Cow.expired()) - { - const auto& Co = Cow.lock(); - found_here = Co->hasStateBlock(sb); - if (found_here && _verbose) _stream << " CapO" << Co->id(); - found = found || found_here; - } - } - - // find in constrained Feature - for (const auto& fow : c->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 (const auto& Low : c->getLandmarkOtherList()) - { - if (!Low.expired()) - { - const auto& Lo = Low.lock(); - found_here = Lo->hasStateBlock(sb); - if (found_here && _verbose) _stream << " LmkO" << Lo->id(); - found = found || found_here; - } - } - - if (_verbose) - { - if (found) - _stream << " found"; - else - _stream << " NOT FOUND !"; - _stream << std::endl; - } - - // check that the state block has been found somewhere - inconsistency_explanation << "The stateblock " << sb << " has not been found (is floating!)"; - log.assertTrue((found), inconsistency_explanation); - - inconsistency_explanation << "The stateblock " << sb << " of factor " << c->id() << " @ " << c << " is null\n"; - log.assertTrue((sb.get() != nullptr), inconsistency_explanation); - } - } - } - } - } // ------------------------ // MAP branch // ------------------------ auto M = map_ptr_; - if (_verbose) - _stream << "Map @ " << M.get() << std::endl; - - // check pointer to Problem - inconsistency_explanation << "The map problem ptr is " << M->getProblem().get() << " but problem is " << P.get() << "\n"; - log.assertTrue((M->getProblem() == P), inconsistency_explanation); + M->check(log, M, _verbose, _stream, tabs); - // Landmarks ======================================================================================= - for (auto L : M->getLandmarkList()) - { - if (_verbose) - { - _stream << " Lmk" << L->id() << " @ " << L.get() << std::endl; - _stream << " -> Prb @ " << L->getProblem().get() << std::endl; - _stream << " -> Map @ " << L->getMap().get() << std::endl; - for (const auto& pair : L->getStateBlockMap()) - { - auto sb = pair.second; - _stream << " " << pair.first << " sb @ " << sb.get(); - if (sb) - { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - - // check problem and map pointers - inconsistency_explanation << "Landmarks' problem ptr is " - << L->getProblem().get() << " but problem is " - << P.get() << "\n"; - - log.assertTrue((L->getProblem() == P), inconsistency_explanation); - - inconsistency_explanation << "The Landmarks' map ptr is " - << L->getMap() << " but map is " - << M << "\n"; - log.assertTrue((M->getProblem() == P), inconsistency_explanation); - - for (auto cby : L->getConstrainedByList()) - { - if (_verbose) - { - _stream << " <- Fac" << cby->id() << " ->"; - - for (const auto& Low : cby->getLandmarkOtherList()) - { - if (!Low.expired()) - { - const auto& Lo = Low.lock(); - _stream << " Lmk" << Lo->id(); - } - } - _stream << std::endl; - } - - // check constrained-by factors - inconsistency_explanation << "constrained-by landmark " << L->id() << " @ " << L - << " not found among constrained-by factors\n"; - log.assertTrue((cby->hasLandmarkOther(L)), inconsistency_explanation); - - for (auto sb : cby->getStateBlockPtrVector()) { - if (_verbose) { - _stream << " sb @ " << sb.get(); - if (sb) { - auto lp = sb->getLocalParametrization(); - if (lp) - _stream << " (lp @ " << lp.get() << ")"; - } - _stream << std::endl; - } - } - } - } if (_verbose) _stream << "--------------------------- Wolf tree " << (log.is_consistent_ ? " OK" : "Not OK !!") << std::endl; if (_verbose) _stream << std::endl; diff --git a/src/processor/processor_base.cpp b/src/processor/processor_base.cpp index 6f28aef4d3393d1baf4a652fa4a06052ba9abb82..c02228864e1db24fb0b43826736a26c1c6688451 100644 --- a/src/processor/processor_base.cpp +++ b/src/processor/processor_base.cpp @@ -227,4 +227,38 @@ void ProcessorBase::print(int _depth, bool _metric, bool _state_blocks, bool _co { printHeader(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs); } +CheckLog ProcessorBase::localCheck(bool _verbose, ProcessorBasePtr _prc_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + auto sen_ptr = getSensor(); + if (_verbose) + { + _stream << _tabs << "Prc" << id() << " @ " << _prc_ptr.get() << " -> Sen" << sen_ptr->id() << std::endl; + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Sen" << sen_ptr->id() << " @ " << sen_ptr.get() << std::endl; + } + + // check problem and sensor pointers + inconsistency_explanation << "Processor problem pointer " << getProblem().get() + << " is different from Sensor problem pointer " << sen_ptr->getProblem().get() << "\n"; + log.assertTrue((getProblem() == sen_ptr->getProblem()), inconsistency_explanation); + + inconsistency_explanation << "Prc" << id() << " @ " << _prc_ptr + << " ---> Sen" << sen_ptr->id() << " @ " << sen_ptr + << " -X-> Prc" << id(); + auto sen_prc_list = sen_ptr->getProcessorList(); + auto sen_has_prc = std::find_if(sen_prc_list.begin(), sen_prc_list.end(), [&_prc_ptr](ProcessorBasePtr prc){ return prc == _prc_ptr;}); + log.assertTrue(sen_has_prc != sen_prc_list.end(), inconsistency_explanation); + + return log; +} +bool ProcessorBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto prc_ptr = std::static_pointer_cast<ProcessorBase>(_node_ptr); + auto local_log = localCheck(_verbose, prc_ptr, _stream, _tabs); + _log.compose(local_log); + return _log.is_consistent_; +} } // namespace wolf diff --git a/src/sensor/sensor_base.cpp b/src/sensor/sensor_base.cpp index f40e6a4e5ca10d9d5369f06ce6e683e97c767ccc..2ae05abfde3dd647d6fca8ce9508f56607b29785 100644 --- a/src/sensor/sensor_base.cpp +++ b/src/sensor/sensor_base.cpp @@ -517,4 +517,61 @@ void SensorBase::print(int _depth, bool _constr_by, bool _metric, bool _state_bl for (auto p : getProcessorList()) p->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog SensorBase::localCheck(bool _verbose, SensorBasePtr _sen_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + if (_verbose) + { + _stream << _tabs << "Sen" << id() << " @ " << _sen_ptr.get() << std::endl; + _stream << _tabs << " " << "-> Prb @ " << getProblem().get() << std::endl; + _stream << _tabs << " " << "-> Hrw @ " << getHardware().get() << std::endl; + for (auto pair: getStateBlockMap()) + { + auto sb = pair.second; + _stream << _tabs << " " << pair.first << " sb @ " << sb.get(); + if (sb) + { + auto lp = sb->getLocalParametrization(); + if (lp) + _stream << " (lp @ " << lp.get() << ")"; + } + _stream << std::endl; + } + } + + std::stringstream inconsistency_explanation; + auto hwd_ptr = getHardware(); + // check problem and hardware pointers + inconsistency_explanation << "Sensor problem pointer " << getProblem().get() + << " different from Hardware problem pointer " << hwd_ptr->getProblem().get() << "\n"; + log.assertTrue((getProblem() == hwd_ptr->getProblem()), inconsistency_explanation); + + inconsistency_explanation << "Sen" << id() << " @ " << _sen_ptr + << " ---> Hwd" << " @ " << hwd_ptr + << " -X-> Sen" << id(); + auto hwd_sen_list = hwd_ptr->getSensorList(); + auto hwd_has_sen = std::find_if(hwd_sen_list.begin(), hwd_sen_list.end(), [&_sen_ptr](SensorBasePtr sen){ return sen == _sen_ptr;}); + log.assertTrue(hwd_has_sen != hwd_sen_list.end(), inconsistency_explanation); + + for(auto prc : getProcessorList()) + { + inconsistency_explanation << "Sen" << id() << " @ " << _sen_ptr + << " ---> Prc" << prc->id() << " @ " << prc + << " -X-> Sen" << id(); + log.assertTrue((prc->getSensor() == _sen_ptr), inconsistency_explanation); + } + return log; +} + +bool SensorBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto sen_ptr = std::static_pointer_cast<SensorBase>(_node_ptr); + auto local_log = localCheck(_verbose, sen_ptr, _stream, _tabs); + _log.compose(local_log); + + for (auto p : getProcessorList()) p->check(_log, p, _verbose, _stream, _tabs + " "); + return _log.is_consistent_; +} + } // namespace wolf diff --git a/src/trajectory/trajectory_base.cpp b/src/trajectory/trajectory_base.cpp index 84007a6cdbd9afece5ff51b271db25f92d4f41ff..fe1bc2f67a5f79fbf8d45f8b1a1ced7c220ace24 100644 --- a/src/trajectory/trajectory_base.cpp +++ b/src/trajectory/trajectory_base.cpp @@ -148,4 +148,30 @@ void TrajectoryBase::print(int _depth, bool _constr_by, bool _metric, bool _stat F->print(_depth, _constr_by, _metric, _state_blocks, _stream, _tabs + " "); } + +CheckLog TrajectoryBase::localCheck(bool _verbose, TrajectoryBasePtr _trj_ptr, std::ostream& _stream, std::string _tabs) const +{ + CheckLog log; + std::stringstream inconsistency_explanation; + + if (_verbose) + { + _stream << _tabs << "Trj @ " << _trj_ptr.get() << std::endl; + } + + // check pointer to Problem + inconsistency_explanation << "Trj->getProblem() [" << getProblem().get() + << "] -> " << " Prb->getTrajectory() [" << getProblem()->getTrajectory().get() << "] -> Trj [" << _trj_ptr.get() << "] Mismatch!\n"; + log.assertTrue((_trj_ptr->getProblem()->getTrajectory().get() == _trj_ptr.get()), inconsistency_explanation); + return log; +} +bool TrajectoryBase::check(CheckLog& _log, std::shared_ptr<NodeBase> _node_ptr, bool _verbose, std::ostream& _stream, std::string _tabs) const +{ + auto trj_ptr = std::static_pointer_cast<TrajectoryBase>(_node_ptr); + auto local_log = localCheck(_verbose, trj_ptr, _stream, _tabs); + _log.compose(local_log); + for (auto F : getFrameList()) + F->check(_log, F, _verbose, _stream, _tabs + " "); + return _log.is_consistent_; +} } // namespace wolf