This project gives you a complete, ready-to-run drone simulator inside Docker on Ubuntu 22.04.
It includes:
- PX4 SITL (the flight software that runs in “Software In The Loop” mode)
- ROS 2 (a common robotics toolkit)
- Gazebo Classic (a 3D world physical simulator)
- mavlink-router (קxposes a communication path for observing and controlling platform behavior)
With it you can:
- Pull ("Download") or build the simulator image in seconds
- Set your own “home” location for the virtual drone
- Run everything without opening any graphics windows
- Automate flights with a simple Python script
- Docker Desktop installed on your computer
- (Optional) A zip file called
px4_sitl.zipif you want to load a saved simulator image - Python 3.8+ and pip to run the example flight script
Just type this in your command line:
docker pull ilanmulakandov/px4_sitlThis always grabs the latest version. For checking you have it, write this command at your command line:
docker images | grep px4_sitlIf you’d rather build the image from scratch:
docker build \
--build-arg BASE_IMAGE=ubuntu \
--build-arg TAG=22.04 \
-t px4_sitl .Note: It is recommended to stick with Ubuntu 22.04 for best results. But if you want to change, you can, and it is recommended to check the integrity of the docker afterwards before any significant operation.
If you have a px4_sitl.zip file:
-
Unzip it to find
px4_sitl.tar.gz. -
In your terminal,
cdinto the directory containing that file. -
Run:
docker load --input px4_sitl.tar.gz
-
Verify with:
docker images | grep px4_sitl
Tip: To save your own image as a ZIP, use:
docker save -o px4_sitl.tar.gz px4_sitl:latestStart the simulator (headless) with:
docker run --rm -it \
-p 14540:14540/udp \
-p 14550:14550/udp \
-e QGC_IP=10.0.0.16 \
-e CONTROL_IP=10.0.0.8 \
-e PX4_HOME_LAT=47.3977 \
-e PX4_HOME_LON=8.5456 \
-e PX4_HOME_ALT=488.0 \
px4_sitlAnd what actually happens when you run this command?
- mavlink-router will launch in the background for data routing.
- Your chosen home coordinates are applied before the simulator starts (PX4_HOME variables).
- PX4 SITL launches with Gazebo Classic automatically.
- Since port 14550 is open, you can point QGroundControl (Real-time drone monitoring app) at UDP port 14550 and immediately see the drone’s location and status-no extra setup needed.
Note: If you use the
run_mission.pyscript, the script uses fixed ports (14540/14550). To run multiple instances simultaneously, manually change these values in the script to avoid conflicts.
You can tweak these values when you run the container:
| Name | Default | What It Means |
|---|---|---|
PX4_HOME_LAT |
47.397751 |
Starting latitude of your virtual drone |
PX4_HOME_LON |
8.545607 |
Starting longitude of your virtual drone |
PX4_HOME_ALT |
488.13123 |
Starting altitude (in meters) |
QGC_IP |
10.0.0.16 |
IP address for QGroundControl (your PC) |
QGC_PORT |
14550 |
UDP port for QGroundControl |
CONTROL_IP |
10.0.0.16 |
IP address for any custom control software |
CONTROL_PORT |
14540 |
UDP port for custom control software |
This Python script executes a robust single-drone mission with safety mechanisms. It will:
- Launch a new PX4 container with a unique name.
- Connect over UDP to the simulator.
- Takeoff using Offboard control to a set altitude.
- Upload a "Triangle" mission (3 waypoints relative to the home location).
- Execute the mission in AUTO mode.
- Monitor progress using a Watchdog:
- If the drone gets stuck between waypoints, the script detects it and resends commands.
- Land at the final position (instead of RTL) and disarm.
- Cleanup: Stops and removes the container automatically.
Tip: Edit the script’s top section to match your IP, ports, and home coordinates.
import asyncio
import subprocess
import uuid
import math
from pymavlink import mavutil
# --- Constants ---
# IP Configuration
LOCAL_IP = "10.0.0.16" # Replace with your actual local IP
DOCKER_IMAGE = "px4_sitl"
# PX4 Home Location
PX4_HOME_LAT = 47.397751
PX4_HOME_LON = 8.545607
PX4_HOME_ALT = 488.13123
# Ports
CONTROL_PORT = 14540
QGC_PORT = 14550
# … rest of script …The script relies on pymavlink for communication and standard Python libraries (asyncio, subprocess, math).
pymavlink>=2.4.15
Install with:
pip install -r requirements.txtEven if you don’t use ROS 2 directly, having it in the same container means:
- You can run tools like rviz2 or ros2 topic echo without extra setup.
- Developers who build advanced behaviors (SLAM, navigation) can start immediately.
- All dependencies live in one place-no version clashes.
This all-in-one setup keeps development smooth and simulation flexible-making it easy to get started. 😄
- Set home first: Always pass your
PX4_HOME_*values before launching. - Unique container names: Prevent collisions in parallel runs.
- Auto-cleanup:
--rmmakes Docker delete the container when it stops. - Offline builds: Use
docker save/loadto share images without internet.
Happy flying! 🛩️