-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Write code for offboard movement #16
- Loading branch information
Showing
10 changed files
with
280 additions
and
60 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
""" | ||
This module implements a function to tell the drone | ||
to starting moving toward a location | ||
""" | ||
|
||
import mavsdk | ||
import mavsdk.offboard | ||
import mavsdk.telemetry | ||
import utm | ||
|
||
from .vector import Vector3 | ||
from .velocity import Velocity | ||
|
||
|
||
async def move_toward( | ||
drone: mavsdk.System, | ||
latitude: float, | ||
longitude: float, | ||
absolute_altitude_m: float, | ||
time_seconds: float = 3.0, | ||
) -> mavsdk.offboard.VelocityNedYaw: | ||
""" | ||
Causes the drone to start moving toward a location; | ||
only sets the drone's velocity once, then returns | ||
Parameters | ||
---------- | ||
drone : mavsdk.System | ||
The drone to move | ||
latitude : float | ||
The latitude, in degrees | ||
longitude : float | ||
The longitude, in degrees | ||
absolute_altitude_m : float | ||
The altitude above mean sea level, in meters | ||
time_seconds : float | ||
Controls how quickly the drone will attempt to move | ||
to the target; the drone may not be able to actually | ||
move this quickly | ||
Returns | ||
------- | ||
The value the drone's velocity was set to, | ||
as a mavsdk.offboard.VelocityNewYaw object | ||
""" | ||
|
||
# Get drone position | ||
drone_position: mavsdk.telemetry.Position = await anext(drone.telemetry.position()) | ||
|
||
# Get drone and target utm positions | ||
target_utm: tuple[float, float, int, str] = utm.from_latlon(latitude, longitude) | ||
drone_utm: tuple[float, float, int, str] = utm.from_latlon( | ||
drone_position.latitude_deg, | ||
drone_position.longitude_deg, | ||
force_zone_number=target_utm[2], | ||
force_zone_letter=target_utm[3], | ||
) | ||
|
||
# Calculate difference in positions | ||
position_diff: Vector3 = Vector3( | ||
target_utm[0] - drone_utm[0], | ||
target_utm[1] - drone_utm[1], | ||
absolute_altitude_m - drone_position.absolute_altitude_m, | ||
) | ||
|
||
# Calculate target velocity based on time_seconds | ||
target_velocity: Vector3 = position_diff / time_seconds | ||
|
||
# Create Velocity object | ||
result: mavsdk.offboard.VelocityNedYaw = Velocity( | ||
target_velocity.y, # north | ||
target_velocity.x, # east | ||
-target_velocity.z, # down | ||
).to_mavsdk_velocitynedyaw() | ||
|
||
# Set drone's velocity | ||
await drone.offboard.set_velocity_ned(result) | ||
|
||
return result |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
""" | ||
This package implements various vector classes | ||
""" | ||
|
||
from .vector3 import Vector3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
""" | ||
This module implements the Vector3 class | ||
""" | ||
|
||
from __future__ import annotations | ||
from dataclasses import dataclass | ||
import math | ||
from typing import Iterator, overload | ||
|
||
|
||
@dataclass(slots=True) | ||
class Vector3: | ||
""" | ||
A 3D vector | ||
Attributes | ||
---------- | ||
x : float | ||
The x component of this vector | ||
y : float | ||
The y component of this vector | ||
z : float | ||
The z component of this vector | ||
length: float | ||
""" | ||
|
||
x: float | ||
y: float | ||
z: float | ||
|
||
@overload | ||
def __init__(self, x: float, y: float, z: float): | ||
... | ||
|
||
@overload | ||
def __init__(self, x: float): | ||
... | ||
|
||
def __init__(self, x: float, y: float | None = None, z: float | None = None): | ||
self.x = x | ||
self.y = x if y is None else y | ||
self.z = x if z is None else z | ||
|
||
def __hash__(self) -> int: | ||
big_hash: int = ((hash(self.x) * 3) + hash(self.y)) * 3 + hash(self.z) | ||
return big_hash & 0xFFFF_FFFF_FFFF_FFFF | ||
|
||
# Implement unpacking | ||
def __iter__(self) -> Iterator[float]: | ||
return iter((self.x, self.y, self.z)) | ||
|
||
# Implement **kwargs unpacking | ||
|
||
def keys(self) -> list[str]: | ||
""" | ||
Gets a list of keys for **kwargs unpacking | ||
Returns | ||
------- | ||
The list ['x', 'y', 'z'] | ||
""" | ||
return ["x", "y", "z"] | ||
|
||
def __getitem__(self, key: str) -> float: | ||
match key: | ||
case "x": | ||
return self.x | ||
case "y": | ||
return self.y | ||
case "z": | ||
return self.z | ||
case _: | ||
raise KeyError(f"{key} is not a valid key of {type(self).__name__}") | ||
|
||
@property | ||
def length(self) -> float: | ||
""" | ||
Calculates the magnitude of this vector | ||
Returns | ||
------- | ||
The magnitude of this vector | ||
""" | ||
return math.hypot(self.x, self.y, self.z) | ||
|
||
def normalized(self) -> Vector3: | ||
""" | ||
Creates a normalized version of this vector | ||
Returns | ||
------- | ||
A vector with the same direction as this vector | ||
and a magnitude of 1.0 (within floating-point error) | ||
""" | ||
return self / self.length | ||
|
||
def __neg__(self) -> Vector3: | ||
return Vector3(-self.x, -self.y, -self.z) | ||
|
||
def __add__(self, rhs: Vector3) -> Vector3: | ||
return Vector3( | ||
self.x + rhs.x, | ||
self.y + rhs.y, | ||
self.z + rhs.z, | ||
) | ||
|
||
def __sub__(self, rhs: Vector3) -> Vector3: | ||
return self + -rhs | ||
|
||
def __mul__(self, rhs: Vector3 | float) -> Vector3: | ||
if isinstance(rhs, Vector3): | ||
return Vector3( | ||
self.x * rhs.x, | ||
self.y * rhs.y, | ||
self.z * rhs.z, | ||
) | ||
return Vector3(self.x * rhs, self.y * rhs, self.z * rhs) | ||
|
||
def __rmul__(self, lhs: float) -> Vector3: | ||
return self * lhs | ||
|
||
def __truediv__(self, rhs: Vector3 | float) -> Vector3: | ||
if isinstance(rhs, Vector3): | ||
return Vector3( | ||
self.x / rhs.x, | ||
self.y / rhs.y, | ||
self.z / rhs.z, | ||
) | ||
return Vector3(self.x / rhs, self.y / rhs, self.z / rhs) |
Oops, something went wrong.