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,
    ])
Beispiel #2
0
    def __init__(
        self,
        target_action,
        log_file,
        timeout=None,
        **kwargs
    ) -> None:
        """
        Construct a SystemMetricCollector action.

        Parameters
        ----------
        target_action : ExecuteProcess
            ExecuteProcess (or Node) instance to collect metrics on
        log_file : str or LaunchSubstitutionsType
            Path to where the collected metrics should be written to
        timeout : int or LaunchSubstitutionsType
            Maximum time to run the metrics collector if the target process does
            not exit

        """
        # These Node/ExecuteProcess arguments are invalid in this context
        # because we implicitly set them right here.
        assert 'arguments' not in kwargs
        assert 'package' not in kwargs
        assert 'executable' not in kwargs
        assert 'executable' not in kwargs

        self.__pid_var_name = '__PROCESS_ID_%d' % id(self)

        kwargs['package'] = 'buildfarm_perf_tests'
        kwargs['executable'] = 'system_metric_collector'
        kwargs['arguments'] = [
            '--log', log_file,
            '--process_pid', LocalSubstitution(self.__pid_var_name)]
        if timeout is not None:
            kwargs['arguments'] += [
                '--timeout',
                str(timeout) if isinstance(timeout, int) else timeout
            ]

        super().__init__(**kwargs)

        self.__target_start_handler = OnProcessStart(
            target_action=target_action, on_start=self.__on_target_start)
        self.__target_exit_handler = OnProcessExit(
            target_action=target_action, on_exit=EmitEvent(
                event=ShutdownProcess(
                    process_matcher=matches_action(self))))
Beispiel #3
0
    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()
Beispiel #4
0
    def run(self):
        """
        Launch the processes under test and run the tests.

        :return: A tuple of two unittest.Results - one for tests that ran while processes were
        active, and another set for tests that ran after processes were shutdown
        """
        test_ld, test_context = self._test_run.normalized_test_description(
            ready_fn=lambda: self._processes_launched.set())

        # Data that needs to be bound to the tests:
        proc_info = ActiveProcInfoHandler()
        proc_output = ActiveIoHandler()
        full_context = dict(test_context, **self._test_run.param_args)
        parsed_launch_arguments = parse_launch_arguments(
            self._launch_file_arguments)
        test_args = {}

        for k, v in parsed_launch_arguments:
            test_args[k] = v

        self._test_run.bind(
            self._test_run.pre_shutdown_tests,
            injected_attributes={
                'proc_info': proc_info,
                'proc_output': proc_output,
                'test_args': test_args,
            },
            injected_args=dict(
                full_context,
                # Add a few more things to the args dictionary:
                **{
                    'proc_info': proc_info,
                    'proc_output': proc_output,
                    'test_args': test_args
                }))
        self._test_run.bind(
            self._test_run.post_shutdown_tests,
            injected_attributes={
                'proc_info': proc_info._proc_info_handler,
                'proc_output': proc_output._io_handler,
                'test_args': test_args,
            },
            injected_args=dict(
                full_context,
                # Add a few more things to the args dictionary:
                **{
                    'proc_info': proc_info._proc_info_handler,
                    'proc_output': proc_output._io_handler,
                    'test_args': test_args
                }))

        # Wrap the test_ld in another launch description so we can bind command line arguments to
        # the test and add our own event handlers for process IO and process exit:
        launch_description = LaunchDescription([
            *self._test_run_preamble,
            RegisterEventHandler(
                OnProcessStart(
                    on_start=lambda info, unused: proc_info.append(info))),
            RegisterEventHandler(
                OnProcessExit(
                    on_exit=lambda info, unused: proc_info.append(info))),
            RegisterEventHandler(
                OnProcessIO(
                    on_stdout=proc_output.append,
                    on_stderr=proc_output.append,
                )),
            launch.actions.IncludeLaunchDescription(
                launch.LaunchDescriptionSource(launch_description=test_ld),
                launch_arguments=parsed_launch_arguments),
        ])

        self._launch_service.include_launch_description(launch_description)

        self._test_tr.start()  # Run the tests on another thread
        self._launch_service.run(
        )  # This will block until the test thread stops it

        if not self._tests_completed.wait(timeout=0):
            # LaunchService.run returned before the tests completed.  This can be because the user
            # did ctrl+c, or because all of the launched nodes died before the tests completed
            print('Processes under test stopped before tests completed')
            # Give some extra help debugging why processes died early
            self._print_process_output_summary(proc_info, proc_output)
            # We treat this as a test failure and return some test results indicating such
            raise _LaunchDiedException()

        inactive_results = unittest.TextTestRunner(
            verbosity=2,
            resultclass=TestResult).run(self._test_run.post_shutdown_tests)

        self._results.append(inactive_results)

        return self._results
def generate_launch_description():
    params_file = LaunchConfiguration(
        'params',
        default=[ThisLaunchFileDir(), '/launch_params.yaml'])

    # make sure the dbc file gets installed with the launch file
    # dbc_file_path = get_package_share_directory('raptor_dbw_can') + \
    #     "/launch/New_Eagle_DBW_3.3.542.dbc"
    dbc_file_path = get_package_share_directory('raptor_dbw_can') + \
        "/launch/CAN1_HIL_test_1.dbc"

    socket_can_receiver_node = LifecycleNode(
        package='ros2_socketcan',
        executable='socket_can_receiver_node_exe',
        name='socket_can_receiver',
        namespace=TextSubstitution(text=''),
        parameters=[{
            'interface': LaunchConfiguration('interface'),
            'interval_sec':
            LaunchConfiguration('interval_sec'),
        }],
        output='screen')

    socket_can_receiver_configure_event_handler = RegisterEventHandler(
        event_handler=OnProcessStart(
            target_action=socket_can_receiver_node,
            on_start=[
                EmitEvent(
                    event=ChangeState(
                        lifecycle_node_matcher=matches_action(socket_can_receiver_node),
                        transition_id=Transition.TRANSITION_CONFIGURE,
                    ),
                ),
            ],
        ),
        condition=IfCondition(LaunchConfiguration('auto_configure')),
    )

    socket_can_receiver_activate_event_handler = RegisterEventHandler(
        event_handler=OnStateTransition(
            target_lifecycle_node=socket_can_receiver_node,
            start_state='configuring',
            goal_state='inactive',
            entities=[
                EmitEvent(
                    event=ChangeState(
                        lifecycle_node_matcher=matches_action(socket_can_receiver_node),
                        transition_id=Transition.TRANSITION_ACTIVATE,
                    ),
                ),
            ],
        ),
        condition=IfCondition(LaunchConfiguration('auto_activate')),
    )

    socket_can_sender_node = LifecycleNode(
        package='ros2_socketcan',
        executable='socket_can_sender_node_exe',
        name='socket_can_sender',
        namespace=TextSubstitution(text=''),
        parameters=[{
            'interface': LaunchConfiguration('interface'),
            'timeout_sec':
            LaunchConfiguration('timeout_sec'),
        }],
        output='screen')

    socket_can_sender_configure_event_handler = RegisterEventHandler(
        event_handler=OnProcessStart(
            target_action=socket_can_sender_node,
            on_start=[
                EmitEvent(
                    event=ChangeState(
                        lifecycle_node_matcher=matches_action(socket_can_sender_node),
                        transition_id=Transition.TRANSITION_CONFIGURE,
                    ),
                ),
            ],
        ),
        condition=IfCondition(LaunchConfiguration('auto_configure')),
    )

    socket_can_sender_activate_event_handler = RegisterEventHandler(
        event_handler=OnStateTransition(
            target_lifecycle_node=socket_can_sender_node,
            start_state='configuring',
            goal_state='inactive',
            entities=[
                EmitEvent(
                    event=ChangeState(
                        lifecycle_node_matcher=matches_action(socket_can_sender_node),
                        transition_id=Transition.TRANSITION_ACTIVATE,
                    ),
                ),
            ],
        ),
        condition=IfCondition(LaunchConfiguration('auto_activate')),
    )

    return LaunchDescription(
        [   
            DeclareLaunchArgument('interface', default_value='can1'),
            DeclareLaunchArgument('interval_sec', default_value='0.01'),
            DeclareLaunchArgument('auto_configure', default_value='true'),
            DeclareLaunchArgument('auto_activate', default_value='true'),
            socket_can_receiver_node,
            socket_can_receiver_configure_event_handler,
            socket_can_receiver_activate_event_handler,

            DeclareLaunchArgument('interface', default_value='can1'),
            DeclareLaunchArgument('timeout_sec', default_value='0.01'),
            DeclareLaunchArgument('auto_configure', default_value='true'),
            DeclareLaunchArgument('auto_activate', default_value='true'),
            socket_can_sender_node,
            socket_can_sender_configure_event_handler,
            socket_can_sender_activate_event_handler,

            Node(
                package='raptor_dbw_can',
                executable='raptor_dbw_can_node',
                output='screen',
                namespace='raptor_dbw_interface',
                parameters=[
                    {"dbw_dbc_file": dbc_file_path}
                ],
                remappings=[
                    ('/raptor_dbw_interface/can_rx', '/from_can_bus'),
                    ('/raptor_dbw_interface/can_tx', '/to_can_bus'),
                ],
            ),
        ])