Fly a Simulated Drone with PX4
Command a virtual drone through a waypoint mission using real autopilot software.
Last reviewed: March 2026Overview
PX4 is the open-source autopilot firmware that powers thousands of commercial and research drones around the world—from delivery vehicles to scientific survey platforms. It handles all the low-level control (reading sensors, firing motors, maintaining attitude) so that mission planners can focus on where the drone should go, not how to keep it in the air. In this project you will run PX4 in simulation so you can experiment freely without risking any real hardware.
The PX4 Software-In-The-Loop (SITL) simulator runs the real flight controller code on your computer, paired with Gazebo—a physics engine that simulates aerodynamics, gravity, and sensor noise. From another terminal, you will send MAVLink commands in Python using the dronekit or MAVSDK library. MAVLink is the communication protocol that real ground control stations use to command drones; the skills transfer directly to real-hardware operations.
By the end of the project you will have programmed a complete autonomous waypoint mission: takeoff, fly to three GPS coordinates, and land safely. You will also learn how to use QGroundControl, the professional ground station software, to monitor telemetry in real time. This is essentially the workflow used by drone operators running commercial surveys and inspections today.
What You'll Learn
- ✓ Explain what SITL simulation is and why it is essential for safe drone software development.
- ✓ Set up PX4 SITL with Gazebo on Ubuntu (or WSL2 on Windows).
- ✓ Send arming, takeoff, waypoint, and landing commands via MAVLink Python API.
- ✓ Read and interpret telemetry data including position, altitude, and battery state.
- ✓ Describe the role of PX4 in the broader drone ecosystem including QGroundControl and MAVLink.
Step-by-Step Guide
Install PX4 SITL and Gazebo
Follow the PX4 Ubuntu setup guide at docs.px4.io to install the development environment (Ubuntu 22.04 is recommended, either natively or in WSL2). Run ubuntu.sh to install all dependencies, then clone the PX4-Autopilot repository: git clone https://github.com/PX4/PX4-Autopilot.git --recursive. Build and launch the default SITL simulation with make px4_sitl gazebo-classic_iris. A 3D quadrotor should appear in Gazebo.
Connect QGroundControl to the simulator
Download QGroundControl (QGC) from qgroundcontrol.com and launch it while SITL is running. QGC will automatically connect over UDP port 14550 and display live telemetry: battery level, GPS fix, altitude, and mode. Explore the map view and the instrument panel. Switch between flight modes (Stabilized, Position, Mission) using the Flight Mode dropdown—these are the same modes used on real vehicles.
Install MAVSDK-Python and test the connection
In a separate terminal, install MAVSDK: pip install mavsdk. Create a Python script that imports asyncio and mavsdk, connects to the simulator with drone = System(); await drone.connect(system_address="udp://:14540"), and prints the vehicle state. Confirm you see position and battery data printing to the console. This confirms your Python code can communicate with the PX4 autopilot via MAVLink.
Arm, take off, and hover
Write an async Python script that arms the drone (await drone.action.arm()), sets the flight mode to Offboard or uses await drone.action.takeoff(), and waits for it to reach hover altitude. Add a asyncio.sleep(5) to hold the hover, then call await drone.action.land(). Run the script and watch the Gazebo drone lift off, hover, and land. Add print statements to show altitude updates from the telemetry stream during the flight.
Program a waypoint mission
Extend your script to fly to three waypoints using drone.mission. Create MissionItem objects for three GPS coordinates near the drone's starting position (offset by small latitude/longitude increments), upload them with await drone.mission.upload_mission(mission_plan), and start the mission with await drone.mission.start_mission(). Print progress updates as each waypoint is reached. Watch the drone fly the square or triangle pattern you defined.
Log and plot the flight path
Stream position telemetry into a list during the mission: collect (latitude, longitude, altitude) at 1 Hz using drone.telemetry.position(). After landing, save the list to a CSV file. Use Matplotlib to plot the GPS track as a top-down map view, marking each waypoint with a red dot. Overlay the commanded waypoints on the actual flown path—any differences reveal tracking error. Export the plot as a PNG for your project report.
Career Connection
See how this project connects to real aerospace careers.
Drone & UAV Ops →
Professional UAV operators use PX4 or ArduPilot with QGroundControl daily; this project teaches the exact workflow used in commercial survey, inspection, and delivery operations.
Aerospace Engineer →
UAV systems engineers write mission software using MAVSDK and MAVLink to implement automated inspection patterns, precision agriculture, and search-and-rescue operations.
Aviation Maintenance →
Drone maintenance technicians need to understand autopilot systems, telemetry interpretation, and flight log analysis—all directly practiced in this project.
Space Operations →
The autonomous mission sequencing skills learned here transfer to spacecraft command sequence design, where robotic systems also execute pre-planned action lists.
Go Further
- Implement a geofence: use MAVSDK to define a polygon boundary and have the drone automatically land if it approaches the edge.
- Add obstacle avoidance by reading simulated LIDAR data from Gazebo and commanding the drone to stop when an object is detected within 3 m.
- Swap the Iris quadrotor for the PX4 fixed-wing model and repeat the waypoint mission—note the differences in takeoff, turn radius, and landing approach.
- Log and replay a flight using PX4's ULog format and PX4Tools in Python to analyze vibration levels and attitude tracking error.