Yu Ge Robotics
Blog
2026-06-081 min read

Designing ROS2 lifecycle nodes for field robots

A practical pattern for keeping robot startup, recovery, and shutdown behavior observable and repeatable.

ROS2C++Architecture

Lifecycle nodes make robot behavior easier to reason about because each node exposes its state. In production systems, I use them for sensors, planners, controllers, and every component that has hardware or network dependencies.

State-first node design

The node should do almost nothing in its constructor. The expensive work belongs in on_configure, activation belongs in on_activate, and cleanup belongs in on_cleanup.

#include <rclcpp_lifecycle/lifecycle_node.hpp>

class MotorBridge : public rclcpp_lifecycle::LifecycleNode {
public:
  MotorBridge() : LifecycleNode("motor_bridge") {}

  CallbackReturn on_configure(const rclcpp_lifecycle::State &) override {
    port_ = declare_parameter<std::string>("port", "/dev/ttyUSB0");
    driver_.connect(port_);
    return CallbackReturn::SUCCESS;
  }

  CallbackReturn on_activate(const rclcpp_lifecycle::State &) override {
    command_sub_ = create_subscription<Twist>("cmd_vel", 10, onCommand);
    return CallbackReturn::SUCCESS;
  }
};

Launch with parameters

Keep lifecycle parameters explicit and versioned with the robot.

motor_bridge:
  ros__parameters:
    port: /dev/ttyUSB0
    watchdog_ms: 250
    frame_id: base_link

This pattern gives operators a predictable control surface and gives developers a cleaner way to test failure modes.