How to know from which vehicle mavlink messages come from in pymavlink

Hello there !

I am trying to make a small interface where I want to display several drones on a map.

I was able to connect to udp port 14550, where I have 5 drones sending mavlink messages and so when I read message GLOBAL_POSITION_INT I have data but I can’t know from which vehicle it came from. So I don’t know which vehicle to print on my map at this position. Does anyone have ideas on how to proceed and what would be a clean way to proceed ?

Thank you in advance !

I maybe don’t have all the answers, but a key to this working is that each drone must have a different MAVLink SYSID. Check out the wiki:

the MAVLink message will then have the SYSID in it’s header for each one.

yes I know, for instance I have 3 drones with sysid 11 to 14 and an other one with sysid 22. But now when I receive a GLOBAL_POSITION_INT message, I don’t know from which vehicle it comes. Maybe there is an other type of message that includes the sysid but until now I didn’t find one.

from pymavlink import mavutil
import numpy

print("start connection")
master = mavutil.mavlink_connection('udpin:0.0.0.0:14550')
master.wait_heartbeat()
print("Connected to system:", master.target_system, ", component:", master.target_component)

while True:
    msg = master.recv_match(blocking=False)
    if msg:
        # Ne garder que les messages de type GLOBAL_POSITION_INT
        if msg.get_type() == "GLOBAL_POSITION_INT":
            data = {
                "lat": msg.lat / 1e7,        # conversion degrés
                "lon": msg.lon / 1e7,
                "alt": msg.relative_alt / 1000.0, # en mètres
                "vit": numpy.sqrt(msg.vx**2/10000+msg.vy**2/10000),       # cm/s -> m/s
                "cap": msg.hdg /100 ,
            }
            print(data)
                

So you’re going to need to check the message header, but I suspect at this point in the code, you’re only going to receive messages from the first system for which you receive a heartbeat.

Also, see this part of the documentation. Multiple systems on the same mavlink object are not well supported, you’ll have to take extra steps which are outlined there.

In the message object, you can call get_srcSystem and get_srcComponent to see where it came from

2 Likes

You can see an example in the Pymavlink repo.

you just need to look at m.target_system property in the rx’d message.

    def __mavlink_packet(self, m) -> MAVFTPReturn:  
        """Handle a mavlink packet."""
        operation_name = "mavlink_packet"
        mtype = m.get_type()
        if mtype != "FILE_TRANSFER_PROTOCOL":
            logging.error("FTP: Unexpected MAVLink message type %s", mtype)
            return MAVFTPReturn(operation_name, FtpError.Fail)

        if (
            m.target_system != self.master.source_system  # <--- see here!
            or m.target_component != self.master.source_component # <--- see here!
        ):

https://github.com/ArduPilot/pymavlink/blob/master/mavftp.py#L1256

1 Like

Yes! So if you set those member variables before you call wait_heartbeat, the system should wait for the heartbeat that matches that system/component, for instance. This can at least help you prove your implementation until you figure out how to handle multiple systems

1 Like