Notes sur l'exploration logique interne de rclpy.spin dans ROS2

        Je viens de commencer à apprendre ROS2 récemment et je ne comprends toujours pas très bien la logique de mise en œuvre interne de rclpy.spin. Après avoir regardé le code, j'ai découvert qu'il appelait spin_once() en boucle. Alors, que fait ce 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()

Dans le code ci-dessus, j'ai créé deux timers dans l'initialisation du nœud, l'un avec un intervalle de 1 s et l'autre avec un intervalle de 2 s. Ensuite, lorsqu'il est appelé dans main, laissez spin_once() s'exécuter 10 fois. Le résultat est le suivant :

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

On peut voir que le spin est en fait similaire à un pool de threads, et tous les rappels du nœud sont placés dans ce pool. Ensuite, exécutez-le 10 fois, ce qui s'avère être beaucoup plus rapide et moins lent. Autrement dit, 11111 sort deux fois et 22222 sort une fois. Un total de 10 fois au total.

Il s'agit du rappel dans create_timer. Le rappel en abonnement a-t-il la même fonction ? J'ai refait l'expérience suivante.

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()

Ensuite, démarrez l'auditeur et le locuteur et constatez qu'ils n'exécutent le rappel que 10 fois, comme suit :

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

Ainsi, qu'il s'agisse d'un rappel en timer ou d'un rappel en abonnement, la méthode de planification saisie dans rclpy.spin() est la même. Il n'y a pas de différence.

Supongo que te gusta

Origin blog.csdn.net/huangzhuofei/article/details/130596393
Recomendado
Clasificación