ROS2中rclpy.spin的内部逻辑探索笔记

        最近刚开始接触学习ROS2,总是不是很理解rclpy.spin的内部实现逻辑。看了代码发现它是循环调用spin_once()。那么这个spin_once()又做了什么呢?

import rclpy
from rclpy.node import Node
import time


class HelloHZF(Node):
    def __init__(self, name):
        super().__init__(name)
        print("Init Run!!!")
        self.mytimer = self.create_timer(1, self.timercallback)
        self.mytimer2 = self.create_timer(2, self.timercallback2)
        print("Go On")

    def timercallback(self):
        self.get_logger().info("111111111111111111111111111")

    def timercallback2(self):
        self.get_logger().info("222222222222222222222222222")



def main(args=None):
    rclpy.init(args=args)
    node = HelloHZF("HaoMingZi_Node")
    #rclpy.spin(node)
    for i in range(0,10):
        rclpy.spin_once(node)
    node.destroy_node()
    rclpy.shutdown()

在上述代码中,我在node的init做了两个timer,一个是间隔1s,一个是间隔2s。然后在main中调用时,让spin_once()执行10次。结果如下:

udeer@udeer-PC:~/dev_ws$ ros2 run aaaaa 111 
Init Run!!!
Go On
[INFO] [1683687464.138775232] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687465.131338797] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687465.132454845] [HaoMingZi_Node]: 222222222222222222222222222
[INFO] [1683687466.131441968] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687467.131162605] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687467.132301120] [HaoMingZi_Node]: 222222222222222222222222222
[INFO] [1683687468.131334806] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687469.131437717] [HaoMingZi_Node]: 111111111111111111111111111
[INFO] [1683687469.132673857] [HaoMingZi_Node]: 222222222222222222222222222
[INFO] [1683687470.131421845] [HaoMingZi_Node]: 111111111111111111111111111

可见,其实spin就类似一个线程池,把node里面的callback都放入这个池子里。然后运行10次,刚好就是速度快的多、速度慢的少。即11111出两次、22222出一次。加起来一共出10次。

这是create_timer里的callback。subscription里的callback也是一样的作用么?我又做了如下实验。

import rclpy
from rclpy.node import Node
from std_msgs.msg import String

# Create Listener Node
class Listener(Node):
    def __init__(self, name):
        super().__init__(name)
        self.sub = self.create_subscription(String, "talk/hzftalk/mywords", self.listenCallback, 10)
        #self.pub = self.create_publisher(String, "talk/hzftalk/mywords", 10)
        #self.timer = self.create_timer(0.5, self.timer_callback)

    def listenCallback(self, msg:String):
        self.get_logger().info('I heard : %s' % msg.data)

def main(args=None):
    rclpy.init(args=args)
    node = Listener("ListenerName")
    for i in range(10):
        rclpy.spin_once(node)
    node.destroy_node()
    rclpy.shutdown()

然后启动listener 和 talker,发现其的确只运行了10遍callback,如下:

udeer@udeer-PC:~/dev_ws$ ros2 run aaaaa 333 
[INFO] [1683688054.920636936] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688055.106918619] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688055.306843618] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688055.506869519] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688055.707022448] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688055.907058273] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688056.106918888] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688056.307077716] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688056.507085334] [ListenerName]: I heard : Hello Hzf
[INFO] [1683688056.708624266] [ListenerName]: I heard : Hello Hzf

因此,无论是timer里的callback、还是subscription里的callback,进入rclpy.spin()里的调度方式是一致的。并没有区别。

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值