|
39 | 39 |
|
40 | 40 |
|
41 | 41 | class ROS2ARIConnector(ROS2ActionMixin, ROS2ServiceMixin, ARIConnector[ROS2ARIMessage]):
|
| 42 | + """ROS2-specific implementation of the ARIConnector. |
| 43 | +
|
| 44 | + This connector provides functionality for ROS2 communication through topics, |
| 45 | + services, and actions, as well as TF (Transform) operations. |
| 46 | +
|
| 47 | + Parameters |
| 48 | + ---------- |
| 49 | + node_name : str, optional |
| 50 | + Name of the ROS2 node. If not provided, generates a unique name with UUID. |
| 51 | + destroy_subscribers : bool, optional |
| 52 | + Whether to destroy subscribers after receiving a message, by default False. |
| 53 | +
|
| 54 | + Methods |
| 55 | + ------- |
| 56 | + get_topics_names_and_types() |
| 57 | + Get list of available topics and their message types. |
| 58 | + get_services_names_and_types() |
| 59 | + Get list of available services and their types. |
| 60 | + get_actions_names_and_types() |
| 61 | + Get list of available actions and their types. |
| 62 | + send_message(message, target, msg_type, auto_qos_matching=True, qos_profile=None, **kwargs) |
| 63 | + Send a message to a specified topic. |
| 64 | + receive_message(source, timeout_sec=1.0, msg_type=None, auto_topic_type=True, **kwargs) |
| 65 | + Receive a message from a specified topic. |
| 66 | + wait_for_transform(tf_buffer, target_frame, source_frame, timeout_sec=1.0) |
| 67 | + Wait for a transform to become available. |
| 68 | + get_transform(target_frame, source_frame, timeout_sec=5.0) |
| 69 | + Get the transform between two frames. |
| 70 | + create_service(service_name, on_request, on_done=None, service_type, **kwargs) |
| 71 | + Create a ROS2 service. |
| 72 | + create_action(action_name, generate_feedback_callback, action_type, **kwargs) |
| 73 | + Create a ROS2 action server. |
| 74 | + shutdown() |
| 75 | + Clean up resources and shut down the connector. |
| 76 | +
|
| 77 | + Notes |
| 78 | + ----- |
| 79 | + Threading Model: |
| 80 | + The connector creates a MultiThreadedExecutor that runs in a dedicated thread. |
| 81 | + This executor processes all ROS2 callbacks and operations asynchronously. |
| 82 | +
|
| 83 | + Subscriber Lifecycle: |
| 84 | + The `destroy_subscribers` parameter controls subscriber cleanup behavior: |
| 85 | + - True: Subscribers are destroyed after receiving a message |
| 86 | + - Pros: Better resource utilization |
| 87 | + - Cons: Known stability issues (see: https://github.com/ros2/rclpy/issues/1142) |
| 88 | + - False (default): Subscribers remain active after message reception |
| 89 | + - Pros: More stable operation, avoids potential crashes |
| 90 | + - Cons: May lead to memory/performance overhead from inactive subscribers |
| 91 | + """ |
| 92 | + |
42 | 93 | def __init__(
|
43 |
| - self, node_name: str = f"rai_ros2_ari_connector_{str(uuid.uuid4())[-12:]}" |
| 94 | + self, |
| 95 | + node_name: str = f"rai_ros2_ari_connector_{str(uuid.uuid4())[-12:]}", |
| 96 | + destroy_subscribers: bool = False, |
44 | 97 | ):
|
45 | 98 | super().__init__()
|
46 | 99 | self._node = Node(node_name)
|
47 |
| - self._topic_api = ROS2TopicAPI(self._node) |
| 100 | + self._topic_api = ROS2TopicAPI(self._node, destroy_subscribers) |
48 | 101 | self._service_api = ROS2ServiceAPI(self._node)
|
49 | 102 | self._actions_api = ROS2ActionAPI(self._node)
|
50 | 103 | self._tf_buffer = Buffer(node=self._node)
|
51 |
| - self.tf_listener = TransformListener(self._tf_buffer, self._node) |
| 104 | + self._tf_listener = TransformListener(self._tf_buffer, self._node) |
52 | 105 |
|
53 | 106 | self._executor = MultiThreadedExecutor()
|
54 | 107 | self._executor.add_node(self._node)
|
@@ -173,7 +226,7 @@ def node(self) -> Node:
|
173 | 226 | return self._node
|
174 | 227 |
|
175 | 228 | def shutdown(self):
|
176 |
| - self.tf_listener.unregister() |
| 229 | + self._tf_listener.unregister() |
177 | 230 | self._node.destroy_node()
|
178 | 231 | self._actions_api.shutdown()
|
179 | 232 | self._topic_api.shutdown()
|
|
0 commit comments