@@ -95,6 +95,7 @@ def __init__(
9595
9696 self .topic_name = None
9797 self .subscriber = None
98+ self .connected = False
9899
99100 self .services = {
100101 'open' : None ,
@@ -119,6 +120,8 @@ def __init__(
119120 }
120121 # create service clients
121122 self .services ["open" ] = self .create_service_client (key = "open" )
123+ if self .services ["open" ] is None :
124+ return # Prevent from waiting more time for other services and exit earlier.
122125 self .services ["close" ] = self .create_service_client (key = "close" )
123126 self .services ["reconfigure" ] = self .create_service_client (key = "reconfigure" )
124127
@@ -160,15 +163,23 @@ def _connect_on_init(self, timeout_sec=1.0):
160163 request .parameters .snapshot_period = self .parameters .snapshot_period
161164 console .logdebug ("establishing a snapshot stream connection [{}][backend]" .format (self .namespace ))
162165 future = self .services ["open" ].call_async (request )
163- rclpy .spin_until_future_complete (self .node , future )
166+ start_time = time .monotonic ()
167+ while not future .done ():
168+ elapsed_time = time .monotonic () - start_time
169+ if elapsed_time > timeout_sec :
170+ console .logerror (f"Timed out waiting to open a connection" )
171+ return
172+ rclpy .spin_once (self .node , timeout_sec = 0.1 )
164173 response = future .result ()
165174 self .topic_name = response .topic_name
166175 # connect to a snapshot stream
167176 start_time = time .monotonic ()
168177 while True :
169178 elapsed_time = time .monotonic () - start_time
170179 if elapsed_time > timeout_sec :
171- raise exceptions .TimedOutError ("timed out waiting for a snapshot stream publisher [{}]" .format (self .topic_name ))
180+ console .logerror (f"Timed out waiting for a snapshot stream publisher [{ self .topic_name } ]" )
181+ self .connected = False
182+ return
172183 if self .node .count_publishers (self .topic_name ) > 0 :
173184 break
174185 time .sleep (0.1 )
@@ -178,6 +189,7 @@ def _connect_on_init(self, timeout_sec=1.0):
178189 callback = self .callback ,
179190 qos_profile = utilities .qos_profile_latched ()
180191 )
192+ self .connected = True
181193 console .logdebug (" ...ok [backend]" )
182194
183195 def shutdown (self ):
@@ -197,6 +209,9 @@ def create_service_client(self, key: str):
197209
198210 Args:
199211 key: one of 'open', 'close'.
212+
213+ Returns:
214+ A client if successful, else None.
200215
201216 Raises:
202217 :class:`~py_trees_ros.exceptions.NotReadyError`: if setup() wasn't called to identify the relevant services to connect to.
@@ -213,9 +228,8 @@ def create_service_client(self, key: str):
213228 )
214229 # hardcoding timeouts will get us into trouble
215230 if not client .wait_for_service (timeout_sec = 3.0 ):
216- raise exceptions .TimedOutError (
217- "timed out waiting for {}" .format (self .service_names ['close' ])
218- )
231+ console .logdebug (f"Timed out waiting for { self .service_names ['close' ]} " )
232+ return None
219233 return client
220234
221235##############################################################################
@@ -253,10 +267,12 @@ def spin(self):
253267 if self .parameters != old_parameters :
254268 if self .snapshot_stream is not None :
255269 self .snapshot_stream .reconfigure (self .parameters )
256- old_parameters = copy .copy (self .parameters )
270+ old_parameters = copy .copy (self .parameters )
257271 if self .enqueued_connection_request_namespace is not None :
258272 self .connect (self .enqueued_connection_request_namespace )
259- self .enqueued_connection_request_namespace = None
273+ # If connection failed, keep retrying with the latest enqueued namespace.
274+ if self .snapshot_stream .connected :
275+ self .enqueued_connection_request_namespace = None
260276 rclpy .spin_once (self .node , timeout_sec = 0.1 )
261277 if self .snapshot_stream is not None :
262278 self .snapshot_stream .shutdown ()
0 commit comments