liwenxiong0721 2023-10-16 23:08 采纳率: 33.3%
浏览 12
已结题

boost库future与then使用

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无法通过,请问哪位知道怎么解决吗?

  • 写回答

17条回答 默认 最新

  • 社区专家-Monster-XH 2023-10-16 23:08
    关注
    获得1.60元问题酬金

    基于Monster 组和GPT的调写:

    • 主要问题出在 boost::shared_future::then 方法的使用上。根据错误消息,编译器无法找到匹配的函数调用,因为 then 方法的候选项期望接收1个参数,但是提供了2个。

    在 Boost 的 then 方法中,通常有三种形式:

    1. future<R>::then(F&& func) const,它只接受一个函数作为参数。
    2. future<R>::then(boost::launch policy, F&& func) const,它接受一个 boost::launch 策略和一个函数。
    3. future<R>::then(Ex& ex, F&& func) const,它接受一个执行器和一个函数。
    • 代码中,传递两个参数:一个是 continuation_executor,另一个是 InStateHandler 实例。根据错误日志,continuation_executor 类型不能转换为 boost::launch,这意味着您可能尝试使用第三种形式的 then,即带有执行器的版本。

    • 这里的问题可能是 InStateHandler 实例不是编译器期望的正确函数对象类型。您需要确保它是一个可以接受 boost::shared_future<boost::shared_ptr<adam::firmware::ImageData>> 作为参数的函数对象,并且有一个返回类型(boost::result_of 在内部用于推断这种类型)。

    • 解决方案可能涉及更正 InStateHandler 的定义,确保它可以作为 then 方法的回调函数,或者更改如何构建和传递这个 InStateHandler 实例。

    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 10月24日
  • 赞助了问题酬金15元 10月18日
  • 修改了问题 10月18日
  • 修改了问题 10月18日
  • 展开全部

悬赏问题

  • ¥15 C++ 句柄后台鼠标拖动如何实现
  • ¥15 有人会SIRIUS 5.8.0这个软件吗
  • ¥30 comsol仿真等离激元
  • ¥15 静电纺丝煅烧后如何得到柔性纤维
  • ¥15 (标签-react native|关键词-镜像源)
  • ¥100 照片生成3D人脸视频
  • ¥15 伪装视频时长问题修改MP4的时长问题,
  • ¥15 JETSON NANO
  • ¥15 VS开发qt时如何在paintgl函数中用pushbutton控制切换纹理
  • ¥20 关于 openpyxl 处理excel文件地问题