Skip to content

Commit ca938be

Browse files
committed
Tasks 1 to 4
1 parent 96bc51a commit ca938be

File tree

4 files changed

+93
-12
lines changed

4 files changed

+93
-12
lines changed

modules/bootcamp/decision_simple_waypoint.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,20 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non
4343
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
4444
# ============
4545

46+
def dist_sq(self, location1: location.Location, location2: location.Location) -> float:
47+
"""
48+
Calculates the squared Euclidean distance between two locations.
49+
"""
50+
return (location1.location_x - location2.location_x) ** 2 + (
51+
location1.location_y - location2.location_y
52+
) ** 2
53+
54+
def clamp(self, val: float, min_val: float, max_val: float) -> float:
55+
"""
56+
Clamps a value between a lower and upper bound.
57+
"""
58+
return min(max_val, max(min_val, val))
59+
4660
def run(
4761
self, report: drone_report.DroneReport, landing_pad_locations: "list[location.Location]"
4862
) -> commands.Command:
@@ -67,9 +81,16 @@ def run(
6781
# ============
6882
# ↓ BOOTCAMPERS MODIFY BELOW THIS COMMENT ↓
6983
# ============
84+
if report.status == drone_status.DroneStatus.HALTED:
85+
dist_waypoint_sq = self.dist_sq(self.waypoint, report.position)
86+
if dist_waypoint_sq < self.acceptance_radius**2:
87+
command = commands.Command.create_land_command()
88+
else:
89+
rel_x = self.clamp(self.waypoint.location_x - report.position.location_x, -60, 60)
90+
rel_y = self.clamp(self.waypoint.location_y - report.position.location_y, -60, 60)
91+
command = commands.Command.create_set_relative_destination_command(rel_x, rel_y)
7092

7193
# Do something based on the report and the state of this class...
72-
7394
# ============
7495
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
7596
# ============

modules/bootcamp/decision_waypoint_landing_pads.py

Lines changed: 55 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
Travel to designated waypoint and then land at a nearby landing pad.
55
"""
66

7+
import math
78
from .. import commands
89
from .. import drone_report
910

@@ -13,7 +14,6 @@
1314
from .. import location
1415
from ..private.decision import base_decision
1516

16-
1717
# Disable for bootcamp use
1818
# No enable
1919
# pylint: disable=duplicate-code,unused-argument
@@ -38,11 +38,26 @@ def __init__(self, waypoint: location.Location, acceptance_radius: float) -> Non
3838
# ============
3939

4040
# Add your own
41-
41+
self.waypoint_reached = False
42+
self.closest_landing_location = None
4243
# ============
4344
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
4445
# ============
4546

47+
def dist_sq(self, location1: location.Location, location2: location.Location) -> float:
48+
"""
49+
Calculates the squared Euclidean distance between two locations.
50+
"""
51+
return (location1.location_x - location2.location_x) ** 2 + (
52+
location1.location_y - location2.location_y
53+
) ** 2
54+
55+
def clamp(self, val: float, min_val: float, max_val: float) -> float:
56+
"""
57+
Clamps a value between a lower and upper bound.
58+
"""
59+
return min(max_val, max(min_val, val))
60+
4661
def run(
4762
self, report: drone_report.DroneReport, landing_pad_locations: "list[location.Location]"
4863
) -> commands.Command:
@@ -69,6 +84,44 @@ def run(
6984
# ============
7085

7186
# Do something based on the report and the state of this class...
87+
if not self.waypoint_reached:
88+
if report.status == drone_status.DroneStatus.HALTED:
89+
dist_waypoint_sq = self.dist_sq(self.waypoint, report.position)
90+
if dist_waypoint_sq < self.acceptance_radius**2:
91+
self.waypoint_reached = True
92+
else:
93+
rel_x = self.clamp(
94+
self.waypoint.location_x - report.position.location_x, -60, 60
95+
)
96+
rel_y = self.clamp(
97+
self.waypoint.location_y - report.position.location_y, -60, 60
98+
)
99+
command = commands.Command.create_set_relative_destination_command(rel_x, rel_y)
100+
else:
101+
if self.closest_landing_location is None:
102+
min_dist_sq = math.inf
103+
for landing_pad_location in landing_pad_locations:
104+
current_dist_sq = self.dist_sq(report.position, landing_pad_location)
105+
if current_dist_sq < min_dist_sq:
106+
min_dist_sq = current_dist_sq
107+
self.closest_landing_location = landing_pad_location
108+
109+
if report.status == drone_status.DroneStatus.HALTED:
110+
dist_location_sq = self.dist_sq(self.closest_landing_location, report.position)
111+
if dist_location_sq < self.acceptance_radius**2:
112+
command = commands.Command.create_land_command()
113+
else:
114+
rel_x = self.clamp(
115+
self.closest_landing_location.location_x - report.position.location_x,
116+
-60,
117+
60,
118+
)
119+
rel_y = self.clamp(
120+
self.closest_landing_location.location_y - report.position.location_y,
121+
-60,
122+
60,
123+
)
124+
command = commands.Command.create_set_relative_destination_command(rel_x, rel_y)
72125

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

modules/bootcamp/detect_landing_pad.py

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -98,31 +98,38 @@ def run(self, image: np.ndarray) -> "tuple[list[bounding_box.BoundingBox], np.nd
9898
# * conf
9999
# * device
100100
# * verbose
101-
predictions = ...
102-
101+
predictions = self.__model.predict(
102+
source=image, conf=0.7, device=self.__DEVICE, verbose=True
103+
)
103104
# Get the Result object
104-
prediction = ...
105+
prediction = predictions[0]
105106

106107
# Plot the annotated image from the Result object
107108
# Include the confidence value
108-
image_annotated = ...
109+
image_annotated = prediction.plot(conf=True)
109110

110111
# Get the xyxy boxes list from the Boxes object in the Result object
111-
boxes_xyxy = ...
112+
boxes_xyxy = prediction.boxes.xyxy
112113

113114
# Detach the xyxy boxes to make a copy,
114115
# move the copy into CPU space,
115116
# and convert to a numpy array
116-
boxes_cpu = ...
117+
boxes_cpu = boxes_xyxy.detach().cpu().numpy()
117118

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

125-
return [], image_annotated
125+
for i in range(boxes_cpu.shape[0]):
126+
result, box = bounding_box.BoundingBox.create(boxes_cpu[i])
127+
if not result:
128+
bounding_boxes.clear()
129+
break
130+
bounding_boxes.append(box)
131+
132+
return bounding_boxes, image_annotated
126133
# ============
127134
# ↑ BOOTCAMPERS MODIFY ABOVE THIS COMMENT ↑
128135
# ============

modules/bootcamp/tests/run_decision_example.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
# to reach the 1st command
2222
# Increase the step size if your computer is lagging
2323
# Larger step size is smaller FPS
24-
TIME_STEP_SIZE = 0.1 # seconds
24+
TIME_STEP_SIZE = 0.05 # seconds
2525

2626
# OpenCV ignores your display settings,
2727
# so if the window is too small or too large,

0 commit comments

Comments
 (0)