-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Autonomous Landing Module #235
base: main
Are you sure you want to change the base?
Changes from 18 commits
178b772
3954351
b80e668
8b822e0
fd8241f
265cae9
6fd5f9e
8b1c536
876b714
0b07de1
38aad9b
1c5b247
398edaa
dc81d8e
af13347
6f4c829
224a7dc
c0af0dc
fb1e009
44656ad
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
""" | ||
Auto-landing script. | ||
""" | ||
|
||
import math | ||
|
||
from pymavlink import mavutil | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm pretty sure you won't need this library |
||
from ..common.modules.logger import logger | ||
from .. import detections_and_time | ||
maxlou05 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
|
||
class AutoLanding: | ||
""" | ||
Auto-landing script. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copy new file docstring here |
||
""" | ||
|
||
__create_key = object() | ||
|
||
@classmethod | ||
def create( | ||
cls, | ||
fov_x: float, | ||
fov_y: float, | ||
im_h: float, | ||
im_w: float, | ||
maxlou05 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
local_logger: logger.Logger, | ||
) -> "tuple [bool, AutoLanding | None ]": | ||
""" | ||
fov_x: The horizontal camera field of view in degrees. | ||
fov_y: The vertical camera field of view in degrees. | ||
im_w: Width of image. | ||
im_h: Height of image. | ||
height_agl: Height above ground level in meters. | ||
|
||
Returns an AutoLanding object. | ||
""" | ||
vehicle = mavutil.mavlink_connection("tcp:localhost:14550") | ||
try: | ||
height_agl_mm = vehicle.messages[ | ||
"GLOBAL_POSITION_INT" | ||
].relative_alt # copied from blue_only.py | ||
height_agl = max(height_agl_mm / 1000, 0.0) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If we need altitude information, you cannot create another connection to the drone since FlightInterface already has one. You need to get the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, this portion should also go into the |
||
local_logger.info(f"Altitude AGL: {height_agl} ", True) | ||
except (KeyError, AttributeError): | ||
local_logger.error("No GLOBAL_POSITION_INT message received") | ||
return False, None | ||
|
||
return True, AutoLanding( | ||
cls.__create_key, fov_x, fov_y, im_h, im_w, height_agl, local_logger | ||
) | ||
|
||
def __init__( | ||
self, | ||
class_private_create_key: object, | ||
fov_x: float, | ||
fov_y: float, | ||
im_h: float, | ||
im_w: float, | ||
height_agl: float, | ||
local_logger: logger.Logger, | ||
) -> None: | ||
""" | ||
Private constructor, use create() method. | ||
""" | ||
assert class_private_create_key is AutoLanding.__create_key, "Use create() method" | ||
|
||
self.fov_x = fov_x | ||
self.fov_y = fov_y | ||
self.im_h = im_h | ||
self.im_w = im_w | ||
self.height_agl = height_agl | ||
self.__logger = local_logger | ||
|
||
def run( | ||
self, bounding_box: detections_and_time.Detection | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think you'll be getting a |
||
) -> "tuple[bool, tuple[float, float, float]]": | ||
""" | ||
Calculates the angles in radians of the bounding box based on its center. | ||
|
||
bounding_box: A detections and time object. | ||
|
||
Return: Tuple of the x and y angles in radians respectively and the target distance in meters. | ||
""" | ||
|
||
x_center, y_center = bounding_box.get_centre() | ||
|
||
angle_x = (x_center - self.im_w / 2) * (self.fov_x * (math.pi / 180)) / self.im_w | ||
angle_y = (y_center - self.im_h / 2) * (self.fov_y * (math.pi / 180)) / self.im_h | ||
|
||
self.__logger.info(f"X angle (rad): {angle_x}", True) | ||
self.__logger.info(f"Y angle (rad): {angle_y}", True) | ||
|
||
x_dist = math.tan(angle_x) * self.height_agl | ||
y_dist = math.tan(angle_y) * self.height_agl | ||
ground_hyp = (x_dist**2 + y_dist**2) ** 0.5 | ||
self.__logger.info(f"Required horizontal correction (m): {ground_hyp}", True) | ||
target_to_vehicle_dist = (ground_hyp**2 + self.height_agl**2) ** 0.5 | ||
self.__logger.info(f"Distance from vehicle to target (m): {target_to_vehicle_dist}", True) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think that instead of making 4 separate lines in the log, you can combine all of these into 1 line, so the timestamps look better (these calculations should be fast anyways) |
||
|
||
return True, (angle_x, angle_y, target_to_vehicle_dist) |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
""" | ||
Auto-landing worker. | ||
""" | ||
|
||
import pathlib | ||
import os | ||
|
||
from utilities.workers import queue_proxy_wrapper | ||
from utilities.workers import worker_controller | ||
from . import auto_landing | ||
from ..common.modules.logger import logger | ||
|
||
|
||
def auto_landing_worker( | ||
fov_x: float, | ||
fov_y: float, | ||
im_h: float, | ||
im_w: float, | ||
input_queue: queue_proxy_wrapper.QueueProxyWrapper, | ||
output_queue: queue_proxy_wrapper.QueueProxyWrapper, | ||
controller: worker_controller.WorkerController, | ||
) -> None: | ||
""" | ||
Worker process. | ||
|
||
input_queue and output_queue are data queues. | ||
controller is how the main process communicates to this worker process. | ||
""" | ||
|
||
worker_name = pathlib.Path(__file__).stem | ||
process_id = os.getpid() | ||
result, local_logger = logger.Logger.create(f"{worker_name}_{process_id}", True) | ||
if not result: | ||
print("ERROR: Worker failed to create logger") | ||
return | ||
|
||
# Get Pylance to stop complaining | ||
assert local_logger is not None | ||
|
||
local_logger.info("Logger initialized", True) | ||
|
||
result, auto_lander = auto_landing.AutoLanding.create(fov_x, fov_y, im_h, im_w, local_logger) | ||
|
||
if not result: | ||
local_logger.error("Worker failed to create class object", True) | ||
return | ||
|
||
# Get Pylance to stop complaining | ||
assert auto_lander is not None | ||
|
||
while not controller.is_exit_requested(): | ||
controller.check_pause() | ||
|
||
input_data = input_queue.queue.get() | ||
if input_data is None: | ||
continue | ||
|
||
result, value = auto_lander.run(input_data) | ||
if not result: | ||
continue | ||
|
||
output_queue.queue.put(value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add calculates the parameters necessary for use with LANDING_TARGET MAVLink command