Skip to content

OffensePlayTest checking that there is Never Excessive Dribbling#3536

Open
adrianchan787 wants to merge 48 commits intoUBC-Thunderbots:masterfrom
adrianchan787:adrian/offense_play_test_dribble
Open

OffensePlayTest checking that there is Never Excessive Dribbling#3536
adrianchan787 wants to merge 48 commits intoUBC-Thunderbots:masterfrom
adrianchan787:adrian/offense_play_test_dribble

Conversation

@adrianchan787
Copy link
Contributor

@adrianchan787 adrianchan787 commented Nov 30, 2025

Description

  • Added a validation status check in offense play test that checks if the friendly team has excessively dribbled
  • Changed the validation status check (NeverExcessivelyDribbles and EventuallyStartsExcessiveDribbles) to look at the dribble_displacement field in World instead of the previous "brute force" method; this (theoretically) aligns more with the AutoRef's implementation of excessive dribbling
  • Added a testing file for the validation status check

Testing Done

- Reran all pytests that used NeverExcessivelyDribbles; some of them were flaky for unrelated reasons e.g. pass_defender_test had a robot enter region validation error first time around
- Created a testing file that tests never excessively and eventually starts dribbling, using the dribble_tactic. (since the main dribbling done in offense_play_test is in dribble_tactic). These tests typically pass but are also flaky; I'll expand more in the comments at the end.

Resolved Issues

Resolves #3452

Length Justification and Key Files to Review

Review Checklist

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

  • [x ] 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.
  • [ x] Remove all commented out code
  • [ x] Remove extra print statements: for example, those just used for testing
  • [ x] Resolve all TODO's: All TODO (or similar) statements should either be completed or associated with a github issue

Additional Comments

  • Not really an addition and more of a few observations and questions. Wanted to still make this PR since I feel like it's not directly related to my current ticket (and also because I've dragged this on for too long lol).

  • Was looking at how the Autoref implemented dribble distance, and from what I understood it seems to compare initial position of the robot to the final position of the ball (see the code snippet below, taken from https://github.com/TIGERs-Mannheim/AutoReferee/tree/53063578e38ac4818849df3196b32a856a5fa41d). If I'm mistaken, please tell me and I'll edit the comments in my branch lol

Screenshot from 2025-11-30 03-23-07
  • However, because they use robot to ball and not e.g. ball to ball, the dribble displacement field is extremely inconsistent. For example, in my tests, if you start the robot in the same location as the ball, you get a different dribble displacement than if you started the robot a meter way. (which I think makes sense? since the orientation with which you start dribbling will probably be different).
  • Similarly, that's why the maximum distance between the initial point location of the ball and its location after dribbling is greater than 1 m. From tests I got up to 1.03 m. However, this maximum limit was pretty flaky for me, and fluctuated between 1.03 and 1.01 m. (which is why there's a decent chance my code won't pass my own tests).
  • So I was wondering if this is an issue? On one hand, (I think?) if this mirrors the Autoref's behaviour, it doesn't matter how inconsistent it is. On the other, I know William said the 1 meter max dribbling was a pretty strict limit, so would it be worthwhile to be conservative and use like 0.98 max distance in testing and tactics?

Sorry if that was a bit unclear, please let me know if it was. Thanks!

@adrianchan787
Copy link
Contributor Author

(oops really sorry not sure if i was supposed to resolve the merge conflict)

@adrianchan787 adrianchan787 marked this pull request as draft November 30, 2025 22:10
@adrianchan787 adrianchan787 marked this pull request as ready for review November 30, 2025 23:01
Copy link
Member

@nycrat nycrat left a comment

Choose a reason for hiding this comment

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

Added some comments, just some refactoring changes recommended but the new implementation of excessive_dribbing validation seems good and the test are thorough

nycrat
nycrat previously approved these changes Jan 31, 2026
Copy link
Member

@nycrat nycrat left a comment

Choose a reason for hiding this comment

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

LGTM

@nycrat
Copy link
Member

nycrat commented Feb 4, 2026

Hey @adrianchan787 could you pull from master so that the ci passes?

@adrianchan787
Copy link
Contributor Author

Hey @adrianchan787 could you pull from master so that the ci passes?

really sorry that it took this long, should be good now

@adrianchan787
Copy link
Contributor Author

adrianchan787 commented Feb 7, 2026

Hey @adrianchan787 could you pull from master so that the ci passes?

really sorry that it took this long, should be good now

Wow I have messed this up horribly one sec (ok i am so incredibly sorry for this cursed git log)

Copy link
Contributor

@Andrewyx Andrewyx 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 so far, I left some feedback!

Comment on lines 8 to 31
- [Installing Software Dependencies](#installing-software-dependencies)
- [Installing an IDE](#installing-an-ide)
- [Installing an IDE: CLion](#installing-an-ide-clion)
- [Getting your Student License](#getting-your-student-license)
- [Installing CLion](#installing-clion)
- [Installing an IDE: VS Code](#installing-an-ide-vs-code)
- [Editing with Vim or NeoVim](#editing-with-vim-or-neovim)
- [Building and Running the Code](#building-and-running-the-code)
- [Building from the command line](#building-from-the-command-line)
- [Building from the command line using the fuzzy finder](#building-from-the-command-line-using-the-fuzzy-finder)
- [Building with CLion](#building-with-clion)
- [Building with VS Code](#building-with-vs-code)
- [Running our AI, Simulator, SimulatedTests or Robot Diagnostics](#running-our-ai-simulator-simulatedtests-or-robot-diagnostics)
- [Debugging](#debugging)
- [Debugging with CLion](#debugging-with-clion)
- [Debugging from the Command Line](#debugging-from-the-command-line)
- [Profiling](#profiling)
- [Callgrind](#callgrind)
- [Tracy](#tracy)
- [Building for the robot](#building-for-the-robot)
- [Deploying Robot Software to the robot](#deploying-robot-software-to-the-robot)
- [Testing Robot Software locally](#testing-robot-software-locally)
- [Setting up Virtual Robocup 2021](#setting-up-virtual-robocup-2021)
- [Setting up the SSL Simulation Environment](#setting-up-the-ssl-simulation-environment)
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Probably unintended formatting change

Comment on lines 52 to 67

# Software Setup

## Introduction

These instructions assume that you have the following accounts setup:
- [GitHub](https://github.com/login)
- [Discord](https://discord.com). Please contact a Thunderbots lead to receive the invite link.

These instructions assume you have a basic understanding of Linux and the command line. There are many great tutorials online, such as [LinuxCommand](http://linuxcommand.org/). The most important things you'll need to know are how to move around the filesystem and how to run programs or scripts.

## Installation and Setup

### Operating systems

We currently only support Linux, specifically Ubuntu.
Copy link
Contributor

Choose a reason for hiding this comment

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

Unintended deletion?

Comment on lines 17 to 20
def get_validation_status(
self,
world,
) -> ValidationStatus:
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: is this formatting right?

"""Checks if any friendly robot is excessively dribbling the ball, i.e. for over 1m.

:param world: The world msg to validate
estimate of max dribble distance (effective dribble distance is length - error margin)
Copy link
Contributor

Choose a reason for hiding this comment

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

Where is this comment directed to?

Comment on lines 31 to 42
if (
world.HasField("dribble_displacement")
and world.dribble_displacement is not None
):
dribble_disp = world.dribble_displacement
dist = tbots_cpp.createSegment(dribble_disp).length()
if dist > (
DribblingConstants.MAX_DRIBBLING_DISTANCE
- DribblingConstants.DRIBBLING_ERROR_MARGIN
):
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

Copy link
Contributor

Choose a reason for hiding this comment

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

@sauravbanna @williamckha Can you take a look at this? I am hesitant to think this code is correct since dribble_displacement might be determined by SensorFusion and in that case, our internal logic is also referencing dribble_displacement when deciding when to let go of the ball.

Additionally, suppose a bug arises in SensorFusion where dribble_displacement is None, but in fact we are dribbling. In that case, this test would pass since it is referencing the value passed on by SensorFusion.

Copy link
Member

Choose a reason for hiding this comment

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

I see your concern. Though imo it does not make sense to return FAILING if dribble_displacement is null, since if it is accurate, that would mean we are not dribbling at all and therefore not breaking the excessive dribbling rule. I would suggest adding an extra validation to the excessively dribbling test that checks if the ball is eventually moved to its destination. This would validate that the ball is actually being dribbled.

Copy link
Member

@williamckha williamckha Feb 14, 2026

Choose a reason for hiding this comment

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

wait nevermind I didn't read the second part of your comment properly. To address that potential bug, we should check that the dribble_displacement member is eventually non null.

class DribblingConstants:
"""Constants to be used to check whether the robot has dribbled beyond competition regulations"""

MAX_DRIBBLING_DISTANCE = 1.0
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: Displacement not distance

@pytest.mark.parametrize(
"initial_location,dribble_destination,final_dribble_orientation, should_excessively_dribble",
[
# Tests Should not excessively dribble
Copy link
Contributor

@Andrewyx Andrewyx Feb 13, 2026

Choose a reason for hiding this comment

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

nit: Unnecessary comment

Copy link
Contributor Author

Choose a reason for hiding this comment

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

probably unclear, but my tests are split between not excessively dribbling and excessively dribbling, hence the comment (there's a corresponding comment below for excessively dribbling). I'll try to format it better?

simulated_test_runner,
):
if should_excessively_dribble:
blue_robot_locations = [tbots_cpp.Point(0, 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.

We probably do not want to set the locations in the test, and instead have them parameterized. This clear separation makes reading the logic of the test cases make more sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

got it makes sense

),
],
)
def test_excessive_dribbling(
Copy link
Contributor

Choose a reason for hiding this comment

The 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 DribbleTactic test. Excessive dribbling is a characteristic of Gameplay more than a particular state, so I think it is a bit odd to be testing it explicitly since it is really just testing the implementation of DribbleTactic itself.

Copy link
Contributor Author

Choose a reason for hiding this comment

The 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.

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.

OffensePlayTest should check that we don't dribble too far

5 participants