Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Example with multiple drones #102

Open
julianoes opened this issue Jul 30, 2019 · 21 comments
Open

Example with multiple drones #102

julianoes opened this issue Jul 30, 2019 · 21 comments

Comments

@julianoes
Copy link
Collaborator

It would be good to provide an example how we can use the Python wrappers to connect to multiple drones at the same time.

It's a bit tricky because we need to run a mavsdk_server for each drone.

@JonasVautherin
Copy link
Collaborator

It's a bit tricky because we need to run a mavsdk_server for each drone.

Or maybe we should extend the API to support multiple drones like in MAVSDK-C++. We talked about that a while ago, if I remember correctly 😊.

@HanbumKo
Copy link

Is there any update?? Or is there any reference issue of this??

@julianoes
Copy link
Collaborator Author

No there is currently no update from our side as it is not our priority.

Would you be able to contribute/work on this?

@HanbumKo
Copy link

Yeah I could. But I need to understand this system and codes before doing this. Is there any additional development documentations of MAVSDK? Thanks.

@julianoes
Copy link
Collaborator Author

You have probably seen this? https://mavsdk.mavlink.io/develop/en/cpp/

Do you already understand the C++ API, gRPC backend and language frontends? If not I'd suggest to look at the C++ API first and see how multiple drones are working there.

@HanbumKo
Copy link

I'm not familiar with gRPC. OK let me see C++ API first and would do that. But now I've been focusing on other project, so I couldn't say 'I can!!'. Thanks!!

@traverseda
Copy link

It's a bit tricky because we need to run a mavsdk_server for each drone.

Or maybe we should extend the API to support multiple drones like in MAVSDK-C++. We talked about that a while ago, if I remember correctly blush.

So it looks to me like currently if you have several mavSDK systems on one ip/port (for example you're using qgroundcontrol's MAVlink forwarding) it picks a random device to communicate with. This is pretty surprising behavior and could easily be a safety issue. I suspect it gets weirder than that, but I didn't continue testing past that point.

Even just keeping the current system where you need multiple mavsdk_server's but allowing you to specify the system-id of the drone you're trying to communicate with would be a big improvement.

@JonasVautherin
Copy link
Collaborator

if you have several mavSDK systems on one ip/port

Assuming that the different systems have a different IP, you could write a simple demultiplexer that would redirect each drone (based on its ip) to a different mavsdk_server instance 👍.

@traverseda
Copy link

I believe that mavlink-router can accomplish this, it's still another jenga block on the tower though and makes it a fair bit harder to develop nice self-container apps that are reliable.

@JonasVautherin
Copy link
Collaborator

I don't think mavlink-router does this 🤔, though it does a lot of other things that you don't need here.

However, such a multiplexer is quite trivial to write (I wrote something similar in ~80 lines of python), and it can totally be part of your main python app, right?

@traverseda
Copy link

How? Are you using pymavlink for that?

@JonasVautherin
Copy link
Collaborator

JonasVautherin commented Apr 25, 2023

No, I just proxy the UDP packets based on the source IP (I assume that each drone has a different IP, and redirect the messages of each drone to the corresponding mavsdk_server instance). No need for MAVLink at all there 😊

@traverseda
Copy link

traverseda commented Apr 25, 2023

Oh, I misunderstood. That's not going to work with qgroundcontrol's mavlink forwarding. I'd prefer to keep the drones connected to both qgroundcontrol and my script for safety reasons.

I don't really understand what the proxy would be doing here that can't be done by just having mavsdk directly connect to each of those IPs separately.

@JonasVautherin
Copy link
Collaborator

I don't really understand what the proxy would be doing here that can't be done by just having mavsdk directly connect to each of those IPs separately.

Well the proxy allows MAVSDK to connect to each IP separately, by having one MAVSDK instance per IP 🤔. It seems like you would like to have multiple drones sending to the same UDP port on MAVSDK, but IMO that is a bad idea (and that's not how mavsdk_server works).

That's not going to work with qgroundcontrol's mavlink forwarding.

Right, I don't know your setup, so I couldn't say.

@traverseda
Copy link

but IMO that is a bad idea (and that's not how mavsdk_server works).

It is however how the actual CPP mavsdk API appears to wrok, where nodes get identified by their sysid's and you can subscribe to an event listener that tells you when a new drone shows up. The functionality exists, it's just exposed over the grpc interface.

Just saying, it's been about 4 years since this issue was opened, and there are still very much use-cases where it's a problem. I can go in to more detail about the specifics of those use cases if needed. The 1000 foot overview is that the default PX4 simulator script uses a UDP-broadcast mode that doesn't seem to work with a direct connection, trying to use a forwarder like the one built-in to qgroundcontrol won't work, there's no real way to auto-detect multiple drones under python, etc. It introduces a fair bit of friction and makes the python SDK unsuitable for making a real app.

This is a bit of an upstream problem as it exists in the mavsdk_server binary implementation and can't really be fixed on the python side of things.

@JonasVautherin
Copy link
Collaborator

JonasVautherin commented Apr 26, 2023

It is however how the actual CPP mavsdk API appears to wrok

It is, and MAVLink allows it. I am just saying that IMO it is a bad idea over a UDP/IP network 🙈. It is easy to handle in C++, but harder to translate to the MAVSDK gRPC system. So I am reluctant to spend a lot of my own time solving this particular problem in this particular way, because I personally believe that it is generally not the right way.

Now if you find a way to add support for that over gRPC in a clean way, then I will be more than happy to review your idea/PR 👍. Just know that when I have to handle multiple drones, I use a proxy, and that's an easy solution (much easier than adding support in gRPC).

@traverseda
Copy link

traverseda commented Apr 26, 2023

If I had the ability to specify what sysid a system is trying to connect to, and a method that let me know when new sysid's became available, I could hack something together using the existing spawn-a-new-server-for-each-drone methodology. That should bring feature parity to the python SDK for auto discovery. I can probably even submit some upstream PR's to the python side of things to wrap it in a nicer interface.

From the python side of things I'd imagine something like

drones={}
startport=50051

watcher=System(port=startport)

async for newdrone in watcher.find_new_broadcasters("udp://:14550"):
    startport+=1
    drone=System(port=startport)
    await drone.connect(system_address=newdrone["system_address"],sysid=newdrone["sysid"])
    drones[newdrone["sysid"]]=drone

Not familiar enough with the internals to know if this makes sense, but would something like that work without breaking your grpc model? Doesn't require you to pass complex objects around or state the sysid in every message.

@JonasVautherin
Copy link
Collaborator

Unfortunately, mavsdk_server only really starts when the drone is detected: https://github.com/mavlink/MAVSDK/blob/main/src/mavsdk_server/src/mavsdk_server_api.cpp#L13. So it's not straightforward to add detection logic there.

To be honest, if I had time to improve that, I would rather spend it working on the direct FFI wrappers (i.e. removing gRPC and calling the C++ API directly from the language bindings). This would bring the C++ discovery to the wrappers. But that is not trivial to do.

@drtrigon
Copy link

We do work with the python (gRPC) library and also encounter the limitations. Thus I am looking for an alternative - as I understand the way to go would be C++. We would prefer to use CSharp instead, but it is declared as "Proof of concept." on the mavsdk webpage. Can you tell me whether it uses gRPC (like python) and suffers from the same limitations or is it like C++ and has full access to all features?

@JonasVautherin
Copy link
Collaborator

C# is not maintained at all, I would advise against using it.

This said, an easy way to support multiple drones is to run multiple instances of MAVSDK and have the drones send MAVLink on different ports. I would (and I did in the past, actually) write a simple proxy that would receive messages from the drones on 14550 and that would redirect them to a new port.

You could maybe ask e.g. @ThomasDebrunner if Auterion would be willing to open source the reverse proxy I wrote, I believe it does exactly that.

@drtrigon
Copy link

drtrigon commented Apr 10, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants