Drone "System" object pass between python processes?

Hello,

I have been trying to pass the MAVSDK drone "System’ object between two different python processes as an argument, such that I have a stand-alone function that connects to mavsdk and creates the drone “System” object in one separate script, and then passes that drone object to another script. It is most likely an issue with my understanding but can anyone tell me why I cannot pass the drone “System” object between separate scripts? Has it something to do with the drone object not being pickleable? I have made two crude scripts below to try to illustrate the problem I have - basically just trying to pass the drone object from one to the other to facilitate printing telemetry.

Thank you very much in advance,

Kind regards,

Jono

Example_Script_1.py:
import asyncio
import multiprocessing
import Example_Script_2
from multiprocessing import Process
from multiprocessing.sharedctypes import Value
async def run():
    #Start the drone in another process (Example_Script_2 in this case).
    #Process(await Example_Script_2.run(dronequeue))
    Process(daemon=True, target=await Example_Script_2.run(dronequeue))
    drone = dronequeue.get()
    # Start the tasks
    asyncio.ensure_future(print_position(drone))
    await asyncio.sleep(10)
async def print_position(drone):
    async for position in drone.telemetry.position():
        print(position)
if __name__ == "__main__":
    # Run the asyncio loop
    dronequeue = multiprocessing.Queue() #Used to transfer the object between processes.
    asyncio.run(run())




Example_Script_2.py:
from mavsdk import System
from multiprocessing.sharedctypes import Value
async def run(dronequeue):
    # Init the drone
    drone = System()
    await drone.connect(system_address="udp://:14540")
    print("connected to drone!!!")
    dronequeue.put(drone)
    return

I challenge that you need multiple processes when using Python asyncio.
At most I would probably use different threads but even that shouldn’t be required.

Taking a step back, what are you actually trying to do?

Hi Julian, thanks very much for your reply. I have been trying to run a main process that connects to and gives typical commands to the drone based upon a certain bespoke logic. In parallel I’m running a “telemetry” thread in the background to update a cloud based database with relevant position information, and also pull data if and when required (needing the drone object). I also have an object detection, classification and location calculation routine that I was hoping to run in the separate process to stay clear of the main program (again ideally utilizing features of the mavsdk drone object). Your challenge is a valid one though, and if I have to re-configure to get correct function I will do so. Any advice is very much appreciated!

Kind regards,

Jono

1 Like

Hello Julian,

I’m still working through the solution here - you did mention that “at most you would probably use different threads” - have you done this before? If so how did you pass the drone object to the second thread?

Thanks very much in advance,

Kind regards,

Jono

It shouldn’t be any different from how you move normal objects between threads. Everything is a reference in Python (as far as I’m aware), so you can pass it normally, I’d say.

Sorry, I’m not a Python expert by any means, and I’m also not too sure of how you integrate Python async code into threads. Maybe @JonasVautherin has some tips.

Haven’t tried with threads (but I guess it’s similar), but I have definitely shared a drone object between different asyncio coroutines, and it “just works”.

1 Like

Hello Jonas and Julian, thank you very much for your advice. I write here my findings:

I had success in passing the “drone” object between two different threads, using “asyncio.run_coroutine_threadsafe(coro,loop)”. Where “coro” is a coroutine that takes on the “drone” argument, and “loop” is the asyncio loop in which the “drone” object was created. This successfully passed the drone between the two threads, however, it seems to need to run the second thread in the same asyncio loop. This is a problem for me as I need to run the two threads at different “rates”, and I don’t want one to have to wait for the other.

Therefore my solution (which is probably quite “agricultural”) is to just connect a second drone object to the same mavsdk server address and port in the second thread. This seems to work, and both the first and second threads can connect and run essentially independently which is what I was after. I was concerned that connecting the second drone instance would upset the first but so far it seems to work.

Note also I was never able to succeed in passing the “drone” object between processes.

Thanks again for your help and advice.

Kind regards,

Jono