PX4 MAVLink-Python Programming: 5. Ensuring MAVLink Reliability

Hello. This is Aiden from the Marketing Team.

Today, I would like to introduce PX4 MAVLink-Python Programming, specifically focusing on Ensuring MAVLink Reliability. Please note that this content is registered under the copyright of our QUAD Drone Research Institute, and we kindly ask you to refrain from unauthorized distribution.


HEARTBEAT

All MAVLink components must periodically broadcast a HEARTBEAT message and receive heartbeats from other systems. A system considers itself connected to another system as long as it regularly receives a HEARTBEAT from it.

The message can be sent using the HEARTBEAT message from the generated Python dialect file. The MAVLink.heartbeat_send() method is defined as follows:

Python
def heartbeat_send(self, type, autopilot, base_mode, custom_mode, system_status, mavlink_version=3, force_mavlink1=False):
    '''
    The heartbeat message shows that a system is present and responding.
    The type of the MAV and Autopilot hardware allow the
    receiving system to treat further messages from this
    system appropriate (e.g. by laying out the user
    interface based on the autopilot).

    type              : Type of the MAV (quadrotor, helicopter, etc.) (type:uint8_t, values:MAV_TYPE)
    autopilot         : Autopilot type / class. (type:uint8_t, values:MAV_AUTOPILOT)
    base_mode         : System mode bitmap. (type:uint8_t, values:MAV_MODE_FLAG)
    custom_mode       : A bitfield for use for autopilot-specific flags (type:uint32_t)
    system_status     : System status flag. (type:uint8_t, values:MAV_STATE)
    mavlink_version   : MAVLink version, not writable by user, gets added by protocol because of magic data type: uint8_t_mavlink_version (type:uint8_t)
    '''

Assuming we are using a mavutil link named the_connection returned by mavutil.mavlink_connection(), you can send a heartbeat as follows:

Python
# Send heartbeat from a GCS (types are define as enum in the dialect file). 
the_connection.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_GCS,
                                                mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0)

# Send heartbeat from a MAVLink application. 
the_connection.mav.heartbeat_send(mavutil.mavlink.MAV_TYPE_ONBOARD_CONTROLLER,
                                                mavutil.mavlink.MAV_AUTOPILOT_INVALID, 0, 0, 0)

The rate at which heartbeats must be transmitted depends on the channel, but it is typically 1Hz.

Generally, it should be sent from the same thread as all other messages. This is to ensure that the heartbeat is only published when the thread is healthy.

Message Signing

Pymavlink supports message signing (authentication) when using MAVLink 2.

The Pymavlink library already implements almost all the expected behavior for signing messages. You only need to provide a secret key and an initial timestamp, and optionally specify callbacks to determine whether outgoing messages should be signed, the link ID, and which unsigned messages (if any) to accept.

How you perform this depends on whether you manage the connection using mavutil or use the MAVLink object directly.

While we won’t cover them in this section, you should also write code for the following:

  • Saving and loading the secret key and the last timestamp from persistent storage.
  • Implement a mechanism for creating and sharing keys. For more details, refer to Message Signing > Secret Key Management.

Signing with the MAVLink Class

If you are using the MAVLink class directly, you can access the MAVLinkSigning object using the MAVLink.signing attribute and set the required properties.

The example/mavtest.py script demonstrates how to do this using a random secret key.

Python
# Create a MAVLink instance (in this case on a file object "f")
mav = mavlink.MAVLink(f)

if signing:
    mav.signing.secret_key = chr(42)*32
    mav.signing.link_id = 0
    mav.signing.timestamp = 0
    mav.signing.sign_outgoing = True

The class does not verify whether the packet’s link_id or initial timestamp are appropriate. The initial timestamp should be based on the current system time. For more details, refer to Message Signing.

Signing with mavutil (MAVLink 2)

If you are managing the connection using mavutil, you can enable or disable signing using the methods shown below.

Python
#Setup signing
def setup_signing(self, secret_key, sign_outgoing=True, allow_unsigned_callback=None, initial_timestamp=None, link_id=None)

# Disable signing (clear secret key and all the other settings specified with setup_signing)
def disable_signing(self):

This method configures the MAVLink object owned by the connection using setup_signing() and provides some additional internal code to manage the state.

  • If you do not specify a link_id, the value will iterate internally.
  • If initial_timestamp is not set, an appropriate value for the current time will be populated by the underlying OS.

Using allow_unsigned_callback

Message Signing > Accepting Unsigned Packets and Accepting Incorrectly Signed Packets specifies that the message signing implementation must provide a mechanism where library users can conditionally choose to accept unsigned or incorrectly signed packets.

Pymavlink provides an optional allow_unsigned_callback() for this purpose.

Python
bool allow_unsigned_callback(self, msgId)

When configured as part of the signing setup, this function is called for unsigned packets (including all MAVLink 1 packets) or packets with incorrect signatures. If the function returns False, the message is dropped; otherwise, it is processed as if it were signed.

The rules for when to accept unsigned packets depend on the specific implementation; however, it is highly recommended to always accept RADIO_STATUS packets to ensure feedback from 3DR radios, which do not support signing.

For example:

Python
# Assuming you already have a connection set up
the_connection = mavutil.mavlink_connection(...)

# Create a callback to specify the messages to accept
def my_allow_unsigned_callback(self,msgId):
    #Allow radio status messages
    if msgId==mavutil.mavlink.MAVLINK_MSG_ID_RADIO_STATUS:
        return True
    return False

# Pass the callback  to the connection (here we also pass an arbitrary secret key)
secret_key = chr(42)*32
the_connection.setup_signing(secret_key, sign_outgoing=True, allow_unsigned_callback=my_allow_unsigned_callback)

YOUTUBE Class

재생

That concludes our look at Ensuring MAVLink Reliability, the fifth step in PX4 MAVLink-Python Programming. In the next post, I will return with an article focusing on MAVLink Reliability: MAVLink 2 Message Signing.


Author: Aiden, Marketing Team at QUAD Drone Lab

Date: March 06, 2026

Similar Posts

답글 남기기

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