# Controll Multi-Drones by keyboard using mavsdk-python

**URL:** <https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771>\
**Category:** MAVSDK\
**Created:** [February 11, 2023, 4:04pm UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771 "2023-02-11T16:04:13Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![theboybylove](https://discuss.px4.io/user_avatar/discuss.px4.io/theboybylove/32/12130_2.png) [@theboybylove](https://discuss.px4.io/u/theboybylove)\
**Post date:** [February 11, 2023, 4:04pm UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/1 "2023-02-11T16:04:13Z")

</div>

Hi everyone,  
Hi everyone, I have written a python script that controls a drone with a keyboard. But when I upgrade to control 2 drones at the same time by connecting 2 simulated drones and giving control commands to both drones, it means that 2 drones will have to move the same but only one moves. Hope you give me advice.  
This is my code below.

```auto
import asyncio
import random
from mavsdk import System
import KeyPressModule as kp

# Test set of manual inputs. Format: [roll, pitch, throttle, yaw]

kp.init()
drone1 = System()
drone2 = System()

roll, pitch, throttle, yaw = 0, 0, 0.5, 0
async def getKeyboardInput(my_drone):
    global roll, pitch, throttle, yaw
    while True:
        roll, pitch, throttle, yaw = 0, 0, 0.5, 0
        value = 1
        if kp.getKey("LEFT"):
            pitch = -value
        elif kp.getKey("RIGHT"):
            pitch = value
        if kp.getKey("UP"):
            roll = value
        elif kp.getKey("DOWN"):
            roll = -value
        if kp.getKey("w"):
            throttle = value
        elif kp.getKey("s"):
            throttle = 0
        if kp.getKey("a"):
            yaw = -value
        elif kp.getKey("d"):
            yaw = value
        elif kp.getKey("i"):
            asyncio.ensure_future(print_flight_mode(my_drone))
        elif kp.getKey("q") and my_drone.telemetry.landed_state():
            await my_drone.action.arm()
        elif kp.getKey("l") and my_drone.telemetry.in_air():
            await my_drone.action.land()
        # print(roll, pitch, throttle, yaw)
        await asyncio.sleep(0.1)

async def print_flight_mode(my_drone):
    async for flight_mode in my_drone.telemetry.flight_mode():
        print("FlightMode:", flight_mode)
        # return flight_mode

async def manual_control_drone(my_drone):
    global roll, pitch, throttle, yaw
    while True:
        print(roll, pitch, throttle, yaw)
        await my_drone.manual_control.set_manual_control_input(roll, pitch, throttle, yaw)
        await asyncio.sleep(0.1)

async def run_drone1():
    asyncio.ensure_future(getKeyboardInput(drone1))
    await drone1.connect(system_address="udp://:14540")
    # This waits till a mavlink based drone is connected
    print("Waiting for drone to connect...")
    async for state in drone1.core.connection_state():
        if state.is_connected:
            print(f"-- Connected to drone!")
            break
    # Checking if Global Position Estimate is ok
    async for health in drone1.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("-- Global position state is good enough for flying.")
            break
    asyncio.ensure_future(manual_control_drone(drone1))

async def run_drone2():
    asyncio.ensure_future(getKeyboardInput(drone2))
    await drone2.connect(system_address="udp://:14541")
    # This waits till a mavlink based drone is connected
    print("Waiting for drone to connect...")
    async for state in drone2.core.connection_state():
        if state.is_connected:
            print(f"-- Connected to drone!")
            break
    # Checking if Global Position Estimate is ok
    async for health in drone2.telemetry.health():
        if health.is_global_position_ok and health.is_home_position_ok:
            print("-- Global position state is good enough for flying.")
            break
    asyncio.ensure_future(manual_control_drone(drone2))

async def run():
    global roll, pitch, throttle, yaw
    """Main function to connect to the drone and input manual controls"""
    await asyncio.gather(run_drone1(), run_drone2())

if __name__ == " __main__":
    # Start the main function
    asyncio.ensure_future(run())

    # Runs the event loop until the program is canceled with e.g. CTRL-C
    asyncio.get_event_loop().run_forever()

```

---

<div class="post-metadata">

**Author:** ![JulianOes](https://discuss.px4.io/user_avatar/discuss.px4.io/julianoes/32/30_2.png) [@JulianOes](https://discuss.px4.io/u/JulianOes)\
**Post date:** [February 12, 2023, 3:19am UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/2 "2023-02-12T03:19:45Z")

</div>

> [@theboybylove](#):
>
> ```auto
> drone1 = System()
> drone2 = System()
> 
> ```

This is not correct. You need to manually run `mavsdk_server_bin` twice with different arguments.

So, for me, this would be:

```auto
.local/lib/python3.10/site-packages/mavsdk/bin/mavsdk_server udp://:14540 -p 50060

```

And:

```auto
.local/lib/python3.10/site-packages/mavsdk/bin/mavsdk_server udp://:14541 -p 50061

```

And then you connect to the two using:

```auto
    drone1 = System(mavsdk_server_address="localhost", port=50060)
    await drone1.connect()

    drone2 = System(mavsdk_server_address="localhost", port=50061)
    await drone2.connect()

```

---

<div class="post-metadata">

**Author:** ![theboybylove](https://discuss.px4.io/user_avatar/discuss.px4.io/theboybylove/32/12130_2.png) [@theboybylove](https://discuss.px4.io/u/theboybylove)\
**Post date:** [February 12, 2023, 3:38am UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/3 "2023-02-12T03:38:44Z")

</div>

thank you very much, i will do it.

---

<div class="post-metadata">

**Author:** ![theboybylove](https://discuss.px4.io/user_avatar/discuss.px4.io/theboybylove/32/12130_2.png) [@theboybylove](https://discuss.px4.io/u/theboybylove)\
**Post date:** [February 12, 2023, 3:48am UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/4 "2023-02-12T03:48:50Z")

</div>

I have tried it and succeeded. Thank you very much

---

<div class="post-metadata">

**Author:** ![theboybylove](https://discuss.px4.io/user_avatar/discuss.px4.io/theboybylove/32/12130_2.png) [@theboybylove](https://discuss.px4.io/u/theboybylove)\
**Post date:** [February 28, 2023, 9:04am UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/5 "2023-02-28T09:04:42Z")

</div>

Hi, My project is almost done and thank you for your enthusiastic support. There is an extra part that is about mavsdk\_server when I have to simulate 3 drones and connect them with python code I have to run 3 more terminals to run mavsdk\_server and that is quite inconvenient. I wonder how can my program connect to multi-drones like QGroundcontrol or is there a way to connect multiple drones automatically?!

---

<div class="post-metadata">

**Author:** ![JulianOes](https://discuss.px4.io/user_avatar/discuss.px4.io/julianoes/32/30_2.png) [@JulianOes](https://discuss.px4.io/u/JulianOes)\
**Post date:** [March 5, 2023, 10:38pm UTC](https://discuss.px4.io/t/controll-multi-drones-by-keyboard-using-mavsdk-python/30771/6 "2023-03-05T22:38:46Z")

</div>

> [@theboybylove](#):
>
> I have to run 3 more terminals to run mavsdk\_server and that is quite inconvenient

If you don’t want multiple terminals, you can just launch them in the same terminal by adding ` &` at the end of each line (that’s space and then ampersant). That way it’s launched in the background.

Alternatively, you can use a script to launch them all (also with ampersand), your you can use screen or tmux instances and launch it in there and then detach, and you can also script that.
