Access create_subscriber and logger without passing around the instantiated Node?

asked 2023-05-03 08:21:41 -0500

Iranaphor gravatar image

When utilising hierarchies of objects in ROS 2; the instantiated Node must be passed into all instances of all child classes to enable access to functionalities such as subscriptions and logging. For an example like the ones below this is fairly trivial, however for nodes which are larger, passing the Node to every object so they can each perform their own logging and manage their own subscribers, can get out of hand. Is there a recommended alternative which works more inline with the ROS 2 standards?

ROS 1 Method

import rospy
import std_msgs.msg

class Subsystem():
    def __init__(self, id):
        self.id = id
        self.sub = rospy.Subscriber('/topic', std_msgs.msg.String, self.cb)

    def cb(self, msg):
        rospy.loginfo(f'{self.id} recieved {msg.data}')

class MyNode():
    def __init__(self):
        self.systems = [Subsystem(1), Subsystem(2)]

if __name__ == '__main__':
    rospy.init_node('node_name')
    new_node = MyNode()
    rospy.spin()

ROS 2 Method

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

class Subsystem():
    def __init__(self, id, parent_node):
        self.id = id
        self.parent_node = parent_node
        self.sub = self.parent_node.create_subscription(std_msgs.msg.String, '/topic', self.cb)

    def cb(self, msg):
        self.parent_node.get_logger().info(f'{self.id} recieved {msg.data}')

class MyNode(Node):
    def __init__(self):
        super().__init__('node_name')
        self.systems = [Subsystem(1, self), Subsystem(2, self)]

def main(args=None):
    rclpy.init(args=args)

    new_node = MyNode()
    rclpy.spin(new_node)

    new_node.destroy_node()
    rclpy.shutdown()

if __name__ == '__main__':
    main()
edit retag flag offensive close merge delete