mavlink / MAVSDK-Python

MAVSDK client for Python.

Home Page:https://mavsdk.mavlink.io

Repository from Github https://github.commavlink/MAVSDK-PythonRepository from Github https://github.commavlink/MAVSDK-Python

The problem of hover not stable

522132 opened this issue · comments

commented

Our team is working on a project where we send control instructions from a computer to a drone's onboard Raspberry Pi, and the Raspberry Pi calls the udp_receive.py file, which receives the instructions and then calls the appropriate function based on the instructions' content, the udp_receive.py file as shown . Currently, we are facing a problem where when we input the takeoff instruction, the drone should take off to 2m and then hover for 30s before landing, but in our actual testing, the hovering is not stable and the drone will rock up and down and side to side. However, the remote control can hover perfectly, so what could be the reason for this?

udp_receive:

#!/usr/bin/env python3

import socket
import asyncio
from mavsdk import System
from mavsdk.mission import (MissionItem, MissionPlan)



async def print_status_text(drone):
    try:
        async for status_text in drone.telemetry.status_text():
            print(f"Status: {status_text.type}: {status_text.text}")
    except asyncio.CancelledError:
        return


async def connect_to_drone():
    drone = System(mavsdk_server_address='localhost',port=50051)
    await drone.connect()
    return drone



async def print_mission_progress(drone):
    async for mission_progress in drone.mission.mission_progress():
        print(f"Mission progress: "
              f"{mission_progress.current}/"
              f"{mission_progress.total}")


async def observe_is_in_air(drone, running_tasks):
    """ Monitors whether the drone is flying or not and
    returns after landing """

    was_in_air = False

    async for is_in_air in drone.telemetry.in_air():
        if is_in_air:
            was_in_air = is_in_air

        if was_in_air and not is_in_air:
            for task in running_tasks:
                task.cancel()
                try:
                    await task
                except asyncio.CancelledError:
                    pass
            await asyncio.get_event_loop().shutdown_asyncgens()

            return




        
    

async def main():

    udp_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    udp_socket.bind(("0.0.0.0", 11111))

    # drone = connect_to_drone()

    drone = System(mavsdk_server_address='localhost',port=50040)
    await drone.connect()

    print("Waiting for drone to connect...")
    async for state in drone.core.connection_state():
        if state.is_connected:
           print(f"-- Connected to drone!")
           break


    try:
        while True:
            data, addr = udp_socket.recvfrom(1024)
            command = data.decode("utf-8")

            # await execute_command(drone, command)
    
            if command == "takeoff":

                print(f"\nExecuting command on drone: {command}")

                #print("-- Arming")
               
               # print("Fetching amsl altitude at home location...")
               # async for terrain_info in drone.telemetry.home():
               #     absolute_altitude = terrain_info.absolute_altitude_m
               #     break

                #await drone.action.arm()

                print("-- Taking off")
                await drone.action.set_takeoff_altitude(2)
                await drone.action.takeoff()

                await asyncio.sleep(30)

                print("-- Landing")
                await drone.action.land()

                pass
            elif command == "land":

                print("-- Landing")
                await drone.action.land()
               
                pass
 
            elif command == "arm":
                print("-- arming")
                await drone.action.arm()
                pass

            elif command == "disarm":
                print("-- disarming")
                await drone.action.disarm()
                pass

            elif command == "mission":

                print(f"Executing command on drone: {command}")
                print_mission_progress_task = asyncio.ensure_future(print_mission_progress(drone))

                running_tasks = [print_mission_progress_task]
                termination_task = asyncio.ensure_future(observe_is_in_air(drone, running_tasks))

                mission_items = []
                mission_items.append(MissionItem(47.3978432,
                                     8.5455860,
                                     10,
                                     10,
                                     True,
                                     float('nan'),
                                     float('nan'),
                                     MissionItem.CameraAction.NONE,
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan')))
                mission_items.append(MissionItem(47.3978361,
                                     8.5453098,
                                     10,
                                     10,
                                     True,
                                     float('nan'),
                                     float('nan'),
                                     MissionItem.CameraAction.NONE,
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan')))
                mission_items.append(MissionItem(47.3977175,
                                     8.5453168,
                                     10,
                                     10,
                                     True,
                                     float('nan'),
                                     float('nan'),
                                     MissionItem.CameraAction.NONE,
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan')))
                mission_items.append(MissionItem(47.3977426,
                                     8.5455935,
                                     10,
                                     10,
                                     True,
                                     float('nan'),
                                     float('nan'),
                                     MissionItem.CameraAction.NONE,
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan'),
                                     float('nan')))
                
                mission_plan = MissionPlan(mission_items)

                await drone.mission.set_return_to_launch_after_mission(True)

                print("-- Uploading mission")
                await drone.mission.upload_mission(mission_plan)

                print("Waiting for drone to have a global position estimate...")
                async for health in drone.telemetry.health():
                    if health.is_global_position_ok and health.is_home_position_ok:
                        print("-- Global position estimate OK")
                        break

                # print("-- Arming")
                # await drone.action.arm()

                print("-- Starting mission")
                await drone.mission.start_mission()

                await termination_task

                pass
            else:
                print(f"Executing command on drone: {command}")

    except KeyboardInterrupt:
        # 处理键盘终端(Ctrl+C)
        print("USer interrupted.")

    finally:
        udp_socket.close()
       # drone.close()



if __name__ == "__main__":

    # Run the asyncio loop
    asyncio.run(main())

What kind of output do you get in your testing? E.g. does it do something like this:

-- arming
-- arming
-- arming
-- arming
-- arming
-- arming
Executing command on drone: takeoff
-- Taking off
Executing command on drone: takeoff
-- Taking off
Executing command on drone: takeoff
-- Taking off

or more something like this:

-- arming
Executing command on drone: takeoff
-- Taking off
commented

Our testing get the second output,there is no extra output, like this:

-- arming
Executing command on drone: takeoff
-- Taking off

Then I don't think your problem comes from MAVSDK 🤔

commented

Thanks for your answer. However, we have another question: Is this takeoff api a takeoff api that requires a higher GPS? If the gps is not good, is there any recommended API that can maintain a high hover? Look forward to your suggestions

You can set the takeoff altitude, something like this in Python:

await drone.action.set_takeoff_altitude(<altitude>)

Is that what you mean?

No more answer, closing.