Could the LifecycleNode API be collapsed into Node itself for ROS 2 L-turtle and make all nodes managed? This would simplify matters by not having to deal with managed vs non-managed nodes together in the same application. Making this a first-class concept in ROS 2 would encourage developers to think through the different states the application could be in and provide them a common pattern to code defensively for them. With some default trivial transition implementations and a default transition manager in the executor itself perhaps to transition from uncofigured to start and then to shutdown, the migration could be manageable.
However, are there reasons why we cannot or should not make all Nodes LifecycleNodes?
I think having an option in NodeOptions (passed to a Node constructor) to enable managed states would be neat to have. I’m sure there are several complexities involved but it’s something worth discussing here.
I think that all nodes having at least a minimal lifecycle would be a good thing. Appropriate defaults and automatic transitions would allow existing nodes to migrate (relatively) easily. However, there is a risk with making all nodes use one lifecycle state machine: Different applications might prefer different lifecycle state machines, depending on their needs.
There are also several things about the current state machine that I would like to revise, and the ability to revise in the future as well is another reason not to have a complex state machine be required for all nodes.
Perhaps a good way forward would be to have a very simple state machine for the default life cycle, with the ability to override it with more complex custom state machines; we could provide some common ones.
Another argument against is the complexity that it would introduce to even the most simple nodes being produced by beginners to ROS. This is something to be very careful about - good defaults might help, but the inherent complexity of having a lifecycle in every node needs to be managed.
I think there are a couple of ways to handle that:
We could make the transition methods optional, so that they don’t have to be implemented and users don’t have to think about lifecycle if they don’t want its benefits. The obvious drawback is that the system then don’t know much about what nodes are ‘really’ lifecycle nodes that it can send transition requests to and which are not ‘actually’ lifecycle nodes. We could store some state in the default transition methods if they’ve been overridden or not, but that starts to get a little messy.
We could make them required, but provide an easy way to have them autotransition to Active so that they don’t need to think about orchestrating their system, if they don’t want to. I actually worked on a new Launch ROS feature for this recently that makes this possible with an autostart=True functionality of LifecycleNode. That does add a bit more required structure to using ROS 2 which I don’t love, even as someone that uses lifecycle nodes for everything.
In either case, it makes it possible for users that want to manage the state machine and/or orchestrate the bring up / current state configuration of their systems to still do so.
Another option is also to just wipe out all docs and examples that use Node and start early to have everything be a LifecycleNode in the learning and education pipelines so that folks naturally value these and use them. Especially now with the launch autostart feature, someone can basically just treat it as an auto-transitioning node if they want to. Rather than building it into the base functionality, we steer folks in this direction through demos, tutorials, docs, and best practices more so than we do today. That might actually be the best option, in my opinion.
I think it’s important that a user can still do ros2 run my_package my_node and it actually starts doing things.
Otherwise the talker/listener examples will become really complicated already…
I believe it’s important to minimize the complexity involved in writing a Node—not just for the benefit of beginners, but also for maintaining large codebases. Lifecycle-based behavior is often unnecessary and, in many cases, shouldn’t be imposed. I support efforts to unify the APIs, such as the approach proposed by @Yadunund using options. However, instead of enabling automatic transitions, I would prefer that Nodes continue to function exactly as they do today when the lifecycle option is not enabled—without exposing any lifecycle-related services.