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

    python使用回调组问题

    已定时 已固定 已锁定 已移动 已解决
    综合问题
    python c++回调组改造python
    2
    3
    620
    正在加载更多帖子
    • 从旧到新
    • 从新到旧
    • 最多赞同
    回复
    • 在新帖中回复
    登录后回复
    此主题已被删除。只有拥有主题管理权限的用户可以查看。
    • 2716585362
      ℡﹏smˋ背靠背の承诺
      最后由 编辑

      https://fishros.com/d2lros2/#/chapt4/4.10服务实现(C++)?id=_2服务端(王二)实现
      上面是c++实现,我想改造成python。
      代码如下

      import rclpy
      from rclpy.node import Node
      # 1. 导入消息类型
      from std_msgs.msg import String,UInt32
      #从村庄接口服务类中导入卖小说服务
      from village_interfaces.srv import SellNovel
      #创建队列
      from queue import Queue,LifoQueue,PriorityQueue
      from rclpy.executors import MultiThreadedExecutor
      from rclpy.callback_groups import MutuallyExclusiveCallbackGroup
      from rclpy.callback_groups import CallbackGroup
      
      class ThrottledCallbackGroup(CallbackGroup):
      
          def __init__(self, node):
              super().__init__()
               # 声明服务端        
              node.get_logger().info('声明服务端----------------------------------')
              self.sell_service = node.create_service(SellNovel,"sell_novel",node.sell_novel_callback)
              self.bucket = 10
              self.bucket_max = 10
             
      
          def can_execute(self, entity):
              """
              Ask group if this entity could be executed.
      
              :param entity: A timer, subscriber, client, or service instance
              :rtype bool: true if a callback can be executed
              """
              return self.bucket > 0
      
          def beginning_execution(self, entity):
              """
              Get permission from the group to execute a callback for an entity.
      
              :param entity: A timer, subscriber, client, or service instance
              :rtype bool: true if the executor has permission to execute it
              """
              with self.lock:
                  if self.bucket > 0:
                      # Take a token
                      self.bucket -= 1
                      return True
                  # The bucket has no tokens
                  return False
      
          def ending_execution(self, entity):
              """
              Notify group that a callback finished executing.
      
              :param entity: A timer, subscriber, client, or service instance
              """
              pass
      
          def timer_callback(self):
              """Replenish the tokens in the bucket at a steady rate."""
              with self.lock:
                  # If there is room in the bucket, add a token to it.
                  if self.bucket < self.bucket_max:
                      self.bucket += 1
      
      
      class createNode(Node):
          """
          对象编写
          """
          def __init__(self,name):
              super().__init__(name)
              self.get_logger().info("大家好,我是%s,我是一名订阅者!" % name)
              # 创建队列
              self.queue_list = Queue(maxsize=0)
              self.msg = ""
              # 2.订阅李四发布的文章
              self.sub_wangwu = self.create_subscription(String,"sexy_girl", self.recv_msg_callback, 10) 
              #3. 创建金钱发布者
              self.pub_money = self.create_publisher(UInt32,"sexy_girl_money", 10) 
              # 声明回调组
              # self.sell_novel_callback_group = ThrottledCallbackGroup(self)
              self.sell_novel_callback_group = MutuallyExclusiveCallbackGroup()
              self.sell_service = self.create_service(SellNovel,"sell_novel",self.sell_novel_callback,callback_group=self.sell_novel_callback_group)
      
          def recv_msg_callback(self,msg):
              """
              3. 获取订阅老四的数据
              """
              self.msg = msg.data
              self.get_logger().info('穷汉王五:我已经收到了李四的稿子,%s' % self.msg)
              """
              4.发布金钱消息给李四
              """
              money = UInt32()
              money.data = 10
              self.pub_money.publish(money)  #将金钱发给李四
              self.queue_list.put(self.msg)
      
          # 买书请求回调函数
          def sell_novel_callback(self,request, response):
              # 判断当前书的数量章节够不够,不够就要攒书,在返回
              # 等待queue_list里面书够 等待就会让当前线程阻塞
              self.get_logger().info('收到一个买书的请求,一共给了%d 元' % request.money)
              # 应给小说数量,一块钱一章
              novelsNum = request.money*1
              # 判断当前书库里书的数量是否满足张三要买的数量,不够则进入等待函数
              if self.queue_list._qsize() < novelsNum:
                  self.get_logger().info('当前艳娘传奇章节存量为%d:不能满足需求,开始等待' % self.queue_list._qsize())
                  # 设置rate周期为1s,代表1s检查一次
                  rate = self.create_rate(1)
                  while (self.queue_list._qsize()<novelsNum):
                      self.get_logger().info('设置rate周期为1s,代表1s检查一次 %s' % rclpy.ok())
                      if rclpy.ok() == False:
                          self.get_logger().info('程序被终止了')
                          return
                      self.get_logger().info('等待中,目前已有%d章,还差%d章' % (self.queue_list._qsize(),novelsNum-self.queue_list._qsize()))
                      rclpy.spin_once(self)
                      rate.sleep()
              self.get_logger().info('当前艳娘传奇章节存量为%d:已经满足需求' % self.queue_list._qsize())
      
              for novel in self.queue_list:        
                  print ('当前小说: %s'% novel)
                  response.novels.append(self.queue_list.get())
              return response
      
      
      def main(args=None):
          """
          王五订阅小说给李四稿费
          """
          rclpy.init(args=args) # 初始化rclpy
          node = createNode("wangwu")  # 新建一个节点
          #rclpy.Executor.add_node(node).spin()  rclcpp::executors::MultiThreadedExecutor exector;
          executor = MultiThreadedExecutor()
          #executor = PriorityExecutor()
          executor.add_node(node)
          executor.spin()
          #rclpy.spin(node) # 保持节点运行,检测是否收到退出指令(Ctrl+C)
          rclpy.shutdown() # 关闭rclpy
      
      

      执行wangwu命令:
      colcon build --packages-select village_li
      source install/setup.bash
      os2 run village_li wangwu_node
      执行购买小说命令:
      ros2 service call /sell_novel village_interfaces/srv/SellNovel "{money: 5}"
      在执行作家李四命令写小说
      1650273990.png
      各位大佬 卡在这个地方不动了 是代码哪儿写错了呢

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

        @271658536 去掉sell_novel_callback中的spin_once()试试,在main中已经有spin了

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

        2716585362 1 条回复 最后回复 回复 引用 0
        • 2716585362
          ℡﹏smˋ背靠背の承诺 @小鱼
          最后由 编辑

          @小鱼 好的小鱼大佬,非常感谢,按照你说的删除后就正常了

          1 条回复 最后回复 回复 引用 0
          • 2716585362 271658536 将这个主题标记为已解决,在
          • 小鱼小 小鱼 在 中 引用了 这个主题
          • 第一个帖子
            最后一个帖子
          皖ICP备16016415号-7
          Powered by NodeBB | 鱼香ROS