Chapter 2: ROS 2 Fundamentals
🟡 Status: 22% Complete (Foundation Only)
This chapter provides comprehensive ROS 2 fundamentals with hands-on labs for pub/sub, services, actions, and transforms.
Foundation content is complete. Labs (P1-P4) are planned but not yet implemented.
→ View Current Content on GitHub (556 lines)
→ View TODO Roadmap (51 remaining tasks)
📖 Quick Overview
What You'll Learn
Learning Objectives:
- Design ROS 2 systems using pub/sub, services, and actions appropriately
- Implement ROS 2 nodes in Python with proper lifecycle management
- Configure launch files for multi-node systems with parameters
- Apply tf2 transforms for humanoid robot kinematics
- Debug common ROS 2 issues systematically
Prerequisites
- Chapter 1: Introduction to Physical AI (completed)
- ROS 2 Humble installed (Ubuntu 22.04)
- Python 3.10+
- Basic understanding of pub/sub patterns
Time Estimate
- Reading: 3-4 hours
- Labs: 8-12 hours (4 labs × 2-3 hours each)
- Assessment: 3 hours
📚 Chapter Structure
✅ Part 1: Foundation (Complete)
Learning Objectives
- 5 measurable objectives mapping to lab deliverables
- Aligned with constitution standards
Prerequisites Section
- Chapter 1 verification
- ROS 2 Humble installation commands
- Verification script:
ros2 doctor --report
Conceptual Overview
- ROS 2 Graph Architecture: Nodes, topics, services, actions, parameters, tf2
- Communication Patterns Decision Tree: When to use pub/sub vs service vs action
- Node Lifecycle: Mermaid state machine diagram
- Humanoid Robot Example: Unitree G1 ROS 2 integration
Communication Patterns Flowchart
graph TD
A[Need to communicate?] --> B{One-way data stream?}
B -->|Yes| C{Real-time sensor data?}
C -->|Yes| D[Topic (pub/sub)]
C -->|No| D
B -->|No| E{Request-response?}
E -->|Yes| F{Long-running task?}
F -->|No| G[Service]
F -->|Yes| H[Action (with feedback)]
style D fill:#4CAF50
style G fill:#2196F3
style H fill:#FF9800
Troubleshooting Guide
- 10+ common errors with solutions:
ImportError: No module named 'rclpy'→ Source ROS 2 setupTopic /imu not published→ Check publisher node runningService /compute_ik timeout→ Server not ready, check ros2 service listtf2 lookup failed: "base_link" to "hand_link"→ Broadcaster not running- ... (7 more errors with detailed solutions)
Glossary
- 20+ ROS 2 terms defined:
- Node: Independent process in ROS 2 graph
- Topic: Named bus for asynchronous data streaming (pub/sub)
- Service: Synchronous request-response RPC
- Action: Long-running task with feedback (async RPC)
- tf2: Transform library for coordinate frame management
- ... (15 more terms)
Quiz
- 10 conceptual questions testing:
- When to use topic vs service vs action
- Node lifecycle states
- tf2 tree structure
- Parameter server concepts
⏳ Part 2: Labs (Planned - Not Implemented)
Lab P1: Pub/Sub Basics
Tasks Remaining: 9 tasks (T012-T020)
What It Will Include:
publisher_node.py: Publishes IMU data at 50Hzsubscriber_node.py: Logs incoming messagespubsub_demo.launch.py: Launches both nodes- Lab README with walkthrough
Acceptance Criteria:
- Publisher sends 50 messages/second (±5Hz)
- Subscriber logs all messages with timestamps
- Launch file starts both nodes with one command
Lab P2: Services & Actions
Tasks Remaining: 11 tasks (T021-T031)
What It Will Include:
ik_server.py: Inverse kinematics service (~70 lines)ik_client.py: Service client (~40 lines)pick_place_server.py: Pick-and-place action with feedback (~100 lines)pick_place_client.py: Action client (~60 lines)
Acceptance Criteria:
- IK service computes joint angles within 100ms
- Pick-place action provides feedback every 10%
- Clients handle timeouts gracefully
Lab P3: Parameters & Launch
Tasks Remaining: 10 tasks (T032-T041)
What It Will Include:
configurable_node.py: Node with dynamic parameters (~80 lines)unitree_g1.yaml: Humanoid-specific configwalker_mini.yaml: Miniature humanoid configmulti_node_system.launch.py: 5+ nodes with conditionals (~120 lines)
Acceptance Criteria:
- Parameters update without node restart
- Launch file supports robot selection via argument
- YAML configs load correctly
Lab P4: Transforms (tf2)
Tasks Remaining: 10 tasks (T042-T051)
What It Will Include:
transform_broadcaster.py: Broadcasts 8+ frames for humanoid (~100 lines)transform_listener.py: Queries transforms with error handling (~80 lines)- Humanoid tf2 tree diagram (Mermaid)
tf2_demo.launch.py: Starts broadcaster and visualizer
Acceptance Criteria:
- tf2 tree has no loops (acyclic)
- Listener queries succeed 99%+ of time
- RViz2 displays full robot skeleton
🔗 Access Content
What's Available Now
- Learning objectives
- Conceptual overview
- Communication patterns flowchart
- Node lifecycle diagram
- Troubleshooting guide (10 errors)
- Glossary (20+ terms)
- Quiz (10 questions)
Coming Soon
- Lab P1: Pub/Sub (9 tasks)
- Lab P2: Services & Actions (11 tasks)
- Lab P3: Parameters & Launch (10 tasks)
- Lab P4: Transforms (10 tasks)
- Assessments rubrics (4 tasks)
- Polish & validation (9 tasks)
Related Artifacts
- Spec: specs/002-ros2-fundamentals/spec.md (4 user stories, 8 functional requirements)
- Plan: specs/002-ros2-fundamentals/plan.md (architecture decisions)
- Tasks: specs/002-ros2-fundamentals/tasks.md (65 total tasks, 14 complete)
- PHRs: 3 Prompt History Records
📊 Completion Status
| Phase | Tasks | Status | Link |
|---|---|---|---|
| Setup | 4 | ✅ Complete | T001-T004 |
| Foundation | 7 | ✅ Complete | T005-T011 |
| Lab P1: Pub/Sub | 9 | ⏳ Pending | T012-T020 |
| Lab P2: Services/Actions | 11 | ⏳ Pending | T021-T031 |
| Lab P3: Parameters/Launch | 10 | ⏳ Pending | T032-T041 |
| Lab P4: Transforms | 10 | ⏳ Pending | T042-T051 |
| Assessments | 4 | ⏳ Pending | T053-T056 |
| Polish | 9 | ⏳ Pending | T057-T065 |
| TOTAL | 65 | 22% (14/65) | - |
🚀 Next Steps
For Students (Using Current Content)
- Read Foundation: GitHub README
- Study Diagrams: Communication patterns + node lifecycle
- Take Quiz: Test conceptual understanding
- Practice: Follow Official ROS 2 Tutorials while waiting for labs
- Reference: Use glossary and troubleshooting guide
For Contributors
Want to help complete the labs? Follow the spec-driven workflow:
- Read Tasks: tasks.md
- Pick a Lab: P1 (easiest) → P2 → P3 → P4 (most complex)
- Implement: Follow task acceptance criteria
- Validate: Test code on Ubuntu 22.04 + ROS 2 Humble
- Submit PR: Reference task IDs in commit messages
Estimated Effort:
- Lab P1: ~3-4 hours (10-12K tokens with Claude Code)
- Lab P2: ~4-5 hours (12-15K tokens)
- Lab P3: ~4-5 hours (12-15K tokens)
- Lab P4: ~5-6 hours (15-18K tokens)
🔬 Development History
Created Using: Spec-Kit Plus /sp.* workflow
- Spec Phase: PHR-001
- Tasks Phase: PHR-002 (65 tasks generated)
- Foundation Implementation: PHR-003 (14 tasks completed)
Quality Status: Foundation passes constitution checklist; labs pending Last Updated: 2025-11-29
📝 Sample: Communication Patterns
When to Use What?
Topic (Pub/Sub) - Continuous Data Streams
Use When:
- Sensor data (IMU, cameras, LiDAR) broadcasting to multiple consumers
- Real-time state updates (odometry, joint states)
- One-to-many or many-to-many communication
Example: Humanoid robot's IMU publishes at 100Hz, consumed by:
- Balance controller
- State estimator
- Data logger
# publisher_node.py
import rclpy
from rclpy.node import Node
from sensor_msgs.msg import Imu
class IMUPublisher(Node):
def __init__(self):
super().__init__('imu_publisher')
self.publisher_ = self.create_publisher(Imu, '/imu/data', 10)
self.timer = self.create_timer(0.02, self.publish_imu) # 50Hz
def publish_imu(self):
msg = Imu()
msg.header.stamp = self.get_clock().now().to_msg()
# ... populate IMU data
self.publisher_.publish(msg)
Service - Request/Response
Use When:
- One-time queries (inverse kinematics, path planning)
- Synchronous operations with guaranteed response
- Client needs result before proceeding
Example: Compute joint angles for target pose
# ik_server.py
from my_interfaces.srv import ComputeIK
def handle_ik_request(request, response):
# Compute inverse kinematics
response.joint_angles = compute_ik(request.target_pose)
response.success = True
return response
srv = node.create_service(ComputeIK, '/compute_ik', handle_ik_request)
Action - Long-Running Tasks with Feedback
Use When:
- Tasks take >1 second (navigation, manipulation)
- Need progress updates (percentage complete, current waypoint)
- Client may cancel mid-execution
Example: Pick-and-place with progress feedback
# pick_place_server.py
class PickPlaceServer(Node):
def execute_callback(self, goal_handle):
feedback = PickPlace.Feedback()
# Phase 1: Move to object (0-33%)
feedback.progress = 0.0
goal_handle.publish_feedback(feedback)
move_to_object()
# Phase 2: Grasp (33-66%)
feedback.progress = 0.33
goal_handle.publish_feedback(feedback)
close_gripper()
# Phase 3: Move to target (66-100%)
feedback.progress = 0.66
goal_handle.publish_feedback(feedback)
move_to_target()
feedback.progress = 1.0
goal_handle.publish_feedback(feedback)
result = PickPlace.Result()
result.success = True
return result
This chapter demonstrates incremental development: foundation complete, labs pending. Transparent TODO tracking shows exactly what's done and what's next.