PX4 MAVLink-Python Programming : 3. Connecting to the drone

Hello! This is Aiden from the Marketing Team.

Today, I would like to introduce PX4 MAVLink-Python programming, specifically focusing on how to ‘Connect’ to a drone. Please note that this content is copyrighted by QUAD Drone Lab, and we kindly ask that you refrain from unauthorized distribution.


Connecting to a drone

Overview

The mavutil module provides the mavlink_connection() method to establish a communication link to a MAVLink system via serial, TCP, or UDP channels. It can also connect to file objects, which is particularly useful when working with telemetry logs.

his method returns an object representing a single system, but it collects messages from multiple systems on the link. While this is suitable for a two-system network, please refer to source-system-filtering if you need to connect via a multi-vehicle IP network.

The mavlink_connection() method takes a connection string that defines the channel, along with several optional arguments for setting the baud rate and other link properties (note that the format of the connection string may automatically set or override some optional arguments).

Connection String

The format for the connection string in mavutil.mavlink_connection() is as follows:

Bash
[protocol:]address[:port]

protocol:

  • Protocol (Optional): This specifies the IP protocol. If not specified, pymavlink will attempt to determine if the address is a serial port (e.g., USB) or a file; otherwise, it defaults to a UDP address.
  • tcp: Initiates a TCP connection at the specified address and port.
  • tcpin: Listens for an incoming TCP connection at the specified address and port.
  • udpin: Listens for incoming UDP packets at the specified address and port.
  • udpout: Initiates a UDP connection to the specified address and port.
  • udp: By default, this is identical to udpin. However, setting the parameter input=False in mavlink_connection() makes it behave the same as udpout.
  • udpcast: A broadcast UDP address and port. This is equivalent to setting the mavlink_connection() parameters to input=False and broadcast=True.
  • address: The IP address, serial port name, or filename.
  • port: The IP port number (required only if the address is an IP address).

Listed below are some example strings that can be used for various types of connections:

Connection TypeConnection StringNotes
Linux computer connected to a vehicle via USB/dev/ttyUSB0Standard for most USB-to-Serial adapters.
Linux computer (e.g., Raspberry Pi) connected via Serial Port/dev/ttyAMA0Requires setting baud=57600.
MAVLink API receiving SITL connection via UDPudpin:localhost:14540Also udp:localhost:14540. Supported by PX4.
MAVLink API initiating SITL connection via UDPudpout:localhost:14540Also udpout:127.0.0.1:14540.
GCS connected to a vehicle via UDP127.0.0.1:14550Or udp:localhost:14550.
SITL connected to a vehicle via TCPtcp:127.0.0.1:5760ArduPilot only; PX4 does not support TCP.
OSX computer connected to a vehicle via USB/dev/cu.usbmodem1macOS specific device path.
Windows computer connected via USBCOM14Example port; check Device Manager for your specific COM number.
Windows computer via 3DR Telemetry RadioCOM14Requires setting baud=57600.

MAVLink does not formally define UDP ports for different purposes; however, there is a de facto standard that MAVLink APIs should listen for SITL connections on UDP port 14540, while Ground Control Stations (GCS) should listen for connections on UDP port 14550.

Practice (Hands-on Lab)

Creating a Practice Environment

In this course, we will use VS Code (Visual Studio Code) as our primary code editor. Please refer to the link for installation instructions.

Create a project directory and open the VS Code editor. (If you are using the training VM, it is already pre-installed.)

Bash
mkdir ~/pymavlink
cd ~/pymavlink
code .

Writing a Connection Setup Example

Create a file named listen.py and write the code as shown below.

Python
from pymavlink import mavutil

# Start a connection listening on a UDP port
# UDP 14550 for primary GSC
#the_connection = mavutil.mavlink_connection('udpin:localhost:14550')
#for ArduPilot
#the_connection = mavutil.mavlink_connection('tcp:localhost:5763')
#for PX4-SITL
the_connection = mavutil.mavlink_connection('udp:localhost:14540')

# Wait for the first heartbeat 
#   This sets the system and component ID of remote system for the link
the_connection.wait_heartbeat()
print("Heartbeat from system (system %u component %u)" % (the_connection.target_system, the_connection.target_component))

Launching ArduPilot SITL

Bash
cd ~/ardupilot/ArduCopter
sim_vehicle.py -v ArduCopter

Once SITL is running properly, launch QGroundControl.

Running the Example Program

Bash
$ python3 listen.py 
Heartbeat from system (system 1 component 0)

After running your first listen.py program, you can see the result of connecting to the drone and receiving a Heartbeat message.

Now, let’s add the following lines to the end of your code.

Using the recv_match method on the the_connection instance created by mavutil.mavlink_connection, this code will print every message received via MAVLink.

Python
while 1:
    msg = the_connection.recv_match(blocking=True)
    print(msg)

You can view all incoming MAVLink messages as shown below.

Bash
$ python3 listen.py 
Heartbeat from system (system 1 component 0)
ATTITUDE {time_boot_ms : 7432233, roll : 0.0012512498069554567, pitch : 0.0010204593418166041, yaw : -0.10418491810560226, rollspeed : 0.00018897373229265213, pitchspeed : 0.0002900350373238325, yawspeed : 0.000815636245533824}
GLOBAL_POSITION_INT {time_boot_ms : 7432233, lat : -353632622, lon : 1491652375, alt : 584060, relative_alt : -26, vx : -1, vy : 1, vz : 0, hdg : 35404}
SYS_STATUS {onboard_control_sensors_present : 1467087919, onboard_control_sensors_enabled : 1382128687, onboard_control_sensors_health : 1467063343, load : 0, voltage_battery : 12587, current_battery : 0, battery_remaining : 100, drop_rate_comm : 0, errors_comm : 0, errors_count1 : 0, errors_count2 : 0, errors_count3 : 0, errors_count4 : 0}
POWER_STATUS {Vcc : 5000, Vservo : 0, flags : 0}
MEMINFO {brkval : 0, freemem : 65535, freemem32 : 131072}
NAV_CONTROLLER_OUTPUT {nav_roll : -0.00024070088693406433, nav_pitch : 0.00018201448256149888, nav_bearing : -5, target_bearing : 0, wp_dist : 0, alt_error : 0.026932982727885246, aspd_error : 0.0, xtrack_error : 0.0}
MISSION_CURRENT {seq : 0}

Now, we will filter the incoming messages to display only the “ATTITUDE” type.

Modify the code you previously added as follows:

Python
while 1:
    msg = the_connection.recv_match(type='ATTITUDE', blocking=True)
    print(msg)

Execute the script.

Bash
$ python3 listen.py 
Heartbeat from system (system 1 component 0)
ATTITUDE {time_boot_ms : 7906233, roll : 0.0012596407905220985, pitch : 0.0010401400504633784, yaw : -0.10935219377279282, rollspeed : 0.0002872312907129526, pitchspeed : 0.000264745089225471, yawspeed : 0.0008267931989394128}
ATTITUDE {time_boot_ms : 7906483, roll : 0.0012574875727295876, pitch : 0.0010377863654866815, yaw : -0.10930610448122025, rollspeed : 0.0003205988323315978, pitchspeed : 0.00030788395088166, yawspeed : 0.0008285849471576512}

You can now see that only ATTITUDE type MAVLink messages are being displayed.


YouTube Class

재생

This concludes the third stage of PX4 MAVLink-Python Programming: Connecting to a Drone. In the next post, we will return with a deep dive into Exchanging MAVLink Messages.


Author: Aiden, Marketing Team at QUAD Drone Lab

Date: February 25, 2026

Similar Posts

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다