2.1 ROS2 Installation and Core Concepts¶
What You'll Learn¶
Get ROS2 running and understand the fundamental concepts:
- What ROS2 is and why it matters for drones
- Install ROS2 Humble on Ubuntu 22.04
- Understand nodes, topics, messages, services, and interfaces
- Learn how ROS2 workspaces function
- Master essential command-line tools
- Set up your workspace for drone development
Time: 60-75 minutes
Prerequisites¶
Before starting, you must have completed:
- Phase 1 complete (SITL + Gazebo working)
- Ubuntu 22.04 LTS
~/simtofly_ws/ros2_wsdirectory exists
What is ROS2?¶
ROS is Not an Operating System¶
Despite its name, ROS (Robot Operating System) is not an operating system like Ubuntu or Windows. It's a robotics middleware framework — a collection of tools, libraries, and conventions that help you build robot software.
| Aspect | Operating System (Ubuntu) | ROS2 |
|---|---|---|
| What it does | Manages hardware, files, processes | Helps robot components communicate |
| Runs on | Bare metal / VM | On top of an OS (Ubuntu) |
| Examples | Ubuntu, Windows, macOS | ROS2 Humble, ROS2 Jazzy |
| Purpose | General computing | Robotics development |
Think of it this way:
- Ubuntu = The foundation of your house
- ROS2 = The electrical wiring that connects all rooms
Why ROS2 for Drones?¶
In Phase 1, you controlled drones through MAVProxy commands:
This works, but has limitations:
- Manual typing — Can't automate complex decisions
- No sensor integration — Hard to add cameras, lidars
- Limited logic — Can't easily do "if battery < 20%, go home"
- No standardization — Your code won't work with other robots
ROS2 solves these problems:
- Programmable — Write Python/C++ code for complex behaviors
- Modular — Each component is independent, easy to swap
- Standardized — Same patterns work for drones, arms, cars
- Ecosystem — Thousands of ready-made packages
- Industry standard — Used by NASA, Amazon, Boston Dynamics
Why ROS2, Not ROS1?¶
ROS1 (original ROS) was created in 2007. ROS2 is a complete rewrite with:
| Feature | ROS1 | ROS2 |
|---|---|---|
| Real-time support | Limited | Built-in |
| Security | None | Encryption, authentication |
| Multi-robot | Difficult | Native support |
| Platforms | Linux only | Linux, Windows, macOS |
| Status | End of life (2025) | Active development |
Always use ROS2 for new projects. ROS1 tutorials you find online won't work with our setup.
Install ROS2 Humble¶
ROS2 Humble is the LTS (Long Term Support) release for Ubuntu 22.04, supported until 2027.
Set Locale¶
ROS2 requires UTF-8 locale. Check yours:
Look for UTF-8 in the output. If you see it, skip ahead. If not:
sudo apt update && sudo apt install locales
sudo locale-gen en_US en_US.UTF-8
sudo update-locale LC_ALL=en_US.UTF-8 LANG=en_US.UTF-8
export LANG=en_US.UTF-8
locale # verify settings

Add ROS2 Repository¶
Ubuntu doesn't include ROS2 by default. We need to add the official repository.
Enable Universe repository:
Add the ROS2 GPG key (verifies packages are authentic):
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb
¶
sudo apt update && sudo apt install curl -y
export ROS_APT_SOURCE_VERSION=$(curl -s https://api.github.com/repos/ros-infrastructure/ros-apt-source/releases/latest | grep -F "tag_name" | awk -F\" '{print $4}')
curl -L -o /tmp/ros2-apt-source.deb "https://github.com/ros-infrastructure/ros-apt-source/releases/download/${ROS_APT_SOURCE_VERSION}/ros2-apt-source_${ROS_APT_SOURCE_VERSION}.$(. /etc/os-release && echo ${UBUNTU_CODENAME:-${VERSION_CODENAME}})_all.deb"
sudo dpkg -i /tmp/ros2-apt-source.deb
Install ROS2 Humble¶
Update package list:
Upgrade package list:ROS 2 packages are built on frequently updated Ubuntu systems. It is always recommended that you ensure your system is up to date before installing new packages.
Install ROS2 desktop (includes visualization tools):This takes: 10-15 minutes depending on internet speed.
What's included:
- Core ROS2 libraries
- RViz2 (visualization)
- Demo nodes for testing
- Common message types
Install Development Tools¶
For building ROS2 packages:
Source ROS2 Setup¶
ROS2 isn't available in your terminal until you "source" it:
What does sourcing do?
- Adds ROS2 commands to your PATH
- Sets environment variables ROS2 needs
- Makes ROS2 tools available
Problem: You'd need to run this every time you open a terminal.
Solution: Add it to your bashrc (runs automatically):
Check the ROS_DISTRO Environment Variable¶
Expected output:

Test some examples¶
Test with demo nodes. Open two terminals:
Terminal 1 — Publisher (talker):
Terminal 2 — Subscriber (listener):
Expected:
-
Terminal 1 prints:
Publishing: 'Hello World: 1','Hello World: 2'... -
Terminal 2 prints:
I heard: [Hello World: 1],[Hello World: 2]...
Press Ctrl+C in both terminals to stop.
You should see the talker saying that it’s Publishing messages and the listener saying I heard those messages. This verifies both the C++ and Python APIs are working properly. If this works, ROS2 is installed correctly.
ROS2 Core Concepts¶
This section explains the fundamental building blocks of ROS2. Understanding these is essential before working with MAVROS and drone control.
Concept 1: Nodes¶
A node is a single executable program that does one specific job.
Real-world analogy:
Think of a drone as a company. Each employee (node) has one job:
- Receptionist — answers calls (receives commands)
- Accountant — tracks money (monitors battery)
- Pilot — flies the plane (controls motors)
- Navigator — plans routes (calculates waypoints)
Each works independently, but they communicate to achieve the company's goals.
In ROS2:
| Node | Job |
|---|---|
mavros_node |
Translates ROS2 ↔ MAVLink |
telemetry_node |
Monitors drone state |
mission_node |
Executes waypoint missions |
camera_node |
Processes camera images |
Why separate nodes?
- Isolation — If camera node crashes, drone keeps flying
- Reusability — Same telemetry node works for any drone
- Modularity — Swap components without rewriting everything
- Distributed — Nodes can run on different computers
Node commands:
Example output of ros2 node info:
/mavros_node
Subscribers:
/mavros/setpoint_position/local: geometry_msgs/msg/PoseStamped
Publishers:
/mavros/state: mavros_msgs/msg/State
/mavros/local_position/pose: geometry_msgs/msg/PoseStamped
Service Servers:
/mavros/cmd/arming: mavros_msgs/srv/CommandBool
This shows what data the node sends, receives, and what services it provides.
Concept 2: Topics¶
A topic is a named channel for streaming data. Nodes publish data to topics, other nodes subscribe to receive it.
Real-world analogy: Think of topics like radio stations:
- Radio station "FM 101.5 Traffic" broadcasts traffic updates
- Anyone with a radio can tune in
- The station doesn't know (or care) who's listening
- Multiple people can listen simultaneously
In ROS2:
Publisher Node Topic Subscriber Nodes
│ │ │
│ ┌─────────────────────┴──────────────────────┐ │
│ │ │ │
MAVROS ──publishes──► /mavros/local_position/pose ──► Your Node
──► RViz
──► Logger
Key characteristics:
- One-to-many — One publisher, unlimited subscribers
- Anonymous — Publisher doesn't know who subscribes
- Asynchronous — Publisher sends whenever ready, subscribers receive when available
- Continuous — Data keeps flowing (unlike services)
Drone topics you'll use:
| Topic | Direction | Data |
|---|---|---|
/mavros/state |
Drone → You | Armed, mode, connected |
/mavros/local_position/pose |
Drone → You | Position (x, y, z) |
/mavros/battery |
Drone → You | Voltage, percentage |
/mavros/setpoint_position/local |
You → Drone | Where to fly |
Topic commands:
# List all topics
ros2 topic list
# See data flowing on a topic
ros2 topic echo /topic_name
# Check how fast data is published
ros2 topic hz /topic_name
# Get topic information
ros2 topic info /topic_name
Example — watching drone state:
Output:
header:
stamp:
sec: 1234567890
nanosec: 123456789
frame_id: ''
connected: true
armed: false
guided: false
mode: STABILIZE
---
The --- separates each message. Data keeps flowing until you press Ctrl+C.
Concept 3: Messages¶
A message defines the structure of data sent on a topic. It's like a form with specific fields.
Real-world analogy:
When you order food delivery, the order form has specific fields:
- Name
- Address
- Items
- Payment method
You can't just write free text — the system expects structured data.
In ROS2:
The topic /mavros/local_position/pose uses message type geometry_msgs/msg/PoseStamped:
geometry_msgs/msg/PoseStamped
├── header
│ ├── stamp (time)
│ └── frame_id (string)
└── pose
├── position
│ ├── x (float)
│ ├── y (float)
│ └── z (float)
└── orientation
├── x (float)
├── y (float)
├── z (float)
└── w (float)
Common message packages:
| Package | Contains | Examples |
|---|---|---|
std_msgs |
Basic types | String, Int32, Float64, Bool |
geometry_msgs |
Geometry | Point, Pose, Twist, Vector3 |
sensor_msgs |
Sensors | Image, LaserScan, NavSatFix |
mavros_msgs |
MAVROS specific | State, Waypoint, CommandBool |
Message commands:
# See message structure
ros2 interface show geometry_msgs/msg/PoseStamped
# List all available message types
ros2 interface list | grep msg
Why does this matter?
When you write code to read drone position, you need to know the structure:
# You need to know that position is inside pose
x = msg.pose.position.x
y = msg.pose.position.y
z = msg.pose.position.z
Without understanding the message structure, you can't access the data.
Concept 4: Services¶
A service is a request/response interaction. You ask for something, wait, and get an answer.
Real-world analogy:
- Topic = Radio broadcast (continuous, one-way)
- Service = Phone call (you ask, they answer)
When you call a restaurant to make a reservation:
- You call (request)
- They check availability (processing)
- They confirm or deny (response)
- Call ends
In ROS2:
Your Node Service MAVROS
│ │ │
│──── Request ────────────► │ │
│ {value: true} │ /mavros/cmd/arming │
│ │ ──────────────────────────►│
│ │ │ (arms motors)
│ │ ◄──────────────────────────│
│◄─── Response ─────────── │ │
│ {success: true} │ │
Key characteristics: - Synchronous — You wait for the response - One-to-one — One client, one server - Blocking — Your code pauses until response arrives - For actions — Do something once, not continuously
When to use services vs topics:
| Use Case | Use |
|---|---|
| Arm the drone | Service (one-time action) |
| Change flight mode | Service (one-time action) |
| Get drone position continuously | Topic (streaming data) |
| Send velocity commands | Topic (continuous control) |
Service commands:
# List all services
ros2 service list
# Check service type
ros2 service type /mavros/cmd/arming
# Call a service from command line
ros2 service call /mavros/cmd/arming mavros_msgs/srv/CommandBool "{value: true}"
Example — arming the drone:
Response:
Concept 5: Interfaces¶
Interfaces is the collective term for message types, service types, and action types. They define the "contract" for communication.
Interfaces
├── Messages (.msg) → Data structure for topics
├── Services (.srv) → Request/Response structure
└── Actions (.action) → Goal/Feedback/Result structure (advanced)
Interface commands:
# List all interfaces
ros2 interface list
# Show a message interface
ros2 interface show geometry_msgs/msg/Twist
# Show a service interface
ros2 interface show mavros_msgs/srv/CommandBool
Service interface example:
Output:
The --- separates request (above) from response (below).
- Request:
value(true = arm, false = disarm) - Response:
success(did it work?) andresult(error code)
Concept 6: Actions (Brief Overview)¶
Actions are for long-running tasks with feedback. We won't use them directly in Phase 2, but you should know they exist.
Example: "Navigate to waypoint 5km away" - Takes minutes to complete - You want progress updates (50% there, 75% there...) - You might want to cancel mid-way
Structure: - Goal — What you want (go to position X) - Feedback — Progress updates (currently at position Y) - Result — Final outcome (reached / failed)
We'll use services and topics which are simpler and sufficient for our needs.
Concept Summary¶
| Concept | What It Is | When to Use | Drone Example |
|---|---|---|---|
| Node | A program | Always — everything is a node | MAVROS, your control code |
| Topic | Data stream | Continuous data | Position, velocity, state |
| Message | Data structure | Defines topic content | PoseStamped, State |
| Service | Request/response | One-time actions | Arm, set mode, takeoff |
| Interface | Type definition | Understanding data | ros2 interface show |
ROS2 Workspaces¶
A workspace is a folder where you develop ROS2 packages. Understanding workspaces prevents many common errors.
Underlay and Overlay¶
ROS2 uses a layered system:
┌─────────────────────────────────────┐
│ Your Workspace │ ← Overlay (your code)
│ ~/simtofly_ws/ros2_ws │
├─────────────────────────────────────┤
│ ROS2 Humble Base │ ← Underlay (system packages)
│ /opt/ros/humble │
└─────────────────────────────────────┘
Underlay = Base ROS2 installation
- Location: /opt/ros/humble
- Contains: Core ROS2, standard messages, tools
- You don't modify this
Overlay = Your workspace
- Location: ~/simtofly_ws/ros2_ws
- Contains: Your packages, custom code
- You build and modify here
Why layers? - Keep system packages safe from your experiments - Your packages can override system packages if needed - Multiple workspaces can stack
Source Order Matters¶
You must source in the correct order:
# 1. First, source the underlay (base ROS2)
source /opt/ros/humble/setup.bash
# 2. Then, source your overlay (your workspace)
source ~/simtofly_ws/ros2_ws/install/setup.bash
If you source in wrong order or forget one, you'll get errors like: - "Package not found" - "Command not found" - Wrong version of package used
Our bashrc setup handles this automatically:
# These lines in ~/.bashrc ensure correct order
source /opt/ros/humble/setup.bash
source ~/simtofly_ws/ros2_ws/install/setup.bash
Workspace Structure¶
~/simtofly_ws/ros2_ws/
├── src/ ← Your source code goes here
│ └── drone_control/ ← Your package
│ ├── package.xml
│ ├── setup.py
│ └── drone_control/
│ └── your_node.py
├── build/ ← Compiled files (auto-generated)
├── install/ ← Installed packages (auto-generated)
└── log/ ← Build logs (auto-generated)
You only edit files in src/. The other folders are created by colcon build.
Set Up Your Workspace¶
Let's set up the ROS2 workspace properly.
Create Workspace Structure¶
Build Empty Workspace¶
Even with no packages, verify the build system works:
Expected output:
Source Your Workspace¶
Add to bashrc for automatic sourcing:
Verify Setup¶
Open a new terminal and test:
If this works without errors, your workspace is configured correctly.
Essential CLI Tools Summary¶
These commands will be your daily tools:
Node Commands¶
ros2 node list # List running nodes
ros2 node info /node_name # Node details (publishers, subscribers, services)
Topic Commands¶
ros2 topic list # List all topics
ros2 topic echo /topic_name # Show live data
ros2 topic info /topic_name # Show message type, publishers, subscribers
ros2 topic hz /topic_name # Show publish rate
ros2 topic echo /topic --once # Show one message and exit
Service Commands¶
ros2 service list # List all services
ros2 service type /service_name # Show service type
ros2 service call /service_name type "{data}" # Call a service
Interface Commands¶
ros2 interface list # List all message/service types
ros2 interface show type_name # Show structure of a type
Package Commands¶
ros2 pkg list # List installed packages
ros2 pkg prefix package_name # Show package install location
Verification Checklist¶
Before moving on, verify:
-
ros2 --versionshows version number - Demo talker/listener test passes
- Understand difference: node, topic, message, service
- Understand underlay vs overlay workspaces
-
~/simtofly_ws/ros2_ws/srcdirectory exists -
colcon buildruns without errors - ROS2 is sourced in bashrc (new terminal works)
What You Accomplished¶
- Understood what ROS2 is and why it matters for drones
- Installed ROS2 Humble on Ubuntu 22.04
- Learned core concepts: nodes, topics, messages, services, interfaces
- Understood workspace structure and underlay/overlay system
- Set up your ROS2 workspace for drone development
- Learned essential CLI tools
What's Next¶
In the next section, we'll install MAVROS — the bridge between ROS2 and ArduPilot. You'll see these concepts come alive with real drone data flowing through topics, and services that arm and control the drone.
Common Questions¶
Q: What's the difference between ROS and OS?¶
OS (Operating System): Manages your computer's hardware, files, and processes. Examples: Ubuntu, Windows, macOS.
ROS (Robot Operating System): A middleware framework that helps robot software components communicate. It runs on top of an OS, not instead of it.
You need Ubuntu (OS) installed first, then ROS2 runs as software on Ubuntu.
Q: Why Humble specifically?¶
ROS2 releases are named alphabetically. Humble is the current LTS (Long Term Support) for Ubuntu 22.04:
| ROS2 Version | Ubuntu Version | Support Until |
|---|---|---|
| Humble | 22.04 | 2027 |
| Iron | 22.04 | 2024 (ended) |
| Jazzy | 24.04 | 2029 |
Humble is the stable choice for Ubuntu 22.04.
Q: Do I need to understand DDS?¶
No. DDS (Data Distribution Service) is the underlying communication layer, but ROS2 abstracts it away. You'll never interact with DDS directly for drone work. Think of it like TCP/IP — you use the internet without knowing the protocol details.
Q: Can I use both MAVProxy and ROS2?¶
Yes! MAVROS connects to SITL, and MAVProxy can connect simultaneously. Useful for debugging: - Monitor in MAVProxy console - Test ROS2 code - See both perspectives
Q: What if I have ROS1 installed?¶
ROS1 and ROS2 can coexist, but not simultaneously in the same terminal. Don't source both. If you have ROS1, ensure your bashrc only sources ROS2:
Q: Why do I need to source setup.bash?¶
Sourcing sets up environment variables that tell your terminal: - Where ROS2 commands are located - Where to find packages - What libraries to use
Without sourcing, your terminal doesn't know ROS2 exists.
Q: What's colcon?¶
colcon is the build tool for ROS2 workspaces. It:
- Finds all packages in src/
- Compiles them in correct dependency order
- Installs them to install/
Similar to make or cmake, but designed for ROS2 multi-package builds.
Troubleshooting¶
"ros2: command not found"¶
Cause: ROS2 not sourced
Solution:
Then add to bashrc as shown earlier.
"colcon: command not found"¶
Cause: Development tools not installed
Solution:
Package installation fails with GPG error¶
Cause: GPG key not added correctly
Solution:
sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg
sudo apt update
Demo nodes don't communicate¶
Cause: Different ROS_DOMAIN_ID or network issues
Solution:
1. Ensure both terminals have same environment (run source ~/.bashrc in both)
2. Check echo $ROS_DOMAIN_ID is same in both (default is empty)
3. Restart both nodes
"Package not found" after building¶
Cause: Workspace not sourced after build
Solution:
You must re-source after every colcon build.
Multiple ROS versions conflicting¶
Cause: Both ROS1 and ROS2 sourced, or multiple ROS2 versions
Solution: Check your ~/.bashrc for conflicting source lines:
Keep only: