Skip to content

Commit

Permalink
Use TypedDict for InputPoint #16
Browse files Browse the repository at this point in the history
  • Loading branch information
RexBerry committed Mar 15, 2023
1 parent 4fdf036 commit 41a860c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 15 deletions.
4 changes: 2 additions & 2 deletions flight/avoidance/movement.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ async def move_toward(
# Calculate target velocity based on time_seconds
target_velocity: Vector3 = position_diff / time_seconds

# Create Velocity object
# Create VelocityNedYaw object
result: mavsdk.offboard.VelocityNedYaw = target_velocity.to_mavsdk_velocitynedyaw(yaw_deg)

# Set drone's velocity
Expand Down Expand Up @@ -155,7 +155,7 @@ async def goto_location_offboard(
position_diff = await _difference_vector(
drone, latitude_deg, longitude_deg, absolute_altitude_m
)
yaw_deg = math.atan2(position_diff.east, position_diff.north)
yaw_deg = math.degrees(math.atan2(position_diff.east, position_diff.north))

try:
while True:
Expand Down
2 changes: 1 addition & 1 deletion flight/avoidance/obstacle_avoidance.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ async def calculate_avoidance_velocity(

# Convert obstacle data to list of Point objects
obstacle_positions: list[Point] = [
Point.from_dict(
Point.from_typed_dict(
in_point,
force_zone_number=drone_position.utm_zone_number,
force_zone_letter=drone_position.utm_zone_letter,
Expand Down
45 changes: 38 additions & 7 deletions flight/avoidance/point.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,27 @@
from __future__ import annotations
from dataclasses import dataclass
import time
from typing import TypedDict

import mavsdk.telemetry
import utm

from .vector.vector3 import Vector3

# Input points are dicts with time and UTM coordinate data
# May change in the future
InputPoint = dict[str, float | str]

class InputPoint(TypedDict):
"""
A dict representing a point to be passed to obstacle avoidance
See the Point class docstring for more info on attributes
"""

utm_x: float
utm_y: float
utm_zone_number: int
utm_zone_letter: str
altitude: float
time: float


@dataclass(slots=True)
Expand All @@ -33,7 +45,7 @@ class Point:
The letter of the UTM latitude band
altitude : float
The altitude of the point above sea level, in meters
time : float | None
time : float
The time at which an object was at this point, in Unix time
"""

Expand All @@ -45,7 +57,7 @@ class Point:
time: float

@classmethod
def from_dict(
def from_typed_dict(
cls,
position_data: InputPoint,
force_zone_number: int | None = None,
Expand All @@ -71,8 +83,8 @@ def from_dict(

utm_x: float = float(position_data["utm_x"])
utm_y: float = float(position_data["utm_y"])
utm_zone_number: int = int(position_data["utm_zone_number"])
utm_zone_letter: str = str(position_data["utm_zone_letter"])
utm_zone_number: int = position_data["utm_zone_number"]
utm_zone_letter: str = position_data["utm_zone_letter"]
if force_zone_number is not None or force_zone_letter is not None:
utm_x, utm_y, utm_zone_number, utm_zone_letter = utm.from_latlon(
*utm.to_latlon(utm_x, utm_y, utm_zone_number, utm_zone_letter),
Expand All @@ -89,6 +101,25 @@ def from_dict(
float(position_data["time"]),
)

def as_typed_dict(self) -> InputPoint:
"""
Converts a Point object to an InputPoint TypedDict
Returns
-------
An InputPoint dict object with the same values
as this Point object
"""

return {
"utm_x": self.utm_x,
"utm_y": self.utm_y,
"utm_zone_number": self.utm_zone_number,
"utm_zone_letter": self.utm_zone_letter,
"altitude": self.altitude,
"time": self.time,
}

@classmethod
def from_mavsdk_position(cls, position: mavsdk.telemetry.Position) -> Point:
"""
Expand Down
12 changes: 7 additions & 5 deletions flight/avoidance/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
"""

import asyncio
import dataclasses
import random
from typing import AsyncIterator

Expand All @@ -14,9 +13,10 @@
import utm

from .avoidance_goto import goto_with_avoidance
from .movement import goto_location_offboard
from .point import InputPoint, Point

TAKEOFF_ALTITUDE: float = 100.0
TAKEOFF_ALTITUDE: float = 40.0


async def takeoff(drone: mavsdk.System, altitude: float) -> None:
Expand All @@ -38,7 +38,7 @@ async def takeoff(drone: mavsdk.System, altitude: float) -> None:
# Temporary solution
# Originally attempted to use telemetry to detect when the desired
# altitude was reached, but telemetry is broken when taking off
await asyncio.sleep(20.0)
await asyncio.sleep(30.0)


async def random_position(
Expand Down Expand Up @@ -119,7 +119,7 @@ async def drone_positions(drone: mavsdk.System) -> AsyncIterator[list[InputPoint

while True:
point: Point = Point.from_mavsdk_position(await anext(drone.telemetry.position()))
in_point: InputPoint = dataclasses.asdict(point)
in_point: InputPoint = point.as_typed_dict()

if len(positions) > 4:
positions = positions[1:]
Expand Down Expand Up @@ -161,10 +161,12 @@ async def avoiding_drone_test(
await drone.offboard.set_velocity_ned(mavsdk.offboard.VelocityNedYaw(0.0, 0.0, 0.0, 0.0))
await drone.offboard.start()

await goto_location_offboard(drone, 10.0, 10.0, 10.0, None)

# Randomly move drone
while True:
pos: tuple[float, float, float] = await random_position(drone)
await goto_with_avoidance(drone, *pos, 0.0, position_updates)
await goto_with_avoidance(drone, *pos, None, position_updates)
await asyncio.sleep(4.0 * random.random() * random.random())


Expand Down

0 comments on commit 41a860c

Please sign in to comment.