-
Notifications
You must be signed in to change notification settings - Fork 123
OffensePlayTest checking that there is Never Excessive Dribbling #3536
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
Changes from all commits
ec7010a
b690a45
c339388
a4f6bc0
544bc55
d928b5d
a3929cf
32cc42d
5b0b98c
2fb03f8
dff8853
8336df9
8d1354f
75141c3
2d235e3
ed1102e
e3afcc5
7edc073
87eb7b9
20f5cfd
e9d2ff6
0e8e809
fd5ceec
da98427
0916bcb
82532bd
7e46bdf
6d9a363
9812bc1
871d210
9022e22
8a2bf29
22ec418
57e14e9
1d98837
14ef1b0
5e15f1a
c0632cd
d36bd78
3edb21c
6cef848
41344a3
417a094
6e3cb23
212b4db
7a55bf4
e77077e
53ed48b
8b1620a
d802f94
25abf85
6016eb2
5f6b5f9
183708e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,184 @@ | ||
| import pytest | ||
|
|
||
| import software.python_bindings as tbots_cpp | ||
| from software.simulated_tests.excessive_dribbling import ( | ||
| NeverExcessivelyDribbles, | ||
| EventuallyStartsExcessivelyDribbling, | ||
| ) | ||
| from proto.message_translation.tbots_protobuf import ( | ||
| WorldState, | ||
| AssignedTacticPlayControlParams, | ||
| DribbleTactic, | ||
| ) | ||
| from software.simulated_tests.simulated_test_fixture import ( | ||
| pytest_main, | ||
| ) | ||
| from proto.message_translation.tbots_protobuf import create_world_state | ||
|
|
||
|
|
||
| @pytest.mark.parametrize( | ||
| "initial_location,dribble_destination,final_dribble_orientation, should_excessively_dribble, blue_robot_location", | ||
| [ | ||
| # The following tests check that DribbleTactic does not false trigger for distances within regulations | ||
| # Dribble Destination for the ball < 1.0 from its starting position | ||
| ( | ||
| tbots_cpp.Point(0.5, 0), | ||
| tbots_cpp.Point(1.02, 0), | ||
| tbots_cpp.Angle(), | ||
| False, | ||
| tbots_cpp.Point(0, 1), | ||
| ), | ||
| # Dribble Testing diagonally | ||
| ( | ||
| tbots_cpp.Point(0.25, 0.25), | ||
| tbots_cpp.Point(0.80, 0.50), | ||
| tbots_cpp.Angle.fromRadians(50), | ||
| False, | ||
| tbots_cpp.Point(0, 1), | ||
| ), | ||
| # Boundary Testing, because of the autoref implementation (initial of position Bot to final of Ball), | ||
| # a conservative max dribble distance (0.95 m) is used | ||
| # Test vertical dribbling | ||
| ( | ||
| tbots_cpp.Point(0.01, 0), | ||
| tbots_cpp.Point(0.96, 0), | ||
| tbots_cpp.Angle(), | ||
| False, | ||
| tbots_cpp.Point(0, 1), | ||
| ), | ||
| # Test horizontal dribbling | ||
| ( | ||
| tbots_cpp.Point(1, 1.5), | ||
| tbots_cpp.Point(1.95, 1.5), | ||
| tbots_cpp.Angle(), | ||
| False, | ||
| tbots_cpp.Point(0, 1), | ||
| ), | ||
| # Test bot and ball in same position | ||
| ( | ||
| tbots_cpp.Point(0, 1), | ||
| tbots_cpp.Point(0.95, 1), | ||
| tbots_cpp.Angle(), | ||
| False, | ||
| tbots_cpp.Point(0, 1), | ||
| ), | ||
| # The following tests check that DribbleTactic correctly triggers for distances outside regulation | ||
| # Dribble Destination for the ball > 1.0 from its starting position | ||
| ( | ||
| tbots_cpp.Point(0, 2), | ||
| tbots_cpp.Point(0, 0.5), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| # Dribble Testing diagonally | ||
| ( | ||
| tbots_cpp.Point(0.1, 1.1), | ||
| tbots_cpp.Point(1.1, 0.1), | ||
| tbots_cpp.Angle.fromRadians(50), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| # Boundary Testing, due to the conservative implementation a dribble distance of 1 m should fail | ||
| # Test Vertical Dribbling | ||
| ( | ||
| tbots_cpp.Point(0, 1), | ||
| tbots_cpp.Point(0, 2), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| # Test Horizontal Dribbling | ||
| ( | ||
| tbots_cpp.Point(1, 2), | ||
| tbots_cpp.Point(0, 2), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| # Test Diagonal Dribbling | ||
| ( | ||
| tbots_cpp.Point(0, 1), | ||
| tbots_cpp.Point(0.6, 1.8), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| # Test robot and ball at same position (affects dribbling orientation and therefore perceived dribble distance) | ||
| ( | ||
| tbots_cpp.Point(0, 0), | ||
| tbots_cpp.Point(0, 1), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| ( | ||
| tbots_cpp.Point(0.0, 0.01), | ||
| tbots_cpp.Point(0.81, 0.61), | ||
| tbots_cpp.Angle(), | ||
| True, | ||
| tbots_cpp.Point(0, 0), | ||
| ), | ||
| ], | ||
| ) | ||
| def test_excessive_dribbling( | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not quite sure what the reasoning was for this test, since the issue this PR is marked for is regarding offense play. Reading through the work here, it appears to be more akin to a
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hmm ig that makes sense. I was thinking (please correct me if I'm wrong or really misguided) but the main dribbling tactic used in offense play is DribbleTactic, and if that's the case if it works in DribbleTactic then it should work everywhere else, including in offense play. As it is easier to test (especially boundary test) DribbleTactic directly rather than test offense play, I was thinking it might be the better option.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if I fully understand Andrew's point, but imo the purpose of this test is clear and makes sense |
||
| initial_location, | ||
| dribble_destination, | ||
| final_dribble_orientation, | ||
| should_excessively_dribble, | ||
| simulated_test_runner, | ||
| blue_robot_location, | ||
| ): | ||
| if should_excessively_dribble: | ||
| # Always and Eventually validation sets for excessive dribbling | ||
| always_validation_sequence_set = [[]] | ||
| eventually_validation_sequence_set = [[EventuallyStartsExcessivelyDribbling()]] | ||
| else: | ||
| # Always and Eventually validation sets for not excessive dribbling | ||
| always_validation_sequence_set = [[NeverExcessivelyDribbles()]] | ||
| eventually_validation_sequence_set = [[]] | ||
|
|
||
| blue_robot_locations = [blue_robot_location] | ||
|
|
||
| simulated_test_runner.simulator_proto_unix_io.send_proto( | ||
| WorldState, | ||
| create_world_state( | ||
| [], | ||
| blue_robot_locations=blue_robot_locations, | ||
| ball_location=initial_location, | ||
| ball_velocity=tbots_cpp.Vector(0, 0), | ||
| ), | ||
| ) | ||
|
|
||
| # Setup Tactic | ||
| params = AssignedTacticPlayControlParams() | ||
| params.assigned_tactics[0].dribble.CopyFrom( | ||
| DribbleTactic( | ||
| dribble_destination=tbots_cpp.createPointProto(dribble_destination), | ||
| final_dribble_orientation=tbots_cpp.createAngleProto( | ||
| final_dribble_orientation | ||
| ), | ||
| allow_excessive_dribbling=True, | ||
| ) | ||
| ) | ||
|
|
||
| simulated_test_runner.blue_full_system_proto_unix_io.send_proto( | ||
| AssignedTacticPlayControlParams, params | ||
| ) | ||
|
|
||
| # Setup no tactics on the enemy side | ||
| params = AssignedTacticPlayControlParams() | ||
| simulated_test_runner.yellow_full_system_proto_unix_io.send_proto( | ||
| AssignedTacticPlayControlParams, params | ||
| ) | ||
|
|
||
| simulated_test_runner.run_test( | ||
| inv_eventually_validation_sequence_set=eventually_validation_sequence_set, | ||
| inv_always_validation_sequence_set=always_validation_sequence_set, | ||
| ag_eventually_validation_sequence_set=eventually_validation_sequence_set, | ||
| ag_always_validation_sequence_set=always_validation_sequence_set, | ||
| ) | ||
|
|
||
|
|
||
| if __name__ == "__main__": | ||
| pytest_main(__file__) | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,5 @@ | ||
| import software.python_bindings as tbots_cpp | ||
| from proto.import_all_protos import * | ||
| from proto.import_all_protos import ValidationStatus, ValidationGeometry | ||
|
|
||
| from software.simulated_tests.validation import ( | ||
| Validation, | ||
|
|
@@ -13,42 +13,61 @@ class ExcessivelyDribbling(Validation): | |
| """Checks if any friendly robot is excessively dribbling the ball, i.e. for over 1m.""" | ||
|
|
||
| def __init__(self): | ||
| self.continous_dribbling_start_point = None | ||
| self.continuous_dribbling_start_point = None | ||
| self.dribbler_tolerance = 0.05 | ||
| self.max_dribbling_displacement = 1.00 | ||
| self.dribbling_error_margin = 0.05 | ||
|
Comment on lines
+17
to
+19
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I would normally make these class constants rather than instance attributes accessed via |
||
|
|
||
| @override | ||
| def get_validation_status(self, world) -> ValidationStatus: | ||
williamckha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| """Checks if any friendly robot is excessively dribbling the ball, i.e. for over 1m. | ||
| """Checks if any friendly robot is excessively dribbling the ball past the max dribble displacement | ||
| minus the dribbling error margin | ||
|
|
||
| :param world: The world msg to validate | ||
| :return: FAILING when the robot is excessively dribbling | ||
| PASSING when the robot is not excessively dribbling | ||
| """ | ||
| ball_position = tbots_cpp.createPoint(world.ball.current_state.global_position) | ||
| for robot in world.friendly_team.team_robots: | ||
| if not tbots_cpp.Robot(robot).isNearDribbler(ball_position, 0.01): | ||
| # if ball is not near dribbler then de-activate this validation | ||
| self.continous_dribbling_start_point = None | ||
| elif ( | ||
| ball_position - (self.continous_dribbling_start_point or ball_position) | ||
| ).length() > 1.0: | ||
| return ValidationStatus.FAILING | ||
| elif self.continous_dribbling_start_point is None: | ||
| # ball is in dribbler, but previously wasn't in dribbler, so set continuous dribbling start point | ||
| self.continous_dribbling_start_point = ball_position | ||
| if tbots_cpp.Robot(robot).isNearDribbler( | ||
| ball_position, self.dribbler_tolerance | ||
| ): | ||
| if self.continuous_dribbling_start_point is None: | ||
| # Set the dribbling validation start point to the current ball position | ||
| self.continuous_dribbling_start_point = ball_position | ||
| elif ( | ||
| ball_position - self.continuous_dribbling_start_point | ||
| ).length() > ( | ||
| self.max_dribbling_displacement - self.dribbling_error_margin | ||
| ): | ||
| return ValidationStatus.FAILING | ||
| return ValidationStatus.PASSING | ||
|
|
||
| # Reset the dribbling validation start point if no robots are near the ball | ||
| self.continuous_dribbling_start_point = None | ||
| return ValidationStatus.PASSING | ||
|
|
||
| @override | ||
| def get_validation_geometry(self, world) -> ValidationGeometry: | ||
| """(override) Shows the max allowed dribbling circle""" | ||
| return create_validation_geometry( | ||
| [tbots_cpp.Circle(self.continous_dribbling_start_point, 1.0)] | ||
| if self.continous_dribbling_start_point is not None | ||
| [ | ||
| tbots_cpp.Circle( | ||
| self.continuous_dribbling_start_point, | ||
| self.max_dribbling_displacement, | ||
williamckha marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ), | ||
| tbots_cpp.Circle( | ||
| self.continuous_dribbling_start_point, | ||
| self.max_dribbling_displacement - self.dribbling_error_margin, | ||
| ), | ||
| ] | ||
| if self.continuous_dribbling_start_point is not None | ||
| else [] | ||
| ) | ||
|
|
||
| @override | ||
| def __repr__(self): | ||
| return "Check that the dribbling robot has not dribbled for more than 1m" | ||
| return f"Check that the dribbling robot has not dribbled for more than {self.max_dribbling_displacement} m minus error margin ({self.dribbling_error_margin} m)" | ||
|
|
||
|
|
||
| ( | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.