boost库future与then使用
代码:
#include "control/states/states.h" // MSVC pre-compiled header for state machine
#include "preparing.h"
#include "prepared.h" // Preparing->Prepared (PrepareOk)
#include "stopping.h" // Viewing->Stopping (PlcStopRequested)
#include "fatal.h" // Viewing->Fatal (AdamFatal)
#include "camera_events.h" // Required for viewing transitions based on Camera events
#include "plc_events.h"
#include "in_state_handler.h"
#include "algorithm_events.h"
#include "application/camera_interface/camera_component.h"
#include "application/control/adam_control.h"
#include "application/control/prepare_component.h"
#include "application/control/plc_communication.h"
#include "application/stream_engine/stream_engine.h"
#include <boost/log/trivial.hpp>
#include <boost/log/expressions.hpp>
#include <boost/thread/future.hpp>
Preparing::Preparing(my_context ctx)
: boost::statechart::state<Preparing, Viewing>(ctx)
, m_exposure_check_count(0)
, logger(outermost_context().name + ".Preparing")
{
BOOST_LOG_SEV(logger, adam::log::inform) << "Entering Preparing state";
outermost_context().components.plc_communication->set_adam_state(adam::hal::Db_AdamToPbb_V1_AdamData::AdamState::Operational_Preparing);
outermost_context().components.stream_engine->set_state(adam::firmware::AdamStatus::Preparing);
outermost_context().components.prepare_component->activate();
schedule_exposure_check();
}
Preparing::~Preparing()
{
outermost_context().components.prepare_component->deactivate();
BOOST_LOG_SEV(logger, adam::log::inform) << "Exited Preparing state";
}
void Preparing::schedule_exposure_check()
{
// First stabilize exposure
//以下代码boost1.61+opencv3.1.0正常编译,boost1.61+opencv4.6.0编译报错,请问怎么改
outermost_context().components.camera_component->get_image(CameraEnums::NextImage)
.then(outermost_context().continuation_executor,
InStateHandler<Preparing, boost::shared_ptr<adam::firmware::ImageData> >(
&outermost_context(),
boost::bind(
&Preparing::check_exposure_stability,
this,
_1)));
}
void Preparing::check_exposure_stability(boost::shared_future<boost::shared_ptr<adam::firmware::ImageData> > image)
{
++m_exposure_check_count;
if (image.has_exception())
{
// Expect original exception has been logged (we might not be able to properly rethrow OpenCV errors here) and
// has also been set to PLC; we will report calibration failure though
outermost_context().components.plc_communication->set_error_algorithm_error(true);
outermost_context().process_event(AdamErrorEvent());
return;
}
boost::shared_ptr<adam::firmware::ImageData> the_image = image.get();
if (the_image->meta_data.image_info.exposure.stable)
{
// Exposure OK -> check displacement
BOOST_LOG_SEV(logger, adam::log::inform) << "Checking displacement on image " << the_image->meta_data.image_info.sequence_nr;
the_image->meta_data.image_info.algorithms_started_at = boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time());
outermost_context().components.prepare_component->enqueue(the_image)
.then(outermost_context().continuation_executor,
InStateHandler<Preparing, PrepareComponentResults>(
&outermost_context(),
boost::bind(
&Preparing::handle_prepare_result,
this,
_1,
the_image)));
}
else if (m_exposure_check_count < 20)
{
BOOST_LOG_SEV(logger, adam::log::inform) << "Waiting for exposure stability (image " << the_image->meta_data.image_info.sequence_nr << " still unstable)";
outermost_context().adam_control->stream_data(the_image, adam::firmware::AdamStatus::Preparing);
schedule_exposure_check();
}
else
{
// Exposure doesn't stablize -> log and mark calibration as failed
BOOST_LOG_SEV(logger, adam::log::error) << "Auto-exposure is not stable at image " << the_image->meta_data.image_info.sequence_nr;
outermost_context().adam_control->stream_data(the_image, adam::firmware::AdamStatus::Preparing);
outermost_context().components.plc_communication->set_error_algorithm_error(true);
outermost_context().process_event(AdamErrorEvent());
return;
}
}
void Preparing::handle_prepare_result(boost::shared_future<PrepareComponentResults> result,
boost::shared_ptr<adam::firmware::ImageData> image)
{
image->meta_data.image_info.finished_at = boost::posix_time::ptime(boost::posix_time::microsec_clock::universal_time());
boost::shared_future<adam::firmware::StreamEngineResults> stream_result = outermost_context().adam_control->stream_data(image, AdamStatus::Preparing);
if (result.has_exception())
{
// Expect original exception has been logged (we might not be able to properly rethrow OpenCV errors here);
// just pump the AlgorithmError event into the state machine
outermost_context().components.plc_communication->set_error_algorithm_error(true);
outermost_context().process_event(AlgorithmError());
return;
}
vision::displacement::Result displacement_result = result.get().image_data->meta_data.displacement_output.result;
BOOST_LOG_SEV(logger, adam::log::inform) << "Prepare result: " << displacement_result;
bool goto_prepared = false;
switch (image->meta_data.displacement_output.result.code)
{
case vision::displacement::Result::NOT_RUN:
// Should not be possible
BOOST_LOG_SEV(logger, adam::log::fatal) << "Prepare result is NOT_RUN, this should not be possible";
outermost_context().components.plc_communication->set_error_algorithm_error(true);
break;
case vision::displacement::Result::DISPLACEMENT_NONE:
// Everything OK
goto_prepared = true;
break;
case vision::displacement::Result::DISPLACEMENT_UNKNOWN:
// Can continue, so go to prepared, but send warning
outermost_context().components.plc_communication->set_warning_camera_displacement_unknown(true);
goto_prepared = true;
break;
case vision::displacement::Result::DISPLACEMENT_CAMERA_TOP:
// Fatal
outermost_context().components.plc_communication->set_fatal_camera_displaced_1(true);
break;
case vision::displacement::Result::DISPLACEMENT_CAMERA_BOT:
// Fatal
outermost_context().components.plc_communication->set_fatal_camera_displaced_2(true);
break;
case vision::displacement::Result::DISPLACEMENT_BOTH:
// Fatal
outermost_context().components.plc_communication->set_fatal_camera_displaced_1(true);
outermost_context().components.plc_communication->set_fatal_camera_displaced_2(true);
break;
}
// Exit state when data is streamed. Processing the event immediately may result in the StreamEngine being deactivated
// before the data is actually streamed.
if (goto_prepared)
{
stream_result.then(outermost_context().continuation_executor,
InStateHandler<Preparing, adam::firmware::StreamEngineResults>(
&outermost_context(),
boost::bind(static_cast<void(adam::firmware::StateMachine::*)(const boost::statechart::event_base&)>(&adam::firmware::StateMachine::process_event),
&outermost_context(),
PrepareOkEvent())));
}
else
{
stream_result.then(outermost_context().continuation_executor,
InStateHandler<Preparing, adam::firmware::StreamEngineResults>(
&outermost_context(),
boost::bind(static_cast<void(adam::firmware::StateMachine::*)(const boost::statechart::event_base&)>(&adam::firmware::StateMachine::process_event),
&outermost_context(),
PrepareProblemEvent())));
}
}
boost::statechart::result Preparing::react(const CameraBufferDepletedEvent& event)
{
(void)event;
outermost_context().components.plc_communication->set_error_processing_time_too_long(true);
return transit<Fatal>();
}
/////////
template<typename TState, typename TFutureResult>
struct InStateHandler
{
// result struct required to allow boost::result_of<>
template<typename> struct result;
template<typename F, typename T>
struct result<F(T)>
{
typedef void type;
};
/**
* Constructor.
*
* @param[in] machine The state machine to check. Typically, from within a state `&outermost_context()` is used.
* @param[in] callback The callback to call if the state machine is in the @c TState state when this handler is executed.
*/
InStateHandler(typename TState::outermost_context_type* machine, boost::function<void(boost::shared_future<TFutureResult>&)> callback)
: m_machine(machine)
, m_callback(callback)
{
}
void operator()(boost::shared_future<TFutureResult>& future)
{
if (m_machine->template state_cast<const TState*>() != NULL)
{
m_callback(future);
}
}
private:
typename TState::outermost_context_type* m_machine;
boost::function<void(boost::shared_future<TFutureResult>&)> m_callback;
};
//boost161+opencv4.6.0编译报错如下:
/home/lwx/firm161/application/control/states/preparing.cpp:58:25: error: no matching function for call to ‘boost::shared_future<boost::shared_ptradam::firmware::ImageData >::then(adam::infra::SchedulerExecutor<>&, adam::firmware::states::InStateHandler<adam::firmware::states::Preparing, boost::shared_ptradam::firmware::ImageData >)’
1)));
^
In file included from /usr/local/include/boost/thread.hpp:24:0,
from /home/lwx/firm161/hal/…/infra/worker_service.h:9,
from /home/lwx/firm161/hal/…/vision/tracking/template_scoring.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/position_enumeration.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/door_tracker.h:3,
from /home/lwx/firm161/hal/…/application/image_data.h:20,
from /home/lwx/firm161/application/control/states/preparing.h:5,
from /home/lwx/firm161/application/control/states/preparing.cpp:2:
/usr/local/include/boost/thread/future.hpp:2130:9: note: candidate: template boost::future<typename boost::result_of<F(boost::shared_future)>::type> boost::shared_future::then(F&&) const [with F = F; R = boost::shared_ptradam::firmware::ImageData]
then(BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
^
/usr/local/include/boost/thread/future.hpp:2130:9: note: template argument deduction/substitution failed:
/home/lwx/firm161/application/control/states/preparing.cpp:58:25: note: candidate expects 1 argument, 2 provided
1)));
^
In file included from /usr/local/include/boost/thread.hpp:24:0,
from /home/lwx/firm161/hal/…/infra/worker_service.h:9,
from /home/lwx/firm161/hal/…/vision/tracking/template_scoring.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/position_enumeration.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/door_tracker.h:3,
from /home/lwx/firm161/hal/…/application/image_data.h:20,
from /home/lwx/firm161/application/control/states/preparing.h:5,
from /home/lwx/firm161/application/control/states/preparing.cpp:2:
/usr/local/include/boost/thread/future.hpp:2133:9: note: candidate: template boost::future<typename boost::result_of<F(boost::shared_future)>::type> boost::shared_future::then(boost::launch, F&&) const [with F = F; R = boost::shared_ptradam::firmware::ImageData]
then(launch policy, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
^
/usr/local/include/boost/thread/future.hpp:2133:9: note: template argument deduction/substitution failed:
/home/lwx/firm161/application/control/states/preparing.cpp:52:35: note: cannot convert ‘((adam::firmware::states::Preparing*)this)->adam::firmware::states::Preparing::.boost::statechart::state<adam::firmware::states::Preparing, adam::firmware::states::Viewing>::.boost::statechart::simple_state<MostDerived, Context, InnerInitial, historyMode>::outermost_context<adam::firmware::states::Preparing, adam::firmware::states::Viewing, boost::mpl::list<mpl::na, mpl::na, mpl::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na, mpl_::na>, (boost::statechart::history_mode)0u>().adam::firmware::StateMachine::continuation_executor’ (type ‘adam::infra::SchedulerExecutor<>’) to type ‘boost::launch’
.then(outermost_context().continuation_executor,
^
In file included from /usr/local/include/boost/thread.hpp:24:0,
from /home/lwx/firm161/hal/…/infra/worker_service.h:9,
from /home/lwx/firm161/hal/…/vision/tracking/template_scoring.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/position_enumeration.h:5,
from /home/lwx/firm161/hal/…/vision/tracking/door_tracker.h:3,
from /home/lwx/firm161/hal/…/application/image_data.h:20,
from /home/lwx/firm161/application/control/states/preparing.h:5,
from /home/lwx/firm161/application/control/states/preparing.cpp:2:
/usr/local/include/boost/thread/future.hpp:2137:9: note: candidate: template<class Ex, class F> boost::future<typename boost::result_of<F(boost::shared_future)>::type> boost::shared_future::then(Ex&, F&&) const [with Ex = Ex; F = F; R = boost::shared_ptradam::firmware::ImageData]
then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const; // EXTENSION
^
/usr/local/include/boost/thread/future.hpp:2137:9: note: template argument deduction/substitution failed:
/usr/local/include/boost/thread/future.hpp: In substitution of ‘template<class Ex, class F> boost::future<typename boost::result_of<F(boost::shared_future)>::type> boost::shared_future::then(Ex&, F&&) const [with Ex = adam::infra::SchedulerExecutor<>; F = adam::firmware::states::InStateHandler<adam::firmware::states::Preparing, boost::shared_ptradam::firmware::ImageData >]’:
/home/lwx/firm161/application/control/states/preparing.cpp:58:25: required from here
/usr/local/include/boost/thread/future.hpp:5059:3: error: no type named ‘type’ in ‘struct boost::result_of<adam::firmware::states::InStateHandler<adam::firmware::states::Preparing, boost::shared_ptradam::firmware::ImageData >(boost::shared_future<boost::shared_ptradam::firmware::ImageData >)>’
shared_future::then(Ex& ex, BOOST_THREAD_FWD_REF(F) func) const
^
/home/lwx/firm161/application/control/states/preparing.cpp: In member function ‘void adam::firmware::states::Preparing::check_exposure_stability(boost::shared_future<boost::shared_ptradam::firmware::ImageData >)’:
问题:
在boost161+opencv3.1.0编译可以通过,在boost161+opencv4.6.0无法通过,请问哪位知道怎么解决吗?