How to launch pipeline of two lifecycle nodes in ROS 2 Crystal in a concise script?
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?