diff --git a/include/core/capture/capture_buffer.h b/include/core/capture/capture_buffer.h deleted file mode 100644 index 6ecabc34ea5d62b3055c84b7cbf0d5cb4a94efed..0000000000000000000000000000000000000000 --- a/include/core/capture/capture_buffer.h +++ /dev/null @@ -1,172 +0,0 @@ -/** - * \file capture_buffer.h - * - * Created on: Jul 12, 2017 - * \author: Jeremie Deray - */ - -#ifndef _WOLF_CAPTURE_BUFFER_H_ -#define _WOLF_CAPTURE_BUFFER_H_ - -#include "core/common/wolf.h" -#include "core/common/time_stamp.h" - -#include <list> -#include <algorithm> - -namespace wolf { - -//using namespace Eigen; - -enum class CaptureBufferPolicy : std::size_t -{ - TIME = 0, - NUM_CAPTURES, - ALL -}; - -/** \brief class for capture buffers. - * - * It consists of a buffer of pre-integrated motions (aka. delta-integrals) that is being filled - * by the motion processors (deriving from ProcessorMotion). - * Each delta-integral is accompanied by a time stamp, a Jacobian and a covariances matrix. - * - * This buffer contains the time stamp and delta-integrals: - * - since the last key-Frame - * - until the frame of this capture. - * - * The buffer can be queried for motion-integrals and delta-integrals corresponding to a provided time stamp, - * with the following rules: - * - If the query time stamp is later than the last one in the buffer, - * the last motion-integral or delta-integral is returned. - * - If the query time stamp is earlier than the beginning of the buffer, - * the earliest Motion or Delta is returned. - * - If the query time stamp matches one time stamp in the buffer exactly, - * the returned motion-integral or delta-integral is the one of the queried time stamp. - * - If the query time stamp does not match any time stamp in the buffer, - * the returned motion-integral or delta-integral is the one immediately before the query time stamp. - */ - -//template <CaptureBufferPolicy policy> -class CaptureBuffer -{ -public: - - CaptureBuffer(const Scalar _buffer_dt, const int _max_capture = -1); - ~CaptureBuffer() = default; - - void push_back(const CaptureBasePtr& capture); - -// std::list<CaptureBasePtr>& get(); -// const std::list<CaptureBasePtr>& get() const; - - const CaptureBasePtr& getCapture(const TimeStamp& _ts) const; - void getCapture(const TimeStamp& _ts, CaptureBasePtr& _motion) const; - - void remove(const CaptureBasePtr& capture); - - void clear(); -// void print(); - - const TimeStamp earliest() const; - const TimeStamp latest() const; - -//private: - - int max_capture_; - Scalar buffer_dt_; - - std::list<CaptureBasePtr> container_; -}; - -CaptureBuffer::CaptureBuffer(const Scalar _buffer_dt, const int _max_capture) : - max_capture_(_max_capture), buffer_dt_(_buffer_dt) -{ - // -} - -void CaptureBuffer::push_back(const CaptureBasePtr& capture) -{ - container_.push_back(capture); - - WOLF_DEBUG("Buffer dt : ", container_.back()->getTimeStamp() - - container_.front()->getTimeStamp(), " vs ", buffer_dt_); - - while (container_.back()->getTimeStamp() - - container_.front()->getTimeStamp() > buffer_dt_) - { - container_.pop_front(); - } -} - -const CaptureBasePtr& CaptureBuffer::getCapture(const TimeStamp& _ts) const -{ - //assert((container_.front().ts_ <= _ts) && "Query time stamp out of buffer bounds"); - auto previous = std::find_if(container_.rbegin(), container_.rend(), - [&](const CaptureBasePtr& c) - { - return c->getTimeStamp() <= _ts; - }); - - if (previous == container_.rend()) - // The time stamp is older than the buffer's oldest data. - // We could do something here, and throw an error or something, but by now we'll return the first valid data - previous--; - - return *previous; -} - -void CaptureBuffer::getCapture(const TimeStamp& _ts, CaptureBasePtr& _capture) const -{ -// //assert((container_.front().ts_ <= _ts) && "Query time stamp out of buffer bounds"); -// auto previous = std::find_if(container_.rbegin(), container_.rend(), -// [&](const Motion& m) -// { -// return c->getTimeStamp() <= _ts; -// }); - -// if (previous == container_.rend()) -// // The time stamp is older than the buffer's oldest data. -// // We could do something here, but by now we'll return the last valid data -// previous--; - -// _capture = *previous; - - _capture = getCapture(_ts); -} - -//inline std::list<CaptureBasePtr>& CaptureBuffer::get() -//{ -// return container_; -//} - -//inline const std::list<CaptureBasePtr>& CaptureBuffer::get() const -//{ -// return container_; -//} - -inline void CaptureBuffer::remove(const CaptureBasePtr& capture) -{ - container_.remove(capture); -} - -inline void CaptureBuffer::clear() -{ - return container_.clear(); -} - -inline const TimeStamp CaptureBuffer::earliest() const -{ - return (!container_.empty())? container_.front()->getTimeStamp() : - InvalidStamp; -} - -inline const TimeStamp CaptureBuffer::latest() const -{ - return (!container_.empty())? container_.back()->getTimeStamp() : - InvalidStamp; -} - -} // namespace wolf - -#endif /* _WOLF_CAPTURE_BUFFER_H_ */ diff --git a/include/core/processor/processor_capture_holder.h b/include/core/processor/processor_capture_holder.h index 46fc538d9a05f53181f7d3d4d5e46a7e0e6a4dc4..db38fc5ab4524db72028a18bf247c05fe45c8b02 100644 --- a/include/core/processor/processor_capture_holder.h +++ b/include/core/processor/processor_capture_holder.h @@ -23,17 +23,7 @@ WOLF_STRUCT_PTR_TYPEDEFS(ProcessorParamsCaptureHolder); */ struct ProcessorParamsCaptureHolder : public ProcessorParamsBase { - Scalar buffer_size = 30; - ProcessorParamsCaptureHolder() = default; - ProcessorParamsCaptureHolder(std::string _unique_name, const wolf::paramsServer & _server): - ProcessorParamsBase(_unique_name, _server) - { - buffer_size = _server.getParam<Scalar>(_unique_name + "/buffer_size"); - } - std::string print() - { - return "\n" + ProcessorParamsBase::print() + "buffer_size: " + std::to_string(buffer_size) + "\n"; - } + using ProcessorParamsBase::ProcessorParamsBase; }; /** @@ -41,42 +31,55 @@ struct ProcessorParamsCaptureHolder : public ProcessorParamsBase */ class ProcessorCaptureHolder : public ProcessorBase { -public: - - ProcessorCaptureHolder(ProcessorParamsCaptureHolderPtr _params_capture_holder); - virtual ~ProcessorCaptureHolder() = default; - virtual void configure(SensorBasePtr _sensor) override { }; - - virtual void process(CaptureBasePtr _capture_ptr) override; - - /** \brief Vote for KeyFrame generation - * - * If a KeyFrame criterion is validated, this function returns true, - * meaning that it wants to create a KeyFrame at the \b last Capture. - * - * WARNING! This function only votes! It does not create KeyFrames! - */ - virtual bool voteForKeyFrame() override { return false; } - - virtual void keyFrameCallback(FrameBasePtr _keyframe_ptr, - const Scalar& _time_tolerance) override; - - /** - * \brief Finds the capture that contains the closest previous motion of _ts - * \return a pointer to the capture (if it exists) or a nullptr (otherwise) - */ - CaptureBasePtr findCaptureContainingTimeStamp(const TimeStamp& _ts) const; - -protected: - - ProcessorParamsCaptureHolderPtr params_capture_holder_; - CaptureBuffer buffer_; - -public: - - static ProcessorBasePtr create(const std::string& _unique_name, - const ProcessorParamsBasePtr _params, - const SensorBasePtr sensor_ptr = nullptr); + public: + + ProcessorCaptureHolder(ProcessorParamsCaptureHolderPtr _params_capture_holder); + virtual ~ProcessorCaptureHolder() = default; + virtual void configure(SensorBasePtr _sensor) override { }; + + protected: + + /** \brief process an incoming capture + * + * The ProcessorCaptureHolder is only triggered in KF (see triggerInCapture()) so this function is not called. + */ + virtual void processCapture(CaptureBasePtr) override {}; + + /** \brief process an incoming key-frame + * + * Each derived processor should implement this function. It will be called if: + * - A new KF arrived and triggerInKF() returned true. + */ + virtual void processKeyFrame(FrameBasePtr _keyframe_ptr, const Scalar& _time_tolerance) override; + + /** \brief trigger in capture + * + * The ProcessorCaptureHolder only processes incoming KF, then it returns false. + */ + virtual bool triggerInCapture(CaptureBasePtr) override {return false;} + + /** \brief trigger in key-frame + * + * Returns true if processKeyFrame() should be called after the provided KF arrived. + */ + virtual bool triggerInKeyFrame(FrameBasePtr _keyframe_ptr, const Scalar& _time_tol_other) override { return true; } + + /** \brief Vote for KeyFrame generation + * + * If a KeyFrame criterion is validated, this function returns true, + * meaning that it wants to create a KeyFrame at the \b last Capture. + * + * WARNING! This function only votes! It does not create KeyFrames! + */ + virtual bool voteForKeyFrame() override { return false; } + + ProcessorParamsCaptureHolderPtr params_capture_holder_; + + public: + + static ProcessorBasePtr create(const std::string& _unique_name, + const ProcessorParamsBasePtr _params, + const SensorBasePtr sensor_ptr = nullptr); }; } // namespace wolf diff --git a/src/processor/processor_capture_holder.cpp b/src/processor/processor_capture_holder.cpp index d8a98166c11ecc1361ed1194a5b2ad0e1b241cb6..5cad88a4e5c5eca8e94d6af99a67eb22ba9e3147 100644 --- a/src/processor/processor_capture_holder.cpp +++ b/src/processor/processor_capture_holder.cpp @@ -12,135 +12,67 @@ namespace wolf { ProcessorCaptureHolder::ProcessorCaptureHolder(ProcessorParamsCaptureHolderPtr _params_capture_holder) : ProcessorBase("CAPTURE HOLDER", _params_capture_holder), - params_capture_holder_(_params_capture_holder), - buffer_(_params_capture_holder->buffer_size) + params_capture_holder_(_params_capture_holder) { // } -void ProcessorCaptureHolder::process(CaptureBasePtr _capture_ptr) +void ProcessorCaptureHolder::processKeyFrame(FrameBasePtr _keyframe_ptr, const Scalar& _time_tolerance) { - buffer_.push_back(_capture_ptr); -} - -void ProcessorCaptureHolder::keyFrameCallback(FrameBasePtr _keyframe_ptr, - const Scalar& _time_tolerance) -{ - assert(_keyframe_ptr->getTrajectory() != nullptr + assert(_keyframe_ptr->getTrajectory() != nullptr && "ProcessorMotion::keyFrameCallback: key frame must be in the trajectory."); - // get keyframe's time stamp - const TimeStamp new_ts = _keyframe_ptr->getTimeStamp(); + // get keyframe's time stamp + const TimeStamp new_ts = _keyframe_ptr->getTimeStamp(); - // find capture whose buffer is affected by the new keyframe - CaptureBasePtr existing_capture = findCaptureContainingTimeStamp(new_ts); + // find capture whose buffer is affected by the new keyframe + CaptureBasePtr existing_capture = buffer_capture_.selectFirstBefore(new_ts, _time_tolerance); + buffer_capture_.removeUpTo(existing_capture->getTimeStamp()); - if (existing_capture == nullptr) - { - WOLF_WARN("Could not find a capture at ts : ", new_ts.get()); - return; - } + if (existing_capture == nullptr) + { + WOLF_WARN("Could not find a capture at ts: ", new_ts.get(), " within time tolerance: ", _time_tolerance); + return; + } - WOLF_DEBUG("ProcessorCaptureHolder::keyFrameCallback", _time_tolerance); - WOLF_DEBUG("Capture of type : ", existing_capture->getType()); - WOLF_DEBUG("CaptureBuffer size : ", buffer_.container_.size()); + WOLF_DEBUG("ProcessorCaptureHolder::keyFrameCallback time tolerance ", _time_tolerance); + WOLF_DEBUG("Capture of type : ", existing_capture->getType()); + WOLF_DEBUG("CaptureBuffer size : ", buffer_capture_.size()); - // add motion capture to keyframe - if (std::abs(new_ts - existing_capture->getTimeStamp()) < _time_tolerance) - { + // add capture to keyframe auto frame_ptr = existing_capture->getFrame(); - if (frame_ptr != _keyframe_ptr) + if (frame_ptr != nullptr && frame_ptr->isKey()) { - // _keyframe_ptr->addCapture(existing_capture); + WOLF_WARN_COND(frame_ptr != _keyframe_ptr, "found a capture already in a different KF"); + WOLF_INFO_COND(frame_ptr == _keyframe_ptr, "found a capture already in a this KF"); + } + else + { + WOLF_INFO("Adding capture laser !"); existing_capture->link(_keyframe_ptr); - //WOLF_INFO("Adding capture laser !"); - - //frame_ptr->remove(); + if (frame_ptr) + frame_ptr->remove(); } - //else - //WOLF_INFO("Capture laser already exists !"); - - // Remove as we don't want duplicates - buffer_.remove(existing_capture); - - return; - } - else - { - WOLF_DEBUG("Capture doesn't fit dt : ", - std::abs(new_ts - existing_capture->getTimeStamp()), - " vs ", _time_tolerance); - - return; - } -} - -CaptureBasePtr ProcessorCaptureHolder::findCaptureContainingTimeStamp(const TimeStamp& _ts) const -{ - WOLF_DEBUG("ProcessorCaptureHolder::findCaptureContainingTimeStamp: ts = ", - _ts.getSeconds(), ".", _ts.getNanoSeconds()); - -// auto capture_ptr = last_ptr_; -// while (capture_ptr != nullptr) -// { -// // capture containing motion previous than the ts found: -// if (buffer_.get().front()->getTimeStamp() < _ts) -// return capture_ptr; -// else -// { -// // go to the previous motion capture -// if (capture_ptr == last_ptr_) -// capture_ptr = origin_ptr_; -// else if (capture_ptr->getOriginFrame() == nullptr) -// return nullptr; -// else -// { -// CaptureBasePtr capture_base_ptr = capture_ptr->getOriginFrame()->getCaptureOf(getSensor()); -// if (capture_base_ptr == nullptr) -// return nullptr; -// else -// capture_ptr = std::static_pointer_cast<CaptureMotion>(capture_base_ptr); -// } -// } -// } - -// return capture_ptr;. - -// auto capt = buffer_.getCapture(_ts); - - /// @todo -// WOLF_WARN("ProcessorCaptureHolder::findCaptureContainingTimeStamp " -// "looking for stamp ", -// _ts.get() - ((long)_ts.get()), -// " in (", -// buffer_.earliest().get() - ((long)buffer_.earliest().get()), ",", -// buffer_.latest().get() - ((long)buffer_.latest().get()), ").\n", -// "Found capture with stamp ", -// capt->getTimeStamp().get() - ((long)capt->getTimeStamp().get())); - -// return capt; - - return buffer_.getCapture(_ts); } ProcessorBasePtr ProcessorCaptureHolder::create(const std::string& _unique_name, const ProcessorParamsBasePtr _params, const SensorBasePtr) { - ProcessorParamsCaptureHolderPtr params; + ProcessorParamsCaptureHolderPtr params; - params = std::static_pointer_cast<ProcessorParamsCaptureHolder>(_params); + params = std::static_pointer_cast<ProcessorParamsCaptureHolder>(_params); - // if cast failed use default value - if (params == nullptr) - params = std::make_shared<ProcessorParamsCaptureHolder>(); + // if cast failed use default value + if (params == nullptr) + params = std::make_shared<ProcessorParamsCaptureHolder>(); - ProcessorCaptureHolderPtr prc_ptr = std::make_shared<ProcessorCaptureHolder>(params); - prc_ptr->setName(_unique_name); + ProcessorCaptureHolderPtr prc_ptr = std::make_shared<ProcessorCaptureHolder>(params); + prc_ptr->setName(_unique_name); - return prc_ptr; + return prc_ptr; } } // namespace wolf