diff --git a/src/proto/parameters.proto b/src/proto/parameters.proto index 2bed9d32de..f95e50b423 100644 --- a/src/proto/parameters.proto +++ b/src/proto/parameters.proto @@ -525,6 +525,10 @@ message DefensePlayConfig (bounds).min_double_value = 0.0, (bounds).max_double_value = 10.0 ]; + + // The max number of crease defender can be created at a moment + required uint32 max_num_crease_defenders = 6 + [default = 1, (bounds).min_int_value = 1, (bounds).max_int_value = 3]; } // The distance at which a threat is considered "immediate" if there is only 1 @@ -634,12 +638,13 @@ message NetworkConfig message CreaseDefenderConfig { + // Unique steal config for crease defenders + required DefenderStealConfig defender_steal_config = 1; + // The additional buffer length for each side of the goal // to determine if crease defender chipping is "towards goal" required double goal_post_offset_chipping = 4 [default = 0.5, (bounds).min_double_value = 0.0, (bounds).max_double_value = 2.0]; - // Unique steal config for crease defenders - required DefenderStealConfig defender_steal_config = 1; } message PassDefenderConfig diff --git a/src/software/ai/hl/stp/play/defense/defense_play_fsm.cpp b/src/software/ai/hl/stp/play/defense/defense_play_fsm.cpp index 3495596ed1..2421a52c5b 100644 --- a/src/software/ai/hl/stp/play/defense/defense_play_fsm.cpp +++ b/src/software/ai/hl/stp/play/defense/defense_play_fsm.cpp @@ -14,15 +14,20 @@ void DefensePlayFSM::defendAgainstThreats(const Update& event) event.common.world_ptr->field(), event.common.world_ptr->friendlyTeam(), event.common.world_ptr->enemyTeam(), event.common.world_ptr->ball(), false); + auto defender_assignment_config = + ai_config.defense_play_config().defender_assignment_config(); auto assignments = getAllDefenderAssignments( enemy_threats, event.common.world_ptr->field(), event.common.world_ptr->ball(), - ai_config.defense_play_config().defender_assignment_config()); + defender_assignment_config); if (assignments.size() == 0) { return; } + unsigned int max_num_crease_defenders = + defender_assignment_config.max_num_crease_defenders(); + // Choose which defender assignments to assign defenders to based on number // of tactics available to set std::vector crease_defender_assignments; @@ -42,17 +47,19 @@ void DefensePlayFSM::defendAgainstThreats(const Update& event) defender_assignment = assignments.front(); } - if (defender_assignment.type == CREASE_DEFENDER) + if (defender_assignment.type == CREASE_DEFENDER && max_num_crease_defenders > 0) { crease_defender_assignments.emplace_back(defender_assignment); + max_num_crease_defenders--; // If we have at least two available defenders, two defenders should // be assigned to the highest scoring crease defender assignment to better // block the shot cone of the most threatening enemy - if (i == 0 && event.common.num_tactics >= 2) + if (i == 0 && event.common.num_tactics >= 2 && max_num_crease_defenders > 0) { crease_defender_assignments.emplace_back(defender_assignment); i++; + max_num_crease_defenders--; } } else diff --git a/src/software/ai/hl/stp/tactic/defender/defender_fsm_base.cpp b/src/software/ai/hl/stp/tactic/defender/defender_fsm_base.cpp index 3aaa25da4e..a3404cc39c 100644 --- a/src/software/ai/hl/stp/tactic/defender/defender_fsm_base.cpp +++ b/src/software/ai/hl/stp/tactic/defender/defender_fsm_base.cpp @@ -9,6 +9,12 @@ bool DefenderFSMBase::ballNearbyWithoutThreat( const TbotsProto::BallStealMode& ball_steal_mode, const TbotsProto::DefenderStealConfig& defender_steal_config) { + if (ball_steal_mode == TbotsProto::BallStealMode::IGNORE) + { + // Do nothing if stealing is disabled + return false; + } + Point robot_position = robot.position(); Point ball_position = world_ptr->ball().position(); @@ -16,41 +22,35 @@ bool DefenderFSMBase::ballNearbyWithoutThreat( world_ptr->friendlyTeam().getNearestRobot(ball_position); std::optional nearest_enemy_to_ball = world_ptr->enemyTeam().getNearestRobot(robot_position); - if (ball_steal_mode == TbotsProto::BallStealMode::IGNORE) - { - // Do nothing if stealing is disabled - return false; - } - else if (nearest_friendly_to_ball.has_value() && - robot.id() != nearest_friendly_to_ball.value().id()) + + if (nearest_friendly_to_ball.has_value() && + robot.id() != nearest_friendly_to_ball.value().id()) { // Do nothing if this robot is not the closest to the ball. Resolves issue of // multiple simultaneous steals return false; } - if (nearest_enemy_to_ball.has_value()) - { - // Get the ball if ball is closer to robot than enemy threat by threshold ratio - // and within max range - double ball_distance_to_friendly = distance(robot_position, ball_position); - double ball_distance_to_enemy = - distance(nearest_enemy_to_ball.value().position(), ball_position); - - bool ball_is_near_friendly = - ball_distance_to_friendly < - ball_distance_to_enemy * - (1.0 - defender_steal_config.max_get_ball_ratio_threshold()); - bool ball_is_within_max_range = - ball_distance_to_friendly <= defender_steal_config.max_get_ball_radius_m(); - bool ball_is_slow = world_ptr->ball().velocity().length() <= - defender_steal_config.max_ball_speed_to_get_m_per_s(); - return ball_is_near_friendly && ball_is_within_max_range && ball_is_slow; - } - else + if (!nearest_enemy_to_ball.has_value()) { return true; } + + // Get the ball if ball is closer to robot than enemy threat by threshold ratio + // and within max range + double ball_distance_to_friendly = distance(robot_position, ball_position); + double ball_distance_to_enemy = + distance(nearest_enemy_to_ball.value().position(), ball_position); + + bool ball_is_near_friendly = + ball_distance_to_friendly < + ball_distance_to_enemy * defender_steal_config.max_get_ball_ratio_threshold(); + bool ball_is_within_max_range = + ball_distance_to_friendly <= defender_steal_config.max_get_ball_radius_m(); + bool ball_is_slow = world_ptr->ball().velocity().length() <= + defender_steal_config.max_ball_speed_to_get_m_per_s(); + + return ball_is_near_friendly && ball_is_within_max_range && ball_is_slow; } void DefenderFSMBase::prepareGetPossession(