Help me understand ros2 execution model
I'm new to ROS2 and struggling to understand how to architect certain aspects of my system. A recurrent problem I'm facing is dealing with nodes that subscribe to specific data and need to provide some functionality to analyze that data. Maybe this piece of (not real) code will make things clearer:
class ExampleNode(Node):
def __init__(self):
super().__init__('a_node')
self.fb_sub = self.create_subscription(
Float32,
'/sensor_data',
self.sensor_callback,
QoSPresetProfiles.SENSOR_DATA,
)
#We will keep a buffer for the last 100 readings
self.readings = deque([],100)
def sensor_callback(self, msg):
self.readings.append(msg.data)
def on_demand_foo(self):
# Processes the data on self.readings in some way
return self.process_data(self.readings)
def process_data(self, data):
#Some processing of data here
return None
def main(args=None):
rclpy.init(args=args)
my_node = ExampleNode()
rclpy.spin(my_node)
result = my_node.on_demand_foo()
rclpy.shutdown()
if __name__ == '__main__':
main()
On the one hand, I need to spin the node such that the readings buffer is full with the latest sensor readings, and when I call the on_demand_foo method, it can give me information based on the latest data. On the other hand, spinning the node will block execution for any other code, so you can't call any class methods after the spin statement.
I feel this is just not how ROS2 is meant to work, so how do you solve this kind of situation? Is it the case that the only way to query nodes to analyze information is through a service call and not through a function call? Is there any way to avoid the overhead of a service/action call and use functions instead?
Thanks in advance for your help!