Skip to content

Lifecycle Node System

Mohsin Mirza edited this page Mar 31, 2026 · 1 revision

Lifecycle Node System

All perception nodes in this pipeline are ROS 2 Lifecycle Nodes. This gives the dispatcher precise control over when models are loaded into GPU memory and when they are released.


Why Lifecycle Nodes?

YOLOv8 models are large. Loading all of them at startup would exhaust VRAM on systems with limited GPU memory. The lifecycle system allows the pipeline to:

  • Load a model only when its task is requested
  • Immediately unload the model when the task is complete
  • Or keep all models pre-loaded for fast task switching

Lifecycle States

┌──────────────┐   configure   ┌──────────────┐   activate   ┌──────────────┐
│ Unconfigured │──────────────▶│   Inactive   │─────────────▶│    Active    │
└──────────────┘               └──────────────┘               └──────────────┘
                                      ▲                               │
                                      │         deactivate            │
                                      └───────────────────────────────┘
                                      │
                               cleanup│
                                      ▼
                               ┌──────────────┐
                               │ Unconfigured │
                               └──────────────┘
State What happens
Unconfigured Node exists but no publishers, subscribers, or models are created
Inactive (Configured) Publishers/subscribers allocated; model loaded into VRAM
Active Node is processing data and publishing results

Eager Loading (Default)

ros2 launch perception action_launch.py lazy_loading:=false

Behaviour:

  • All nodes are configured (models loaded into VRAM) at startup
  • Tasks only toggle activatedeactivate
  • Fast task execution — no model loading overhead per task
  • High VRAM usage — all models stay resident

Lifecycle per task:

Startup:  configure all nodes → Inactive
Task:     activate relevant nodes → Active → deactivate → Inactive
Shutdown: cleanup all nodes → Unconfigured

Lazy Loading

ros2 launch perception action_launch.py lazy_loading:=true

Behaviour:

  • Nodes start in Unconfigured state; nothing is loaded at startup
  • Each task triggers a full configure → activate cycle (loads model)
  • After task: deactivate → cleanup (fully unloads model from VRAM)
  • Slower per task — model load time added to each request
  • Low VRAM usage — only one model in memory at a time

Lifecycle per task:

Task:  configure node (load model) → activate → process → deactivate → cleanup (unload)

Choosing a Mode

Scenario Recommended Mode
Dedicated GPU with sufficient VRAM Eager (default)
Shared GPU / limited VRAM Lazy
Frequent repeated tasks Eager
Infrequent, ad-hoc tasks Lazy

Manual Lifecycle Control

You can manually control any node's state for debugging:

# Check all lifecycle node states
for node in $(ros2 lifecycle nodes); do echo -n "$node: "; ros2 lifecycle get $node; done
 
# Manually activate a node
ros2 lifecycle set /subdoor_pose_estimator activate
 
# Check a single node
ros2 lifecycle get /table_height_estimator

Valid transition commands: configure · activate · deactivate · cleanup · shutdown


Parameter Updates (Lazy Mode Note)

When a task needs to override a node's parameters (e.g. changing the target_class for a YOLO node), parameters must be set while the node is in the Inactive state — i.e. after configure but before activate. The dispatcher handles this automatically via the SetParameters service before calling activate.

Clone this wiki locally