Skip to content

control ball before chipping in GoalieFSM - #3869

Open
annieisawesome2 wants to merge 7 commits into
UBC-Thunderbots:masterfrom
annieisawesome2:control-before-chip
Open

annieisawesome2 wants to merge 7 commits into
UBC-Thunderbots:masterfrom
annieisawesome2:control-before-chip

Conversation

@annieisawesome2

@annieisawesome2 annieisawesome2 commented Aug 9, 2026

Copy link
Copy Markdown
Contributor

Description

Previously when goalie chipped, it transitioned straight into PivotKickFSM even if the ball wasn't under control. Goalie was able to attempt chipping before securing ball. This PR adds DribbleFSM step that dribbles to control the ball and orient towards chip target before we hand off to PivotKickFSM.

Added a new guard controlBallForChip action which drives DribbleFSM to position ball at a safe chip origin and orients towards target.

Implemented new methods ballControlled and controlBallForChip. Updated goalie_fsm_test.cpp so FSM expects to land in DribbleFSM first and reaches PivotKickFSM after ball repositioned near dribbler (has possession).

Testing Done

So far only unit tests in goalie_fsm_test.cpp updated to assert new dribble state before chipping. It would be great to test on actual robot too.

Additional pytests added to check that the goalie gets the ball and then has to leave the no chip rectangle before the ball gets chipped. What we see in this video is the seuence of DribbleFSM -> KickState -> terminate. It only checkes the world outcomes in order not the FSM states. It doesn't really show that the goalieFSM stayed in dribble until ballControlled before going into PivotKickFSM. The chip happened after repositioning.

I would say the C++ unit tests should be what we use to test the fsm logic since we assert the states.

Screen.Recording.2026-08-19.at.1.09.30.PM.mov

Resolved Issues

resolves #2897

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

@nycrat nycrat left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

These changes look good so far. I'm just a bit unsure about how the ballControlled guard works with the new FSM logic. Also as you said it would be nice to have this tested physically, but writing a simulated pytest to demonstrate that the goalie actually gains possession and moves the ball out of the no chip zone before chipping would be nice.

Comment thread src/software/ai/hl/stp/tactic/goalie/goalie_fsm.cpp
Comment thread src/software/ai/hl/stp/tactic/goalie/goalie_fsm.h
DribbleFSM_S + Update_E[ballInInflatedDefenseArea_G] / retrieveFromDeadZone_A,
DribbleFSM_S + Update_E[shouldEvacuateCrease_G] / retrieveFromDeadZone_A,
DribbleFSM_S + Update_E[shouldPivotChip_G] / controlBallForChip_A,
DribbleFSM_S + Update_E[ballInInflatedDefenseArea_G] / controlBallForChip_A,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Same here, why is this logic changed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Glancing at the comment above I thought this was from one of my other issues, but no this logic was changed because once the goalie enters DribbleFSM_S, something still has to call the dribble sub-FSM on every Update tick. Basically, when we enter DribbleFSM through the new controlBallForChip, this actually only happens once. We loop through sub FSMs until ballControlled is true so the shouldEvacuateCrease / retrieveFromDeadZone line replaces the old ballInInflatedDefenseArea / retrieveFromDeadZone just so the dead zone retrieval and chip don't share the same loop. The ballInInflatedDefenseArea / controlBallForChip fallback prevents exiting chip prep if shouldPivotChip flickers during dribbling.

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.

[Gameplay] Goalie: control the ball before we try to chip it away

3 participants