鱼香ROS社区
    • 版块
    • 最新
    • 未解决
    • 已解决
    • 群组
    • 注册
    • 登录
    紧急通知:禁止一切关于政治&VPN翻墙等话题,发现相关帖子会立马删除封号
    提问前必看的发帖注意事项: 社区问答规则(小鱼个人)更新 | 高质量帖子发布指南

    关于ros2 action发布时回调函数的模板函数格式问题

    已定时 已固定 已锁定 已移动 未解决
    综合问题
    nav2 ros2 action 模板函数
    4
    11
    432
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 小伊小
      机器人小伊
      最后由 编辑

      从您提供的错误信息来看,问题出在尝试将std::bind的结果赋值给rclcpp_action::Client<>::GoalResponseCallback类型的成员变量上,而std::bind返回的是一个不可转换为std::function的绑定对象(特别是当涉及到模板和完美转发时)。此外,您使用的模板函数goal_response_callback在std::bind的上下文中也没有正确地指定模板参数。

      在ROS 2中,您应该使用lambda表达式来代替std::bind,因为lambda表达式与std::function的兼容性更好,并且更易于理解和使用。

      这里是一个使用lambda表达式来设置goal_response_callback的例子:

      send_goal_options.goal_response_callback =
          [this](std::shared_future<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>::SharedPtr> future) {
              this->goal_response_callback_helper(future);
          };
      
      // 辅助函数,用于处理回调,避免在lambda中直接写太多代码
      template<typename T>
      void goal_response_callback_helper(T future) {
          if (debug) {
              // ...(您的日志代码)
              auto goal_handle = future.get();
              if (!goal_handle) {
                  RCLCPP_ERROR(this->get_logger(), "Goal was rejected by server");
              } else {
                  RCLCPP_INFO(this->get_logger(), "Goal accepted by server, waiting for result");
              }
          }
      }
      

      请注意,我创建了一个名为goal_response_callback_helper的辅助函数来处理实际的回调逻辑,因为lambda表达式内不适合直接写大量代码。另外,由于lambda表达式已经捕获了this指针,因此可以直接在lambda内部调用类的成员函数。

      关于C++标准的问题,虽然您设置了CMAKE_CXX_STANDARD 14,但错误消息中显示的路径和错误类型通常与C++11相关。这可能是因为ROS 2的某些部分或依赖项仍然使用C++11。然而,这不太可能是您遇到的主要问题,因为lambda表达式和std::function在C++11中就已经是可用的了。

      如果上述解决方案不起作用,或者您遇到其他编译错误,请检查ROS 2文档以确保您的代码与ROS 2的API兼容,并考虑升级您的ROS 2版本(如果可能的话)。


      以上为生成回答,仅供参考~

      我是小伊,已接入ChatGpt,所有回复,仅供参考~

      24291485052 1 条回复 最后回复 回复 引用 0
      • 24291485052
        Plaech @小伊
        最后由 编辑

        @小伊 在 关于ros2 action发布时回调函数的模板函数格式问题 中说:

        send_goal_options.goal_response_callback =
        [this](std::shared_future<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>::SharedPtr> future) {
        this->goal_response_callback_helper(future);
        };

        不对,这样修改后报错还是大同小异,不能解决我的问题

        /home/vr/ros2_hoist/src/hoist_decision/src/hoist_decision.cpp:79:13: error: no match for ‘operator=’ (operand types are ‘rclcpp_action::Client<nav2_msgs::action::NavigateToPose>::GoalResponseCallback’ {aka ‘std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>’} and ‘hoist_decision::GoToPose(geometry_msgs::msg::Pose_<std::allocator<void> >::SharedPtr, int, int)::<lambda(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > >)>’)
           79 |             };
              |             ^
        In file included from /usr/include/c++/11/functional:59,
                         from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
                         from /usr/include/c++/11/algorithm:74,
                         from /home/vr/ros2_hoist/src/hoist_decision/src/hoist_decision.cpp:3:
        /usr/include/c++/11/bits/std_function.h:530:9: note: candidate: ‘template<class _Functor> std::function<_Res(_ArgTypes ...)>::_Requires<std::function<_Res(_ArgTypes ...)>::_Callable<_Functor>, std::function<_Res(_ArgTypes ...)>&> std::function<_Res(_ArgTypes ...)>::operator=(_Functor&&) [with _Functor = _Functor; _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >}]’
          530 |         operator=(_Functor&& __f)
              |         ^~~~~~~~
        /usr/include/c++/11/bits/std_function.h:530:9: note:   template argument deduction/substitution failed:
        In file included from /usr/include/c++/11/bits/move.h:57,
                         from /usr/include/c++/11/bits/exception_ptr.h:43,
                         from /usr/include/c++/11/exception:153,
                         from /usr/include/c++/11/ios:39,
                         from /usr/include/c++/11/ostream:38,
                         from /usr/include/c++/11/iostream:39,
                         from /home/vr/ros2_hoist/src/hoist_decision/src/hoist_decision.cpp:1:
        /usr/include/c++/11/type_traits: In substitution of ‘template<bool _Cond, class _Tp> using __enable_if_t = typename std::enable_if::type [with bool _Cond = false; _Tp = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>&]’:
        /usr/include/c++/11/bits/std_function.h:353:8:   required by substitution of ‘template<class _Res, class ... _ArgTypes> template<class _Cond, class _Tp> using _Requires = std::__enable_if_t<_Cond::value, _Tp> [with _Cond = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>::_Callable<hoist_decision::GoToPose(geometry_msgs::msg::Pose_<std::allocator<void> >::SharedPtr, int, int)::<lambda(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > >)>, hoist_decision::GoToPose(geometry_msgs::msg::Pose_<std::allocator<void> >::SharedPtr, int, int)::<lambda(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > >)>, std::__invoke_result<hoist_decision::GoToPose(geometry_msgs::msg::Pose_<std::allocator<void> >::SharedPtr, int, int)::<lambda(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > >)>&, std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > > >; _Tp = std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>&; _Res = void; _ArgTypes = {std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >}]’
        /usr/include/c++/11/bits/std_function.h:530:2:   required by substitution of ‘template<class _Functor> std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>::_Requires<std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>::_Callable<_Functor, typename std::enable_if<(! std::is_same<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)> >::value), std::decay<_Tp> >::type::type, std::__invoke_result<typename std::enable_if<(! std::is_same<typename std::remove_cv<typename std::remove_reference<_Tp>::type>::type, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)> >::value), std::decay<_Tp> >::type::type&, std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > > >, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>&> std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>::operator=<_Functor>(_Functor&&) [with _Functor = hoist_decision::GoToPose(geometry_msgs::msg::Pose_<std::allocator<void> >::SharedPtr, int, int)::<lambda(std::shared_future<std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> > >)>]’
        /home/vr/ros2_hoist/src/hoist_decision/src/hoist_decision.cpp:79:13:   required from here
        /usr/include/c++/11/type_traits:2205:11: error: no type named ‘type’ in ‘struct std::enable_if<false, std::function<void(std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose> >)>&>’
         2205 |     using __enable_if_t = typename enable_if<_Cond, _Tp>::type;
              |           ^~~~~~~~~~~~~
        In file included from /usr/include/c++/11/functional:59,
                         from /usr/include/c++/11/pstl/glue_algorithm_defs.h:13,
                         from /usr/include/c++/11/algorithm:74,
                         from /home/vr/ros2_hoist/src/hoist_decision/src/hoist_decision.cpp:3:
        
        
        1 条回复 最后回复 回复 引用 0
        • 小伊小
          机器人小伊
          最后由 编辑

          这个错误是因为你试图将一个 lambda 表达式赋值给一个 rclcpp_action::ClientGoalHandle 类型的 std::function 回调,但是 lambda 表达式的参数类型与 std::function 所期望的参数类型不匹配。

          在你的代码中,lambda 表达式是这样的:

          [this](std::shared_future<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>::SharedPtr> future) {
              this->goal_response_callback_helper(future);
          };
          

          而 rclcpp_action::Client<nav2_msgs::action::NavigateToPose>::GoalResponseCallback 应该是一个接受 std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>> 的 std::function。

          但是,你的 lambda 表达式中接受的是 std::shared_future 的一个模板实例,而不是直接接受 std::shared_ptr。

          要修复这个错误,你需要确保 lambda 表达式的参数类型与 rclcpp_action::Client 所期望的回调类型相匹配。由于 rclcpp_action::Client 并不直接处理 std::shared_future,你应该使用一个 std::shared_ptr 而不是 std::shared_future。

          如果你需要在回调函数中使用 std::shared_future(这通常不是 rclcpp_action 的标准用法),你可能需要改变你的设计,以便回调函数能够访问包含 std::shared_future 的某个对象或状态。

          但是,在大多数情况下,你应该直接传递 std::shared_ptr,如下所示:

          send_goal_options.goal_response_callback =
          [this](std::shared_ptr<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>> goal_handle) {
              // 你的回调函数逻辑,这里可以使用 goal_handle
              this->goal_response_callback_helper(goal_handle);
          };
          

          请注意,我将 std::shared_future 替换为 std::shared_ptr<rclcpp_action::ClientGoalHandle<...>>。

          确保你的 goal_response_callback_helper 函数也接受相同类型的参数。如果它确实需要 std::shared_future(这通常不是 ROS 2 actions 的情况),你需要重新设计你的代码以适应这一点。


          以上为生成回答,仅供参考~

          我是小伊,已接入ChatGpt,所有回复,仅供参考~

          1 条回复 最后回复 回复 引用 0
          • minemyemailsM
            minemyemails
            最后由 编辑

            std::bind(&hoist_decision::goal_response_callback<std::shared_future<rclcpp_action::ClientGoalHandle<nav2_msgs::action::NavigateToPose>::SharedPtr>>, this, _1 );
            这个代码的长度真是糟糕啊😀

            24291485052 1 条回复 最后回复 回复 引用 0
            • 24291485052
              Plaech @minemyemails
              最后由 编辑

              @minemyemails 😂 确实是这样的,但是模板定义就这么长。
              不过我这个错误解决不掉,改用普通函数了

              1 条回复 最后回复 回复 引用 0
              • 小鱼小
                小鱼 技术大佬 @2429148505
                最后由 编辑

                @2429148505 https://gitee.com/ohhuo/ros2bookcode/raw/master/chapt7/chapt7_ws/src/fishbot_application_cpp/src/nav2pose.cpp 可以参考这个代码

                新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

                24291485052 3 条回复 最后回复 回复 引用 1
                • 24291485052
                  Plaech @小鱼
                  最后由 编辑

                  @小鱼 太好了,可惜才看到😮 。

                  1 条回复 最后回复 回复 引用 0
                  • 24291485052
                    Plaech @小鱼
                    最后由 编辑

                    @小鱼 这个cookboot很好啊,之前怎么没宣传一下。之前看到你的教学中有提到一个cookbook,但好像点不进去

                    1 条回复 最后回复 回复 引用 0
                    • 24291485052
                      Plaech @小鱼
                      最后由 编辑

                      @小鱼 发现是新书中的代码,快快出书吧

                      小鱼小 1 条回复 最后回复 回复 引用 0
                      • 小鱼小
                        小鱼 技术大佬 @2429148505
                        最后由 编辑

                        @2429148505 在预售了,预计8月中旬到货,等我店里上架,会更便宜点,已经要求编辑按最低价格定价了

                        新书配套视频:https://www.bilibili.com/video/BV1GW42197Ck/

                        1 条回复 最后回复 回复 引用 0
                        • 第一个帖子
                          最后一个帖子
                        皖ICP备16016415号-7
                        Powered by NodeBB | 鱼香ROS