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
21 changes: 18 additions & 3 deletions modules/bootcamp/decision_simple_waypoint.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non
# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Add your own
self.has_landed = False

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down Expand Up @@ -67,11 +67,26 @@ def run(
# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============
# Calculate distance to waypoint
delta_x = self.waypoint.location_x - report.position.location_x
delta_y = self.waypoint.location_y - report.position.location_y
dist = (delta_x**2 + delta_y**2) ** 0.5

if self.has_landed:
return command

# Do something based on the report and the state of this class...
if report.status.name == "LANDED":
self.has_landed = True
return command

if dist > self.acceptance_radius:
if report.status.name == "HALTED":
command = commands.Command.create_set_relative_destination_command(delta_x, delta_y)
else:
if report.status.name == "HALTED":
command = commands.Command.create_land_command()

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

return command
47 changes: 42 additions & 5 deletions modules/bootcamp/decision_waypoint_landing_pads.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,9 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non
# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Add your own
self.has_landed = False
self.reached_waypoint = False
self.closest_landing_pad = None

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down Expand Up @@ -67,11 +68,47 @@ def run(
# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Do something based on the report and the state of this class...
if self.has_landed:
return command

if report.status.name == "LANDED":
self.has_landed = True
return command

if not self.reached_waypoint:
# Calculate distance to waypoint
delta_x = self.waypoint.location_x - report.position.location_x
delta_y = self.waypoint.location_y - report.position.location_y
dist = (delta_x**2 + delta_y**2) ** 0.5

if dist > self.acceptance_radius:
if report.status.name == "HALTED":
command = commands.Command.create_set_relative_destination_command(delta_x, delta_y)
else:
self.reached_waypoint = True
# Find closest landing pad
min_dist = float("inf")
for pad in landing_pad_locations:
pad_delta_x = pad.location_x - report.position.location_x
pad_delta_y = pad.location_y - report.position.location_y
pad_dist = (pad_delta_x**2 + pad_delta_y**2) ** 0.5
if pad_dist < min_dist:
min_dist = pad_dist
self.closest_landing_pad = pad
else:
# Move to closest landing pad
delta_x = self.closest_landing_pad.location_x - report.position.location_x
delta_y = self.closest_landing_pad.location_y - report.position.location_y
dist = (delta_x**2 + delta_y**2) ** 0.5

if dist > self.acceptance_radius:
if report.status.name == "HALTED":
command = commands.Command.create_set_relative_destination_command(delta_x, delta_y)
else:
if report.status.name == "HALTED":
command = commands.Command.create_land_command()

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

return command
63 changes: 30 additions & 33 deletions modules/bootcamp/detect_landing_pad.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,43 +86,40 @@ def run(self, image: np.ndarray) -> "tuple[list[bounding_box.BoundingBox], np.nd
Return: A tuple of (list of bounding boxes, annotated image) .
The list of bounding boxes can be empty.
"""
# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Ultralytics has documentation and examples

# Use the model's predict() method to run inference
# Parameters of interest:
# * source
# * conf
# * device
# * verbose
predictions = ...
# Run inference using the model's predict method
# Set confidence threshold to 0.7, use the correct device, and suppress verbose output
predictions = self.__model.predict(
source=image,
conf=0.7,
device=self.__DEVICE,
verbose=False,
)

# Get the Result object
prediction = ...
# Get the first (and only) Result object
prediction = predictions[0]

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

# Get the xyxy boxes list from the Boxes object in the Result object
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 = prediction.boxes
if boxes is not None and boxes.xyxy is not None:
boxes_xyxy = boxes.xyxy
else:
boxes_xyxy = []

# Detach the xyxy boxes to make a copy, move to CPU, and convert to numpy array
if hasattr(boxes_xyxy, "cpu"):
boxes_cpu = boxes_xyxy.cpu().numpy()
else:
boxes_cpu = np.array(boxes_xyxy)

# 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 = ...

return [], image_annotated
# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
# ============
for i in range(boxes_cpu.shape[0]):
bounds = boxes_cpu[i]
result, box = bounding_box.BoundingBox.create(bounds)
if result and box is not None:
bounding_boxes.append(box)

return bounding_boxes, image_annotated
Loading