Skip to content
This repository was archived by the owner on Sep 21, 2025. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions modules/bootcamp/decision_simple_waypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@
from .. import drone_report

# Disable for bootcamp use
# pylint: disable-next=unused-import
from .. import drone_status
from .. import location
from ..private.decision import base_decision


# Disable for bootcamp use
# No enable
# pylint: disable=duplicate-code,unused-argument


class DecisionSimpleWaypoint(base_decision.BaseDecision):
Expand All @@ -39,6 +36,10 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non

# Add your own

self.has_sent_landing_command = False
self.min_bounds = -60
self.max_bounds = 60

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
# ============
Expand Down Expand Up @@ -69,6 +70,32 @@ def run(
# ============

# Do something based on the report and the state of this class...
# ensuring drone is within bounds
if (
self.waypoint.location_x >= self.min_bounds
and self.waypoint.location_x <= self.max_bounds
and self.waypoint.location_y >= self.min_bounds
and self.waypoint.location_y <= self.max_bounds
):
proximity = (self.waypoint.location_x - report.position.location_x) ** 2 + (
self.waypoint.location_y - report.position.location_y
) ** 2
# when the drone is halted but not at the destination
if (
report.status == drone_status.DroneStatus.HALTED
and proximity > self.acceptance_radius**2
):
command = commands.Command.create_set_relative_destination_command(
self.waypoint.location_x - report.position.location_x,
self.waypoint.location_y - report.position.location_y,
)
# when the drone is at the destination and is halted
if (
report.status == drone_status.DroneStatus.HALTED
and proximity < self.acceptance_radius**2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably put <= just in case that it happens to be equal.

):
command = commands.Command.create_land_command()
self.has_sent_landing_command = True

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down
70 changes: 67 additions & 3 deletions modules/bootcamp/decision_waypoint_landing_pads.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,12 @@
from .. import drone_report

# Disable for bootcamp use
# pylint: disable-next=unused-import
from .. import drone_status
from .. import location
from ..private.decision import base_decision


# Disable for bootcamp use
# No enable
# pylint: disable=duplicate-code,unused-argument


class DecisionWaypointLandingPads(base_decision.BaseDecision):
Expand All @@ -38,11 +35,25 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non
# ============

# Add your own
self.has_sent_landing_command = False
self.send_landing_command = False
self.reached_landing_pad = False
self.min_bounds = -60
self.max_bounds = 60

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
# ============

def distance_to_pad_squared(
self, report: drone_report.DroneReport, landing_pad: location.Location
) -> float:
"""returns distance squared"""
dist = (report.position.location_x - landing_pad.location_x) ** 2 + (
report.position.location_y - landing_pad.location_y
) ** 2
return dist

def run(
self, report: drone_report.DroneReport, landing_pad_locations: "list[location.Location]"
) -> commands.Command:
Expand All @@ -69,6 +80,59 @@ def run(
# ============

# Do something based on the report and the state of this class...
if (
self.waypoint.location_x >= self.min_bounds
and self.waypoint.location_x <= self.max_bounds
and self.waypoint.location_y >= self.min_bounds
and self.waypoint.location_y <= self.max_bounds
):

if report.status == drone_status.DroneStatus.HALTED:

if self.send_landing_command:
command = commands.Command.create_land_command()
self.has_sent_landing_command = True
return command

# calculating location of nearest landing pad
smallest_dist_x = float("inf")
smallest_dist_y = float("inf")
smallest_dist = smallest_dist_x**2 + smallest_dist_y**2
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can just set it to infinity, as you don't really need to calculate infinity squared

for landing_pad in landing_pad_locations:
new_dist = self.distance_to_pad_squared(report, landing_pad)
if new_dist < smallest_dist:
smallest_dist = new_dist
smallest_dist_x = landing_pad.location_x
smallest_dist_y = landing_pad.location_y

# if drone is at the waypoint
if (
(self.waypoint.location_x - report.position.location_x) ** 2
+ (self.waypoint.location_y - report.position.location_y) ** 2
) < self.acceptance_radius**2:

# if nearest landing pad is at the waypoint, land
if smallest_dist < self.acceptance_radius**2:
self.send_landing_command = True

# if not, set relative destination to nearest landing pad
else:
command = commands.Command.create_set_relative_destination_command(
smallest_dist_x - report.position.location_x,
smallest_dist_y - report.position.location_y,
)
self.reached_landing_pad = True
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't really know that the drone has reached the landing pad here, you only know that you told the drone to go towards the landing pad. What if it doesn't get there?


# drone moves to nearest landing pad, then lands
elif self.reached_landing_pad:
self.send_landing_command = True

# if drone halts unexpectedly, neither at the waypoint or at the nearest landing pad
else:
command = commands.Command.create_set_relative_destination_command(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do you know that you should go to the waypoint and not the landing pad? What if you were en route towards the landing pad?

self.waypoint.location_x - report.position.location_x,
self.waypoint.location_y - report.position.location_y,
)

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down
28 changes: 18 additions & 10 deletions modules/bootcamp/detect_landing_pad.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============
# Bootcampers remove the following lines:
# Allow linters and formatters to pass for bootcamp maintainers
# No enable
# pylint: disable=unused-argument,unused-private-member,unused-variable

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
# ============
Expand Down Expand Up @@ -98,31 +96,41 @@ def run(self, image: np.ndarray) -> "tuple[list[bounding_box.BoundingBox], np.nd
# * conf
# * device
# * verbose
predictions = ...
predictions = self.__model.predict(image, conf=0.7, device=self.__DEVICE, verbose=False)

# Get the Result object
prediction = ...
prediction = predictions[0]

# Plot the annotated image from the Result object
# Include the confidence value
image_annotated = ...
image_annotated = prediction.plot(conf=True)

# Get the xyxy boxes list from the Boxes object in the Result object
boxes_xyxy = ...
boxes_xyxy = prediction.boxes.xyxy

# Detach the xyxy boxes to make a copy,
# move the copy into CPU space,
# and convert to a numpy array
boxes_cpu = ...
boxes_cpu = boxes_xyxy.detach().cpu().numpy()

# Loop over the boxes list and create a list of bounding boxes
bounding_boxes = []
# Hint: .shape gets the dimensions of the numpy array
# for i in range(0, ...):
# # Create BoundingBox object and append to list
# result, box = ...
# result, box = ...
# result=0

for i in range(0, np.shape(boxes_cpu)[0]):

(result, box) = bounding_box.BoundingBox.create(boxes_cpu[i])

if result:
bounding_boxes.append(box)
else:
return [], image_annotated

return [], image_annotated
return bounding_boxes, image_annotated
# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
# ============
2 changes: 1 addition & 1 deletion modules/bootcamp/tests/run_decision_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
# to reach the 1st command
# Increase the step size if your computer is lagging
# Larger step size is smaller FPS
TIME_STEP_SIZE = 0.1 # seconds
TIME_STEP_SIZE = 4 # seconds

# OpenCV ignores your display settings,
# so if the window is too small or too large,
Expand Down
Binary file added yolov8n.pt
Binary file not shown.