How to launch pipeline of two lifecycle nodes in ROS 2 Crystal in a concise script?

asked 2019-02-08 02:06:20 -0500

ralph-lange gravatar image

The main node of the fmi_adapter package for ROS 2 inherits from the LifecycleNode class. Together with the fmi_adapter package, I created a small examples packages with a launch file starting two instances of this node as a pipeline. The launch script first configures and then activates both node instances A and B in the style: Invoke B, invoke A, configure B, configure A, activate B, activate A.

A_node = launch_ros.actions.LifecycleNode(...)

B_node = launch_ros.actions.LifecycleNode(...)

configure_B_node = launch.actions.EmitEvent(
    event=launch_ros.events.lifecycle.ChangeState(
        lifecycle_node_matcher=launch.events.process.matches_action(B_node),
        transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE,
    )
)

activate_B_node = launch.actions.EmitEvent(event=launch_ros.events.lifecycle.ChangeState(
    lifecycle_node_matcher=launch.events.process.matches_action(B_node),
    transition_id=lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE))

configure_A_node = launch.actions.EmitEvent(
    event=launch_ros.events.lifecycle.ChangeState(
        lifecycle_node_matcher=launch.events.process.matches_action(A_node),
        transition_id=lifecycle_msgs.msg.Transition.TRANSITION_CONFIGURE))

activate_A_node = launch.actions.EmitEvent(
    event=launch_ros.events.lifecycle.ChangeState(
        lifecycle_node_matcher=launch.events.process.matches_action(A_node),
        transition_id=lifecycle_msgs.msg.Transition.TRANSITION_ACTIVATE))

on_inactive_B_handler = launch.actions.RegisterEventHandler(
    launch_ros.event_handlers.OnStateTransition(
        target_lifecycle_node=B_node, goal_state='inactive',
        entities=[configure_A_node]))

on_inactive_A_handler = launch.actions.RegisterEventHandler(
    launch_ros.event_handlers.OnStateTransition(
        target_lifecycle_node=A_node, goal_state='inactive',
        entities=[activate_B_node]))

on_active_B_handler = launch.actions.RegisterEventHandler(
    launch_ros.event_handlers.OnStateTransition(
        target_lifecycle_node=B_node, goal_state='active',
        entities=[activate_A_node]))

description = launch.LaunchDescription()
description.add_action(on_inactive_B_handler)
description.add_action(on_inactive_A_handler)
description.add_action(on_active_B_handler)
description.add_action(B_node)
description.add_action(A_node)
description.add_action(configure_B_node)

(cf. https://github.com/boschresearch/fmi_... )

This solution seems quite lengthy to me. Is this the right approach? Are there any helper-functions available to implement this task more concisely?

edit retag flag offensive close merge delete