Skip to content
This repository was archived by the owner on Sep 21, 2025. It is now read-only.

Conversation

@steadyfall
Copy link

I have completed all the 4 given tasks and have created a PR, as per the bootcamp docs

# Plot the annotated image from the Result object
# Include the confidence value
image_annotated = ...
image_annotated = prediction.plot(pil=True, 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.

The expected image is a numpy ndarray, not a PIL object.

Copy link
Author

Choose a reason for hiding this comment

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

According to the Ultralytics documentation, setting img = True would return numpy.ndarray type, but that was not the case.

When I tried running pytest with pil=True, conf=True, all 3 tests passed, whereas running pytest with img=True, conf=True failed all 3 tests.

The error message was the following: AttributeError: 'bool' object has no attribute 'data'.

I do not know whether this is a bug or something else.

Copy link
Contributor

@Xierumeng Xierumeng Sep 20, 2023

Choose a reason for hiding this comment

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

The img parameter's type itself is expected to be np.ndarray . This is so that you can pass in an existing image that Ultralytics will draw over, but this bootcamp does not use it.

If you leave pil=True , what is image_annotated object? Do the test output images look fine?

# move the copy into CPU space,
# and convert to a numpy array
boxes_cpu = ...
boxes_cpu = prediction.boxes.cpu().xyxy.numpy()
Copy link
Contributor

Choose a reason for hiding this comment

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

Use boxes_xyxy . Also detach before moving to the CPU.

Copy link
Author

Choose a reason for hiding this comment

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

What do you mean by "detach"?

Copy link
Contributor

Choose a reason for hiding this comment

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

Pytorch tensors have a detach() method, use that.

Comment on lines +115 to +116
if result:
bounding_boxes.append(box)
Copy link
Contributor

Choose a reason for hiding this comment

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

In statistics, it is preferred to remove the whole data point if there is an issue (here, the data point is an image). (You do not need to change anything here, just something to think about).

Copy link
Author

Choose a reason for hiding this comment

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

Does that mean removing the entire list of bounding boxes if even one bounding box has an issue?

Copy link
Contributor

@Xierumeng Xierumeng Sep 20, 2023

Choose a reason for hiding this comment

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

Correct, an empty list would be returned instead (the entire image is skipped). But you don't need to change anything.


# Add your own
self.action_dict = dict(zip(("MOVE", "HALT", "LAND"), range(3,6)))
self.origin = location.Location(0,0)
Copy link
Contributor

Choose a reason for hiding this comment

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

What if the drone didn't start at (0,0) , but could start anywhere?

Copy link
Author

Choose a reason for hiding this comment

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

Then, in that case, wouldn't we need to keep track of the initial position of the drone?

Copy link
Contributor

Choose a reason for hiding this comment

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

Yes. Alternatively, don't use the initial position of the drone.

Comment on lines 95 to 97
landing_pad_distances = list(map(lambda loc: shortest_distance(loc, given_location), landing_pad_locations))
landing_pad_hashmap = dict(zip(landing_pad_locations, landing_pad_distances))
landing_pad_hashmap = tuple(sorted(list(landing_pad_hashmap.items()), key=lambda i: i[1]))
Copy link
Contributor

Choose a reason for hiding this comment

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

This is very convoluted and creates many new objects that will need to be destroyed. Is there a more space efficient way?

Also, sorting is not very efficient. It's possible to get the minimum without sorting the list of landing pad locations.

Copy link
Author

Choose a reason for hiding this comment

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

Fixed this with initializing closest_location variable with first location in the list and doing a for loop for the rest of the list to replace the closer location with closest_location in steadyfall@f42441a.

x_2, y_2 = target_location.location_x, target_location.location_y
x_square = (x_2 - x_1) ** 2
y_square = (y_2 - y_1) ** 2
return (x_square + y_square) ** 0.5
Copy link
Contributor

Choose a reason for hiding this comment

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

Square roots are computationally expensive. Is there another way? (You do not need to change anything here, just something to think about.

Copy link
Author

Choose a reason for hiding this comment

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

I do not square root the number and only square root it when required?

Copy link
Contributor

Choose a reason for hiding this comment

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

That just procrastinating the work, it doesn't eliminate it. What would happen if there was no square root?

Comment on lines 148 to 153
if (self.check_if_near_target(landing_pad, report_position)
and (shortest_distance(self.waypoint, report_position) - shortest_distance(self.waypoint, landing_pad) < 0.1)
and (
(self.check_if_near_target(landing_pad, self.origin) and self.check_if_near_target(self.waypoint, self.origin))
or (not self.check_if_near_target(report_position, self.origin))
)):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is also a bit complex. What about checking whether the drone has already arrived at the waypoint (e.g. storing some state)?

Copy link
Author

Choose a reason for hiding this comment

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

This is also a bit complex. What about checking whether the drone has already arrived at the waypoint (e.g. storing some state)?

I had tried doing that, but since this method runs in an infinite loop, any data that I try to store goes away.

Copy link
Contributor

@Xierumeng Xierumeng Sep 20, 2023

Choose a reason for hiding this comment

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

Declare variables (e.g. self.variable_name ) in __init__() and use those (e.g. a = self.variable_name , self.variable_name = 5 ). Declare as few or as many as you need.

Those are instance/object variables and will persist with the lifetime of the object.

Returns the relative x and y coordinates for drone to be sent to.
"""
relative_x, relative_y = self.distance_between_waypoint(given_location)
return (relative_x, relative_y)
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove unneeded parantheses.

# ============

# Add your own
self.action_dict = dict(zip(("MOVE", "HALT", "LAND"), range(3,6)))
Copy link
Contributor

Choose a reason for hiding this comment

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

Can use enum instead.

Comment on lines +108 to +109
if action is None:
pass
Copy link
Contributor

Choose a reason for hiding this comment

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

Redundant, remove.

# ============

@staticmethod
def shortest_distance(target_location:location.Location, given_location:location.Location) -> float:
Copy link
Contributor

Choose a reason for hiding this comment

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

Good use of static method!

y_square = (y_2 - y_1) ** 2
return (x_square + y_square) ** 0.5

def relative_coordinates_of_target(self, target_location:location.Location, given_location:location.Location) -> "tuple[float, float]":
Copy link
Contributor

Choose a reason for hiding this comment

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

This can also be static.

"""
relative_location_x = target_location.location_x - given_location.location_x
relative_location_y = target_location.location_y - given_location.location_y
return (relative_location_x, relative_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.

Remove unneeded parantheses.

Returns the relative x and y coordinates for drone to be sent to.
"""
relative_x, relative_y = self.relative_coordinates_of_target(target_location, given_location)
divider = 1
Copy link
Contributor

Choose a reason for hiding this comment

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

Remove this since it doesn't do anything.

"""
Finds out the closest landing pad from the given location by checking out their distances.
"""
closest_location = landing_pad_locations[0]
Copy link
Contributor

Choose a reason for hiding this comment

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

What if there were no landing pads? (You do not need to change anything, just something to think about).

Comment on lines +99 to +100
distance_from_given_location = DecisionWaypointLandingPads.shortest_distance(landing_pad, given_location)
distance_from_closest_location = DecisionWaypointLandingPads.shortest_distance(closest_location, given_location)
Copy link
Contributor

Choose a reason for hiding this comment

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

Calculating the distance repeatedly for the closest landing pad is wasteful, is there a way to avoid this?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants