Access create_subscriber and logger without passing around the instantiated Node?
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()