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

    ros2自定义客户端中spin_until_future_complete的问题

    已定时 已固定 已锁定 已移动
    ROS 2相关问题
    ros2 service
    3
    13
    3.3k
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • LorryL
      Lorry @小鱼
      最后由 编辑

      @小鱼 小鱼,我大概明白上面方法的意思。但是在实践上有些蒙(原谅我基础有点差)
      动手学ROS2中代码:

      // 3.发送异步请求,然后等待返回,返回时调用回调函数
      client_->async_send_request(
      request, std::bind(&ServiceClient01::result_callback_, this,
      std::placeholders::_1));
      
      void result_callback_(
      rclcpp::Client<example_interfaces::srv::AddTwoInts>::SharedFuture result_future) 
      {
          auto response = result_future.get();
          RCLCPP_INFO(this->get_logger(), "计算结果:%ld", response->sum);
        }
      

      其中,SharedFuture是在回调中使用,回调中如果使用了wait_for(),也不能够实现同步获取response吧?我其实是想实现客户端发送请求,然后同步获取响应,这能实现吗?

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

        @Lorry 在 ros2自定义客户端中spin_until_future_complete的问题 中说:

        client_->async_send_reques

        注意这个函数有返回值,返回的就是future

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

        LorryL 3 条回复 最后回复 回复 引用 0
        • LorryL
          Lorry @小鱼
          最后由 编辑

          @小鱼 这一点我忽略了😿

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

            @小鱼 小鱼,使用wait_for()确实能让线程等待,但是最终接收到的数据的状态一直都是timeout。
            其中,我客户端相关代码:

            auto result=Client_->async_send_request(request);
                std::future_status status =result.wait_for(100ms);
                if (status == std::future_status::timeout)//子线程还没执行完
            	{
            		RCLCPP_INFO(this->get_logger(),"Time out,Failed!");
            	}
            	else if (status == std::future_status::ready)//子线程已执行完
            	{
            		RCLCPP_INFO(this->get_logger(),"Ready.....");
            	}
            

            我监测了服务端用于处理请求的耗时,大概是5~20ms之间,客户端等待100ms应该能成功接收到返回的response。不知道为什么每次等待100ms,status 一直都是std::future_status::timeout。(是我代码写错了?😂 )

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

              @小鱼 我对服务端的回调函数的定义也有些疑问,rclpy的定义方式中,会将response作为返回值,在将response赋值后进行回调,如

              def add_two_ints_callback(self, request, response):
                  response.sum = request.a + request.b
                  self.get_logger().info('Incoming request\na: %d b: %d' % (request.a, request.b))
                      return response
              

              而rclcpp中,并没有指定返回值,只是将response赋值,如:

              void add(const std::shared_ptr<example_interfaces::srv::AddTwoInts::Request> request,
                        std::shared_ptr<example_interfaces::srv::AddTwoInts::Response>      response)
              {
                response->sum = request->a + request->b;
                RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "Incoming request\na: %ld" " b: %ld",
                              request->a, request->b);
                RCLCPP_INFO(rclcpp::get_logger("rclcpp"), "sending back response: [%ld]", (long int)response->sum);
              }
              

              那response是在赋值后直接发送给client了吗?

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

                @Lorry 在 ros2自定义客户端中spin_until_future_complete的问题 中说:

                不知道为什么每次等待100ms

                std::future_status status =result.wait_for(100ms);

                你的代码是这样写的呀,可以不传参试试

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

                LorryL 2 条回复 最后回复 回复 引用 0
                • 小鱼小
                  小鱼 技术大佬 @Lorry
                  最后由 编辑

                  @Lorry 两者不同是因为编程语言限制,c++可以直接传指针,给指针赋值,而python直接将对象返回比较直接。

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

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

                    @小鱼 我找到解决办法了。我代码中是通过定时器完成定时的客户端请求,所以是在定时循环中发起的async_send_request(request)。当不指定定时器的回调组时,result.wait_for(100ms)一定会等待100ms,并且状态一定是std::future_status::timeout。我后来指定了定时器的回调组rclcpp::CallbackGroupType::MutuallyExclusive,wait_for函数就能正常接收到服务端的返回信息。
                    其实我之前一直以为MutuallyExclusive回调组和不指定回调组的效果一样,看来还要再去看看回调组的原理(对了,wait_for函数必须要传参才行,不传参的是wait)

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

                      @小鱼 贴一下timer部分的代码,有同样问题的可以看一下

                      callback_group_timer=this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
                          Timer_ = this->create_wall_timer(
                            5000ms, std::bind(&S7ClinetNode::time_callback, this),callback_group_timer);
                      
                      1 1 条回复 最后回复 回复 引用 0
                      • 小鱼小
                        小鱼 技术大佬 @Lorry
                        最后由 编辑

                        @Lorry ☺️好嘞

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

                        1 条回复 最后回复 回复 引用 0
                        • 1
                          18801286624 @Lorry
                          最后由 编辑

                          @Lorry 在 ros2自定义客户端中spin_until_future_complete的问题 中说:

                          @小鱼 贴一下timer部分的代码,有同样问题的可以看一下

                          callback_group_timer=this->create_callback_group(rclcpp::CallbackGroupType::MutuallyExclusive);
                              Timer_ = this->create_wall_timer(
                                5000ms, std::bind(&S7ClinetNode::time_callback, this),callback_group_timer);
                          

                          现在遇到了同样的问题,也是result.wait_for一定会等待100ms,并且状态一定是timeout,区别是我是在订阅话题的回调函数中发起的客户端请求,请问有有办法可以解决吗?

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