Skip to main content

Section 1: Nodes and the Graph

Estimated Reading Time: 7 minutes Bloom's Level: Understand, Apply Key Learning: What are ROS 2 nodes and how they form a computation graph


What is a ROS 2 Node?​

A node is an independent ROS 2 program. It's a single, focused process that does one thing well.

Think of it like this:

  • Traditional robot code: One big program does everything (sensing, planning, control)
  • ROS 2 code: Many small programs, each doing one thing (sensor driver, planner, controller)

Real-World Analogy​

Imagine a restaurant:

  • Traditional approach: One chef does everything (prep, cooking, plating, cleaning)
  • ROS 2 approach: Specialized stations
    • Prep station (sensor input)
    • Cooking station (processing)
    • Plating station (control)
    • Each station communicates with the next

Why Nodes?​

āœ… Modularity: Easy to understand, test, and reuse āœ… Reliability: One failing node doesn't crash everything āœ… Scalability: Run nodes on different computers āœ… Flexibility: Mix and match nodes for different robots


The ROS 2 Graph​

A running ROS 2 system is a graph of communicating nodes:

         ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”
│ Sensor Driver Node │
│ (camera_node) │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
│
[Topic: /image]
│
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€v──────────┐
│ Processing Node │
│ (detector_node) │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”¬ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜
│
[Topic: /detections]
│
ā”Œā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€v──────────┐
│ Control Node │
│ (controller_node) │
ā””ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”€ā”˜

Key components:

  • Nodes (boxes): Independent programs
  • Topics (arrows): Communication channels
  • Messages (flow): Data traveling through topics

Each node:

  • Runs independently
  • Doesn't know about other nodes
  • Only cares about topics it uses

Your First ROS 2 Node: Hello, ROS 2!​

Let's create the simplest possible ROS 2 node:

Code Example 1: hello_node.py​

Location: code-examples/ros2_packages/hello_world_py/

Generated by: ros2-code-generator skill

# File: hello_world_py/hello_world_py/hello_node.py
import rclpy
from rclpy.node import Node

class HelloNode(Node):
"""Simple node that prints a greeting."""

def __init__(self):
# Initialize the node with name 'hello_node'
super().__init__('hello_node')

# Create a timer that calls a callback every 1 second
self.timer = self.create_timer(1.0, self.timer_callback)

# Counter for demonstration
self.i = 0

def timer_callback(self):
"""This function is called every 1 second."""
self.get_logger().info(f'Hello, ROS 2! Message #{self.i}')
self.i += 1

def main(args=None):
# Initialize ROS 2
rclpy.init(args=args)

# Create and run the node
node = HelloNode()
rclpy.spin(node) # Keep the node running (blocking call)

# Cleanup
rclpy.shutdown()

if __name__ == '__main__':
main()

Understanding the Code​

Line by line (annotated by code-explainer subagent):

import rclpy
  • Import ROS 2 Python client library
from rclpy.node import Node
  • Import the Node base class (all ROS 2 nodes inherit from this)
class HelloNode(Node):
  • Create our custom node class that inherits from Node
super().__init__('hello_node')
  • Initialize the Node parent class
  • 'hello_node' is the node's unique name in the ROS 2 graph
self.create_timer(1.0, self.timer_callback)
  • Create a timer that calls timer_callback every 1.0 second
  • Timers are how nodes do periodic work
self.get_logger().info(...)
  • Log a message visible in the console
  • get_logger() is inherited from Node class
rclpy.init(args=args)
  • Initialize ROS 2 (must be called before creating nodes)
rclpy.spin(node)
  • Start the event loop for this node
  • The node will keep running until you press Ctrl+C

Running Your First Node​

Step 1: Build the Package​

cd physical-ai-textbook/code-examples
colcon build --packages-select hello_world_py

Step 2: Source the Environment​

source ~/physical-ai-textbook/install/setup.bash

Step 3: Run the Node​

ros2 run hello_world_py hello_node

Expected Output​

[INFO] [hello_node]: Hello, ROS 2! Message #0
[INFO] [hello_node]: Hello, ROS 2! Message #1
[INFO] [hello_node]: Hello, ROS 2! Message #2
...

Press Ctrl+C to stop the node.


Inspecting the Node​

While the node is running (in another terminal), try these commands:

See All Nodes​

ros2 node list

Output:

/hello_node

Get Node Information​

ros2 node info /hello_node

Output:

/hello_node
Subscribers:
Publishers:
Service Servers:
Service Clients:
Action Servers:
Action Clients:

(This node doesn't publish or subscribe to anything yet - that's next!)


Anatomy of a ROS 2 Node​

Every ROS 2 node has these parts:

PartPurposeExample
ClassInherits from Nodeclass HelloNode(Node)
__init__Create publishers, subscribers, timersself.create_timer()
CallbackCode that runs when event happenstimer_callback()
MainEntry point, init ROS, spinrclpy.init(), rclpy.spin()

Node Lifecycle​

Every ROS 2 node goes through these phases:

1. Initialize ROS 2
rclpy.init()
↓
2. Create Node
HelloNode()
↓
3. Create Resources (publishers, subscribers, services)
self.create_timer(), self.create_publisher(), etc.
↓
4. Spin (keep running, process events)
rclpy.spin(node)
↓
5. Shutdown
rclpy.shutdown()

Key Takeaways​

āœ… A node is an independent ROS 2 program āœ… Every node inherits from the Node class āœ… Nodes are connected by topics and services āœ… Nodes run independently and don't know about each other āœ… Use timers to make nodes do work periodically


Try It Yourself​

Modify hello_node.py to:

  • Change the message text
  • Change the timer interval from 1.0 second to 2.0 seconds
  • Remove the counter (don't increment self.i)
  • Log messages at different levels: .info(), .warning(), .error()

Next Steps​

Now that you understand nodes, let's look at how they communicate:

šŸ‘‰ Next: Section 2: Topics - Publish and Subscribe

Or jump to:


Resources​


Section Status: Complete āœ… Skills Used: ros2-code-generator, code-explainer