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

# Add your own
self.command_index = 0
self.commands = [
commands.Command.create_set_relative_destination_command( 4, 1),
commands.Command.create_set_relative_destination_command( 0.0, -2),
commands.Command.create_set_relative_destination_command(-4, 1),
]
Comment on lines +41 to +45
Copy link
Contributor

Choose a reason for hiding this comment

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

let's not hardcode the coordinates - use self.waypoint instead

self.has_sent_landing_command = False

# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down Expand Up @@ -68,10 +74,14 @@ def run(self,
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Do something based on the report and the state of this class...
if report.status == drone_report.drone_status.DroneStatus.HALTED and self.command_index<len(self.commands):
command = self.commands[self.command_index]
self.command_index += 1

# Remove this when done
raise NotImplementedError
elif report.status == drone_report.drone_status.DroneStatus.HALTED and not self.has_sent_landing_command:
self.has_sent_landing_command = True
command = commands.Command.create_land_command()
Comment on lines +77 to +83
Copy link
Contributor

Choose a reason for hiding this comment

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

make sure we're using the acceptance radius here - if the drone is too far from the waypoint, we don't want to land there



# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down
41 changes: 35 additions & 6 deletions modules/bootcamp/decision_waypoint_landing_pads.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,26 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float):
print("Waypoint: " + str(waypoint))

self.acceptance_radius = acceptance_radius


# ============
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Add your own
self.command_index = 0
self.commands = [
commands.Command.create_set_relative_destination_command(waypoint.location_x, waypoint.location_y)
]
self.landed_at_waypoint = False
self.has_sent_landing_command = False
self.landing_pad_cache = None

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

def getL2Norm(self, l1: location.Location, l2: location.Location) -> int:
Copy link
Contributor

Choose a reason for hiding this comment

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

technically this doesn't give us the L2 norm - it gives the square of the L2 norm, let's rename the function to be more descriptive (btw, we try to use snake_case instead of camelCase)

return (l2.location_x - l1.location_x) * (l2.location_x - l1.location_x) + (l2.location_y - l1.location_y) * (l2.location_y - l1.location_y)
Copy link
Contributor

Choose a reason for hiding this comment

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

let's use ** 2 to make it explicit that we're squaring and not multiplying


def run(self,
report: drone_report.DroneReport,
landing_pad_locations: "list[location.Location]") -> commands.Command:
Expand All @@ -68,10 +77,30 @@ def run(self,
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
# ============

# Do something based on the report and the state of this class...

# Remove this when done
raise NotImplementedError
if report.status == drone_report.drone_status.DroneStatus.HALTED and self.command_index<len(self.commands):
command = self.commands[self.command_index]
self.command_index += 1

elif report.status == drone_report.drone_status.DroneStatus.HALTED and not self.landed_at_waypoint:

self.landed_at_waypoint = True
Copy link
Contributor

Choose a reason for hiding this comment

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

we're not actually landing at the waypoint here, just stopped, let's rename this to be more descriptive

min_landing_distance = 10000000
Copy link
Contributor

Choose a reason for hiding this comment

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

let's try to not use arbitrary values or magic numbers - set this to infinity instead with min_landing_distance = float('inf')

for landing_pad in landing_pad_locations:
distance_to_lp = self.getL2Norm(landing_pad, report.position)
if distance_to_lp < min_landing_distance:
self.landing_pad_cache = landing_pad
min_landing_distance = distance_to_lp

location_delta_x = self.landing_pad_cache.location_x - report.position.location_x
location_delta_y = self.landing_pad_cache.location_y - report.position.location_y
self.commands.append(commands.Command.create_set_relative_destination_command(location_delta_x, location_delta_y))
command = self.commands[self.command_index]

self.command_index += 1

elif report.status == drone_report.drone_status.DroneStatus.HALTED and not self.has_sent_landing_command:
self.has_sent_landing_command = True
command = commands.Command.create_land_command()
Comment on lines +80 to +103
Copy link
Contributor

Choose a reason for hiding this comment

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

let's use the acceptance radius here too - we don't want to land if the drone is too far from the waypoint


# ============
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
Expand Down
23 changes: 13 additions & 10 deletions modules/bootcamp/detect_landing_pad.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,32 +86,35 @@ def run(self, image: np.ndarray) -> "tuple[list[bounding_box.BoundingBox], np.nd
# * conf
# * device
# * verbose
predictions = ...
predictions = self.__model.predict(source=image, conf=0.7, show_conf=True)
Copy link
Contributor

Choose a reason for hiding this comment

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

Take a look at the parameters of interest above - we want to set the source, conf, device, and verbose (but not the show_conf)


# 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.orig_img
Copy link
Contributor

Choose a reason for hiding this comment

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

We're looking for the annotated image (with the confidence threshold), not the original image


# 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, ...):
for i in range(0, boxes_cpu.shape[0]):
# Create BoundingBox object and append to list
# result, box = ...
Comment on lines 108 to -111
Copy link
Contributor

Choose a reason for hiding this comment

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

let's remove this commented out code since we're not using it (the if statement and result, box =) we can go back for it in the git history if we ever need it


# Remove this when done
raise NotImplementedError
result, box = bounding_box.BoundingBox.create(boxes_cpu[i])

if not result:
return ([], image_annotated)
Copy link
Contributor

Choose a reason for hiding this comment

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

let's remove unnecessary brackets, return [], image annotated will work here


bounding_boxes.append(box)
return bounding_boxes, image_annotated

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