diff --git a/doc/utql/Vision/MarkerTracker.xml b/doc/utql/Vision/MarkerTracker.xml index 55fa8ce..2990b21 100644 --- a/doc/utql/Vision/MarkerTracker.xml +++ b/doc/utql/Vision/MarkerTracker.xml @@ -95,6 +95,15 @@ + + + + Enables Running the marker tracking in a seperate thread. + + + + + @@ -216,6 +225,15 @@ + + + + Enables Running the marker tracking in a seperate thread. + + + + + diff --git a/src/utVisionComponents/ChessboardFunctions.cpp b/src/utVisionComponents/ChessboardFunctions.cpp index 3646a11..9ce19e3 100644 --- a/src/utVisionComponents/ChessboardFunctions.cpp +++ b/src/utVisionComponents/ChessboardFunctions.cpp @@ -293,7 +293,10 @@ class ChessboardFunctionsComponent } else // m_scaleFactor == 0 { -#if CV_MAJOR_VERSION > 1 && CV_MINOR_VERSION > 2 + +// added DEACTIVATED because of error of cv::Mat constructor +#if CV_MAJOR_VERSION > 1 && CV_MINOR_VERSION > 2 && DEACTIVATED + cv::Mat calib_image( *img, false ); std::vector< cv::Point2f > centers; //( CvPoint2D32f == cv::Point2f ) diff --git a/src/utVisionComponents/MarkerTracker.cpp b/src/utVisionComponents/MarkerTracker.cpp index 86cdab1..38a4b0c 100644 --- a/src/utVisionComponents/MarkerTracker.cpp +++ b/src/utVisionComponents/MarkerTracker.cpp @@ -410,7 +410,15 @@ MarkerTracker::MarkerTracker( const std::string& sName, boost::shared_ptr< Graph , m_bEdgeRefinement( true ) , m_info( 0.06f ) , m_lastTime( 0 ) + , m_State(state_stopped) + , m_pThread(nullptr) + , m_bThreadingEnabled(false) { + if (subgraph->m_DataflowAttributes.hasAttribute("enableThreading")) // enable threading + m_bThreadingEnabled = subgraph->m_DataflowAttributes.getAttributeString("enableThreading") == "true"; + + m_pThread = boost::shared_ptr< boost::thread >(new boost::thread(boost::bind(&MarkerTracker::threadFunction, this))); + // get configuration if( subgraph->hasNode( "Marker" ) ) subgraph->getNode( "Marker" )->getAttributeData( "markerSize", m_info.fSize ); @@ -438,6 +446,44 @@ MarkerTracker::MarkerTracker( const std::string& sName, boost::shared_ptr< Graph LOG4CPP_INFO( logger, "MarkerTracker configuration: edgebased refinement: " << m_bEdgeRefinement << " enableTracking: " << m_info.bEnableTracking << " enablePixelFlow: " << m_info.bEnablePixelFlow << " enableFlipCheck " << m_info.bEnableFlipCheck << " bEnableFastTracking " << m_info.bEnableFastTracking ); } +/*! *************************************************************************** +\brief + +\return void + +\author tbochtl \date 17.11.2017 +******************************************************************************/ +void MarkerTracker::start() +{ + if (m_bThreadingEnabled == false) return; + + boost::mutex::scoped_lock l(m_Mutex); + m_State = state_running; + m_NewEventCondition.notify_all(); +} + +/*! *************************************************************************** +\brief + +\return void + +\author tbochtl \date 17.11.2017 +******************************************************************************/ +void MarkerTracker::stop() +{ + boost::mutex::scoped_lock l(m_Mutex); + if (m_State != state_stopped) + { + // tell thread to stop + m_State = state_stopping; + m_NewEventCondition.notify_all(); + + // wait until thread has actually stopped + while (m_State != state_stopped) + m_NewEventCondition.wait(l); + } +} + bool MarkerTracker::debug() { return m_debugPort.isConnected(); @@ -457,7 +503,61 @@ bool MarkerTracker::useEdgeRefinement() const return m_bEdgeRefinement; } void MarkerTracker::pushImage( const Measurement::ImageMeasurement& m ) - { getModule().trackMarkers( m ); } +{ + if (m_bThreadingEnabled == false) + { + getModule().trackMarkers(m); + } + else + { + boost::mutex::scoped_lock l(m_Mutex); + m_measurement = m; + + m_NewEventCondition.notify_all(); + } +} + +/*! *************************************************************************** +\brief + +\return void + +\author tbochtl \date 15.11.2017 +******************************************************************************/ +void MarkerTracker::threadFunction() +{ + Measurement::ImageMeasurement m; + while (true) + { + if (m_State == state_running && m_measurement.invalid() == false) + { + m_Mutex.lock(); + m = m_measurement; + m.time(m_measurement.time()); + m_measurement = Measurement::ImageMeasurement(); + m_Mutex.unlock(); + getModule().trackMarkers(m); + } + else if (m_State == state_end) + { + return; + } + else if (m_State == state_stopping) + { + // stop and wait for something to happen + m_State = state_stopped; + + // tell other threads we have stopped + m_NewEventCondition.notify_all(); + } + else + { + // wait for something to happen + boost::mutex::scoped_lock l(m_Mutex); + m_NewEventCondition.wait(l); + } + } +} //MultiMarkerTracker MultiMarkerTracker::MultiMarkerTracker( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > subgraph, const IdKey& componentKey, MarkerTrackerModule* pModule ) diff --git a/src/utVisionComponents/MarkerTracker.h b/src/utVisionComponents/MarkerTracker.h index aa23d19..f54771b 100644 --- a/src/utVisionComponents/MarkerTracker.h +++ b/src/utVisionComponents/MarkerTracker.h @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -60,6 +61,31 @@ #include #endif +namespace Ubitrack { + namespace Dataflow { + /** + * \internal + * Defines how to extract the priority out of a data type. + * Specialized for image measurements to reduce the maximum queue length. + */ + template<> + struct EventTypeTraits< Measurement::ImageMeasurement > + { + unsigned long long getPriority(const Measurement::ImageMeasurement& m) const + { + return m.time(); + } + + /** the maximum queue length for images is 1! */ + int getMaxQueueLength() const + { + return 1; + } + }; + + } +} + // get a logger static log4cpp::Category& logger( log4cpp::Category::getInstance( "Ubitrack.Vision.MarkerTracker" ) ); @@ -333,6 +359,10 @@ class MarkerTracker public: MarkerTracker( const std::string& sName, boost::shared_ptr< Graph::UTQLSubgraph > subgraph, const IdKey& componentKey, MarkerTrackerModule* pModule ); + // start and stop functions for all processes + virtual void start(); + virtual void stop(); + /** is the debug port connected? */ bool debug(); @@ -367,6 +397,26 @@ class MarkerTracker // some variables where the module stores information Measurement::Timestamp m_lastTime; + bool m_bThreadingEnabled; + + // temp image for the image queue function (used in threading mode) + Measurement::ImageMeasurement m_measurement; + + // the event dispatching thread + boost::shared_ptr< boost::thread > m_pThread; + + // current state of the event thread + enum { state_running, state_stopping, state_stopped, state_end } m_State; + + // condition variable for thread synchronization + boost::condition m_NewEventCondition; + + // mutex for thread synchronization + boost::mutex m_Mutex; + + // queue thread function + void threadFunction(); + friend class MarkerTrackerModule; };