Lifecycle interface

Core lifecycle for modular robotics systems

Configure · Activate · Run · Transition · Shutdown

Mental Model

Lifecycle interface

Core lifecycle for modular robotics systems

The library stays readable when each concept is tied to an explicit lifecycle phase.

Read this page before the API reference. It describes the intended mental model of the library.

Lifecycle Flow

⚙ Configure

Components create ROS-facing resources in configure hooks, not in their constructor.

▶ Activate

Runtime behavior becomes live only when the node activates managed entities.

▶ Run

Publish, subscribe, call services, and tick timers only while the active state is explicit.

🔁 Transition

The node owns transition propagation, so components do not invent a second control plane.

■ Shutdown

Cleanup and shutdown release resources and leave no hidden runtime state behind.

What A Component Is

LifecycleComponent is not a ROS node. It is a managed entity owned by a lifecycle node.

A component does not spin, does not own the executor, and does not define the ROS 2 lifecycle state machine. Its job is narrower: hold one focused slice of behavior behind explicit lifecycle hooks.

Ownership Model

LifecycleComponentNode owns components. The node is the ROS 2 lifecycle node. Components live inside that node and are registered there.

LifecycleComponentNode
  ├── LifecyclePublisherComponent
  ├── LifecycleSubscriberComponent
  ├── LifecycleTimerComponent
  ├── LifecycleServiceServerComponent
  ├── LifecycleServiceClientComponent
  └── Custom LifecycleComponent

Think in terms of one lifecycle node coordinating several small managed parts, not one large class doing everything.

Who Drives Transitions

The node drives lifecycle transitions. Configure, activate, deactivate, cleanup, shutdown, and error handling enter through the node. The node then propagates the transition to each registered component.

This matters because the library does not create a second control plane. The lifecycle entry point stays explicit and centralized.

Resource Management Happens In Hooks

Components create and destroy ROS resources through explicit hooks.

  • Create publishers, subscriptions, and similar ROS resources during configure.

  • Enable runtime behavior during activate.

  • Disable or gate runtime behavior during deactivate.

  • Release ROS resources during cleanup.

For standard ROS resources, the pre-built library components apply these rules automatically. LifecycleTimerComponent, LifecyclePublisherComponent, LifecycleSubscriberComponent, and the service components each encapsulate the configure / activate / deactivate / cleanup plumbing internally. A node that composes those components needs no _on_activate or _on_deactivate overrides for those resources — the library gates each one based on activation state without any application code. Reserve the explicit hook overrides for resources that have no library equivalent: hardware handles, custom sensor connections, or application-specific runtime state.

State contract. The lifecycle is the interface: resource creation belongs to configure, runtime work belongs to active states, and teardown belongs to cleanup and shutdown.

Do not treat __init__ as the place where runtime ROS resources become live. The library is designed so resource lifetime follows lifecycle transitions.

Activation Must Stay Explicit

Activation state must be explicit and predictable. If a component is inactive, that fact must be reflected in its behavior.

The library favors visible gating over implicit background behavior. When code becomes active or inactive, that change should follow the lifecycle transition directly.

No Hidden State Machine

lifecore_ros2 avoids hidden state machines. It uses the native ROS 2 lifecycle model and keeps component behavior aligned with it.

Users should not have to reason about a second internal status model to understand whether a component can publish, receive, or hold resources.

Prefer Small Components

Prefer small focused components over large monolithic nodes.

Good components usually own one responsibility:

  • one publisher path

  • one subscriber path

  • one bounded piece of integration logic

This keeps lifecycle behavior readable, testable, and predictable. If one class starts owning many unrelated resources and rules, the lifecycle model becomes harder to follow.

In practice, the library works best when the node is the owner and coordinator, and each component stays narrow.