How to Setup Development Environment using ROS 2 (Jazzy), Mavros, and Gazebo

December 1, 2024 (1y ago)

by Satrya

I've recently started learning ROS 2 to dive deeper into robotics programming, particularly for drone development. The most time-consuming part for me is setting up and configuring the development environment.

I plan to use MAVROS to communicate with PX4 as the drone firmware and use Gazebo Harmonic to simulate the control code before deploying it in the real world.

I'm running ROS 2 Jazzy on Ubuntu 24.04 arm64, using UTM as my virtualized operating system.

Here's the system design architecture I plan to implement! Drone Development Stack ROS2

When building the PX4 firmware, I encountered some issues due to certain packages not being available for the arm64 architecture, specifically gcc-multilib and g++-multilib. As a result, I had to ignore these in the PX4 ubuntu.sh setup.

Here are the steps I followed:

Install MAVROS#

I installed mavros using binary package that comes with ROS package.

sudo apt install ros-jazzy-mavros

Then install geographiclib datasets.

wget https://raw.githubusercontent.com/mavlink/mavros/ros2/mavros/scripts/install_geographiclib_datasets.sh

chmod +x install_geographiclib_datasets.sh

sudo ./install_geographiclib_datasets.sh

Install PX4 SITL#

To install PX4 Software-in-the-Loop (SITL), I needed to clone the PX4 repository and build it from source. I set the directory to my home folder (~).

git clone https://github.com/PX4/PX4-Autopilot.git --recursive

Next is to install dependencies for our operating system to build that. Because there's slighty different architecture with amd64, i need to ignore the unsupported package in that script.

nvim /PX4-Autopilot/Tools/setup/ubuntu.sh

remove gcc-multilib and g++-multilib, so the code looks like this:

	sudo DEBIAN_FRONTEND=noninteractive apt-get -y --quiet --no-install-recommends install \
		automake \
		binutils-dev \
		bison \
		build-essential \
		flex \
		gcc-arm-none-eabi \
		gdb-multiarch \

Install dependencies packages with modified script.

./ubuntu.sh

After that, I built the PX4 SITL base. I made sure the directory was set to PX4-Autopilot.

cd ~/PX4-Autopilot
make px4_sitl

I needed to run Gazebo along with the model. PX4 provides built-in models and worlds that can be used with parameters when running make px4_sitl.

I encountered a problem when running Gazebo in a virtual environment—it crashed because the video accelerator for Ogre2 is not supported. To fix this, I needed to set the Gazebo render engine to use Ogre version 1, which supports the video accelerator. To do this, I updated ~/.bashrc and added the following line:

export PX4_GZ_SIM_RENDER_ENGINE=ogre

Finally, I can spawn a PX4 with X500 multicopter in Gazebo.

make px4_sitl gz_x500

let's it's running on the terminal.

Also, I added the alias on my ~/.bashrc to quick launch the command, so I just typed px4sitl to launch the simulation.

alias px4sitl="cd ~/PX4-Autopilot/ && make px4_sitl gz_x500"

Launch Mavros node#

To perform a simple test and check my MAVROS connection to PX4, I can launch the px4.launch file, which spawns the MAVROS node. Then, I observe the state topic using a CLI command.

By default, PX4 SITL listens on UDP port 14540, and MAVROS sends messages to port 14557 to communicate with PX4. Therefore, I need to set up the fcu_url MAVROS parameter correctly.

I open a new terminal and run these commands:

ros2 launch mavros px4.launch fcu_url:=udp://:14540@localhost:14557

The successfull integration willy output the logs something like this:

[mavros_node-1] [INFO] [1733020026.399315046] [mavros.mavros]: MAVROS UAS via /uas1 started. MY ID 1.191, TARGET ID 1.1
[mavros_node-1] [INFO] [1733020026.402953182] [mavros.imu]: IMU: Attitude quaternion IMU detected!
[mavros_node-1] [INFO] [1733020026.410506499] [mavros.imu]: IMU: High resolution IMU detected!
[mavros_node-1] [INFO] [1733020026.410533916] [mavros.mavros_router]: link[1001] detected remote address 1.191
[mavros_node-1] [INFO] [1733020026.911781115] [mavros.mavros]: CON: Got HEARTBEAT, connected. FCU: PX4 Autopilot

And I can subscribe to some topics, such as /mavros/state.

ros2 topic echo /mavros/state

this will output:

---
header:
  stamp:
    sec: 1733020572
    nanosec: 27459056
  frame_id: ''
connected: true
armed: false
guided: true
manual_input: false
mode: AUTO.LOITER
system_status: 0
---

That indicates the integration run without problem.

QGroundControl as GCS application.#

Since I'm using MAVROS, I can set the gcs_url parameter in the MAVROS node to a specific host and port so that QGroundControl can receive the connection from PX4 SITL.

First, make sure QGroundControl is already installed. Then, set the gcs_url parameter to udp://@GCS_IP:14550, where GCS_IP is the IP address where QGroundControl is running. In my case, since I run QGC on a different host, I set it to 77.22.9.4 instead of localhost.

Here's the MAVROS CLI command to launch px4.launch with the fcu_url and gcs_url parameters set:

ros2 launch mavros px4.launch fcu_url:=udp://:14540@localhost:14557 gcs_url:=udp://@77.22.9.4:14550

and the logs will looks like this:

[mavros_node-1] [INFO] [1733021343.847928736] [mavros.mavros_router]: MAVROS Router started
[mavros_node-1] [INFO] [1733021343.847966833] [mavros.mavros_router]: Requested to add endpoint: type: 0, url: udp://:14540@localhost:14557
[mavros_node-1] [INFO] [1733021343.847976267] [mavros.mavros_router]: Endpoint link[1000] created
[mavros_node-1] [INFO] [1733021343.848251976] [mavros.mavros_router]: link[1000] opened successfully
[mavros_node-1] [INFO] [1733021343.848275674] [mavros.mavros_router]: Requested to add endpoint: type: 1, url: udp://@77.22.9.4:14550
[mavros_node-1] [INFO] [1733021343.848282129] [mavros.mavros_router]: Endpoint link[1001] created
[mavros_node-1] [INFO] [1733021343.848334897] [mavros.mavros_router]: link[1001] opened successfully
[mavros_node-1] [INFO] [1733021343.848347445] [mavros.mavros_router]: Requested to add endpoint: type: 2, url: /uas1
[mavros_node-1] [INFO] [1733021343.848353043] [mavros.mavros_router]: Endpoint link[1002] created

Now, I can take off the drone using QGroundControl, click the takoff command on the left sidebar and the drone will takeoff.

Here's the screenshot of Gazebo and QGroundControl that runs PX4 software in the loop (SITL).

Demo PX4 SITL with Gazebo and QGC

References:#