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

[Gameplay] Avoid Aimless Kick/Chip by Defenders #3230

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

Conversation

Andrewyx
Copy link
Contributor

@Andrewyx Andrewyx commented Jun 22, 2024

Please fill out the following before requesting review on this PR

Description

Changes Crease Defender Autochip behaviour such that robots only chip in dire circumstances.
Further adds new Chip Validation

Crease defenders now only autochip incoming balls when:

  1. Crease Defender is not facing friendly net
  2. Crease Defender has enemy in front to justify chipping over
  3. The ball && crease defender is near the friendly net

Further adds the following:

  • Also gives crease defenders the ability to chase after ball with DribbleFSM when the ball is nearby and unguarded based on threshold values.
  • Includes new crease_defender_tactic_test.py pytest with simulated tests. Removed/replaces certain outdated C++ tests.

Testing Done

Adds new chip validation test which passes when ball is threshold meters off the ground. This allows us to test if chip behaviour occurs.

Resolved Issues

Resolves #3220

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

Suggests new ticket reworking the visual component of the ball_if_off_ground validation test. This test validates changes in the z axis and the current 2D shape system is not enough to visualize this. It is purely a visual change and is not urgent, but will take some time to think of a new way to visualize.

@Andrewyx Andrewyx changed the title Andrewyx/aimless chip [Gameplay] Avoid Aimless Kick/Chip by Defenders Jun 22, 2024
ai_config.robot_navigation_obstacle_config()),
std::make_shared<CreaseDefenderTactic>(
ai_config.robot_navigation_obstacle_config())};
std::make_shared<CreaseDefenderTactic>(ai_config),
Copy link
Contributor

Choose a reason for hiding this comment

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

can you delete the TODO above this line. Doesn't seem relevant anymore

Comment on lines 39 to 46
std::vector<Robot> enemy_robots = event.common.world_ptr->enemyTeam().getAllRobots();
for (int i = 0; i < static_cast<int>(event.common.world_ptr->enemyTeam().numRobots()); i++) {
if (contains(zone, enemy_robots[i].position()))
{
return true;
}
}
return false;
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: try refactoring to use std::any_of: https://en.cppreference.com/w/cpp/algorithm/all_any_none_of

Comment on lines 132 to 135
// DEBUG: Visualizes threat stadium
LOG(VISUALIZE) << *createDebugShapes({
*createDebugShape(threat_zone, std::to_string(event.common.robot.id()), "threatzone")
});
Copy link
Contributor

Choose a reason for hiding this comment

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

remove to delete when you're done


if (goal_intersections.empty()
&& CreaseDefenderFSM::isAnyEnemyInZone(event, threat_zone)
&& robot_to_net_m <= event.common.world_ptr->field().totalYLength() / 2)
Copy link
Contributor

Choose a reason for hiding this comment

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

why did you use YLength() here?

also this should be a constant with the word THRESHOLD in it

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This ensures that chips only occur when the ball is somewhat near our net. This cannot be a constant since this value must scale with field size and this is only determined in runtime

Comment on lines 137 to 150
if (goal_intersections.empty()
&& CreaseDefenderFSM::isAnyEnemyInZone(event, threat_zone)
&& robot_to_net_m <= event.common.world_ptr->field().totalYLength() / 2)
{
// Autochip only if the robot is not facing the net, there is an enemy in front, and robot is close to net
auto_chip_or_kick = AutoChipOrKick{
AutoChipOrKickMode::AUTOCHIP,
chip_distance
};
}
else
{
auto_chip_or_kick = AutoChipOrKick{AutoChipOrKickMode::OFF, 0};
}
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
if (goal_intersections.empty()
&& CreaseDefenderFSM::isAnyEnemyInZone(event, threat_zone)
&& robot_to_net_m <= event.common.world_ptr->field().totalYLength() / 2)
{
// Autochip only if the robot is not facing the net, there is an enemy in front, and robot is close to net
auto_chip_or_kick = AutoChipOrKick{
AutoChipOrKickMode::AUTOCHIP,
chip_distance
};
}
else
{
auto_chip_or_kick = AutoChipOrKick{AutoChipOrKickMode::OFF, 0};
}
auto_chip_or_kick = AutoChipOrKick{AutoChipOrKickMode::OFF, 0};
if (goal_intersections.empty()
&& CreaseDefenderFSM::isAnyEnemyInZone(event, threat_zone)
&& robot_to_net_m <= event.common.world_ptr->field().totalYLength() / 2)
{
// Autochip only if the robot is not facing the net, there is an enemy in front, and robot is close to net
auto_chip_or_kick = AutoChipOrKick{
AutoChipOrKickMode::AUTOCHIP,
chip_distance
};
}

Comment on lines 216 to 217
constexpr double GET_POSSESSION_THRESHOLD_M = 1;
constexpr double THREAT_THRESHOLD_M = GET_POSSESSION_THRESHOLD_M * 2;
Copy link
Contributor

Choose a reason for hiding this comment

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

this should be in the header so that we can find these constants easily

Comment on lines 220 to 226
LOG(VISUALIZE) << *createDebugShapes({
*createDebugShape(
Circle(robot_position, GET_POSSESSION_THRESHOLD_M),
std::to_string(event.common.robot.id()) + "1",
"ballzone"
)
});
Copy link
Contributor

Choose a reason for hiding this comment

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

remember to remove this when you're done

boost::sml::back::process<DribbleFSM::Update> processEvent)
{
DribbleFSM::ControlParams control_params{
.dribble_destination = Point(),
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
.dribble_destination = Point(),
.dribble_destination = event.common.world_ptr->ball().position(),

{
DribbleFSM::ControlParams control_params{
.dribble_destination = Point(),
.final_dribble_orientation = Angle(),
Copy link
Contributor

Choose a reason for hiding this comment

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

should be oriented towards the enemy net

*MoveFSM_S + Update_E / blockThreat_A, MoveFSM_S = X,
*MoveFSM_S + Update_E[ballNearbyWithoutThreat_G] / prepareGetPossession_A = DribbleFSM_S,
MoveFSM_S + Update_E / blockThreat_A, MoveFSM_S = X,
DribbleFSM_S + Update_E[!ballNearbyWithoutThreat_G] / blockThreat_A = X,
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
DribbleFSM_S + Update_E[!ballNearbyWithoutThreat_G] / blockThreat_A = X,
DribbleFSM_S + Update_E[!ballNearbyWithoutThreat_G] / blockThreat_A = MoveFSM,

*
* @param event CreaseDefenderFSM::Update event
* @param zone a stadium shape that defines the zone
* @param zone a stadium shape that defines the zone
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
* @param zone a stadium shape that defines the zone

Comment on lines +61 to +62
fsm_map.at(tactic_update.robot.id())
->process_event(DribbleFSM::Update(dribble_control_params, tactic_update));
Copy link
Contributor

Choose a reason for hiding this comment

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

do we need this? I'm not 100% sure if this is necessary

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No idea why, but weirdly yes

@@ -33,8 +35,7 @@ class CreaseDefenderTactic : public Tactic
*
* @param robot_obstacle_inflation_factor The amount to inflate the robot obstacles
*/
explicit CreaseDefenderTactic(
TbotsProto::RobotNavigationObstacleConfig robot_navigation_obstacle_config);
explicit CreaseDefenderTactic(TbotsProto::AiConfig ai_config);
Copy link
Contributor

Choose a reason for hiding this comment

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

incorrect docs for this function

@@ -71,8 +71,7 @@ std::shared_ptr<Tactic> createTactic(const TbotsProto::CreaseDefenderTactic &tac
TbotsProto::AiConfig ai_config)
{
// TODO-AKHIL: Implement this
auto tactic = std::make_shared<CreaseDefenderTactic>(
ai_config.robot_navigation_obstacle_config());
auto tactic = std::make_shared<CreaseDefenderTactic>(ai_config);
Copy link
Contributor

Choose a reason for hiding this comment

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

you can delete the previous TODO

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.

left some interim feedback. Looks like one of the CHECKs fail when we play AI vs AI. I think the update that I suggested to crease_defender_fsm.h may fix this issue

@Andrewyx Andrewyx marked this pull request as ready for review June 29, 2024 09:47
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] Avoid aimless kick/chip by defenders
2 participants