Skip to main content

Chapter 3 Summary: Python Integration with rclpy

Generated by: Summary workflow Time to Review: 5-7 minutes Covers: Key concepts, mental models, and common mistakes


Key Takeaways

1. rclpy is the Python Interface to ROS 2

  • rclpy allows you to create ROS 2 nodes in Python
  • Nodes inherit from the Node class
  • Every node must call rclpy.spin() to stay alive and process callbacks

2. Publishers Send Velocity Commands

  • Create publishers for Twist messages to /cmd_vel
  • Twist contains linear velocity (m/s) and angular velocity (rad/s)
  • Publish repeatedly in a control loop (10 Hz typical), not just once

3. Control Loops Must Run Repeatedly

  • Use timers to create periodic callbacks (every 0.1 seconds for 10 Hz)
  • Publish velocity commands in each callback
  • Robot receives repeated commands and moves smoothly

4. Parameters Configure Behavior at Runtime

  • Declare parameters with default values
  • Read parameter values in code
  • React to parameter changes without restarting

5. Actions Are for Goal-Reaching Tasks

  • Actions send goals with feedback and results
  • Action servers execute goals and send progress
  • Use actions for navigation, manipulation, long-running tasks

6. Python Control Integrates with Chapter 2 Robots

  • URDF defines robot structure (Chapter 2)
  • Python code publishes commands (Chapter 3)
  • Gazebo receives commands and moves robot

Mental Models

Model 1: Node as an Active Process

Node = Executable Process

┌─────────────────────────────┐
│ VelocityController Node │
├─────────────────────────────┤
│ Publisher: /cmd_vel │
│ Timer: 0.1 sec (10 Hz) │
│ Callback: timer_callback() │
│ │
│ While spinning: │
│ Every 0.1 sec: │
│ - Create Twist message │
│ - Publish to /cmd_vel │
│ - Gazebo reads message │
│ - Robot moves │
└─────────────────────────────┘

Model 2: Control Loop as Repeated Publication

WRONG (One-shot):
Publish Twist -> Robot moves once -> Stop

RIGHT (Control loop):
Publish Twist ─┐
Publish Twist ─┼─> Robot moves smoothly
Publish Twist ─┤ (receives repeated commands)
Publish Twist ─┘

Model 3: Parameter-Based Configuration

Parameter Server
┌──────────────────────┐
│ max_velocity: 1.0 │
│ robot_name: "arm1" │
│ enable_logging: true │
└──────────────────────┘
│ read
v
Python Node reads at runtime

v
Behavior changes (without recompile)

Model 4: Action Pattern for Goal-Seeking

ACTION PATTERN:

Client Server
│ │
├─ Send Goal: "Move to 10" ─>│
│ │
│<──── Feedback: "at 3" ────┤
│<──── Feedback: "at 5" ────┤
│<──── Feedback: "at 8" ────┤
│ │
│<─── Result: "Success" ────┤
│ │

Concept Map

rclpy (Python Interface)
├─ Node (Executable process)
│ ├─ Publisher (sends messages to topics)
│ │ └─ Twist (velocity message: linear + angular)
│ ├─ Timer (periodic callbacks)
│ │ └─ Control loop (e.g., 10 Hz)
│ ├─ Parameter (configuration value)
│ │ └─ Declare, Read, React to changes
│ └─ Action (goal-oriented communication)
│ ├─ Action Server (executes goals)
│ ├─ Action Client (sends goals)
│ └─ Feedback + Result (progress + completion)

└─ Integration with Chapter 2
└─ Python code controls URDF robots in Gazebo

Common Mistakes and How to Avoid Them

Mistake 1: Publishing Velocity Once Instead of in a Loop

Problem:

msg = Twist()
msg.linear.x = 1.0
publisher.publish(msg) # Publish once
# Robot doesn't move sustainably

Fix: Use a timer callback:

self.timer_ = self.create_timer(0.1, self.timer_callback)

def timer_callback(self):
msg = Twist()
msg.linear.x = 1.0
self.publisher_.publish(msg) # Publish every 0.1 sec

Mistake 2: Forgetting to Declare Parameter Before Using It

Problem:

# Directly try to read parameter
value = self.get_parameter('max_velocity').value
# Parameter doesn't exist -> ERROR

Fix: Declare first:

self.declare_parameter('max_velocity', 1.0)
value = self.get_parameter('max_velocity').value

Mistake 3: Publishing to Wrong Topic

Problem:

publisher = self.create_publisher(Twist, '/my_topic', 10)
# Gazebo listens to /cmd_vel, not /my_topic
# Robot doesn't respond

Fix: Use standard topic:

publisher = self.create_publisher(Twist, '/cmd_vel', 10)

Mistake 4: Not Spinning the Node

Problem:

def main():
rclpy.init()
node = VelocityController()
# Missing: rclpy.spin(node)
node.destroy_node()
# Node exits immediately

Fix: Add spin():

def main():
rclpy.init()
node = VelocityController()
rclpy.spin(node) # Keep node alive
node.destroy_node()

Mistake 5: Confusing Service (Ch1) with Action (Ch3)

Wrong Use:

  • Service: "Navigate to location" (expects immediate response)
  • Action: "Print hello" (doesn't need feedback)

Right Use:

  • Service: "Get robot battery level" (one-shot query)
  • Action: "Navigate to location" (long-running, needs feedback)

Mistake 6: Not Handling Parameter Changes

Problem:

# Read parameter once in __init__
max_vel = self.get_parameter('max_velocity').value
# If parameter changes at runtime, code doesn't know

Fix: Read parameter in callback:

def timer_callback(self):
max_vel = self.get_parameter('max_velocity').value
# Reads fresh value each time

Quick Reference: Common Patterns

Creating and Using a Publisher

# In __init__:
self.publisher_ = self.create_publisher(Twist, '/cmd_vel', 10)

# In callback:
msg = Twist()
msg.linear.x = 0.5
self.publisher_.publish(msg)

Using Parameters

# In __init__:
self.declare_parameter('max_velocity', 1.0)

# In callback:
max_vel = self.get_parameter('max_velocity').get_parameter_value().double_value

Control Loop with Timer

# In __init__:
self.timer_ = self.create_timer(0.1, self.timer_callback) # 10 Hz

# Callback runs every 0.1 seconds
def timer_callback(self):
# Publish commands
self.publisher_.publish(msg)

Comparison: Chapter 1 vs Chapter 2 vs Chapter 3

AspectCh1: ROS 2 BasicsCh2: URDFCh3: Python
What:How ROS 2 worksRobot descriptionRobot control
Learn:Nodes, topics, servicesLinks, joints, physicsPublishers, parameters, actions
Build:Node examplesURDF filesPython nodes
Use:Understand communicationDescribe robotsControl robots
Integration:Foundation for allDefines robot structureUses Chapter 2 robots

What You Can Now Do

✅ Write Python ROS 2 nodes that control robots ✅ Publish velocity commands to make robots move ✅ Create control loops at fixed frequency (10 Hz) ✅ Configure code using parameters (runtime changes) ✅ Implement goal-reaching behaviors (actions) ✅ Integrate Python control with URDF robots (Chapter 2) ✅ Debug node communication using ROS 2 CLI tools


What Comes Next

Advanced Topics (Future Modules)

  • Custom message types (beyond standard Twist)
  • Launch files for multi-node systems
  • Sensor integration (cameras, lidar, IMU)
  • Real robot deployment and safety

Applications

  • Mobile robot navigation
  • Robot arm manipulation
  • Autonomous systems
  • Sensor-based behaviors

Next Chapter (If Available)

  • Advanced ROS 2 patterns
  • Multi-robot coordination
  • Real robot integration

Review Checklist

Before moving to next material, verify you:

  • Understand rclpy node structure and inheritance
  • Can create publishers and send Twist messages
  • Know why control loops must run repeatedly
  • Can declare and read parameters
  • Understand difference between service and action
  • Know when to use each communication pattern
  • Can implement simple velocity controllers
  • Completed all 3 exercises

If you checked all boxes, you've mastered Chapter 3!


Practice Problems (Optional)

Try these without references:

  1. Easy: Write pseudocode for a node that publishes constant forward velocity
  2. Medium: Explain why rclpy.spin() is necessary
  3. Medium: Design a parameter-based controller that limits robot speed
  4. Hard: When would you use an action instead of a service? Give 2 examples

Resources for Deeper Learning

Official ROS 2 Documentation

ROS 2 Command Line Tools

  • ros2 node list - List all nodes
  • ros2 topic list - List all topics
  • ros2 topic echo /cmd_vel - Monitor topic messages
  • ros2 param list - List all parameters
  • ros2 param set - Change parameter value

Next Steps

  1. Immediate: Review the exercises and run your solutions
  2. Practice: Modify code examples to experiment
  3. Challenge: Create a robot that moves in a specific pattern
  4. Next Chapter: Advanced ROS 2 topics or real robot integration

Summary Status: Complete Last Updated: 2025-11-30 Chapter Completion: Ready for final quality evaluation