Skip to main content

Uav_api is a python package that provides a HTTP interface for MAVLink commands for ardupilot vehicles

Project description

Uav_api

This is the repository for Uav_api, an API for UAV autonomous flights. The Uav_api enables UAV movement, telemetry and basic command execution such as RTL and TAKEOFF through HTTP requests, facilitating remote controlled flights, both programmatically and manually. In addition to that, Uav_api supports protocol execution for autonomous flights, oferring the same interface as gradysim-nextgen simulator. At last but not least, Uav_api can be used for simulations based on Ardupilot's SITL.

Installation

Prerequisites

Python 3.10 is required If simulated flights are intended, installing Ardupilot's codebase is necessary. To do that follow the instructions at https://ardupilot.org/dev/docs/where-to-get-the-code.html (Don't forget to build the environment after cloning). In addition to that, following the steps for running the SITL is also required, which are stated at https://ardupilot.org/dev/docs/SITL-setup-landingpage.html

Cloning the repository

To install Uav_api simply clone this repository.

git clone git@github.com:Project-GrADyS/uav_api.git

Install required packages

To install required python packages run the command bellow from the root folder of the repository:

pip3 install -r requirements.txt

Executing a Real flight

Starting Uav_api

To start the server, run the following command:

python3 uav_api.py --port [port for API] --uav_connection [ardupilot_connection] --connection_type [udpin or updout] --sysid [sysid for ardupilot]

Alternatively, you can use a configuration file in the .ini format.

This file is located at flight_examples/config.ini

[API]
port = 8020
uav_connection = 127.0.0.1:17171
connection_type = udpin
sysid = 12

And run the command:

python3 uav_api.py --config flight_examples/config.ini

To get better insight on the arguments for uav_api.py run the command bellow:

python3 uav_api --help

Testing API

To verify the initialization of the API go to the endpoint localhost:[your_port]/docs. image

Once inside the web page, scroll to telemetry router and execute the telemetry/general endpoint. image

If everything is fine, the answer should look like this. image

And that's it! You can start sending HTTP requests to Uav_api

Executing a Simulated flight

Starting Uav_api

To instantiate the API, run the script uav_api.py through the following command:

python3 uav_api.py --simulated true This command initiates both the SITL, and the Uav_api API. The connection addres of the SITL instance is 127.0.0.1:17171 and the api is hosted at localhost:8000 by default but both of this parameters can be modified by arguments.

Testing and feedback

To manually test the api access the auto-generated swagger endpoint at http://localhost:8000/docs.

image

To get visual feedback of drone position and telemetry use Mission Planner, or any other ground station software of your preference, and connect to UDP port 15630 (for wsl users this may not work, check the parameters section for uav_api.py and search for gs_connection for more).

image

Flying through scripts

One of the perks of using Uav_control is simplifying UAV flights coordinated by scripts. Here are some examples:

Simple Takeoff and Landing

This file is located at flight_examples/takeoff_land.py

import requests
base_url = "http://localhost:8000"

# Arming vehicle
arm_result = requests.get(f"{base_url}/command/arm")
if arm_result.status_code != 200:
    print(f"Arm command fail. status_code={arm_result.status_code}")
    exit()
print("Vehicle armed.")

# Taking off
params = {"alt": 30}
takeoff_result = requests.get(f"{base_url}/command/takeoff", params=params)
if takeoff_result.status_code != 200:
    print(f"Take off command fail. status_code={takeoff_result.status_code}")
    exit()
print("Vehicle took off")

# Landing...
land_result = requests.get(f"{base_url}/command/land")
if land_result.status_code != 200:
    print(f"Land command fail. status_code={land_result.status_code}")
    exit()
print("Vehicle landed.")

NED Square

In this example the uav will move following a square with 100 meters side. This file is located at flight_examples/ned_square.

import requests
base_url = "http://localhost:8000"

# Arming vehicle
arm_result = requests.get(f"{base_url}/command/arm")
if arm_result.status_code != 200:
    print(f"Arm command fail. status_code={arm_result.status_code}")
    exit()
print("Vehicle armed.")

# Taking off
params = {"alt": 30}
takeoff_result = requests.get(f"{base_url}/command/takeoff", params=params)
if takeoff_result.status_code != 200:
    print(f"Take off command fail. status_code={takeoff_result.status_code}")
    exit()
print("Vehicle took off")

square_points = [
    (100, 100, -50),
    (100, -100, -50),
    (-100, -100, -50),
    (-100, 100, -50)
]

# Moving
for point in square_points:
    point_data = {
        "x": point[0],
        "y": point[1],
        "z": point[2]
    }
    point_result = requests.post(f"{base_url}/movement/go_to_ned_wait", json=point_data)
    if point_result.status_code != 200:
        print(f"Go_to_ned_wait command fail. status_code={point_result.status_code} point={point}")
        exit()
    print(f"Vehicle at ({point[0]}, {point[1]}, {point[2]})")

# Returning to launch
rtl_result = requests.get(f"{base_url}/command/rtl")
if rtl_result.status_code != 200:
    print(f"RTL command fail. status_code={rtl_result.status_code}")
    exit()
print("Vehicle landed at launch.")

NED Square (Polling)

This example does the same thing as the last one but this time instead of using the go_to_ned_wait endpoint we will take a polling aproach using go_to_ned. While more verbose, this way of verifying position allows your program to do other things while the uav has not arrived to the specified location. This file is located at flight_examples/ned_square_polling.py.

import requests
import time
import math

base_url = "http://localhost:8000"

def euclidean_distance(point1, point2):
    return math.sqrt((point1[0] - point2[0])**2 + (point1[1] - point2[1])**2 + (point1[2] - point2[2])**2)

def wait_for_point(point, max_error, timeout):
    start = time.time()
    while time.time() < start + timeout:
        ned_result = requests.get(f"{base_url}/telemetry/ned")
        if ned_result.status_code != 200:
            print(f"Ned telemetry fail. status_code={ned_result.status_code}")
            exit()
        ned_pos = ned_result.json()["info"]["position"]
        print(ned_pos)
        ned_point = (ned_pos["x"], ned_pos["y"], ned_pos["z"])
        distance = euclidean_distance(point, ned_point)
        if distance < max_error:
            return True
    return False


# Arming vehicle
arm_result = requests.get(f"{base_url}/command/arm")
if arm_result.status_code != 200:
    print(f"Arm command fail. status_code={arm_result.status_code}")
    exit()
print("Vehicle armed.")

# Taking off
params = {"alt": 30}
takeoff_result = requests.get(f"{base_url}/command/takeoff", params=params)
if takeoff_result.status_code != 200:
    print(f"Take off command fail. status_code={takeoff_result.status_code}")
    exit()
print("Vehicle took off")

square_points = [
    (100, 100, -50),
    (100, -100, -50),
    (-100, -100, -50),
    (-100, 100, -50)
]

# Moving
for point in square_points:
    point_data = {
        "x": point[0],
        "y": point[1],
        "z": point[2]
    }
    point_result = requests.post(f"{base_url}/movement/go_to_ned", json=point_data)
    if point_result.status_code != 200:
        print(f"Go_to_ned command fail. status_code={point_result.status_code} point={point}")
        exit()

    arrived = wait_for_point(point, max_error=3, timeout=60)
    if not arrived:
        print(f"Error while going to point {point}")
        exit()
    print(f"Vehicle at ({point[0]}, {point[1]}, {point[2]})")

# Returning to launch
rtl_result = requests.get(f"{base_url}/command/rtl")
if rtl_result.status_code != 200:
    print(f"RTL command fail. status_code={rtl_result.status_code}")
    exit()
print("Vehicle landed at launch.")

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

uav_api-0.0.2.tar.gz (210.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

uav_api-0.0.2-py3-none-any.whl (40.5 kB view details)

Uploaded Python 3

File details

Details for the file uav_api-0.0.2.tar.gz.

File metadata

  • Download URL: uav_api-0.0.2.tar.gz
  • Upload date:
  • Size: 210.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for uav_api-0.0.2.tar.gz
Algorithm Hash digest
SHA256 deb432410087ca7c9d20f9aed55c3a07e4ccb2173b649bf9b9bae1b4dea6a8c0
MD5 cddd8f5dbdcb9bd12adc8c5713a8ab9c
BLAKE2b-256 1bf9ca5046cc34a02bc48a3b91c2cddcc57ccb298e8320fe36ebc06eef59d4d1

See more details on using hashes here.

File details

Details for the file uav_api-0.0.2-py3-none-any.whl.

File metadata

  • Download URL: uav_api-0.0.2-py3-none-any.whl
  • Upload date:
  • Size: 40.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.1.0 CPython/3.12.3

File hashes

Hashes for uav_api-0.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 14b44b5f5c25f01ede36a8b1fe5e139c4f982ae50ff311303e15f3edbc99dc2c
MD5 876792e33c5cb69dbcd4c1ccf52c25de
BLAKE2b-256 9a7aa0f77789aa8f17aef1913dc4df26644672ae5536115fc1d7166c429552e1

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page