Skip to content

Session 13: GO2 Simulation Setup

Week: 13 Element: ICTPRG439 Element 3.1-3.2 Duration: 4 hours Phase: GO2 Capstone Project


⚠️ Important Update — Server Race Condition Fix (Action Required Before Submission)

A race condition has been identified in the GO2 simulation where the built-in 60Hz controller fights your action server for joint control — causing the robot to snap back or joints to fail to hold position.

Before submitting your capstone, apply the freeze/unfreeze fix to your _execute_callback.

→ Read the full Server Race Condition Fix

Due to this issue, everyone has been granted an extension until 22/06/2026. Please submit a short video with your code to Blackboard to speed up marking.


Session Introduction

This session marks the beginning of your capstone project: creating a new behavior for the Unitree GO2 quadruped robot. You'll work with a pre-existing ROS2 simulation package (go2_ros2_sim_py), applying your ICTPRG439 component integration skills and preparing for the OOP implementation in upcoming sessions.

The GO2 is a sophisticated quadruped robot capable of walking, sitting, standing, and navigating complex terrain. Your goal over the next five sessions is to extend this robot with a high five action—making it lift a front leg and high five at people.

Today you'll:

  1. Clone and build the GO2 simulation package
  2. Run the Gazebo simulation
  3. Test existing behaviors (sit, stand, walk)
  4. Explore the codebase to understand its architecture
  5. Document your findings for ICTPRG439 portfolio evidence

Session Slides

View the presentation slides for this session (covers Sessions 13 & 14):

📊 Open Slides in New Window

The slides contain: - GO2 robot overview and 5-session project roadmap - ROS2 topics vs services recap - CLI control: sit, stand, walk, teleop - Codebase tour and architecture - GO2Controller OOP wrapper class design - Implementation tasks and unit testing


Learning Objectives

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

  • Clone and build a ROS2 simulation package from source
  • Launch Gazebo simulation with the GO2 robot
  • Control the robot using ROS2 CLI tools (services, topics)
  • Navigate the codebase to identify key components
  • Document component architecture for ICTPRG439 evidence

Session Structure

  1. Environment Setup - Clone repository, install dependencies, build
  2. Running the Simulation - Launch Gazebo, verify robot spawns
  3. Testing Existing Behaviors - Use ROS2 CLI to control robot
  4. Codebase Exploration - Understand package structure and behaviors
  5. Portfolio Documentation - Record findings for ICTPRG439

Part 1: Environment Setup (WSL2 + Ubuntu 24.04)

1.1 Prerequisites: WSL2 & Ubuntu 24.04

This course uses WSL2 (Windows Subsystem for Linux 2) with Ubuntu 24.04 (Noble) and ROS2 Jazzy.

What is WSL2?

WSL2 is a lightweight Linux environment running on Windows. For this course:

  • Treat it like a virtual machine you manage
  • Run all ROS2/robotics work inside WSL2, not on Windows
  • Your files live in the Linux filesystem for performance
  • GUI (Gazebo/RViz) displays on Windows via WSLg or VcXsrv

Checking your setup

Your should have by now installed WSL2 and Ubuntu 24.04 on your machine. Verify:

# Open WSL2 terminal (Start menu → Ubuntu 24.04, or Windows Terminal)
cat /etc/os-release | grep PRETTY_NAME
# Should show: Ubuntu 24.04 LTS (Noble) or similar

GPU & Display

If you have an NVIDIA GPU:

  • Windows driver must be ≥ 510 (auto-exposed to WSL2)
  • WSLg (Windows 11 / Win10 21H2+) works automatically
  • Fallback: export LIBGL_ALWAYS_SOFTWARE=1 if Gazebo shows black screen

File Access

Keep ROS2 files inside the WSL2 Linux filesystem for performance:

  • Linux files: /home/<username>/... (use these for robotics)
  • Windows files: /mnt/c/Users/<username>/... (slower, avoid for development)
  • File browser: Windows Start → \\wsl$\Ubuntu-24.04\home\...

Opening WSL2 Terminal

Method 1 (Recommended): Windows Terminal

  • Start menu → Windows Terminal
  • Click dropdown → Ubuntu 24.04

Method 2: Direct launch - Start menu → Ubuntu 24.04

Method 3: PowerShell

wsl  # Opens WSL2 in your home directory

Common Beginner Issues

Issue Solution
"ros2: command not found" Forgot to source ~/go_sim/go2_sim.env
Gazebo black screen Run export LIBGL_ALWAYS_SOFTWARE=1 then try again
Files not syncing Keep files in /home/..., not /mnt/c/...
GUI won't display Windows 11 WSLg works out of box; Win10 needs VcXsrv
Network issues Restart WSL with wsl --shutdown in PowerShell, then reopen

1.2 Run the WSL2 Installation Script

The new go2_ros2_sim_py repository includes a one-shot install script that handles everything (ROS2 Jazzy, Gazebo Harmonic, dependencies, workspace setup) in ~15 minutes.

# Inside WSL2 terminal
cd ~

# Download the install script
curl -O https://raw.githubusercontent.com/prgrobots/go2_ros2_sim_py/main/install%20/go2_sim_setup.sh

# Make it executable
chmod +x go2_sim_setup.sh

# Run it (answer 'y' to prompts, do NOT run as root)
./go2_sim_setup.sh

Script does (12 automated steps):

  1. Update system packages
  2. Install ROS2 Jazzy + Gazebo Harmonic
  3. Install Nav2 stack
  4. Install CycloneDDS + teleop tools
  5. Set up NVIDIA GPU passthrough (if available)
  6. Clone this repo + build simulation workspace
  7. Create ~/go_sim/go2_sim.env (environment file)
  8. Clone real dog bridge (go2_ros2_sdk)
  9. Build SDK workspace
  10. Create ~/go2_sdk/go2_sdk.env
  11. Configure CycloneDDS for loopback

After script completes:

# Verify installation
ls -la ~/ | grep go_sim
# Should show: go_sim/ directory

# Source the environment
source ~/go_sim/go2_sim.env

# Verify ROS2 Jazzy
echo $ROS_DISTRO
# Should show: jazzy

Installation Complete

You now have two workspaces: - ~/go_sim/ — Simulation (this repo) - ~/go2_sdk/ — Real robot bridge (for later)

Always source ~/go_sim/go2_sim.env before using the simulator.

1.3 Clone the GO2 Repository (Already Done by Script)

The install script already cloned the go2_ros2_sim_py repository into ~/go_sim/src/.

Verify the structure:

ls -la ~/go_sim/src/
# You should see: go2_description/, go2_ros2_sim_py/, gazebo_sim/, etc.

The go2_ros2_sim_py repository is your ICTPRG439 pre-existing component. You'll evaluate, integrate, and extend it.

# View repository structure
cd ~/go_sim/src/go2_ros2_sim_py
ls -la

ICTPRG439 Evidence Point

Take a screenshot of the ~/go_sim/src/ directory. This is evidence of Element 3.1: Configure development environment.

1.4 Verify Build Success

The script already built all packages. Verify:

# Source the environment
source ~/go_sim/go2_sim.env

# Check build outputs
ls -la ~/go_sim/install/
# You should see: gazebo_sim/, go2_description/, quadropted_controller/, etc.

Expected: Directories for each package. Warnings during build are acceptable.

1.5 Add Sourcing to .bashrc (Optional)

For convenience, auto-source the environment in every new terminal:

echo "source ~/go_sim/go2_sim.env" >> ~/.bashrc

Then every new WSL2 terminal will have ROS2 ready.


Part 2: Running the Simulation

2.1 Source the Environment

The environment file (go2_sim.env) sets up everything automatically:

# Source the simulation environment
source ~/go_sim/go2_sim.env

# Verify ROS2 Jazzy is active
echo $ROS_DISTRO
# Should show: jazzy

2.2 Launch the Simulation

# Launch Gazebo with GO2 robot
ros2 launch gazebo_sim launch.py

What you should see:

  • Gazebo window opens
  • GO2 robot appears in the world
  • Robot is in default standing position

ICTPRG439 Evidence Point

Take a screenshot of Gazebo with the GO2 robot. This is evidence of Element 3.2: Construct test programs.

2.3 Troubleshooting

ROS2 command not found:

# Did you forget to source the environment?
source ~/go_sim/go2_sim.env

Gazebo black screen:

# Try software rendering fallback
export LIBGL_ALWAYS_SOFTWARE=1
source ~/go_sim/go2_sim.env
ros2 launch gazebo_sim launch.py

Gazebo doesn't start:

# Check for stuck processes
killall -9 gz

# Try again
ros2 launch gazebo_sim launch.py

Part 3: Testing Existing Behaviors

3.1 Understanding the Robot Interface

Open a new terminal (keep Gazebo running) and explore the robot's ROS2 interface:

# Source environment (new terminal)
source ~/go_sim/go2_sim.env

# List all topics
ros2 topic list

# List all services
ros2 service list

Key topics you should see:

  • /robot1/cmd_vel - Velocity commands (Twist messages)
  • /robot1/robot_mode - Robot mode commands

Key services you should see:

  • /robot1/robot_behavior_command - Behavior commands (sit, walk, up)

3.2 Robot Modes

The GO2 has three modes:

Mode Description Movement
REST Default position Cannot move
STAND Standing, can rotate Rotation only
TROT Walking mode Full movement

3.3 Testing Sit/Stand Behaviors

Use the behavior service to control the robot:

# Make the robot sit
ros2 service call /robot1/robot_behavior_command \
  quadropted_msgs/srv/RobotBehaviorCommand "{command: 'sit'}"

Watch the Gazebo window—the robot should sit down!

# Make the robot stand and enable walking
ros2 service call /robot1/robot_behavior_command \
  quadropted_msgs/srv/RobotBehaviorCommand "{command: 'walk'}"
# Make the robot stand (locked, no walking)
ros2 service call /robot1/robot_behavior_command \
  quadropted_msgs/srv/RobotBehaviorCommand "{command: 'up'}"

Test Each Behavior

Try all three commands (sit, walk, up) and observe the robot's response in Gazebo.

3.4 Testing Movement

With the robot in walk mode, you can control movement:

# Use teleop keyboard (in a new terminal)
ros2 run teleop_twist_keyboard teleop_twist_keyboard \
  --ros-args -r /cmd_vel:=/robot1/cmd_vel

Keyboard controls:

  • i - Move forward
  • , - Move backward
  • j - Turn left
  • l - Turn right
  • k - Stop

ICTPRG439 Evidence Point

Record a short screen capture of you controlling the robot with teleop. This is evidence of Element 3.2: Use provided example programs.


Part 4: Codebase Exploration

Understanding the existing code is essential for extending it with your high five action.

4.1 Package Structure

cd ~/go_sim/src/go2_ros2_sim_py
tree -L 2

Key directories:

Directory Contents Relevance
go2_description/ URDF, meshes Robot model (don't modify)
gazebo_sim/ Launch files, worlds Simulation setup
quadropted_controller/ Behavior code Where you'll add high five
quadropted_msgs/ Custom messages/services Interface definitions

4.2 Understanding the Controller

The controller is where behaviors are implemented:

cd ~/go_sim/src/go2_ros2_sim_py/quadropted_controller
ls -la

Key files to examine:

# Look at the package structure
cat package.xml

# Find Python source files
find . -name "*.py" | head -20

4.3 Finding Behavior Implementation

Search for where sit, walk, and up commands are handled:

# Search for behavior command handling
grep -r "sit\|walk\|command" --include="*.py" .

Key Finding

Note which file(s) handle the robot_behavior_command service. This is where you'll add your high five command in Session 15.

4.4 Document Your Findings

Create a simple architecture diagram showing: 1. The packages in the workspace 2. How they communicate (topics, services) 3. Where behavior logic lives


Part 5: ICTPRG439 Portfolio Evidence

5.1 Component Evaluation

For your portfolio, document the following about go2_ros2_sim_py:

Repository Info:

# Check repository details
cd ~/go_sim/src/go2_ros2_sim_py
git remote -v
# Should show: https://github.com/prgrobots/go2_ros2_sim_py.git

Licensing Analysis:

# Check for license file
ls -la | grep -i license
cat LICENSE
# Or check README for license information

Dependencies:

# List ROS2 dependencies
grep depend ~/go_sim/src/go2_ros2_sim_py/*/package.xml

# List Python dependencies
pip3 list | grep -E "numpy|scipy|transforms3d"

Suitability:

  • Does it have the behaviors we need? (sit, stand ✓)
  • Is it actively maintained?
  • Can we extend it?

5.2 Evidence Checklist

By end of session, you should have:

  • Screenshot of ~/go_sim/src/ directory
  • Screenshot of Gazebo with GO2 robot
  • Screen recording of teleop control
  • Notes on codebase structure
  • Repository information (URL, license)
  • Dependency list
  • Architecture diagram (simple sketch is fine)

Summary

Today you: 1. Set up the GO2 simulation environment 2. Tested existing behaviors (sit, stand, walk) 3. Explored the codebase to understand its structure 4. Documented findings for ICTPRG439 portfolio

Next session: You'll create your own ROS2 Python package (go2_high_five) with a GO2Controller wrapper class.

Coming up: Unit Testing with @patch

In Session 14 you'll write unit tests for the controller you build. Because the tests need to run without a real robot, you'll use @patch — a decorator from Python's built-in unittest.mock library that temporarily replaces a real object with a fake (MagicMock) for the duration of a single test.

You already know how to assert return values:

# Familiar from Sessions 1–3
def test_add(self):
    self.assertEqual(add(2, 3), 5)

With @patch you do the same thing, but swap out a hardware dependency so the function under test thinks it's talking to a real robot:

from unittest.mock import patch

@patch('my_robot.driver.send_command')   # replace real hardware call
def test_stand(self, mock_send):
    mock_send.return_value = True        # fake: pretend it succeeded
    result = robot.stand()
    self.assertTrue(result)
    mock_send.assert_called_once_with('stand')  # verify what was sent

The mock_send argument is injected automatically — you don't create it yourself.

Why this matters for robotics: Hardware may be shared, expensive, or simply not on your desk. Mocking lets you run a full test suite on a laptop with no robot connected. CI/CD pipelines (e.g. GitHub Actions) also have no hardware access — mock-based tests are the only way to get automated coverage.

Real Python — Understanding the Python Mock Library


Homework (3 hours)

  1. Complete evidence collection for ICTPRG439 portfolio
  2. Create component evaluation matrix comparing:
  3. go2_ros2_sim_py (this package)
  4. unitree_mujoco (official Unitree simulator)
  5. Building from scratch
  6. Identify the exact file where you'll add high five action
  7. Sketch pseudocode for high five (lift leg, oscillate)

← Week 12 - ROS2 Services | Learning Plan | Week 14 - GO2Controller →