def generate_launch_description(): keystroke_node = Node(package='keystroke', node_executable='keystroke_listen', output='screen', node_name='keystroke_listen', parameters=[{ 'exit_on_esc': True }], arguments=['__log_level:=warn']) twist_node = Node(package='keystroke', node_executable='keystroke_arrows_to_twist', output='screen', node_name='arrows_to_twist', parameters=[{ 'publish_period': 0.1, 'linear_scale': 0.1, 'angular_scale': 0.2 }]) return LaunchDescription([ keystroke_node, twist_node, RegisterEventHandler(event_handler=OnProcessExit( target_action=keystroke_node, on_exit=[EmitEvent(event=Shutdown())], )), RegisterEventHandler(event_handler=OnProcessExit( target_action=twist_node, on_exit=[EmitEvent(event=Shutdown())], )) ])
def generate_launch_description(): gazebo = IncludeLaunchDescription( PythonLaunchDescriptionSource([ os.path.join(get_package_share_directory('gazebo_ros'), 'launch'), '/gazebo.launch.py' ]), ) gazebo_ros2_control_demos_path = os.path.join( get_package_share_directory('gazebo_ros2_control_demos')) xacro_file = os.path.join(gazebo_ros2_control_demos_path, 'urdf', 'test_cart_velocity.xacro.urdf') doc = xacro.parse(open(xacro_file)) xacro.process_doc(doc) params = {'robot_description': doc.toxml()} node_robot_state_publisher = Node(package='robot_state_publisher', executable='robot_state_publisher', output='screen', parameters=[params]) spawn_entity = Node( package='gazebo_ros', executable='spawn_entity.py', arguments=['-topic', 'robot_description', '-entity', 'cartpole'], output='screen') load_joint_state_controller = ExecuteProcess(cmd=[ 'ros2', 'control', 'load_controller', '--set-state', 'start', 'joint_state_broadcaster' ], output='screen') load_joint_trajectory_controller = ExecuteProcess(cmd=[ 'ros2', 'control', 'load_controller', '--set-state', 'start', 'velocity_controller' ], output='screen') load_imu_sensor_broadcaster = ExecuteProcess( cmd=['ros2', 'control', 'load_controller', 'imu_sensor_broadcaster'], output='screen') return LaunchDescription([ RegisterEventHandler(event_handler=OnProcessExit( target_action=spawn_entity, on_exit=[load_joint_state_controller], )), RegisterEventHandler(event_handler=OnProcessExit( target_action=load_joint_state_controller, on_exit=[load_joint_trajectory_controller], )), RegisterEventHandler(event_handler=OnProcessExit( target_action=load_joint_trajectory_controller, on_exit=[load_imu_sensor_broadcaster], )), gazebo, node_robot_state_publisher, spawn_entity, ])
def generate_launch_description(): set_tty_launch_config_action = launch.actions.SetLaunchConfiguration( "emulate_tty", "True") # Launch Description ld = launch.LaunchDescription() # Watchdog node watchdog_node = LifecycleNode(package='sw_watchdog', node_executable='simple_watchdog', node_namespace='', node_name='simple_docker_watchdog', output='screen', arguments=['220', '--publish', '--activate'] #arguments=['__log_level:=debug'] ) # Make the Watchdog node take the 'activate' transition watchdog_activate_trans_event = EmitEvent(event=ChangeState( lifecycle_node_matcher=launch.events.matches_action(watchdog_node), transition_id=lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE, )) # When the watchdog reaches the 'inactive' state from 'active', log message # and restart monitored entity (via docker) watchdog_inactive_handler = RegisterEventHandler( OnStateTransition( target_lifecycle_node=watchdog_node, start_state='deactivating', goal_state='inactive', entities=[ # Log LogInfo(msg="Watchdog transitioned to 'INACTIVE' state."), # Restart the monitored entity OpaqueFunction(function=docker_restart), # Change state event (inactive -> active) watchdog_activate_trans_event, ], )) # When Shutdown is requested, clean up docker shutdown_handler = RegisterEventHandler( OnShutdown( on_shutdown=[ # Log LogInfo(msg="watchdog_in_docker was asked to shutdown."), # Clean up docker OpaqueFunction(function=docker_stop), ], )) # Add the actions to the launch description. # The order they are added reflects the order in which they will be executed ld.add_action(set_tty_launch_config_action) ld.add_action(OpaqueFunction(function=docker_run)) ld.add_action(watchdog_node) ld.add_action(watchdog_inactive_handler) ld.add_action(shutdown_handler) return ld
def generate_launch_description(): share_dir = get_package_share_directory('ros2_ouster') parameter_file = LaunchConfiguration('params_file') node_name = 'ouster_driver' params_declare = DeclareLaunchArgument( 'params_file', default_value=os.path.join(share_dir, 'params', 'os1.yaml'), description='FPath to the ROS2 parameters file to use.') driver_node = LifecycleNode( package='ros2_ouster', executable='ouster_driver', name=node_name, output='screen', emulate_tty=True, parameters=[parameter_file], namespace='/', ) configure_event = EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(driver_node), transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE, )) activate_event = RegisterEventHandler( OnStateTransition( target_lifecycle_node=driver_node, goal_state='inactive', entities=[ LogInfo( msg="[LifecycleLaunch] Ouster driver node is activating."), EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(driver_node), transition_id=lifecycle_msgs.msg.Transition. TRANSITION_ACTIVATE, )), ], )) # TODO make lifecycle transition to shutdown before SIGINT shutdown_event = RegisterEventHandler( OnShutdown(on_shutdown=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_node_name(node_name=node_name), transition_id=lifecycle_msgs.msg.Transition. TRANSITION_ACTIVE_SHUTDOWN, )), LogInfo(msg="[LifecycleLaunch] Ouster driver node is exiting."), ], )) return LaunchDescription([ params_declare, driver_node, activate_event, configure_event, shutdown_event, ])
def generate_launch_description(): share_dir = get_package_share_directory('serial_driver') node_name = 'serial_bridge_node' params_declare = DeclareLaunchArgument( 'params_file', default_value=os.path.join(share_dir, 'params', 'example.params.yaml'), description='File path to the ROS2 parameters file to use') bridge_node = LifecycleNode( package='serial_driver', executable='serial_bridge', name=node_name, namespace=TextSubstitution(text=''), parameters=[LaunchConfiguration('params_file')], output='screen', ) configure_event_handler = RegisterEventHandler( event_handler=OnProcessStart( target_action=bridge_node, on_start=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(bridge_node), transition_id=Transition.TRANSITION_CONFIGURE, ), ), ], )) activate_event_handler = RegisterEventHandler( event_handler=OnStateTransition( target_lifecycle_node=bridge_node, start_state='configuring', goal_state='inactive', entities=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_action(bridge_node), transition_id=Transition.TRANSITION_ACTIVATE, ), ), ], )) shutdown_event_handler = RegisterEventHandler(event_handler=OnShutdown( on_shutdown=[ EmitEvent(event=ChangeState( lifecycle_node_matcher=matches_node_name(node_name), transition_id=Transition.TRANSITION_ACTIVE_SHUTDOWN, )) ])) return LaunchDescription([ params_declare, bridge_node, configure_event_handler, activate_event_handler, shutdown_event_handler, ])
def generate_launch_description(): robot_description_content = Command([ PathJoinSubstitution([FindExecutable(name='xacro')]), " ", PathJoinSubstitution([ FindPackageShare('gazebo_ros2_control_demos'), 'urdf', 'test_gripper_mimic_joint.xacro.urdf' ]), ]) robot_description = {"robot_description": robot_description_content} node_robot_state_publisher = Node(package='robot_state_publisher', executable='robot_state_publisher', output='screen', parameters=[robot_description]) gazebo = IncludeLaunchDescription( PythonLaunchDescriptionSource( [FindPackageShare("gazebo_ros"), "/launch", "/gazebo.launch.py"]), ) spawn_entity = Node( package='gazebo_ros', executable='spawn_entity.py', arguments=['-topic', 'robot_description', '-entity', 'gripper'], output='screen') load_joint_state_controller = ExecuteProcess(cmd=[ 'ros2', 'control', 'load_controller', '--set-state', 'start', 'joint_state_broadcaster' ], output='screen') load_gripper_controller = ExecuteProcess(cmd=[ 'ros2', 'control', 'load_controller', '--set-state', 'start', 'gripper_controller' ], output='screen') return LaunchDescription([ RegisterEventHandler(event_handler=OnProcessExit( target_action=spawn_entity, on_exit=[load_joint_state_controller], )), RegisterEventHandler(event_handler=OnProcessExit( target_action=load_joint_state_controller, on_exit=[load_gripper_controller], )), gazebo, node_robot_state_publisher, spawn_entity, ])
def generate_launch_description(): """Generate launch description with multiple components.""" container = ComposableNodeContainer( node_name='my_container', node_namespace='my_namespace', package='rclcpp_components', node_executable='component_container', composable_node_descriptions=[ ComposableNode(package='demo_nodes_cpp', node_plugin='demo_nodes_cpp::Talker', node_name='talker'), ComposableNode(package='sw_watchdog', node_plugin='sw_watchdog::SimpleHeartbeat', node_name='heartbeat', parameters=[{ 'period': 200 }], extra_arguments=[{ 'use_intra_process_comms': True }]), ], output='screen') # When Shutdown is requested (launch), clean up all child processes shutdown_handler = RegisterEventHandler( OnShutdown( on_shutdown=[ # Log LogInfo(msg="heartbeat_composition was asked to shutdown."), # Clean up OpaqueFunction(function=group_stop), ], )) return launch.LaunchDescription([container, shutdown_handler])
def add_fixture_action( self, launch_description, action, exit_allowed=[0], ): """ Add action used as testing fixture. If a process action and it exits, a shutdown event is emitted. """ launch_description.add_action(action) if isinstance(action, ExecuteProcess): def on_fixture_process_exit(event, context): process_name = event.action.process_details['name'] allowed_to_exit = exit_allowed if isinstance(exit_allowed, list): allowed_to_exit = event.returncode in exit_allowed if not context.is_shutdown and not allowed_to_exit: rc = event.returncode if event.returncode else 1 self.__processes_rc[process_name] = rc return EmitEvent(event=Shutdown( reason='{} fixture process died!'.format( process_name))) launch_description.add_action( RegisterEventHandler( OnProcessExit(target_action=action, on_exit=on_fixture_process_exit))) return action
def generate_launch_description(): set_tty_launch_config_action = launch.actions.SetLaunchConfiguration( "emulate_tty", "True") watchdog_node = LifecycleNode( package='sw_watchdog', node_executable='windowed_watchdog', node_namespace='', node_name='windowed_watchdog', output='screen', arguments=['220', '3', '--publish', '--activate'] #arguments=['__log_level:=debug'] ) # When the watchdog reaches the 'inactive' state, log a message watchdog_inactive_handler = RegisterEventHandler( OnStateTransition( target_lifecycle_node=watchdog_node, goal_state='inactive', entities=[ # Log LogInfo(msg="Watchdog transitioned to 'INACTIVE' state."), ], )) return launch.LaunchDescription([ set_tty_launch_config_action, watchdog_node, watchdog_inactive_handler ])
def execute(self, context: LaunchContext) -> Optional[List[Action]]: """ Execute the action. Most work is delegated to :meth:`launch_ros.actions.Node.execute`, except for the composable nodes load action if it applies. """ load_actions = None # type: Optional[List[Action]] if self.__composable_node_descriptions is not None: from .load_composable_nodes import LoadComposableNodes # Perform load action once the container has started. load_actions = [ RegisterEventHandler( event_handler=OnProcessStart( target_action=self, on_start=[ LoadComposableNodes( composable_node_descriptions=self.__composable_node_descriptions, target_container=self ) ] ) ) ] container_actions = super().execute(context) # type: Optional[List[Action]] if container_actions is not None and load_actions is not None: return container_actions + load_actions if container_actions is not None: return container_actions if load_actions is not None: return load_actions return None
def generate_launch_description(): localization_benchmark_supervisor_node = Node( package='localization_performance_modelling', node_executable='localization_benchmark_supervisor', node_name='localization_benchmark_supervisor', output='screen', emulate_tty=True, parameters=[LaunchConfiguration('configuration')], ) return LaunchDescription([ # Set env var to print messages to stdout immediately SetEnvironmentVariable('RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1'), DeclareLaunchArgument('configuration', description='Configuration yaml file path'), DeclareLaunchArgument('use_sim_time', description='Use simulation/bag clock if true'), localization_benchmark_supervisor_node, Node(package='nav2_lifecycle_manager', node_executable='lifecycle_manager', node_name='lifecycle_manager', output='screen', parameters=[{ 'use_sim_time': LaunchConfiguration('use_sim_time') }, { 'node_names': [ 'map_server', 'amcl', 'controller_server', 'planner_server', 'recoveries_server', 'bt_navigator', 'waypoint_follower' ] }]), RegisterEventHandler(event_handler=OnProcessExit( target_action=localization_benchmark_supervisor_node, on_exit=EmitEvent(event=Shutdown(reason='supervisor_finished')))), ])
def generate_launch_description(): return launch.LaunchDescription( [ IncludeLaunchDescription( PythonLaunchDescriptionSource( [get_package_share_directory(robot), "/launch/nav-core.py"] ), launch_arguments={ "namespace": robot, "params_file": os.path.join( get_package_share_directory(robot), "param", f"{robot}.yml" ), }.items(), ) for robot in robots ] + [ RegisterEventHandler( event_handler=OnProcessExit( on_exit=[ EmitEvent(event=Shutdown()), ] ) ) ] )
def generate_launch_description(): teleop_config = Path(get_package_share_directory('openrover_demo'), 'config', 'teleop.yaml') assert teleop_config.is_file() nodes = [ Node( package='keystroke', node_executable='keystroke_listen', output='screen', arguments=['__log_level:=warn'], parameters=[teleop_config] ), Node( package='keystroke', node_executable='keystroke_arrows_to_twist', output='screen', arguments=['__log_level:=info'], parameters=[teleop_config] )] events = [RegisterEventHandler( event_handler=OnProcessExit( target_action=n, on_exit=[EmitEvent(event=Shutdown())] ) ) for n in nodes] return LaunchDescription([ SetEnvironmentVariable('RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1'), *nodes, *events ])
def add_test_action(self, launch_description, action): """ Add action used for testing. If either all test actions exited with a return code of zero or any test action exited with a non-zero return code a shutdown event is emitted. """ assert isinstance(action, ExecuteProcess), \ 'The passed action must be a ExecuteProcess action' self.__test_processes.append(action) def on_test_process_exit(event, context): nonlocal action nonlocal self self.__test_returncodes[action] = event.returncode if len(self.__test_returncodes) == len(self.__test_processes): shutdown_event = Shutdown( reason='all test processes finished') return EmitEvent(event=shutdown_event) launch_description.add_action( RegisterEventHandler(OnProcessExit( target_action=action, on_exit=on_test_process_exit, )) )
def generate_launch_description(): return launch.LaunchDescription([ IncludeLaunchDescription( PythonLaunchDescriptionSource( [get_package_share_directory(robot), "/launch/interfaces.py"]), launch_arguments={ "namespace": robot, "params_file": os.path.join(get_package_share_directory(robot), "param", f"{robot}.yml"), }.items(), ) for robot in robots ] + [ GroupAction([ Node( package="strategix", executable="strategix", output="screen", ), ]) ] + [ RegisterEventHandler(event_handler=OnProcessExit(on_exit=[ EmitEvent(event=Shutdown()), ])) ])
def generate_launch_description(): return launch.LaunchDescription( [ IncludeLaunchDescription( PythonLaunchDescriptionSource( [get_package_share_directory(robot), "/launch/interfaces.py"] ), launch_arguments={ "namespace": robot, "params_file": os.path.join( get_package_share_directory(robot), "param", f"{robot}.yml" ), }.items(), ) for robot in robots ] + [ IncludeLaunchDescription( PythonLaunchDescriptionSource( [ get_package_share_directory("assurancetourix"), "/launch/launch.py", ] ), launch_arguments={ "namespace": "assurancetourix", "params_file": os.path.join( get_package_share_directory("assurancetourix"), "param", "assurancetourix.yml", ), }.items(), ) ] + [ GroupAction( [ Node( package="strategix", executable="strategix", output="screen", ), WebotsLauncher( mode="realtime", world="tools/simulation/worlds/cdr2022.wbt", ), ] ) ] + [ RegisterEventHandler( event_handler=OnProcessExit( on_exit=[ EmitEvent(event=Shutdown()), ] ) ) ] )
def test_launch_service_emit_event(): """ Test the emitting of events in the LaunchService class. Also covers basic tests for include_launch_description(), run(), and shutdown(). """ ls = LaunchService(debug=True) assert ls._LaunchService__context._event_queue.qsize() == 0 from launch.actions import OpaqueFunction from launch.actions import RegisterEventHandler from launch.event_handler import EventHandler handled_events = queue.Queue() ld = LaunchDescription([ RegisterEventHandler(EventHandler( matcher=lambda event: True, entities=OpaqueFunction( function=lambda context: handled_events.put(context.locals.event), ), )) ]) ls.include_launch_description(ld) assert ls._LaunchService__context._event_queue.qsize() == 1 class MockEvent: name = 'Event' ls.emit_event(MockEvent()) assert ls._LaunchService__context._event_queue.qsize() == 2 assert handled_events.qsize() == 0 t = threading.Thread(target=ls.run, kwargs={'shutdown_when_idle': False}) t.start() # First event (after including description of event handler). handled_events.get(block=True, timeout=5.0) # Emit and then check for a second event. ls.emit_event(MockEvent()) handled_events.get(block=True, timeout=5.0) # Shutdown (generates a third event) and join the thread. ls.shutdown() t.join() # Check that the shutdown event was handled. handled_events.get(block=False) assert handled_events.qsize() == 0 ls.emit_event(MockEvent()) assert handled_events.qsize() == 0 assert ls.run(shutdown_when_idle=True) == 0 handled_events.get(block=False)
def test_register_event_handler_description(): """Test that describe_sub_entities and describe_conditional_sub_entities methods behave.""" action = Action() action2 = Action() # Sanity Check - not part of the event handler event_handler = EventHandler( matcher=lambda: True, entities=[action] ) action_under_test = RegisterEventHandler(event_handler) assert action_under_test.describe_sub_entities() == [] # There should be a single condition described assert len(action_under_test.describe_conditional_sub_entities()) == 1 # Get the condition tuple of (Text, [LaunchDescriptionEntity]) condition = action_under_test.describe_conditional_sub_entities()[0] assert condition[1] != [] assert action in condition[1] assert action2 not in condition[1]
def setUpClass(cls): # It's easier to actually capture some IO from the launch system than it is to fake it # but it takes a few seconds. We'll do it once and run tests on the same captured # IO proc_env = os.environ.copy() proc_env['PYTHONUNBUFFERED'] = '1' cls.proc_output = ActiveIoHandler() cls.proc_1 = launch.actions.ExecuteProcess(cmd=TEST_CMD, name='terminating_proc', env=proc_env) # This process should be distinguishable by its cmd line args cls.proc_2 = launch.actions.ExecuteProcess(cmd=TEST_CMD + ['--extra'], name='terminating_proc', env=proc_env) # This process should be distinguishable by its different name cls.proc_3 = launch.actions.ExecuteProcess(cmd=TEST_CMD + ['node:=different_name'], name='terminating_proc', env=proc_env) launch_description = launch.LaunchDescription([ cls.proc_1, cls.proc_2, cls.proc_3, # This plumbs all the output to our IoHandler just like the LaunchTestRunner does RegisterEventHandler( OnProcessStart(on_start=lambda event, _: cls.proc_output.track( event.process_name))), RegisterEventHandler( OnProcessIO( on_stdout=cls.proc_output.append, on_stderr=cls.proc_output.append, )) ]) launch_service = launch.LaunchService() launch_service.include_launch_description(launch_description) launch_service.run()
def add_test_action(self, launch_description, action): """ Add action used for testing. If either all test actions have completed or a process action has exited with a non-zero return code, a shutdown event is emitted. """ test_name = 'test_{}'.format(id(action)) if isinstance(action, ExecuteProcess): def on_test_process_exit(event, context): if event.returncode != 0: process_name = event.action.process_details['name'] self.__processes_rc[process_name] = event.returncode return self._fail( test_name, reason='{} test failed!'.format(process_name)) return self._succeed(test_name) launch_description.add_action( RegisterEventHandler( OnProcessExit(target_action=action, on_exit=on_test_process_exit))) else: def on_test_completion(event, context): future = event.action.get_asyncio_future() if future is not None: if future.cancelled(): return self._drop(test_name) exc = future.exception() if exc is not None: return self._fail(test_name, str(exc)) return self._succeed(test_name) launch_description.add_action( RegisterEventHandler( OnExecutionComplete(target_action=action, on_completion=on_test_completion))) launch_description.add_action(action) self._arm(test_name) return action
def test_register_unregister_event_handler_execute(): """ Test the execute method. Tests both the RegisterEventHandler and UnregisterEventHandler action classes. """ launch_context = LaunchContext() event_handler = EventHandler(matcher=lambda: True) # Register event handler register_event_handler_action = RegisterEventHandler(event_handler) register_event_handler_action.execute(launch_context) # Unregister the same event handler unregister_event_handler_action = UnregisterEventHandler(event_handler) unregister_event_handler_action.execute(launch_context) # Expect ValueError when trying to unregister the event handler a second time with pytest.raises(ValueError): unregister_event_handler_action.execute(launch_context)
def generate_launch_description(): synchronization = LaunchConfiguration('synchronization') package = LaunchConfiguration('package') executable = LaunchConfiguration('executable') world = LaunchConfiguration('world') gui = LaunchConfiguration('gui') mode = LaunchConfiguration('mode') publish_tf = LaunchConfiguration('publish_tf') node_parameters = LaunchConfiguration('node_parameters') robot_name = LaunchConfiguration('robot_name') node_name = LaunchConfiguration('node_name') use_sim_time = LaunchConfiguration('use_sim_time') # Webots webots = WebotsLauncher(world=world, mode=mode, gui=gui) # Driver node controller = ControllerLauncher( package=package, executable=executable, parameters=[ node_parameters, { 'synchronization': synchronization, 'use_joint_state_publisher': publish_tf } ], output='screen', arguments=[ '--webots-robot-name', robot_name, '--webots-node-name', node_name ], ) # Robot state publisher robot_state_publisher = Node( package='robot_state_publisher', executable='robot_state_publisher', output='screen', parameters=[{ 'robot_description': '<robot name=""><link name=""/></robot>', 'use_sim_time': use_sim_time }], condition=launch.conditions.IfCondition(publish_tf)) return LaunchDescription(ARGUMENTS + [ robot_state_publisher, webots, controller, # Shutdown launch when Webots exits. RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit( target_action=webots, on_exit=[EmitEvent(event=launch.events.Shutdown())], )) ])
def generate_test_description(ready_fn): node_env = os.environ.copy() node_env["PYTHONUNBUFFERED"] = "1" return LaunchDescription([ Node(package='apex_rostest', node_executable='echo_node', env=node_env), RegisterEventHandler( StdoutReadyListener( "echo_node", "ready", actions=[OpaqueFunction(function=lambda context: ready_fn())])) ])
def generate_rviz_launch_description(namespace="robot"): # Get the launch directory titan_dir = get_package_share_directory("titan") rviz_config_file = os.path.join(titan_dir, "rviz", "namespaced_view.rviz") use_namespace = "true" namespaced_rviz_config_file = ReplaceString( source_file=rviz_config_file, replacements={"<robot_namespace>": ("/", namespace)}, ) start_namespaced_rviz_cmd = Node( condition=IfCondition(use_namespace), package="rviz2", executable="rviz2", name="rviz2", namespace=namespace, # TODO: FIX onload MUTEX ERROR # arguments=['-d', namespaced_rviz_config_file], output="screen", remappings=[ ("/tf", "tf"), ("/tf_static", "tf_static"), ("/goal_pose", "goal_pose"), ("/clicked_point", "clicked_point"), ("/initialpose", "initialpose"), ], ) exit_event_handler_namespaced = RegisterEventHandler( condition=IfCondition(use_namespace), event_handler=OnProcessExit( target_action=start_namespaced_rviz_cmd, on_exit=EmitEvent(event=Shutdown(reason="rviz exited")), ), ) # Create the launch description and populate ld = LaunchDescription() # Add any conditioned actions ld.add_action(start_namespaced_rviz_cmd) # Add other nodes and processes we need ld.add_action(exit_event_handler_namespaced) return ld
def generate_launch_description(): # Webots arguments = [ '--mode=realtime', '--world=' + os.path.join(get_package_share_directory('webots_ros2_epuck'), 'worlds', 'epuck_world.wbt') ] webots = Node(package='webots_ros2_core', node_executable='webots_launcher', arguments=arguments, output='screen') # Controller node synchronization = LaunchConfiguration('synchronization', default=False) controller = ControllerLauncher(package='webots_ros2_epuck', node_executable='driver', parameters=[{ 'synchronization': synchronization }], output='screen') # Rviz node use_rviz = LaunchConfiguration('rviz', default=False) rviz_config = os.path.join( get_package_share_directory('webots_ros2_epuck'), 'resource', 'all.rviz') rviz = Node(package='rviz2', node_executable='rviz2', output='screen', arguments=['--display-config=' + rviz_config], condition=launch.conditions.IfCondition(use_rviz)) # Launch descriptor launch_entities = [ webots, controller, rviz, # Shutdown launch when Webots exits. RegisterEventHandler(event_handler=launch.event_handlers.OnProcessExit( target_action=webots, on_exit=[EmitEvent(event=launch.events.Shutdown())], )) ] return LaunchDescription(launch_entities)
def test_wait_for_ready(self): data = [] self.launch_description.add_entity( RegisterEventHandler( StdoutReadyListener( node_name="terminating_node", ready_txt="Ready", actions=[ OpaqueFunction( function=lambda context: data.append('ok')) ]))) launch_service = LaunchService() launch_service.include_launch_description(self.launch_description) launch_service.run() # If the StdoutReadyListener worked, we should see 'ok' in the data self.assertIn('ok', data)
def setUpClass(cls): # It's easier to actually capture some IO from the launch system than it is to fake it # but it takes a few seconds. We'll do it once and run tests on the same captured # IO proc_env = os.environ.copy() proc_env["PYTHONUNBUFFERED"] = "1" cls.proc_output = ActiveIoHandler() cls.proc_1 = launch.actions.ExecuteProcess( cmd=[TEST_PROC_PATH], env=proc_env ) # This process should be distinguishable by its cmd line args cls.proc_2 = launch.actions.ExecuteProcess( cmd=[TEST_PROC_PATH, '--extra'], env=proc_env ) # This process should be distinguishable by its different name cls.proc_3 = launch.actions.ExecuteProcess( cmd=[TEST_PROC_PATH, 'node:=different_name'], env=proc_env ) launch_description = launch.LaunchDescription([ cls.proc_1, cls.proc_2, cls.proc_3, # This plumbs all the output to our IoHandler just like the ApexRunner does RegisterEventHandler( OnProcessIO( on_stdout=cls.proc_output.append, on_stderr=cls.proc_output.append, ) ) ]) launch_service = launch.LaunchService() launch_service.include_launch_description(launch_description) launch_service.run()
def test_wait_for_wrong_message(self): data = [] self.launch_description.add_entity( RegisterEventHandler( StdoutReadyListener( node_name="different_node", ready_txt="not_ready", actions=[ OpaqueFunction( function=lambda context: data.append('ok')) ]))) launch_service = LaunchService() launch_service.include_launch_description(self.launch_description) launch_service.run() # We should not get confused by output that doesn't match the ready_txt self.assertNotIn('ok', data)
def setUpClass(cls): # It's easier to actually capture some IO from the launch system than it is to fake it # but it takes a few seconds. We'll do it once and run tests on the same captured # IO node_env = os.environ.copy() node_env["PYTHONUNBUFFERED"] = "1" cls.proc_output = ActiveIoHandler() cls.node_1 = Node(package='apex_rostest', node_executable='terminating_node', env=node_env) # This node should be distinguishable by its cmd line args cls.node_2 = Node(package='apex_rostest', node_executable='terminating_node', arguments=['--extra'], env=node_env) # This node should be distinguishable by its diffetent node name cls.node_3 = Node(package='apex_rostest', node_executable='terminating_node', node_name='different_name', env=node_env) launch_description = LaunchDescription([ cls.node_1, cls.node_2, cls.node_3, # This plumbs all the output to our IoHandler just like the ApexRunner does RegisterEventHandler( OnProcessIO( on_stdout=cls.proc_output.append, on_stderr=cls.proc_output.append, )) ]) launch_service = LaunchService() launch_service.include_launch_description(launch_description) launch_service.run()
def execute(self, context: LaunchContext): continue_after_fail = self.__continue_after_fail if not isinstance(continue_after_fail, bool): continue_after_fail = perform_substitutions( context, normalize_to_list_of_substitutions( continue_after_fail)).lower() if continue_after_fail in ['true', 'on', '1']: continue_after_fail = True elif continue_after_fail in ['false', 'off', '1']: continue_after_fail = False else: raise ValueError( 'continue_after_fail should be a boolean, got {}'.format( continue_after_fail)) on_first_action_exited = OnProcessExit( target_action=self.__actions[0], on_exit=lambda event, context: ([InOrderGroup(self.__actions[1:])] if event.exitcode == 0 or continue_after_fail else [])) return [ self.__actions[0], RegisterEventHandler(on_first_action_exited) ]