Beispiel #1
0
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
    ])
Beispiel #2
0
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():

    # use: 'zed' for "ZED" camera - 'zedm' for "ZED mini" camera
    camera_model = 'zed'

    # URDF file to be loaded by Robot State Publisher
    urdf = os.path.join(get_package_share_directory('stereolabs_zed'), 'urdf',
                        camera_model + '.urdf')

    # ZED Configurations to be loaded by ZED Node
    config_common = os.path.join(get_package_share_directory('stereolabs_zed'),
                                 'config', 'common.yaml')

    config_camera = os.path.join(get_package_share_directory('stereolabs_zed'),
                                 'config', camera_model + '.yaml')

    # Set LOG format
    os.environ[
        'RCUTILS_CONSOLE_OUTPUT_FORMAT'] = '{time}: [{name}] [{severity}]\t{message}'

    # Launch Description
    ld = launch.LaunchDescription()

    # Prepare the ZED node
    zed_node = LifecycleNode(
        node_namespace='zed',  # must match the namespace in config -> YAML
        node_name='zed_node',  # must match the node name in config -> YAML
        package='stereolabs_zed',
        node_executable='zed_wrapper_node',
        output='screen',
        parameters=[
            config_common,  # Common parameters
            config_camera,  # Camera related parameters
        ])

    # Prepare the Robot State Publisher node
    rsp_node = Node(node_name='zed_state_publisher',
                    package='robot_state_publisher',
                    node_executable='robot_state_publisher',
                    output='screen',
                    arguments=[urdf, 'robot_description:=zed_description'])

    # Make the ZED node take the 'configure' transition
    zed_configure_trans_event = EmitEvent(event=ChangeState(
        lifecycle_node_matcher=launch.events.matches_action(zed_node),
        transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE,
    ))

    # Make the ZED node take the 'activate' transition
    zed_activate_trans_event = EmitEvent(event=ChangeState(
        lifecycle_node_matcher=launch.events.matches_action(zed_node),
        transition_id=lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE,
    ))

    # Shutdown event
    shutdown_event = EmitEvent(event=launch.events.Shutdown())

    # When the ZED node reaches the 'inactive' state from 'unconfigured', make it take the 'activate' transition and start the Robot State Publisher
    zed_inactive_from_unconfigured_state_handler = RegisterEventHandler(
        OnStateTransition(
            target_lifecycle_node=zed_node,
            start_state='configuring',
            goal_state='inactive',
            entities=[
                # Log
                LogInfo(
                    msg=
                    "'ZED' reached the 'INACTIVE' state, start the 'Robot State Publisher' node and 'activating'."
                ),
                # Robot State Publisher
                rsp_node,
                # Change State event ( inactive -> active )
                zed_activate_trans_event,
            ],
        ))

    # When the ZED node reaches the 'inactive' state from 'active', it has been deactivated and it will wait for a manual activation
    zed_inactive_from_active_state_handler = RegisterEventHandler(
        OnStateTransition(
            target_lifecycle_node=zed_node,
            start_state='deactivating',
            goal_state='inactive',
            entities=[
                # Log
                LogInfo(
                    msg=
                    "'ZED' reached the 'INACTIVE' state from 'ACTIVE' state. Waiting for manual activation..."
                )
            ],
        ))

    # When the ZED node reaches the 'active' state, log a message.
    zed_active_state_handler = RegisterEventHandler(
        OnStateTransition(
            target_lifecycle_node=zed_node,
            goal_state='active',
            entities=[
                # Log
                LogInfo(msg="'ZED' reached the 'ACTIVE' state"),
            ],
        ))

    # When the ZED node reaches the 'finalized' state, log a message and exit.
    zed_finalized_state_handler = RegisterEventHandler(
        OnStateTransition(
            target_lifecycle_node=zed_node,
            goal_state='finalized',
            entities=[
                # Log
                LogInfo(
                    msg=
                    "'ZED' reached the 'FINALIZED' state. Killing the node..."
                ),
                shutdown_event,
            ],
        ))

    # Add the actions to the launch description.
    # The order they are added reflects the order in which they will be executed.
    ld.add_action(zed_inactive_from_unconfigured_state_handler)
    ld.add_action(zed_inactive_from_active_state_handler)
    ld.add_action(zed_active_state_handler)
    ld.add_action(zed_finalized_state_handler)
    ld.add_action(zed_node)
    ld.add_action(zed_configure_trans_event)

    return ld
Beispiel #6
0
def generate_launch_description():
    # Get the launch directory
    pkg_dir = get_package_share_directory('clean_up')
    nav_dir = get_package_share_directory('gb_navigation')
    manipulation_dir = get_package_share_directory('gb_manipulation')
    gb_world_model_dir = get_package_share_directory('gb_world_model')
    world_config_dir = os.path.join(gb_world_model_dir, 'config')

    namespace = LaunchConfiguration('namespace')
    dope_params_file = LaunchConfiguration('dope_params_file')

    declare_dope_params_cmd = DeclareLaunchArgument(
        'dope_params_file',
        default_value=os.path.join(get_package_share_directory('dope_launch'),
                                   'config', 'config_pose.yaml'),
        description='Full path to the TF Pose Estimation parameters file to use'
    )

    declare_namespace_cmd = DeclareLaunchArgument('namespace',
                                                  default_value='',
                                                  description='Namespace')

    stdout_linebuf_envvar = SetEnvironmentVariable(
        'RCUTILS_CONSOLE_STDOUT_LINE_BUFFERED', '1')

    gb_manipulation_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory('gb_manipulation'),
                         'launch', 'gb_manipulation_launch.py')))

    gb_navigation_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory('gb_navigation'),
                         'launch', 'nav2_tiago_launch.py')))

    plansys2_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory('plansys2_bringup'),
                         'launch', 'plansys2_bringup_launch_monolithic.py')),
        launch_arguments={
            'model_file':
            pkg_dir + '/pddl/domain.pddl:' + nav_dir + '/pddl/domain.pddl'
        }.items())

    dope_cmd = IncludeLaunchDescription(
        PythonLaunchDescriptionSource(
            os.path.join(get_package_share_directory('dope_launch'), 'launch',
                         'dope_launch.py')),
        launch_arguments={'dope_params_file': dope_params_file}.items())

    # Specify the actions
    clean_up_executor_cmd = LifecycleNode(package='clean_up',
                                          executable='cleanup_executor_node',
                                          name='cleanup_executor_node')

    emit_event_to_request_that_clean_up_executor_configure_transition = EmitEvent(
        event=ChangeState(
            lifecycle_node_matcher=launch.events.matches_action(
                clean_up_executor_cmd),
            transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE,
        ))

    emit_event_to_request_that_clean_up_executor_activate_transition = EmitEvent(
        event=ChangeState(
            lifecycle_node_matcher=launch.events.matches_action(
                clean_up_executor_cmd),
            transition_id=lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE,
        ))

    on_configure_clean_up_executor_handler = RegisterEventHandler(
        OnStateTransition(
            target_lifecycle_node=clean_up_executor_cmd,
            goal_state='inactive',
            entities=[
                emit_event_to_request_that_clean_up_executor_activate_transition
            ]))

    # Specify the dependencies
    vision_cmd = LifecycleNode(package='clean_up',
                               executable='vision_sim_node',
                               name='vision')
    emit_event_to_request_that_vision_configure_transition = EmitEvent(
        event=ChangeState(
            lifecycle_node_matcher=launch.events.matches_action(vision_cmd),
            transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE,
        ))

    attention_manager_cmd = Node(package='gb_attention',
                                 executable='attention_server',
                                 output='screen')

    wm_cmd = Node(package='gb_world_model',
                  executable='world_model_main',
                  output='screen',
                  parameters=[world_config_dir + '/world.yml'])

    ld = LaunchDescription()

    # Set environment variables
    ld.add_action(stdout_linebuf_envvar)
    ld.add_action(declare_namespace_cmd)
    ld.add_action(declare_dope_params_cmd)

    # Declare the launch options

    # Event handlers
    ld.add_action(on_configure_clean_up_executor_handler)

    ld.add_action(gb_manipulation_cmd)
    ld.add_action(gb_navigation_cmd)
    ld.add_action(plansys2_cmd)
    ld.add_action(clean_up_executor_cmd)
    ld.add_action(vision_cmd)

    ld.add_action(emit_event_to_request_that_vision_configure_transition)
    ld.add_action(
        emit_event_to_request_that_clean_up_executor_configure_transition)

    ld.add_action(attention_manager_cmd)
    ld.add_action(wm_cmd)
    ld.add_action(dope_cmd)

    return ld
Beispiel #7
0
def generate_launch_description():
    package_name = 'ifm3d_ros2'
    node_namespace = 'ifm3d'
    node_name = 'camera'
    node_exe = 'camera_standalone'

    # os.environ['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = \
    #   "[{%s}] {%s} [{%s}]: {%s}\n({%s}() at {%s}:{%s})" % \
    #    ("severity", "time", "name", "message",
    #      "function_name", "file_name", "line_number")
    os.environ['RCUTILS_CONSOLE_OUTPUT_FORMAT'] = \
      "[{%s}] {%s} [{%s}]: {%s}" % ("severity", "time", "name", "message")

    # XXX: This is a hack, there does not seem to be a nice way (or at least
    # finding the docs is not obvious) to do this with the ROS2 launch api
    #
    # Basically, we are trying to allow for passing through the command line
    # args to the launch file through to the node executable itself (like ROS
    # 1).
    #
    # My assumption is that either:
    # 1. This stuff exists somewhere in ROS2 and I don't know about it yet
    # 2. This stuff will exist in ROS2 soon, so, this will likely get factored
    #    out (hopefully soon)
    #
    parameters = []
    remaps = []
    for arg in sys.argv:
        if ':=' in arg:
            split_arg = arg.split(sep=':=', maxsplit=1)
            assert len(split_arg) == 2

            if arg.startswith("ns"):
                node_namespace = split_arg[1]
            elif arg.startswith("node"):
                node_name = split_arg[1]
            elif arg.startswith("params"):
                parameters.append(tuple(split_arg)[1])
            else:
                remaps.append(tuple(split_arg))

    def add_prefix(tup):
        assert len(tup) == 2
        if node_namespace.startswith("/"):
            prefix = "%s/%s" % (node_namespace, node_name)
        else:
            prefix = "/%s/%s" % (node_namespace, node_name)

        retval = [None, None]

        if not tup[0].startswith(prefix):
            retval[0] = prefix + '/' + tup[0]
        else:
            retval[0] = tup[0]

        if not tup[1].startswith(prefix):
            retval[1] = prefix + '/' + tup[1]
        else:
            retval[1] = tup[1]

        return tuple(retval)

    remaps = list(map(add_prefix, remaps))

    #------------------------------------------------------------
    # Nodes
    #------------------------------------------------------------

    #
    # Coord frame transform from camera_optical_link to camera_link
    #
    tf_node = \
      ExecuteProcess(
          cmd=['ros2', 'run', 'tf2_ros', 'static_transform_publisher',
               '0', '0', '0', str(-pi/2.), '0', str(-pi/2.),
               str(node_name + "_link"), str(node_name + "_optical_link")],
               #output='screen',
               log_cmd=True
          )

    #
    # The camera component
    #
    camera_node = \
      LifecycleNode(
          package=package_name,
          node_executable=node_exe,
          node_namespace=node_namespace,
          node_name=node_name,
          output='screen',
          parameters=parameters,
          remappings=remaps,
          log_cmd=True,
          )

    #------------------------------------------------------------
    # Events we need to emit to induce state transitions
    #------------------------------------------------------------

    camera_configure_evt = \
      EmitEvent(
          event=ChangeState(
              lifecycle_node_matcher = \
                launch.events.matches_action(camera_node),
              transition_id = lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE
              )
          )

    camera_activate_evt = \
      EmitEvent(
          event=ChangeState(
              lifecycle_node_matcher = \
                launch.events.matches_action(camera_node),
              transition_id = lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE
              )
          )

    camera_cleanup_evt = \
      EmitEvent(
          event=ChangeState(
              lifecycle_node_matcher = \
                launch.events.matches_action(camera_node),
              transition_id = lifecycle_msgs.msg.Transition.TRANSITION_CLEANUP
              )
          )

    camera_shutdown_evt = EmitEvent(event=launch.events.Shutdown())

    #------------------------------------------------------------
    # These are the edges of the state machine graph we want to autonomously
    # manage
    #------------------------------------------------------------

    #
    # unconfigured -> configuring -> inactive
    #
    camera_node_unconfigured_to_inactive_handler = \
      RegisterEventHandler(
          OnStateTransition(
              target_lifecycle_node = camera_node,
              start_state = 'configuring',
              goal_state = 'inactive',
              entities = [
                  LogInfo(msg = "Emitting 'TRANSITION_ACTIVATE' event"),
                  camera_activate_evt,
                  ],
              )
          )

    #
    # active -> deactivating -> inactive
    #
    camera_node_active_to_inactive_handler = \
      RegisterEventHandler(
          OnStateTransition(
              target_lifecycle_node = camera_node,
              start_state = 'deactivating',
              goal_state = 'inactive',
              entities = [
                  LogInfo(msg = "Emitting 'TRANSITION_CLEANUP' event"),
                  camera_cleanup_evt,
                  ],
              )
          )

    #
    # inactive -> cleaningup -> unconfigured
    #
    camera_node_inactive_to_unconfigured_handler = \
      RegisterEventHandler(
          OnStateTransition(
              target_lifecycle_node = camera_node,
              start_state = 'cleaningup',
              goal_state = 'unconfigured',
              entities = [
                  LogInfo(msg = "Emitting 'TRANSITION_CONFIGURE' event"),
                  camera_configure_evt,
                  ],
              )
          )

    #
    # * -> errorprocessing -> unconfigured
    #
    camera_node_errorprocessing_to_unconfigured_handler = \
      RegisterEventHandler(
          OnStateTransition(
              target_lifecycle_node = camera_node,
              start_state = 'errorprocessing',
              goal_state = 'unconfigured',
              entities = [
                  LogInfo(msg = "Emitting 'TRANSITION_CONFIGURE' event"),
                  camera_configure_evt,
                  ],
              )
          )

    #
    # * -> shuttingdown -> finalized
    #
    camera_node_shuttingdown_to_finalized_handler = \
      RegisterEventHandler(
          OnStateTransition(
              target_lifecycle_node = camera_node,
              start_state = 'shuttingdown',
              goal_state = 'finalized',
              entities = [
                  LogInfo(msg = "Emitting 'SHUTDOWN' event"),
                  camera_shutdown_evt,
                  ],
              )
          )

    #------------------------------------------------------------
    # Now, add all the actions to a launch description and return it
    #------------------------------------------------------------

    ld = LaunchDescription()
    ld.add_action(camera_node_unconfigured_to_inactive_handler)
    ld.add_action(camera_node_active_to_inactive_handler)
    ld.add_action(camera_node_inactive_to_unconfigured_handler)
    ld.add_action(camera_node_errorprocessing_to_unconfigured_handler)
    ld.add_action(camera_node_shuttingdown_to_finalized_handler)
    ld.add_action(tf_node)
    ld.add_action(camera_node)
    ld.add_action(camera_configure_evt)

    return ld
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'),
                ],
            ),
        ])