Skip to main content

Week 4: ROS 2 Nodes and Topics

This lesson focuses on the core communication system of ROS 2, which is built around Nodes and Topics. These two components form the foundation of how different parts of a robot communicate with each other in real time.

Understanding nodes and topics is mandatory before moving toward robot control, navigation, perception, and AI-based automation.


Learning Objectives​

By the end of this lesson, you will be able to:

  1. Define what a Node is in ROS 2 and explain its role in distributed systems
  2. Explain what a Topic is and how the Publisher-Subscriber model works
  3. Create ROS 2 nodes in Python with proper lifecycle management
  4. Implement publishers and subscribers to exchange data between nodes
  5. Visualize topic data flow using ROS 2 command-line tools and RViz
  6. Apply node-topic architecture to humanoid robotics systems

Prerequisites​

  • ROS 2 Humble installed on Ubuntu 22.04 or Docker container
  • Python 3.8+ with basic understanding of classes and functions
  • Completed Week 3: ROS 2 Architecture & Core Concepts
  • Terminal/command-line proficiency
  • Text editor or IDE (VS Code recommended)

1. Introduction​

Imagine a humanoid robot trying to walk. Its camera needs to detect obstacles, its IMU needs to track balance, its motors need position commands, and its AI brain needs to coordinate everything. How do these components communicate without creating a tangled mess of dependencies?

ROS 2 solves this with Nodes and Topics - a elegant publish-subscribe architecture that keeps components loosely coupled, independently testable, and easily replaceable. This lesson explores how these building blocks enable modular robotics systems.


2. Conceptual Overview​

What is a Node?​

A Node is a single executable process that performs one specific task in your robot system. Think of nodes as specialized workers in a factory:

  • Camera Node: Captures images from robot's camera
  • Motor Controller Node: Sends commands to motors
  • AI Perception Node: Detects objects in images
  • Balance Controller Node: Maintains humanoid stability

Each node runs independently and communicates with others through topics.

What is a Topic?​

A Topic is a named communication channel where nodes publish and subscribe to messages. It's like a radio frequency:

  • Publishers broadcast messages on a topic (like a radio transmitter)
  • Subscribers listen for messages on that topic (like a radio receiver)
  • Multiple nodes can publish and subscribe to the same topic

Key Principle: Publishers and subscribers don't know about each other directly - they only know the topic name. This decoupling is what makes ROS 2 so flexible.


3. Technical Deep Dive​

Node Architecture​

Every ROS 2 node inherits from the Node class and includes:

┌───────────────────────────────────┐
│ ROS 2 Node │
│ │
│ ┌─────────────────────────────┐ │
│ │ Publishers │ │
│ │ - Send messages │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ Subscribers │ │
│ │ - Receive messages │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ Timers │ │
│ │ - Periodic callbacks │ │
│ └─────────────────────────────┘ │
│ │
│ ┌─────────────────────────────┐ │
│ │ Parameters │ │
│ │ - Runtime configuration │ │
│ └─────────────────────────────┘ │
└───────────────────────────────────┘

Topic Communication Flow​

Publisher Node                    Subscriber Node
┌──────────────┐ ┌──────────────┐
│ │ │ │
│ publish() │ │ callback() │
│ │ │ │ ▲ │
│ ▼ │ │ │ │
│ ┌────────┐ │ │ ┌────────┐ │
│ │Message │ │ Topic: /data │ │Message │ │
│ └────────┘ │ ─────────────► │ └────────┘ │
│ │ │ │
└──────────────┘ └──────────────┘
DDS Middleware (Data Distribution Service)

Message Types​

ROS 2 uses strongly-typed messages. Common types include:

  • std_msgs/String: Simple text messages
  • std_msgs/Int32: Integer values
  • geometry_msgs/Twist: Velocity commands (linear/angular)
  • sensor_msgs/Image: Camera images
  • sensor_msgs/JointState: Robot joint positions

4. Diagrams​

Pub-Sub Communication Pattern​

┌────────────────────────────────────────────────────────────┐
│ ROS 2 Graph │
│ │
│ ┌──────────────┐ Topic: /robot/cmd_vel │
│ │ Teleop Node ├──────────────────────► │
│ │ (Publisher) │ geometry_msgs/Twist │
│ └──────────────┘ │ │
│ │ │
│ ▼ │
│ ┌──────────────────┐ │
│ │ Motor Driver │ │
│ │ (Subscriber) │ │
│ └──────────────────┘ │
│ │
│ ┌──────────────┐ Topic: /camera/image │
│ │ Camera Node ├──────────────────────► │
│ │ (Publisher) │ sensor_msgs/Image │
│ └──────────────┘ │ │
│ │ │
│ ├──────►┌─────────────┐
│ │ │ Vision Node │
│ │ │(Subscriber) │
│ │ └─────────────┘
│ │ │
│ └──────►┌─────────────┐
│ │ Recorder │
│ │(Subscriber) │
│ └─────────────┘
└────────────────────────────────────────────────────────────┘

5. Code Examples​

Example 1: Simple Publisher Node​

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class PublisherNode(Node):
def __init__(self):
super().__init__('simple_publisher')

# Create publisher on topic '/robot/status'
self.publisher_ = self.create_publisher(
String,
'/robot/status',
10 # Queue size
)

# Create timer to publish every 1 second
self.timer = self.create_timer(1.0, self.timer_callback)
self.counter = 0

self.get_logger().info('Publisher node started')

def timer_callback(self):
msg = String()
msg.data = f'Robot status update #{self.counter}'

self.publisher_.publish(msg)
self.get_logger().info(f'Published: "{msg.data}"')

self.counter += 1

def main(args=None):
rclpy.init(args=args)
node = PublisherNode()

try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

ROS 2 Humble Compatible ✅

Example 2: Simple Subscriber Node​

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String

class SubscriberNode(Node):
def __init__(self):
super().__init__('simple_subscriber')

# Create subscriber on topic '/robot/status'
self.subscription = self.create_subscription(
String,
'/robot/status',
self.listener_callback,
10
)

self.get_logger().info('Subscriber node started')

def listener_callback(self, msg):
self.get_logger().info(f'Received: "{msg.data}"')

def main(args=None):
rclpy.init(args=args)
node = SubscriberNode()

try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

ROS 2 Humble Compatible ✅

Example 3: Humanoid Joint Publisher​

#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import JointState
import math

class HumanoidJointPublisher(Node):
def __init__(self):
super().__init__('humanoid_joint_publisher')

self.publisher_ = self.create_publisher(
JointState,
'/humanoid/joint_states',
10
)

self.timer = self.create_timer(0.1, self.publish_joint_states)
self.angle = 0.0

self.get_logger().info('Humanoid joint publisher started')

def publish_joint_states(self):
msg = JointState()
msg.header.stamp = self.get_clock().now().to_msg()

# Define joints for humanoid robot
msg.name = ['left_hip', 'left_knee', 'left_ankle',
'right_hip', 'right_knee', 'right_ankle']

# Simulate walking motion with sine wave
self.angle += 0.05
offset = math.sin(self.angle)

msg.position = [
offset * 0.3, # left hip
abs(offset) * 0.6, # left knee
-offset * 0.2, # left ankle
-offset * 0.3, # right hip
abs(-offset) * 0.6,# right knee
offset * 0.2 # right ankle
]

self.publisher_.publish(msg)
self.get_logger().info(f'Published joint states (angle: {self.angle:.2f})')

def main(args=None):
rclpy.init(args=args)
node = HumanoidJointPublisher()

try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
finally:
node.destroy_node()
rclpy.shutdown()

if __name__ == '__main__':
main()

ROS 2 Humble Compatible ✅


6. Hands-On Exercises​


7. Quiz​

📝 Week 4 Knowledge Check

1. What is a ROS 2 Node?

2. What communication pattern do Topics use in ROS 2?

3. Can multiple nodes subscribe to the same topic?

4. What does the 'queue size' parameter (10) mean in create_publisher()?

5. What command lists all active topics in a ROS 2 system?

6. In the Publisher-Subscriber model, do publishers and subscribers know about each other directly?

7. What happens if a subscriber callback function takes too long to execute?

8. Which message type would you use to send velocity commands to a robot?


8. Summary​

Key Takeaways:

  • Nodes are independent executable processes that perform specific tasks in a ROS 2 system
  • Topics are named communication channels using the Publish-Subscribe pattern
  • Publishers send messages to topics; Subscribers receive messages from topics
  • Publishers and subscribers are loosely coupled - they don't know about each other directly
  • Multiple publishers and subscribers can use the same topic simultaneously
  • ROS 2 uses strongly-typed messages (std_msgs, sensor_msgs, geometry_msgs)
  • Queue size determines how many messages to buffer when sending/receiving
  • DDS middleware handles the underlying network communication automatically
  • Node-topic architecture enables modular, distributed, fault-tolerant robotics systems
  • Essential command-line tools: ros2 topic list, ros2 topic echo, ros2 node list

9. Glossary​

  • Node: A single executable process in ROS 2 that performs a specific task
  • Topic: A named communication channel for message exchange between nodes
  • Publisher: A node component that sends messages to a topic
  • Subscriber: A node component that receives messages from a topic
  • Publish-Subscribe (Pub-Sub): A messaging pattern where senders (publishers) and receivers (subscribers) are decoupled through an intermediary (topic)
  • Message Type: The data structure format for messages (e.g., String, Int32, Twist)
  • Queue Size: The number of messages to buffer when publishing/subscribing faster than processing
  • Callback Function: A function automatically called when a subscriber receives a message
  • DDS (Data Distribution Service): The middleware layer ROS 2 uses for network communication
  • rclpy: The ROS 2 Client Library for Python
  • Spin: The function that keeps a node running and processing callbacks

10. Further Reading​

  1. ROS 2 Humble Official Documentation - Nodes

  2. ROS 2 Humble Official Documentation - Topics

  3. Writing a Simple Publisher and Subscriber (Python)

  4. About ROS 2 Interfaces (Messages, Services, Actions)

  5. DDS and ROS 2 Middleware


Version: ROS 2 Humble License: CC BY-SA 4.0