ROS 2 Humble Installation Guide

Course Requirements

Tutorial Session: September 10, Wednesday
Required OS: Ubuntu 22.04 LTS with ROS 2 Humble
Verification Tool: ros2 doctor --report

Core Documentation

Course Presentations

📚 ROS2 Tutorial Materials
  • ROS2 Humble Complete Guide - September 10, 2025 class presentation covering:
    • Installation & Setup troubleshooting (Python version conflicts)
    • Real TurtleBot3 message examples with live data
    • Complete architecture overview with visual diagrams
    • Comprehensive command reference and practical examples

Option 1: Dual Boot (Recommended)

Windows + Ubuntu 22.04
  • Video Guide
  • Requirements: 100GB+ partition, UEFI/BIOS access
  • Tool: Balena Etcher for USB creation
macOS + Ubuntu 22.04
Multi-Boot PC Setup

Configure Ubuntu 18.04/20.04/22.04 alongside Windows. Remote access via Illinois VPN + AnyDesk supported.

Option 2: Virtual Machine

Platform: Windows/MacOS

For Apple Silicon (M1/M2/M3/M4) Macs:
  • UTM (Universal Turing Machine) - Recommended for ARM64
    • UTM Download
    • Use Ubuntu 22.04 ARM64 image
    • Better performance than VirtualBox on Apple Silicon
For Intel Macs/Windows:
Performance Note: Add export LIBGL_ALWAYS_SOFTWARE=true for software rendering

Option 4: Docker

Platform-Independent Solution

⚠️ Special Considerations for Apple Silicon (ARM64)

Critical Information for M1/M2/M3/M4 Mac Users

Gazebo Classic (Version 11) does not support ARM64 architecture. This significantly impacts TurtleBot3 and other simulations.

Architecture Compatibility Quick Reference

Component Intel/AMD (x86_64) Apple Silicon (ARM64)
ROS2 Humble ✅ Full Support ✅ Full Support
Gazebo Classic ✅ apt install ❌ Not Available
Gazebo Fortress ✅ Full Support ✅ Full Support (Recommended)
TurtleBot3 Sim ✅ apt install ⚠️ Build from source
GPU Acceleration (UTM) ✅ Available ❌ Not Available

Recommended Solutions for ARM64

  1. Best Option: Use Gazebo Fortress (new Gazebo) with ROS2 Humble
    sudo apt install gz-fortress ros-humble-ros-gz-bridge
  2. Docker with ARM64 Images:
  3. UTM Virtualization (Limited):
    • ⚠️ No GPU acceleration for 3D graphics
    • Requires: export LIBGL_ALWAYS_SOFTWARE=true
    • UTM Download

TurtleBot3 on ARM64 - Known Issues

Student Report (Chahit Jain, Sept 2025):
When trying to install TurtleBot3 simulation on Apple M3:
  • sudo apt install ros-humble-turtlebot3-gazeboE: Unable to locate package
  • Building from source fails due to libgazebo-dev not available for ARM64
  • Even with OSRF repository added, Gazebo Classic has no ARM64 binaries
Solution: Use Gazebo Fortress or provided bag files for assignments.

For Coding Exercise 1 (ARM64 Users)

  • Option 1: Use pre-recorded bag files provided on course website
  • Option 2: Create mock joint state publishers (sample code in Piazza)
  • Option 3: Use campus lab computers (x86_64) remotely via SSH
  • Option 4: Pair program with students who have x86_64 hardware
Instructor Note: For easiest setup, use a 2-year-old Windows laptop with NVIDIA GPU. Alternative evaluation methods available for ARM64 users - contact TAs during office hours.

Installation Verification

Run these commands in a new terminal to verify your ROS2 Humble installation:

# Source ROS2 environment
source /opt/ros/humble/setup.bash

# Quick health check
ros2 doctor

# Comprehensive diagnostic report
ros2 doctor --report
Success Indicator: You should see "All systems go!" or similar positive diagnostics output.

⚠️ Critical Debugging Guide for Coding Exercise 1

📍 The Three Fatal Errors (95% of Student Failures)

Before submitting your code, check for these common mistakes that cause immediate failure:

Fatal Error #1: Using math.radians() on Gyro Data

❌ WRONG (Instant Failure)
def callback_Gy(self, msg):
    self.gyro_yaw = msg.data

def timer_callback(self):
    # This will cause huge errors!
    self.theta += dt * math.radians(self.gyro_yaw)
✅ CORRECT
def callback_Gy(self, msg):
    self.gyro_yaw = msg.data  # Already in rad/s!

def timer_callback(self):
    # Gyro data is already in rad/s
    self.theta += dt * self.gyro_yaw
Remember: The gyroscope data from /Gyro_yaw is ALREADY in radians per second (rad/s). Using math.radians() converts it again, making values ~57x smaller than they should be!

Fatal Error #2: Wrong Update Order

❌ WRONG Order
# Updates position with OLD theta
self.x += dt * v * math.cos(self.theta)
self.y += dt * v * math.sin(self.theta)
# Then updates theta (too late!)
self.theta += dt * self.gyro_yaw
✅ CORRECT Order
# FIRST update theta
self.theta += dt * self.gyro_yaw
# THEN use new theta for position
self.x += dt * v * math.cos(self.theta)
self.y += dt * v * math.sin(self.theta)

Critical: You MUST update theta BEFORE updating x,y position!

Fatal Error #3: GPS Addition Instead of Replacement (Part 2)

❌ WRONG (Causes Drift)
def callback_GPS(self, msg):
    gps_x, gps_y = lonlat2xyz(msg.latitude,
                               msg.longitude,
                               self.lat0, self.lon0)
    # Adding causes accumulation!
    self.x += gps_x
    self.y += gps_y
✅ CORRECT
def callback_GPS(self, msg):
    # GPS gives absolute position
    self.x, self.y = lonlat2xyz(msg.latitude,
                                msg.longitude,
                                self.lat0, self.lon0)
    # Direct replacement, no addition!

Remember: GPS provides absolute position in the world frame. You must REPLACE position, not add to it!

🔧 Non-Negotiable Constants

Required Values:
  • dt = 0.1 seconds (NEVER calculate from timestamps)
  • L = 0.3 meters (robot wheelbase)
  • First GPS = origin (store as lat0, lon0)
Correct Implementation:
def __init__(self):
    super().__init__()
    # Initialize at origin
    self.x = 0.0
    self.y = 0.0
    self.theta = 0.0

    # Constants - DO NOT CHANGE
    self.dt = 0.1  # Fixed timestep
    self.L = 0.3   # Wheelbase

🚀 Quick Launch Script

Save this as launch_coding_ex1.sh:
#!/bin/bash
# Terminal 1: Play bag file
gnome-terminal -- bash -c "source /opt/ros/humble/setup.bash; \
ros2 bag play ~/Desktop/CS498GC_MobileRobotics_Fall2025/2022_CS498_mobile_robotics/Assignments/2022_coding_ex1_CS498/solar_house/solar_house.db3 --loop; exec bash"

# Terminal 2: Run your node
gnome-terminal -- bash -c "source /opt/ros/humble/setup.bash; \
cd ~/Desktop/CS498GC_MobileRobotics_Fall2025/2022_CS498_mobile_robotics/'ROS2 files'/mobile_robotics; \
source install/setup.bash; \
ros2 run mobile_robotics coding_ex1_part1; exec bash"

# Terminal 3: Monitor output
gnome-terminal -- bash -c "cd ~/Desktop/CS498GC_MobileRobotics_Fall2025/2022_CS498_mobile_robotics/'ROS2 files'/mobile_robotics; \
tail -f results_part1.txt; exec bash"

echo "Launched all terminals for Coding Exercise 1!"

Make it executable: chmod +x launch_coding_ex1.sh


📚 Assignment 4 - Mobile Manipulator Setup

Assignment 4 Overview

  • Part A (25 points): Released Sept 5, Due Nov 21 - Deploy and teleoperate Husky + UR3 in Gazebo
  • Part B (75 points): Released Nov 24, Due Dec 4 - Implement SLAM, sensor fusion, and path planning
  • System: 13-DOF mobile manipulator (Husky base + UR3 arm + parallel gripper)

OS Compatibility Matrix

Ubuntu Version ROS Version Recommended For Notes
20.04 LTS ROS1 Noetic Legacy systems Stable, well-documented
22.04 LTS ROS2 Humble Primary choice Course standard
24.04 LTS ROS2 Jazzy RTX 50-series GPUs For driver issues

Common Hardware Issues & Solutions

NVIDIA Driver Issues (RTX 50-series)
  • If screen freezes: Press Ctrl+Alt+F3 to switch to TTY
  • Consider Ubuntu 24.04 + ROS2 Jazzy for newer GPUs
  • Recovery: sudo apt-get install --reinstall nvidia-driver-535
Apple Silicon (M1/M2/M3/M4)
  • Use UTM with Ubuntu 22.04 ARM64
  • Expect software rendering (no GPU acceleration)
  • Docker ARM64 images available as alternative
Virtual Machine Performance
  • Allocate minimum 8GB RAM, 6 CPU cores
  • Enable virtualization in BIOS/UEFI
  • Add to ~/.bashrc: export LIBGL_ALWAYS_SOFTWARE=true

🎮 ROS2 Control Tutorial - Essential for Assignment 4

Credit: This excellent resource was discovered by Mirielle Tan, who successfully used it to complete Assignment 4 Part 1!

Understanding ROS2 Control Framework

ROS2 Control is a framework for robots that acts as a middleman between robot hardware and software. It's essential for controlling the Husky+UR3 mobile manipulator in Assignment 4.

Key Components:
  • Controller Manager: Manages multiple controllers (loads, unloads, coordinates execution)
  • Resource Manager: Manages hardware interfaces and communication with actual hardware
  • Hardware Interfaces:
    • Command Interfaces: Write to hardware (position, velocity, effort commands)
    • State Interfaces: Read from hardware (current position, velocity, effort)
Common Controllers for Assignment 4:
  • Joint Trajectory Controller: For arm movements (takes trajectory goals)
  • Diff Drive Controller: For mobile base (takes cmd_vel commands)
  • Gripper Action Controller: For gripper control
  • Joint State Broadcaster: Publishes joint states to /joint_states topic

Quick Start Commands

Install ROS2 Control Packages:
sudo apt-get install ros-${ROS_DISTRO}-ros2-control \
                     ros-${ROS_DISTRO}-ros2-controllers \
                     ros-${ROS_DISTRO}-gripper-controllers \
                     ros-${ROS_DISTRO}-gazebo-ros2-control
Essential Controller Commands:
# List active controllers
ros2 control list_controllers

# List hardware interfaces
ros2 control list_hardware_interfaces

# Load and activate a controller
ros2 control load_controller --set-state active arm_controller

# Move the arm (example)
ros2 topic pub --once /arm_controller/joint_trajectory \
  trajectory_msgs/msg/JointTrajectory \
  "{joint_names: ['shoulder_pan_joint', 'shoulder_lift_joint', ...],
    points: [{positions: [0.0, -1.57, 0.0, ...],
    time_from_start: {sec: 3}}]}"
Gripper Control (Robotiq):
# Open gripper
ros2 topic pub /gripper_controller/command std_msgs/msg/Float64 "{data: 0.0}" --once

# Close gripper
ros2 topic pub /gripper_controller/command std_msgs/msg/Float64 "{data: 0.7}" --once

YAML Configuration Example

Create a controllers.yaml file to configure your controllers:

controller_manager:
  ros__parameters:
    update_rate: 10

    arm_controller:
      type: joint_trajectory_controller/JointTrajectoryController

    base_controller:
      type: diff_drive_controller/DiffDriveController
      command_interface: "velocity"  # CRITICAL LINE often missing!

    joint_state_broadcaster:
      type: joint_state_broadcaster/JointStateBroadcaster

arm_controller:
  ros__parameters:
    joints:
      - shoulder_pan_joint
      - shoulder_lift_joint
      - elbow_joint
      - wrist_1_joint
      - wrist_2_joint
      - wrist_3_joint
    command_interfaces:
      - position
    state_interfaces:
      - position
📚 Full Tutorial: For the complete step-by-step guide including URDF modifications, launch files, and Python/C++ examples, see: How to Control a Robotic Arm Using ROS 2 Control and Gazebo

🚀 Mars World Setup for Assignment 4 Part 2

Assignment 4 Part 2: Implement SLAM with your mobile manipulator in a Mars environment! Due December 9, 2025.

Mars Environment Features

  • Realistic Mars terrain with NASA/JPL resources
  • Custom Mars world for Husky+UR3 navigation
  • SLAM challenges with Martian obstacles
  • Optional: Fun race track on Mars surface!
  • Inspired by MASt3R-SLAM (CVPR 2025)
Setup Guide:

Complete Mars world setup instructions available: View Mars Tutorial

Part 2 Requirements:
  • Sensor Fusion (15 pts): EKF implementation
  • Path Planning & Control (15 pts): Navigate Mars terrain
  • SLAM Implementation (10 pts): 2D mapping with laser scanner
  • Mars Bonus (+10 pts): Complete tasks in Mars environment
  • Documentation (10 pts): RSS format technical report
Reference Paper: MASt3R-SLAM: Real-Time Dense SLAM with 3D Reconstruction Priors
Project Page | MASt3R Foundation Model

📖 Additional Resources

Course Materials

  • Mobile Robotics Textbooks - Essential PDFs for the course
  • Office Hours: In-person at SC 4407 (check Campuswire for Zoom sessions)
  • Gradescope: Course ID: 1102297, Entry Code: KDP5G8
  • GitHub TA Username: kulbir-ahluwalia (add to private repos)

📚 Git & GitHub Reference Guide

Essential for CS498GC: All assignments require GitHub submission. Master these commands for efficient version control!

GitHub Education Cheat Sheet

Quick reference for common Git operations used throughout the course:

  • Repository Setup: Clone, fork, and initialize repositories
  • Version Control: Add, commit, push, and pull changes
  • Branching: Create and merge branches for feature development
  • Collaboration: Pull requests and code reviews
  • Troubleshooting: Common Git issues and solutions

Quick Git Commands for CS498GC

Initial Setup (Do Once)
# Configure your identity
git config --global user.name "Your Name"
git config --global user.email "your.email@illinois.edu"

# Clone course repository
git clone https://github.com/yourusername/CS498GC_assignments.git
cd CS498GC_assignments
Daily Workflow
# Check status
git status

# Stage your changes
git add coding_ex1_part1.py coding_ex1_part2.py

# Commit with descriptive message
git commit -m "feat: Implement wheel odometry with gyro fusion"

# Push to GitHub
git push origin main
For Gradescope Submissions
# Create submission branch
git checkout -b assignment4-submission

# Tag your final version
git tag -a v1.0 -m "Assignment 4 Final Submission"
git push origin v1.0

# Add TA as collaborator
# Add username: kulbir-ahluwalia to your private repository
⚠️ Common Git Mistakes to Avoid
  • Don't commit large files (rosbags, videos > 100MB) - use Git LFS
  • Don't commit build artifacts (build/, install/, log/ folders)
  • Always use .gitignore for ROS2 projects
  • Never force push to main/master branch unless absolutely necessary
  • Write clear commit messages - future you will thank present you!

ROS2 .gitignore Template

Use this .gitignore for your ROS2 workspace:

# ROS2 build artifacts
build/
install/
log/

# Python
__pycache__/
*.pyc
*.pyo
*.egg-info/

# Results
*.txt
*.csv
*.db3

# IDE
.vscode/
.idea/
*.swp

# OS
.DS_Store
Thumbs.db
View Complete ROS .gitignore Template

✅ Final Verification

Debugging Checklist

Before asking for help, verify:
  • ☐ Bag file playing (see topic messages)
  • ☐ Input topics showing Hz values (~10 Hz for gyro)
  • ☐ /odom topic publishing at ~10 Hz
  • ☐ Node running without Python errors
  • ☐ RViz2 Fixed Frame set to 'odom' (not 'map')
  • ☐ Path display added with buffer 10000
  • ☐ Output file showing changing x,y values
  • ☐ No math.radians() on gyro data
  • ☐ Theta updated BEFORE position
  • ☐ GPS replaces (not adds to) position