Skip to content

Pytest validation #3123

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

Open
wants to merge 81 commits into
base: master
Choose a base branch
from
Open

Conversation

suchirss
Copy link
Contributor

Please fill out the following before requesting review on this PR

Description

This PR addresses issue #2809. kickoff_play_test.py has been written to test the following rules for kickoff:

  1. During friendly kickoff, a maximum of one friendly robot is within the center circle and the remaining friendly robots are within the friendly half.
  2. After friendly kickoff is initiated, the ball leaves its starting point by a distance of at least 0.05m within 15 seconds.
  3. During enemy kickoff, all friendly robots are in the friendly half and none are in the center circle.

kickoff_play_test.py uses NumberOfRobotsAlwaysStaysInRegion() in the always validation sequence set and BallEventuallyExitsRegion() in the eventually validation sequence set to verify the above rules.

robot_enters_regions.py was modified so that NumberOfRobotsAlwaysStaysInRegion() is able to accept multiple regions as parameters.

or_validation.py was created to implement OR logic when running a group of tests - this is used in kickoff_play_test.py to check that either 0 or 1 robots are in centerCircle.

This test discovered that our AI currently violates kickoff rule #3 outlined above - a friendly robot enters the enemy half during enemyKickoff. As such, issue #3119 was created.

Testing Done

./tbots.py test //software/ai/hl/stp/play:kickoff_play_test -t was used to visualize the kickoff_play_test on Thunderscope. All three tests can be seen in this GIF:
3DEnemyKickoffPlay_fail

Resolved Issues

resolves #2809

Length Justification and Key Files to Review

Review Checklist

It is the reviewers responsibility to also make sure every item here has been covered

  • Function & Class comments: All function definitions (usually in the .h file) should have a javadoc style comment at the start of them. For examples, see the functions defined in thunderbots/software/geom. Similarly, all classes should have an associated Javadoc comment explaining the purpose of the class.
  • Remove all commented out code
  • Remove extra print statements: for example, those just used for testing
  • Resolve all TODO's: All TODO (or similar) statements should either be completed or associated with a github issue

PhilD71 and others added 30 commits June 2, 2022 19:14
Fixes that need to be made in future commits:
- build errors across several validation testing files
- unnecessary comments need to be erased
Bugs:
- several validation files don't build
…o not enter a region. Incomplete process but committing prior to laptop dying.
@github-actions github-actions bot added the Stale Inactive pull requests label Jan 6, 2025
@suchirss suchirss removed the Stale Inactive pull requests label Jan 11, 2025
suchirss and others added 5 commits January 10, 2025 22:08
…est-validation.

Also ran formatting script.

# Conflicts:
#	src/software/simulated_tests/BUILD
#	src/software/simulated_tests/ball_enters_region.py
#	src/software/simulated_tests/or_validation.py
#	src/software/simulated_tests/robot_enters_region.py
…pe. Ex: ALWAYS validation and EVENTUALLY validation can both be passed to or_validation.
…pe. Ex: ALWAYS validation and EVENTUALLY validation can both be passed to or_validation.
if validation_type != validation_type_initial:
raise TypeError("type of validation instances is not consistent")
return validation_type_initial
return ValidationType
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
return ValidationType
return self.validations[0].get_validation_type(world)

Copy link
Contributor

Choose a reason for hiding this comment

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

bump

if validation_type != validation_type_initial:
raise TypeError("type of validation instances is not consistent")
return validation_type_initial
return ValidationType
Copy link
Contributor

Choose a reason for hiding this comment

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

I think the constructor should check that the validation types are consistent

def __init__(self, validations):
        """An OR extension to the validation function"""
        assert len(validations) > 0
        validation_type_initial = validations[0].get_validation_type()
        for validation in validations:
            validation_type = validation.get_validation_type()
            if validation_type != validation_type_initial:
                raise TypeError("Type of validation instances is not consistent")
        self.validations = validations

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why do validation types put into the function need to be consistent?

If we wanted to check if either an always validation or eventually validation are passing, then the OrValidation class would not be able to support this (provided that this check is kept).

Copy link
Contributor

Choose a reason for hiding this comment

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

Our underlying validation code doesn't support mixing eventually and always validations:

def run_validation_sequence_sets(
. So, if we try to do something like that, we should warn the programmer that it probably won't work



@pytest.mark.parametrize("is_friendly_test", [True, False])
# TODO 3119 Fix KickoffEnemyPlay
Copy link
Contributor

Choose a reason for hiding this comment

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

this TODO has been fixed, you can delete it

Copy link
Contributor

@itsarune itsarune left a comment

Choose a reason for hiding this comment

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

looking good! some minor stuff

@suchirss suchirss self-assigned this Feb 15, 2025
…ots are in friendlyHalf + centerCircle is now within the if is_friendly_test and else blocks.

Added BallAlwaysMoveFromRest() validation to OrValidation() with NumberOfRobotsAlwaysStaysInRegion() so that once the ball moves, the test still passes if the robots enters regions that would have previously made the test fail.

Added debugging statements to ball_moves_from_rest and or_validation. Pending removal.
@suchirss
Copy link
Contributor Author

Note: pushed PR right now to allow others to debug. Not yet ready for review to merge PR.

Copy link
Contributor

github-actions bot commented Apr 1, 2025

This PR is stale because it has been open for 30 days with no activity. Remove stale label or comment or this will be closed in 5 days.

@github-actions github-actions bot added the Stale Inactive pull requests label Apr 1, 2025
Copy link
Contributor

github-actions bot commented Apr 7, 2025

This PR was closed because it has been stalled for 5 days with no activity.

@github-actions github-actions bot closed this Apr 7, 2025
@itsarune itsarune reopened this Apr 10, 2025
@itsarune itsarune removed the Stale Inactive pull requests label Apr 10, 2025
req_robot_cnt=6,
),
]
)
)
Copy link
Contributor

Choose a reason for hiding this comment

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

you could reduce the duplication in this code a bit:

ball_moves_at_rest_validation = BallAlwaysMovesFromRest(
    position=tbots_cpp.Point(0, 0),
    threshold=0.01
)

expected_centre_circle_or_validations_set = [
    ball_moves_at_rest_validation,
    NumberOfRobotAlwaysStaysInRegion(
        regions = [
            tbots_cpp.Field.createSSLDivisionBField().centerCircle()
        ],
        req_robot_cnt = 0
    )
]

friendly_regions = [tbots_cpp.Field.createSSLDivisionBField().friendlyHalf()]

if friendly_test:
    expected_centre_circle_or_validations_set.append(
        NumberOfRobotsAlwaysStaysInRegion(
            regions=[
                tbots_cpp.Field.createSSLDivisionBField().centerCircle()
            ],
            req_robot_cnt = 1
        )
    )
else:
   friendly_regions.append(tbots_cpp.Field.createSSLDivisionBField().centerCircle())

expected_robot_regions_or_validations_set = [
    ball_moves_at_rest_validation,
    NumberOfRobotAlwaysStaysInRegion(
       regions=friendly_regions,
       req_robot_cnt=6
    )
]

always_validation_sequence_set[0] = [
    OrValidation(expected_centre_circle_or_validations_set)),
    OrValidation(expected_robot_regions_or_validations_set)
]

OrValidation(
[
BallAlwaysMovesFromRest(
position=tbots_cpp.Point(0, 0), threshold=0.01
Copy link
Contributor

Choose a reason for hiding this comment

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

OrValidation(
[
BallAlwaysMovesFromRest(
position=tbots_cpp.Point(0, 0), threshold=0.01
Copy link
Contributor

Choose a reason for hiding this comment

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

OrValidation(
[
BallAlwaysMovesFromRest(
position=tbots_cpp.Point(0, 0), threshold=0.01
Copy link
Contributor

Choose a reason for hiding this comment

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

Copy link
Contributor

@itsarune itsarune left a comment

Choose a reason for hiding this comment

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

nice work! looks like you got the test to pass (I ran it locally)

I suggest cleaning up some of the logic tho

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.

Validation for Kickoff Test Play
7 participants