Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Decision module #163

Merged
merged 24 commits into from
Feb 10, 2024
Merged

Decision module #163

merged 24 commits into from
Feb 10, 2024

Conversation

jivankesan
Copy link
Contributor

No description provided.

Comment on lines 38 to 43
max_distance = (
max(distances) or 1
) # Avoid division by zero if all distances are zero
max_variance = (
max(variances) or 1
) # Avoid division by zero if all variances are zero
Copy link
Contributor

Choose a reason for hiding this comment

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

We probably don't want to set the max distance or variance to 1 if they're all 0. 1 is the maximum possible variance, but not the maximum possible distance (or the minimum possible distance), so this could cause a logic issue.
If all variances are 0, we should return no landing pads, if all distances are 0, that means we're on top of a landing pad and should land.


def run(
self,
states: odometry_and_time.OdometryAndTime,
Copy link
Contributor

Choose a reason for hiding this comment

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

Change the naming to be more descriptive, it's the current state (not multiple states), so maybe current_state?

Comment on lines 72 to 73
if distance_to_best_bad <= self.__distance_tolerance:
# Issue a landing command if within tolerance
Copy link
Contributor

Choose a reason for hiding this comment

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

Put the comment before the if statement

Comment on lines 82 to 83
else:
# Move to best location if not within tolerance
Copy link
Contributor

Choose a reason for hiding this comment

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

Same as above

),
)
else:
# Default to hover if no pad is found
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 returning a hover command, so change the comment to say something more like "Default to do nothing if no pad is found"

Comment on lines 1 to 2
import pytest
from modules.decision import decision
Copy link
Contributor

Choose a reason for hiding this comment

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

2 lines between system module imports and local module imports. Also add a docstring to the file

modules/decision/decision.py Show resolved Hide resolved
Comment on lines 7 to 8

# Test parameters
Copy link
Contributor

Choose a reason for hiding this comment

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

2 lines between imports and constant declarations (put the comment on the same line as the constant)

dy = pad.position_y - current_position.odometry_data.position.east
return (dx**2 + dy**2) ** 0.5

def weight_pads(
Copy link
Contributor

Choose a reason for hiding this comment

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

make this a private function

Copy link
Contributor

@TongguangZhang TongguangZhang left a comment

Choose a reason for hiding this comment

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

mostly formatting things, but you should test the distance to pad and weight pad functions, not just the run function.

Comment on lines 21 to 24
def distance_to_pad(
pad: object_in_world.ObjectInWorld,
current_position: odometry_and_time.OdometryAndTime,
):
Copy link
Contributor

Choose a reason for hiding this comment

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

format functions declarations like this

def func(arg1 :int,
               arg2 :string) -> float:
    pass

Comment on lines 32 to 36
def __weight_pads(
self,
pads: "list[object_in_world.ObjectInWorld]",
current_position: odometry_and_time.OdometryAndTime,
):
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

Comment on lines 74 to 78
def run(
self,
curr_state: odometry_and_time.OdometryAndTime,
pads: "list[object_in_world.ObjectInWorld]",
):
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

position_x, position_y, spherical_variance
)
assert success
return pad
Copy link
Contributor

Choose a reason for hiding this comment

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

use yield in a pytest fixture

position_x, position_y, spherical_variance
)
assert success
return pad
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

Comment on lines 101 to 103
def test_decision_within_tolerance(
self, decision_maker, best_pad_within_tolerance, pads, states
):
Copy link
Contributor

Choose a reason for hiding this comment

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

same as function formatting comment above, but you don't need a type annotation for the return type

Comment on lines 116 to 118
def test_decision_outside_tolerance(
self, decision_maker, best_pad_outside_tolerance, pads, states
):
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

res, command = decision_maker.run(states, [])

assert res == False
assert command is None # when no pads found
Copy link
Contributor

Choose a reason for hiding this comment

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

single empty line at end of file

)
# Default to do nothing if no pads are found
else:
return False, None
Copy link
Contributor

Choose a reason for hiding this comment

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

single empty line at end of file

Comment on lines 107 to 114
total_pads = [best_pad_within_tolerance] + pads
res, command = decision_maker.run(states, total_pads)

assert res
assert (
command.get_command_type()
== decision_command.DecisionCommand.CommandType.LAND_AT_ABSOLUTE_POSITION
)
Copy link
Contributor

Choose a reason for hiding this comment

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

Place right side values into variables. Format of all tests should be:

Setup: Sets up objects to be tested and expected values (and assert the result)
Run: Run the method/function and get the actual value.
Test: Assert actual == expected.

Have spaces between each of the 3 sections, name the variables actual and expected.

Copy link
Collaborator

@Xierumeng Xierumeng left a comment

Choose a reason for hiding this comment

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

Reviewed.

modules/decision/decision.py Outdated Show resolved Hide resolved
modules/decision/decision.py Outdated Show resolved Hide resolved
modules/decision/decision.py Outdated Show resolved Hide resolved
modules/decision/decision.py Outdated Show resolved Hide resolved
modules/decision/decision.py Outdated Show resolved Hide resolved
tests/test_decision.py Outdated Show resolved Hide resolved
tests/test_decision.py Outdated Show resolved Hide resolved
tests/test_decision.py Outdated Show resolved Hide resolved
tests/test_decision.py Outdated Show resolved Hide resolved
Create a mock OdometryAndTime instance with the drone positioned within tolerance of the landing pad.
"""
# Creating the position within tolerance of the specified landing pad.
position = drone_odometry_local.DronePositionLocal.create(9.0, 19.0, -5.0)[
Copy link
Collaborator

Choose a reason for hiding this comment

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

The construction pattern used for testing is as follows:

result, name_of_data = namespace.ClassName.create(...)
assert result
assert name_of_data is not None

# Use name_of_data somewhere...

Comment on lines 75 to 76
1
] # Example altitude of -5 meters
Copy link
Contributor

Choose a reason for hiding this comment

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

if this fits on the line you don't need to make it multiline

Comment on lines 78 to 80
orientation = drone_odometry_local.DroneOrientationLocal.create_new(0.0, 0.0, 0.0)[
1
]
Copy link
Contributor

Choose a reason for hiding this comment

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

same as above

modules/decision/decision.py Show resolved Hide resolved
Copy link
Contributor

@TongguangZhang TongguangZhang left a comment

Choose a reason for hiding this comment

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

LGTM!

@jivankesan jivankesan merged commit 3003423 into main Feb 10, 2024
1 check passed
@jivankesan jivankesan deleted the decision_module branch February 10, 2024 23:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants