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

    ros2 python call_async(异步回调)方法求助

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

      ros2 不建议使用同步请求,但是在实际的场景中,同步请求没办法避免,所以为了实现同步效果,我在异步请求的回调函数中修改成员变量的值,当值改变时确定回复已收到,代码为:

      client.call_async(request).add_done_callback(self.callback)
      time.sleep(0.004)
      if(self.is_ok):
         print('ok')
      

      在callback(self)函数中会修改self.is_ok为True。
      在实际测试中,使用这种策略可以在我笔记本电脑中正常输出ok,但是换一台台式电脑,异步的回调函数一直等到当前函数执行完成后才会执行,台式电脑中,异步回调函数的线程id和主函数相同,好像异步回调一直被主线程卡住。
      有大佬了解异步回调的机制,或者有什么比较好使的方法能够完成同步请求吗?(python和c++都能聊聊)

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

        @Lorry 可以给服务的客户端一个单独的回调组,相当于有数据来了到另外一个回调组进行处理,这样就不会卡主线程,等另外一个回调组处理完,你的is_ok设成true,这样就可以在主线程进行检测

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

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

          @Lorry 也可以这样,你单独开回调组给客户端的回调函数,然后你的后续逻辑直接在回调函数调用,也可以保证时序

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

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

            @小鱼 程序中我确实也给client单独指定了回调组,类型是ReentrantCallbackGroup,笔记本电脑中确实是回调和主线程不卡,但是在台式机中,回调一定要等到主线程执行完才会执行

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

              @小鱼 在 ros2 python call_async(异步回调)方法求助 中说:

              @Lorry 可以给服务的客户端一个单独的回调组,相当于有数据来了到另外一个回调组进行处理,这样就不会卡主线程,等另外一个回调组处理完,你的is_ok设成true,这样就可以在主线程进行检测

              回调组如果指定类型为ReentrantCallbackGroup,即便多个订阅或者client都使用同一个回调组, 应该不会相互阻塞吧?

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

                @Lorry 虽然回调组在单独的县城了,但启动回调的线程还是主线程,所以主线程不要阻塞,要做阻塞的事情单独开线程做。

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

                1 条回复 最后回复 回复 引用 0
                • 15223469361
                  孤缘
                  最后由 编辑

                  ros2同步调用其实是好用的,虽然文档里写的不建议用。
                  其次可以试试将异步调用封装成同步的

                          future = call_async(request)
                          while True:
                              if future.done():
                                  break
                  
                  LorryL 1 条回复 最后回复 回复 引用 0
                  • LorryL
                    Lorry @1522346936
                    最后由 编辑

                    @1522346936 我之前也是这样使用,但是经常出问题,会出现死循环。还是需要把异步调用封装成同步才行

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