PX4 MAVLink-Python Programming: 4. Sending and Receiving MAVLink Messages

Hello. This is Aiden from the marketing team.

Today, I would like to introduce PX4 MAVLink-Python programming, specifically focusing on sending and receiving MAVLink messages. Please note that this content is registered under the copyright of our QUAD Drone Lab, and we kindly ask you to refrain from unauthorized distribution.


Sending and Receiving MAVLink Messages

Sending Messages

This is the main protocol handling class for MAVLink. It is defined in each dialect module and includes methods for all messages in the message definition, following the format <message_name>_send().MAVLink

Message field values are passed as arguments to the function. Fields that are identical across all messages (e.g., source system, source component) are defined within the class. Each message is documented in the dialect source code, even when it is automatically generated.

For example, the system_time_send() function is used to send a SYSTEM_TIME message as shown below.

Python
def system_time_send(self, time_unix_usec, time_boot_ms, force_mavlink1=False):
    '''
    The system time is the time of the master clock, typically the
    computer clock of the main onboard computer.

    time_unix_usec    : Timestamp (UNIX epoch time). (uint64_t)
    time_boot_ms      : Timestamp (time since system boot). (uint32_t)
    '''

When using mavutil for link management, the mav attribute provides access to a configured class object that can be used for message transmission. For example, to send a SYSTEM_TIME message using a MAVLink link named the_connection, use the following:

Python
the_connection.mav.system_time_send(time_unix_usec, time_boot_ms)

If you are not using mavutil, you must manually create and configure the object so that it can identify the channel used for message transmission, which is typically represented by the MAVLink attribute.

Receiving Messages

Synchronous access to the last received message of a specific type can be achieved using the mavutil.messages attribute. For example, if you are using a mavutil link named the_connection, you can do the following:

Python
try: 
    altitude = the_connection.messages['GPS_RAW_INT'].alt  # Note, you can access message fields as attributes!
    timestamp = the_connection.time_since('GPS_RAW_INT')
    print("Current Alt is %dm" % (altitude/1000))
except:
    print('No GPS_RAW_INT message received')

Alternatively, you can use the mavutil.recv_match() method to wait for and intercept a message as it arrives.

Python
def recv_match(self, condition=None, type=None, blocking=False, timeout=None):
    '''Receive the next MAVLink message that matches the given type and condition
    type:        Message name(s) as a string or list of strings - e.g. 'SYS_STATUS'
    condition:   Condition based on message values - e.g. 'SYS_STATUS.mode==2 and SYS_STATUS.nav_mode==4'
    blocking:    Set to wait until message arrives before method completes. 
    timeout:     ? <!-- timeout for blocking message when the system will return. Is this just a time? -->
    '''

For example, you can wait for a message as follows (setting blocking=False means it will not wait):

Python
msg = the_connection.recv_match(blocking=True)

To obtain a specific message with a particular attribute value (e.g., SYS_STATUS), you can use the following approach instead:

Python
# Wait for a 'SYS_STATUS' message with the specified values.
msg = the_connection.recv_match(type='SYS_STATUS', blocking=True)

In addition, you must ensure that the message is valid before using it.

Python
msg = the_connection.recv_match(type='SYS_STATUS',blocking=True)

if msg.get_type() == "BAD_DATA":
    if mavutil.all_printable(msg.data):
        sys.stdout.write(msg.data)
        sys.stdout.flush()
else:
    #Message is valid
    # Use the attribute
    print('Status: %s' % msg.battery_remaining)

The MAVLink_message object returned is a subclass specific to that message. You can access message fields as class attributes, as shown for the mode in the code snippet above. If necessary, you can also query the MAVLink_message for information regarding its signature, CRC, and other header details.

Requesting Specific Messages

emote systems typically stream a default set of messages to connected Ground Control Stations (GCS), cameras, or other systems. This default set is often hard-coded and is inevitably limited to reduce traffic on the communication channel.

Systems can also request additional information by sending a REQUEST_DATA_STREAM message, which specifies the required stream (MAV_DATA_STREAM) and its corresponding rate.

Messages are sent using request_data_stream_send() (where the arg.rate below represents the desired transmission rate in Hz).

Python
# Request all data streams
the_connection.mav.request_data_stream_send(the_connection.target_system, the_connection.target_component,
                                        mavutil.mavlink.MAV_DATA_STREAM_ALL, args.rate, 1)

[Reference] MAVLink Message List

{% embed url=”https://mavlink.io/en/messages/common.html#messages” %}


YOUTUBE Class

재생

This concludes the fourth step of PX4 MAVLink-Python programming, focusing on sending and receiving MAVLink messages. In the next post, I will return with an article on ensuring MAVLink reliability.


Author: Aiden, Marketing Team at QUAD Drone Lab

Date: March 05, 2026

Similar Posts

답글 남기기

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