def send_goals(node, action_type, tests): import rclpy from rclpy.action import ActionClient action_client = ActionClient(node, action_type, 'test/action/' + action_type.__name__) if not action_client.wait_for_server(20): print('Action server not available after waiting', file=sys.stderr) return 1 test_index = 0 while rclpy.ok() and test_index < len(tests): print('Sending goal for test number {}'.format(test_index), file=sys.stderr) test = tests[test_index] invalid_feedback = False # On feedback, check the feedback is valid def feedback_callback(feedback): nonlocal invalid_feedback if not test.is_feedback_valid(feedback): invalid_feedback = True goal_handle_future = action_client.send_goal_async( test.goal, feedback_callback=feedback_callback) rclpy.spin_until_future_complete(node, goal_handle_future) goal_handle = goal_handle_future.result() if not goal_handle.accepted: print('Goal rejected', file=sys.stderr) return 1 get_result_future = goal_handle.get_result_async() rclpy.spin_until_future_complete(node, get_result_future) result = get_result_future.result() if not test.is_result_valid(result): return 1 if invalid_feedback: return 1 test_index += 1 return 0
def _call_get_transitions(node, states, service_name): clients = {} futures = {} # create clients for node_name in states.keys(): clients[node_name] = node.create_client(GetAvailableTransitions, f'{node_name}/{service_name}') # wait until all clients have been called while True: for node_name in [n for n in states.keys() if n not in futures]: # call as soon as ready client = clients[node_name] if client.service_is_ready(): request = GetAvailableTransitions.Request() future = client.call_async(request) futures[node_name] = future if len(futures) == len(clients): break rclpy.spin_once(node, timeout_sec=1.0) # wait for all responses for future in futures.values(): rclpy.spin_until_future_complete(node, future) # return transitions from current state or exception for each node transitions = {} for node_name, future in futures.items(): if future.result() is not None: response = future.result() transitions[node_name] = [] for transition_description in response.available_transitions: if (states[node_name] is None or transition_description.start_state == states[node_name]): transitions[node_name].append(transition_description) else: transitions[node_name] = future.exception() return transitions
def shutdown(self): self.info_msg('Shutting down') self.action_client.destroy() transition_service = 'lifecycle_manager_navigation/manage_nodes' mgr_client = self.create_client(ManageLifecycleNodes, transition_service) while not mgr_client.wait_for_service(timeout_sec=1.0): self.info_msg(transition_service + ' service not available, waiting...') req = ManageLifecycleNodes.Request() req.command = ManageLifecycleNodes.Request().SHUTDOWN future = mgr_client.call_async(req) try: self.info_msg('Shutting down navigation lifecycle manager...') rclpy.spin_until_future_complete(self, future) future.result() self.info_msg( 'Shutting down navigation lifecycle manager complete.') except Exception as e: # noqa: B902 self.error_msg('Service call failed %r' % (e, )) transition_service = 'lifecycle_manager_localization/manage_nodes' mgr_client = self.create_client(ManageLifecycleNodes, transition_service) while not mgr_client.wait_for_service(timeout_sec=1.0): self.info_msg(transition_service + ' service not available, waiting...') req = ManageLifecycleNodes.Request() req.command = ManageLifecycleNodes.Request().SHUTDOWN future = mgr_client.call_async(req) try: self.info_msg('Shutting down localization lifecycle manager...') rclpy.spin_until_future_complete(self, future) future.result() self.info_msg( 'Shutting down localization lifecycle manager complete') except Exception as e: # noqa: B902 self.error_msg('Service call failed %r' % (e, ))
def __spawn(self): models = [[ "beer", "/root/robotic_arm/models/beer/model.sdf", (-0.18, 0.5, 0.) ], [ "coke_can", "/root/robotic_arm/models/coke_can/model.sdf", (0.24, 0.5, 0.) ]] for model in models: request = SpawnEntity.Request() request.name = model[0] request.xml = open(model[1], 'r').read() request.robot_namespace = "spawned_object" request.initial_pose.position.x, request.initial_pose.position.y, request.initial_pose.position.z = model[ 2] done = False while not done: future = self.spawn_client.call_async(request) rclpy.spin_until_future_complete(self.entity_spawner, future) if future.result().success: done = True
def wait_for_message(self, topic, topic_type, timeout=None, qos_profile=None, executor=None): """ Wait for one message from topic. This will create a new subcription to the topic, receive one message, then unsubscribe. Do not call this method in a callback or a deadlock may occur. """ s = None try: future = Future() s = self.create_subscriber( topic_type, topic, lambda msg: future.set_result(msg), qos_profile=qos_profile) rclpy.spin_until_future_complete(self, future, self.executor, timeout) finally: if s is not None: self.destroy_subscription(s) return future.result()
def main(args=None): rclpy.init(args=args) node = Node("add_nums_client") client = node.create_client(AddTwoInts, "add_nums_service") while not client.wait_for_service(1): node.get_logger().info("waiting for " + client.srv_name) request = AddTwoInts.Request() request.a = 1 request.b = 2 future = client.call_async(request) rclpy.spin_until_future_complete(node, future) try: response = future.result() node.get_logger().info("Got " + str(response.sum)) except Exception as e: node.get.get_logger().error("Service error %r" % (e,)) rclpy.shutdown()
def reset(self): """ Reset the agent for a particular experiment condition. """ self.iterator = 0 if self.reset_jnts is True: # reset simulation while not self.reset_sim.wait_for_service(timeout_sec=1.0): self.node.get_logger().info( 'service not available, waiting again...') reset_future = self.reset_sim.call_async(Empty.Request()) rclpy.spin_until_future_complete(self.node, reset_future) # Take an observation self.ob = self.take_observation() while self.ob is None: self.ob = self.take_observation() # Return the corresponding observation return self.ob
def test_send_goal_async_with_feedback_before_goal(self): ac = ActionClient(self.node, Fibonacci, 'fibonacci') try: self.assertTrue(ac.wait_for_server(timeout_sec=2.0)) # Publish feedback before goal has been accepted goal_uuid = UUID(uuid=list(uuid.uuid4().bytes)) self.mock_action_server.publish_feedback(goal_uuid) self.timed_spin(1.0) self.assertEqual(self.feedback, None) # Send a goal and then publish feedback future = ac.send_goal_async( Fibonacci.Goal(), feedback_callback=self.feedback_callback, goal_uuid=goal_uuid) rclpy.spin_until_future_complete(self.node, future, self.executor) # Check the feedback was not received self.assertEqual(self.feedback, None) finally: ac.destroy()
def submit_task_request(self, req_msg) -> str: """ Task Submission - This function will trigger a ros srv call to the dispatcher node, and return a response. Function will return a Task ID """ print("Submit Task Request!") try: future = self.submit_task_srv.call_async(req_msg) rclpy.spin_until_future_complete(self, future, timeout_sec=0.5) response = future.result() if response is None: self.get_logger().warn('/submit_task srv call failed') elif not response.success: self.node.get_logger().error( 'Dispatcher node failed to accept task') else: self.get_logger().info( f'New Dispatch task_id {response.task_id}') return response.task_id except Exception as e: self.get_logger().error('Error! Submit Srv failed %r' % (e, )) return ""
def __publish_arm_cmds(self, action): # set joint angle for i in range(6): self.arm_cmd_msgs[i].position = 100 * float( action[i]) * 3.1416 / 180 # publish five times to the joint angle topic for j in range(5): self.arm_cmd_nodes_pubs[i][1].publish(self.arm_cmd_msgs[i]) # set gripper request self.arm_cmd_msgs[-1].goal_angularposition = float(action[6]) while not self.arm_cmd_nodes_pubs[-1][1].wait_for_service( timeout_sec=1.0): continue goal_accepted = False while not goal_accepted: gripper_future = self.arm_cmd_nodes_pubs[-1][1].call_async( self.arm_cmd_msgs[-1]) rclpy.spin_until_future_complete(self.arm_cmd_nodes_pubs[-1][0], gripper_future) if gripper_future.result() is not None: if gripper_future.result().goal_accepted: goal_accepted = True
def get_available_states(lifecycle_node): node = rclpy.create_node('lc_client_py') service_name = lifecycle_node + '/get_available_states' cli = node.create_client(GetAvailableStates, service_name) if not cli.wait_for_service(timeout_sec=5.0): node.get_logger().warn('Unable to call service %s' % service_name) return req = GetAvailableStates.Request() future = cli.call_async(req) rclpy.spin_until_future_complete(node, future) if future.result() is not None: resp = future.result() node.get_logger().info('%s has %u available states' % (lifecycle_node, len(resp.available_states))) for state in resp.available_states: node.get_logger().info('id: %u\tlabel: %s' % (state.id, state.label)) else: node.get_logger.error('Exception %r during call %s' % (future.exception(), service_name))
def test_expire_goals_one(self): # 1 second timeout action_server = ActionServer( self.node, Fibonacci, 'fibonacci', execute_callback=self.execute_goal_callback, result_timeout=1, ) goal_msg = Fibonacci.Impl.SendGoalService.Request() goal_msg.goal_id = UUID(uuid=list(uuid.uuid4().bytes)) goal_future = self.mock_action_client.send_goal(goal_msg) rclpy.spin_until_future_complete(self.node, goal_future, self.executor) self.assertEqual(1, len(action_server._goal_handles)) # After two seconds the internal goal handle should be destroyed self.timed_spin(2.1) self.assertEqual(0, len(action_server._goal_handles)) action_server.destroy()
def moveGripper(self, vel, pos, effort): self.vel = vel self.pos = pos self.effort = effort print('moveGripper', self.vel, self.pos, self.effort) req = ControlFinger.Request() req.goal_velocity = self.vel # velocity range: 30 - 250 mm/s req.goal_effort = self.effort # forces range: 10 - 125 N req.goal_linearposition = self.pos # position range 0 - 0.87 rad future = self.cli.call_async(req) rclpy.spin_until_future_complete(self.node, future) if future.result() is not None: self.node.get_logger().info('Goal accepted: %d: ' % future.result().goal_accepted) else: self.node.get_logger().error( 'Exception while calling service: %r' % future.exception()) done = True return done
def backup(self, backup_dist=0.15, backup_speed=0.025, time_allowance=10): self.debug("Waiting for 'Backup' action server") while not self.backup_client.wait_for_server(timeout_sec=1.0): self.info("'Backup' action server not available, waiting...") goal_msg = BackUp.Goal() goal_msg.target = Point(x=float(backup_dist)) goal_msg.speed = backup_speed goal_msg.time_allowance = Duration(sec=time_allowance) self.info( f'Backing up {goal_msg.target.x} m at {goal_msg.speed} m/s....') send_goal_future = self.backup_client.send_goal_async( goal_msg, self._feedbackCallback) rclpy.spin_until_future_complete(self, send_goal_future) self.goal_handle = send_goal_future.result() if not self.goal_handle.accepted: self.error('Backup request was rejected!') return False self.result_future = self.goal_handle.get_result_async() return True
def main(args=None): rclpy.init(args=args) node = Node("add_two_ints_no_oop") client= node.create_client(AddTwoInts, "add_two_ints") while not client.wait_for_service(1.0): node.get_logger().warn("waiting for server Add Two Ints...") request= AddTwoInts.Request() request.a= 3 request.b= 4 future= client.call_async(request) rclpy.spin_until_future_complete(node, future) try: response= future.result() node.get_logger().info(str(request.a) + " + " + str(request.b) + " = " + str(response.sum)) except Exception as e: node.get_logger().error("service call failed %r" % (e,)) rclpy.shutdown()
def test_config(self): #axis = self.node.get_parameter('axis').value # ref_config = rospy.get_param('/{}/thruster_manager'.format(NS)) srv_name = '/{}/thruster_manager/get_config'.format(NS) cli = self.node.create_client(GetThrusterManagerConfig, srv_name) if not cli.wait_for_service(timeout_sec=30): self.fail('service %s not available...' % srv_name) # srv = rospy.ServiceProxy('/{}/thruster_manager/get_config'.format(NS), GetThrusterManagerConfig) # tm_config = srv() req = GetThrusterManagerConfig.Request() future = cli.call_async(req) rclpy.spin_until_future_complete(self.node, future) tm_config = future.result() self.assertEqual(tm_config.tf_prefix, '/test_vehicle/') self.assertEqual(tm_config.base_link, 'base_link') self.assertEqual(tm_config.thruster_frame_base, 'thruster_') self.assertEqual(tm_config.thruster_topic_suffix, '/input') self.assertEqual(tm_config.timeout, -1) self.assertEqual(tm_config.max_thrust, 1000.0) self.assertEqual(tm_config.n_thrusters, 3) if AXIS == 'x': tam_flat = AXIS_X_TAM.flatten() elif AXIS == 'y': tam_flat = AXIS_Y_TAM.flatten() elif AXIS == 'z': tam_flat = AXIS_Z_TAM.flatten() self.assertEqual(len(tm_config.allocation_matrix), tam_flat.size, tam_flat) for x, y in zip(tam_flat, tm_config.allocation_matrix): self.assertAlmostEqual(x, y)
def call_set_parameters(*, node, node_name, parameters): # create client client = node.create_client( SetParameters, '/{node_name}/set_parameters'.format_map(locals())) # call as soon as ready ready = client.wait_for_service(timeout_sec=5.0) if not ready: raise RuntimeError('Wait for service timed out') request = SetParameters.Request() request.parameters = parameters future = client.call_async(request) rclpy.spin_until_future_complete(node, future) # handle response response = future.result() if response is None: e = future.exception() raise RuntimeError('Exception while calling service of node ' "'{args.node_name}': {e}".format_map(locals())) return response
def service_caller(node, service_name, service_type, request, service_timeout=10.0): cli = node.create_client(service_type, service_name) if not cli.service_is_ready(): node.get_logger().debug( f'waiting {service_timeout} seconds for service {service_name} to become available...' ) if not cli.wait_for_service(service_timeout): raise RuntimeError(f'Could not contact service {service_name}') node.get_logger().debug(f'requester: making request: {request}\n') future = cli.call_async(request) rclpy.spin_until_future_complete(node, future) if future.result() is not None: return future.result() else: raise RuntimeError( f'Exception while calling service: {future.exception()}')
def runNavigateAction(self, goal_pose: Optional[Pose] = None): # Sends a `NavToPose` action request and waits for completion self.info_msg("Waiting for 'NavigateToPose' action server") while not self.action_client.wait_for_server(timeout_sec=1.0): self.info_msg( "'NavigateToPose' action server not available, waiting...") self.goal_pose = goal_pose if goal_pose is not None else self.goal_pose goal_msg = NavigateToPose.Goal() goal_msg.pose = self.getStampedPoseMsg(self.goal_pose) self.info_msg("Sending goal request...") send_goal_future = self.action_client.send_goal_async(goal_msg) rclpy.spin_until_future_complete(self, send_goal_future) goal_handle = send_goal_future.result() if not goal_handle.accepted: self.error_msg("Goal rejected") return False self.info_msg("Goal accepted") get_result_future = goal_handle.get_result_async() future_return = True self.info_msg("Waiting for 'NavigateToPose' action to complete") rclpy.spin_until_future_complete(self, get_result_future) status = get_result_future.result().status if status != GoalStatus.STATUS_SUCCEEDED: self.info_msg(f"Goal failed with status code: {status}") return False if not future_return: return False self.info_msg("Goal succeeded!") return True
def main(args=None): rclpy.init(args=args) node = rclpy.create_node('client_test') client = node.create_client(ImageClassificationSrv, 'image_classification') def vision_info_callback(vision_info_msg): node.get_logger().info(f'received vision info {repr(vision_info_msg)}') node.create_subscription(VisionInfoMsg, 'vision_info', vision_info_callback, qos_profile=qos_profile_vision_info) img_path = tf.keras.utils.get_file( 'YellowLabradorLooking_new.jpg', 'https://storage.googleapis.com/download.tensorflow.org/example_images/YellowLabradorLooking_new.jpg' ) # noqa: E501 while not client.wait_for_service(timeout_sec=1.0): node.get_logger().info('service not available, waiting again...') req = ImageClassificationSrv.Request() req.image = img_utils.jpg_to_image_msg(img_path) future = client.call_async(req) rclpy.spin_until_future_complete(node, future) if future.result() is not None: classification = future.result().classification node.get_logger().info( f'Result of classification:\n{str(classification.results)}') else: node.get_logger().error( f'Exception while calling service: {repr(future.exception())}') node.destroy_node() rclpy.shutdown()
def call_change_states(*, node, transitions): clients = {} futures = {} # create clients for node_name in transitions.keys(): client = node.create_client( ChangeState, '/{node_name}/change_state'.format_map(locals())) clients[node_name] = client # wait until all clients have been called while True: for node_name in [n for n in transitions.keys() if n not in futures]: # call as soon as ready client = clients[node_name] if client.service_is_ready(): request = ChangeState.Request() request.node_name = node_name request.transition = transitions[node_name] future = client.call_async(request) futures[node_name] = future if len(futures) == len(clients): break rclpy.spin_once(node, timeout_sec=1.0) # wait for all responses for future in futures.values(): rclpy.spin_until_future_complete(node, future) # return success flag or exception for each node results = {} for node_name, future in futures.items(): if future.result() is not None: response = future.result() results[node_name] = response.success else: results[node_name] = future.exception() return results
def requester(service_pkg, service_name, namespace): import rclpy # Import the service module = importlib.import_module(service_pkg + '.srv') srv_mod = getattr(module, service_name) req = srv_mod.Request() resp = srv_mod.Response() srv_fixtures = [[req, resp]] service_name = 'test/service/' + service_name rclpy.init(args=[]) try: node = rclpy.create_node('requester', namespace=namespace) try: # wait for the service to be available client = node.create_client(srv_mod, service_name) tries = 15 while rclpy.ok() and not client.wait_for_service(timeout_sec=1.0) and tries > 0: print('service not available, waiting again...') tries -= 1 assert tries > 0, 'service still not available, aborting test' print('requester: beginning request') # Make one call to that service for req, resp in srv_fixtures: future = client.call_async(req) rclpy.spin_until_future_complete(node, future) assert repr(future.result()) == repr(resp), \ 'unexpected response %r\n\nwas expecting %r' % (future.result(), resp) print('received reply #%d of %d' % ( srv_fixtures.index([req, resp]) + 1, len(srv_fixtures))) finally: node.destroy_node() finally: rclpy.shutdown()
def get_lifecycle_state(self): """ Get lifecycle state. Arguments --------- None Returns ------- label : int """ future = self.client_get_state.call_async(GetState.Request()) rclpy.spin_until_future_complete(self, future, executor=self.executor, timeout_sec=self.timeout_sec) if future.result() is None: raise RuntimeError( "Interpreter tried to get current lifecycle state, but failed." ) return future.result().current_state.label
def main(args=None): rclpy.init(args=args) add_three_client = AddThreeIntClient() future = add_three_client.send_request() rclpy.spin_until_future_complete(add_three_client, future) if future.done(): try: response = future.result() except Exception: raise RuntimeError( 'exception while calling service: %r' % future.exception() ) else: add_three_client.get_logger().info('==== Service Call Done ====') add_three_client.get_logger().info(f'Status_message : {add_three_client.req.a} + \ {add_three_client.req.b} + {add_three_client.req.c} = {response.sum}') finally: add_three_client.get_logger().warn('==== Shutting down node. ====') add_three_client.destroy_node() rclpy.shutdown()
def check_for_statistic_publications(args=None) -> None: """ Check that all nodes publish a statistics message. :param args: """ try: future = Future() rclpy.init(args=args) node = StatisticsListener(future, list(EXPECTED_LIFECYCLE_NODES)) rclpy.spin_until_future_complete(node, future, timeout_sec=TIMEOUT_SECONDS) if node.received_all_published_stats: logging.info('check_for_statistic_publications success') else: raise SystemMetricsEnd2EndTestException( 'check_for_statistic_publications failed.' ' Absent publisher(s): ' + str(node.expected_lifecycle_nodes)) finally: node.destroy_node() rclpy.shutdown()
def call_describe_parameters(*, node, node_name, parameter_names=None): # create client client = node.create_client(DescribeParameters, f'{node_name}/describe_parameters') # call as soon as ready ready = client.wait_for_service(timeout_sec=5.0) if not ready: raise RuntimeError('Wait for service timed out') request = DescribeParameters.Request() if parameter_names: request.names = parameter_names future = client.call_async(request) rclpy.spin_until_future_complete(node, future) # handle response response = future.result() if response is None: e = future.exception() raise RuntimeError( f"Exception while calling service of node '{node_name}': {e}") return response
def main(args=None): rclpy.init(args=args) robot_spawn_node = SpawnRobot() future = robot_spawn_node.send_req() rclpy.spin_until_future_complete(robot_spawn_node, future) if future.done(): try: response = future.result() except Exception: raise RuntimeError('exception while calling service: %r' % future.exception()) else: robot_spawn_node.get_logger().info('==== Service Call Done ====') robot_spawn_node.get_logger().info( f'Status_message : {response.status_message}') finally: robot_spawn_node.get_logger().warn('==== Shutting down node. ====') robot_spawn_node.destroy_node() rclpy.shutdown()
def unload_component_from_container(*, node, remote_container_node_name, component_uids): """ Unload a component from a running container synchronously. :param node: an `rclpy.Node` instance :param remote_container_node_name: of the container node to unload the component from :param component_uids: list of unique IDs of the components to be unloaded """ unload_node_client = node.create_client( composition_interfaces.srv.UnloadNode, '{}/_container/unload_node'.format(remote_container_node_name) ) try: unload_node_client.wait_for_service() for uid in component_uids: request = composition_interfaces.srv.UnloadNode.Request() request.unique_id = uid future = unload_node_client.call_async(request) rclpy.spin_until_future_complete(node, future) response = future.result() yield uid, not response.success, response.error_message finally: node.destroy_client(unload_node_client)
def followPath(self, path, controller_id='', goal_checker_id=''): """Send a `FollowPath` action request.""" self.debug("Waiting for 'FollowPath' action server") while not self.follow_path_client.wait_for_server(timeout_sec=1.0): self.info("'FollowPath' action server not available, waiting...") goal_msg = FollowPath.Goal() goal_msg.path = path goal_msg.controller_id = controller_id goal_msg.goal_checker_id = goal_checker_id self.info('Executing path...') send_goal_future = self.follow_path_client.send_goal_async( goal_msg, self._feedbackCallback) rclpy.spin_until_future_complete(self, send_goal_future) self.goal_handle = send_goal_future.result() if not self.goal_handle.accepted: self.error('Follow path was rejected!') return False self.result_future = self.goal_handle.get_result_async() return True
def main(args=None): rclpy.init(args=args) node = rclpy.create_node('minimal_client') cli = node.create_client(AddTwoInts, 'add_two_ints') req = AddTwoInts.Request() req.a = 41 req.b = 1 while not cli.wait_for_service(timeout_sec=1.0): node.get_logger().info('service not available, waiting again...') future = cli.call_async(req) rclpy.spin_until_future_complete(node, future) if future.result() is not None: node.get_logger().info( 'Result of add_two_ints: for %d + %d = %d' % (req.a, req.b, future.result().sum)) else: node.get_logger().info('Service call failed %r' % (future.exception(),)) node.destroy_node() rclpy.shutdown()
def make_get_parameters_request(self, node: str, names: List[str]) -> List[ParameterValue]: """ Make a request to a GetParameters service of a node. :param node: Node to make the request to. :param names: Parameter names to request from the node. :return: Returns the values that are retrieved from the service call. """ srv_name = f"{node}/get_parameters" if srv_name not in self.get_parameter_clients: client = self.create_client(GetParameters, srv_name) self.get_parameter_clients[srv_name] = client else: client = self.get_parameter_clients[srv_name] while not client.wait_for_service(timeout_sec=1): self.get_logger().info( f"Waiting for {srv_name} to become available.") future = client.call_async(GetParameters.Request(names=names)) rclpy.spin_until_future_complete(self, future) return future.result().values
def main(args=None): rclpy.init(args=args) node = rclpy.create_node('minimal_client') cli = node.create_client(AddTwoInts, 'add_two_ints') req = AddTwoInts.Request() req.a = 41 req.b = 1 while not cli.wait_for_service(timeout_sec=1.0): node.get_logger().info('service not available, waiting again...') future = cli.call_async(req) rclpy.spin_until_future_complete(node, future) if future.result() is not None: node.get_logger().info('Result of add_two_ints: for %d + %d = %d' % (req.a, req.b, future.result().sum)) else: node.get_logger().info('Service call failed %r' % (future.exception(), )) node.destroy_node() rclpy.shutdown()
def requester(service_name, namespace): import rclpy from test_msgs.service_fixtures import get_test_srv # Import the service service_pkg = 'test_msgs' module = importlib.import_module(service_pkg + '.srv') srv_mod = getattr(module, service_name) srv_fixtures = get_test_srv(service_name) service_name = 'test/service/' + service_name rclpy.init(args=[]) try: node = rclpy.create_node('requester', namespace=namespace) try: # wait for the service to be available client = node.create_client(srv_mod, service_name) tries = 15 while rclpy.ok() and not client.wait_for_service(timeout_sec=1.0) and tries > 0: print('service not available, waiting again...') tries -= 1 assert tries > 0, 'service still not available, aborting test' print('requester: beginning request') # Make one call to that service for req, resp in srv_fixtures: future = client.call_async(req) rclpy.spin_until_future_complete(node, future) assert repr(future.result()) == repr(resp), \ 'unexpected response %r\n\nwas expecting %r' % (future.result(), resp) print('received reply #%d of %d' % ( srv_fixtures.index([req, resp]) + 1, len(srv_fixtures))) finally: node.destroy_node() finally: rclpy.shutdown()