Composable LifeCycle Node
Reading the demos and examples as well as the rclcpp source, it seems that currently the LifeCycleNode interface is a completely independent interface from the normal Node class, with the normal node embedded inside it. In principle it seems there should be nothing stopping us from making lifecycle nodes which are also composable and be able to load multiple managed nodes in one executable.
However, as it stands I think neither the launch system not the composable container interface can support this use case? Trying to register and load a life cycle node as a component on run time unsurprisingly yields a Poco exception.
undefined symbol: _ZN16rclcpp_lifecycle15node_interfaces22LifecycleNodeInterface10on_cleanupERKNS_5StateE)
In addition in the launchros interface currently the lifecycle and component launch interface are entirely separate and seems to have nothing to do with each other. Even if I compose at compile time and launch a single executable using the lifecycle interface of launchros, I'm not sure if it is able to correctly emit and receive the correct events.
Has anyone tried this before? It would be quite cool to have both working together since lifecycles and a unified node API were IMO one of the two most impactful features in ROS 2.
EDIT: Just as a bit of an update, I eventually tried to run a lifecycle node with manual composition, it does work since the lifecycle transitions are just service calls, but I had to use the CLI to invoke the transitions. Still not sure if launch_ros can handle this situation correctly
Asked by eric1221bday on 2019-09-20 06:13:06 UTC
Answers
It is possible to develop a node which inherits from rclcpp::LifecycleNode
and also is registered as a component. You can find an example that I did a while back for Dashing here. However, I believe that the shortcoming in launch_ros
still exists, even in Eloquent. I've created an issue on the launch_ros
Github repo to get visibility.
Asked by Josh Whitley on 2020-04-02 17:21:22 UTC
Comments
I believe this issue covers the same functionality: https://github.com/ros2/launch_ros/issues/41
Asked by rasmusan- on 2020-04-03 03:42:52 UTC
Thanks, I think you're right. I closed it as a duplicate.
Asked by Josh Whitley on 2020-04-06 12:57:34 UTC
Just to elaborate further on Josh Whitley's answer: This is still true in ROS2 Galactic. You can write a node that inherits from rclcpp::LifecycleNode
, implements the lifecycle states, and is launched as either a standalone Node or ComposableNode. However the mechanisms in ros_launch that automate the state transitions only work with LifecycleNode objects. This means that without them, lifecycle nodes will start in the "unconfigured" state, and won't automatically configure or activate themselves, much less shut down properly.
If you really need to run a lifecycle node inside a container, this leaves you with a couple of options (other users please feel free to chime in with any I've missed):
- Manually force the state changes with CLI commands, e.g.
$ ros2 lifecycle set /<node_name> configure/activate/shutdown
. I've tested this out and can confirm it works. Visit this lifecycle demo readme for more information. - Create another node that is responsible for managing the state changes via service calls. This is what the Nav2 package does with its nav2_lifecycle_manager. If you have a look here you will see an example of a Nav2 package which launches quite a few lifecycle nodes as ComposableNodes. For more information on the service calls that can transition states, see the same lifecycle demo readme.
- You could try this cascade_lifecycle package which extends the lifecycle node interface and adds state transition self-calls that you can make from the source code. I haven't tried this myself yet so I can't confirm if it works.
- Wait until official support for lifecycle nodes in containers has been added. There is a large body of work underway to re-write how the underlying node execution process works, and part of this includes changing the lifecycle process so that it is just a trait that you can add to any node (composable or otherwise). You can read the discussion on the redesign here: #215, and track the corresponding PR here: #272
Asked by M@t on 2022-03-20 18:10:31 UTC
Comments
I'd like to see some feedback on this too. I have found the same shortcoming in the
launch_ros
architecture. @william - any comment?Asked by Josh Whitley on 2020-02-19 01:44:51 UTC
Hi, is there any update on this? All I could find is this issue: https://github.com/ros2/launch_ros/issues/41
Asked by relffok on 2020-03-24 18:27:37 UTC