Quick Reference Guide
Essential commands, concepts, and troubleshooting for Module 1.
ROS 2 Essential Commands
Node Management
# List all running nodes
ros2 node list
# Get node information
ros2 node info /node_name
# Kill a node
# Use Ctrl+C in the terminal running the node
Topic Operations
# List all topics
ros2 topic list
# Show topic info (message type, publishers, subscribers)
ros2 topic info /topic_name
# Echo messages from a topic
ros2 topic echo /topic_name
# Publish to a topic (one-time)
ros2 topic pub /topic_name std_msgs/msg/String "{data: 'Hello'}"
# Publish continuously at 10 Hz
ros2 topic pub -r 10 /topic_name std_msgs/msg/String "{data: 'Hello'}"
# Measure topic frequency
ros2 topic hz /topic_name
# Measure topic bandwidth
ros2 topic bw /topic_name
Service Operations
# List all services
ros2 service list
# Call a service
ros2 service call /service_name example_interfaces/srv/AddTwoInts "{a: 5, b: 3}"
# Get service type
ros2 service type /service_name
# Find services of a specific type
ros2 service find example_interfaces/srv/AddTwoInts
Action Operations
# List all actions
ros2 action list
# Send action goal
ros2 action send_goal /action_name action_type "{goal_fields}"
# Get action info
ros2 action info /action_name
Parameter Operations
# List parameters of a node
ros2 param list /node_name
# Get parameter value
ros2 param get /node_name parameter_name
# Set parameter value
ros2 param set /node_name parameter_name value
Common Message Types
std_msgs
from std_msgs.msg import String, Int32, Float32, Bool
# String message
msg = String()
msg.data = "Hello, ROS 2!"
# Numeric messages
int_msg = Int32()
int_msg.data = 42
float_msg = Float32()
float_msg.data = 3.14
geometry_msgs
from geometry_msgs.msg import Twist, Pose, Point
# Twist (velocity command)
cmd = Twist()
cmd.linear.x = 0.5 # m/s forward
cmd.angular.z = 0.2 # rad/s rotation
# Point
point = Point()
point.x = 1.0
point.y = 2.0
point.z = 0.0
sensor_msgs
from sensor_msgs.msg import JointState, Imu
# Joint states
joint_msg = JointState()
joint_msg.name = ['joint1', 'joint2']
joint_msg.position = [0.5, 1.0]
joint_msg.velocity = [0.1, 0.2]
joint_msg.effort = [5.0, 10.0]
# IMU data
imu_msg = Imu()
imu_msg.orientation.x = 0.0
imu_msg.orientation.y = 0.0
imu_msg.orientation.z = 0.0
imu_msg.orientation.w = 1.0
URDF Quick Reference
Basic Link
<link name="link_name">
<visual>
<geometry>
<box size="0.1 0.1 0.1"/>
<!-- Or: <cylinder radius="0.05" length="0.2"/> -->
<!-- Or: <sphere radius="0.05"/> -->
</geometry>
<material name="color_name">
<color rgba="1 0 0 1"/> <!-- Red -->
</material>
</visual>
<collision>
<geometry>
<box size="0.1 0.1 0.1"/>
</geometry>
</collision>
<inertial>
<mass value="1.0"/>
<inertia ixx="0.001" ixy="0" ixz="0"
iyy="0.001" iyz="0" izz="0.001"/>
</inertial>
</link>
Basic Joint
<joint name="joint_name" type="revolute">
<parent link="parent_link"/>
<child link="child_link"/>
<origin xyz="0 0 0.1" rpy="0 0 0"/>
<axis xyz="0 1 0"/> <!-- Rotation around Y-axis -->
<limit lower="-1.57" upper="1.57" effort="100" velocity="2.0"/>
<dynamics damping="0.5" friction="0.1"/>
</joint>
Joint Types
- revolute: Rotation with limits (e.g., knee 0° to 150°)
- continuous: Unlimited rotation (e.g., wheels)
- prismatic: Linear motion (e.g., telescoping)
- fixed: No motion (rigidly attached)
- floating: 6-DOF free motion (base link)
URDF Validation
# Check URDF syntax
check_urdf robot.urdf
# Visualize in RViz
ros2 launch urdf_tutorial display.launch.py model:=robot.urdf
# Generate kinematic tree
urdf_to_graphviz robot.urdf
Xacro Macros
Property Definition
<xacro:property name="wheel_radius" value="0.05"/>
<xacro:property name="wheel_width" value="0.02"/>
Macro Definition
<xacro:macro name="wheel" params="prefix reflect">
<link name="${prefix}_wheel">
<visual>
<geometry>
<cylinder radius="${wheel_radius}" length="${wheel_width}"/>
</geometry>
</visual>
</link>
<joint name="${prefix}_wheel_joint" type="continuous">
<parent link="base_link"/>
<child link="${prefix}_wheel"/>
<origin xyz="0 ${reflect * 0.2} 0" rpy="0 0 0"/>
<axis xyz="0 1 0"/>
</joint>
</xacro:macro>
Macro Usage
<!-- Call macro for left and right wheels -->
<xacro:wheel prefix="left" reflect="1"/>
<xacro:wheel prefix="right" reflect="-1"/>
Convert Xacro to URDF
ros2 run xacro xacro robot.urdf.xacro > robot.urdf
Common Issues and Solutions
ROS 2 Not Found
# Error: ros2: command not found
# Solution: Source ROS 2 setup
source /opt/ros/humble/setup.bash
# Add to ~/.bashrc for persistence
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc
No Module Named 'rclpy'
# Error: ModuleNotFoundError: No module named 'rclpy'
# Solution: Install ROS 2 Python packages
sudo apt install python3-rclpy
# Or source ROS 2 environment
source /opt/ros/humble/setup.bash
Topic Not Publishing
# Check if node is running
ros2 node list
# Check topic existence
ros2 topic list
# Check topic info
ros2 topic info /topic_name
# Echo topic to see messages
ros2 topic echo /topic_name
URDF Not Loading
# Validate URDF syntax
check_urdf robot.urdf
# Common issues:
# - Missing parent/child links
# - Invalid joint types
# - Malformed XML
# - Circular dependencies
Python Node Template
#!/usr/bin/env python3
import rclpy
from rclpy.node import Node
from std_msgs.msg import String
class MyNode(Node):
def __init__(self):
super().__init__('my_node_name')
# Publisher
self.publisher_ = self.create_publisher(String, 'topic_name', 10)
# Subscriber
self.subscription = self.create_subscription(
String,
'input_topic',
self.callback,
10
)
# Timer
self.timer = self.create_timer(1.0, self.timer_callback)
self.get_logger().info('Node initialized')
def callback(self, msg):
self.get_logger().info(f'Received: {msg.data}')
def timer_callback(self):
msg = String()
msg.data = 'Hello'
self.publisher_.publish(msg)
def main(args=None):
rclpy.init(args=args)
node = MyNode()
try:
rclpy.spin(node)
except KeyboardInterrupt:
pass
node.destroy_node()
rclpy.shutdown()
if __name__ == '__main__':
main()
Coordinate Frames
ROS 2 Convention
- X: Forward
- Y: Left
- Z: Up
Rotation (rpy - Roll Pitch Yaw)
- Roll: Rotation around X-axis
- Pitch: Rotation around Y-axis
- Yaw: Rotation around Z-axis
Quaternion to Euler
import math
def quaternion_to_euler(x, y, z, w):
# Roll (x-axis rotation)
roll = math.atan2(2*(w*x + y*z), 1 - 2*(x**2 + y**2))
# Pitch (y-axis rotation)
pitch = math.asin(2*(w*y - z*x))
# Yaw (z-axis rotation)
yaw = math.atan2(2*(w*z + x*y), 1 - 2*(y**2 + z**2))
return roll, pitch, yaw
Debugging Tips
Enable Debug Logging
ros2 run --prefix 'ros2 topic echo' package_name node_name
Use RQT Tools
# Node graph visualization
rqt_graph
# Plot topic data
rqt_plot /topic_name/field
# Message publisher GUI
rqt_publisher
# Service caller GUI
rqt_service_caller
# All-in-one dashboard
rqt
Check TF Tree
# View transform tree
ros2 run tf2_tools view_frames
# Echo specific transform
ros2 run tf2_ros tf2_echo parent_frame child_frame
Performance Tips
Reduce CPU Usage
# Use appropriate QoS settings
from rclpy.qos import QoSProfile, QoSReliabilityPolicy
qos = QoSProfile(depth=10)
qos.reliability = QoSReliabilityPolicy.BEST_EFFORT
self.publisher_ = self.create_publisher(String, 'topic', qos)
Optimize Callback Frequency
# Use timers instead of high-rate subscriptions
# Bad: subscribing to 1000 Hz topic and processing each message
# Good: subscribing and processing at needed rate (e.g., 10 Hz)
self.timer = self.create_timer(0.1, self.process_data) # 10 Hz
Next Steps
- Practice: Try modifying the code examples in
static/code/module1/ - Experiment: Create your own custom messages and services
- Build: Design a simple humanoid leg with URDF
- Advanced: Integrate multiple sensors in a single controller
Quick Links: