Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 20 additions & 1 deletion src/software/ai/evaluation/defender_assignment.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "software/geom/algorithms/convex_angle.h"
#include "software/geom/algorithms/distance.h"
#include "software/geom/algorithms/intersection.h"
#include "software/geom/algorithms/intersects.h"
#include "software/math/math_functions.h"

std::vector<DefenderAssignment> getAllDefenderAssignments(
Expand Down Expand Up @@ -45,8 +46,26 @@ std::vector<DefenderAssignment> getAllDefenderAssignments(
Segment(primary_threat_position, filtered_threats.at(i).robot.position());
double threat_rating = static_cast<double>(filtered_threats.size()) - i;
passing_lanes.emplace_back(ShootingLane{lane, threat_rating});

Point intercept_point;
if (distance(lane.midPoint(), filtered_threats.at(i).robot.position()) < 1.2 ||
intersects(field.friendlyDefenseArea(), lane))
{
// We can use the midpoint if it is close enough to the receiver to prevent
// a chip pass or the segment goes through the goalie box
intercept_point = lane.midPoint();
}
else
{
// Otherwise we will position the defender closer to the
intercept_point =
filtered_threats.at(i).robot.position() +
(primary_threat_position - filtered_threats.at(i).robot.position())
.normalize(1.2);
}

assignments.emplace_back(
DefenderAssignment{PASS_DEFENDER, lane.midPoint(), threat_rating});
DefenderAssignment{PASS_DEFENDER, intercept_point, threat_rating});
}

// Construct goal lanes.
Expand Down
18 changes: 17 additions & 1 deletion src/software/ai/evaluation/enemy_threat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "software/ai/evaluation/calc_best_shot.h"
#include "software/ai/evaluation/intercept.h"
#include "software/ai/evaluation/possession.h"
#include "software/geom/algorithms/contains.h"
#include "software/geom/algorithms/intersects.h"
#include "software/world/team.h"

Expand Down Expand Up @@ -42,7 +43,22 @@ std::map<Robot, std::vector<Robot>, Robot::cmpRobotByID> findAllReceiverPasserPa
Segment(passer.position(), receiver.position()));
});

if (!pass_blocked)
bool chick_pass_blocked = std::any_of(
obstacles.begin(), obstacles.end(),
[passer, receiver](const Robot &obstacle)
{
Segment pass_lane = Segment(passer.position(), receiver.position());
return contains(
Circle(pass_lane.midPoint(), pass_lane.length() / 2.0),
obstacle.position()) // Here we check if the obstacle is
// between the receiver and passer
&& contains(
Circle(receiver.position(), 1.2),
obstacle.position()); // Here we check if the obstacle
// is too close to the receiver
});

if (!pass_blocked || !chick_pass_blocked)
{
if (receiver_passer_pairs.count(receiver) > 0)
{
Expand Down
58 changes: 54 additions & 4 deletions src/software/ai/evaluation/enemy_threat_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ TEST(FindAllPasserReceiverPairsTest,
AngularVelocity::zero(), Timestamp::fromSeconds(0));
Robot friendly_robot_1 = Robot(1, Point(3, 2), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));
Robot friendly_robot_2 = Robot(2, Point(5, 0), Vector(0, 0), Angle::zero(),
Robot friendly_robot_2 = Robot(2, Point(3, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

// Blocks the pass from robot 0 to robot 2
// Blocks the pass from robot 0 to robot 2, is close enough to robot 2 to prevent a
// chip pass
Robot enemy_robot_0 = Robot(0, Point(2, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

Expand All @@ -62,6 +63,33 @@ TEST(FindAllPasserReceiverPairsTest,
EXPECT_EQ(result, expected_result);
}

TEST(FindAllPasserReceiverPairsTest,
two_passers_one_receiver_with_no_pass_blocked_by_obstacles)
{
Robot friendly_robot_0 = Robot(0, Point(0, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));
Robot friendly_robot_1 = Robot(1, Point(3, 2), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));
Robot friendly_robot_2 = Robot(2, Point(5, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

// Is too far awar from robot 2 to block a chip pass
Robot enemy_robot_0 = Robot(0, Point(2, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

std::vector<Robot> all_robots{friendly_robot_0, friendly_robot_1, friendly_robot_2,
enemy_robot_0};

auto result = findAllReceiverPasserPairs({friendly_robot_0, friendly_robot_1},
{friendly_robot_2}, all_robots);

std::map<Robot, std::vector<Robot>, Robot::cmpRobotByID> expected_result = {
std::make_pair(friendly_robot_2,
std::vector<Robot>{friendly_robot_0, friendly_robot_1})};

EXPECT_EQ(result, expected_result);
}

TEST(FindAllPasserReceiverPairsTest, all_passes_blocked)
{
Robot friendly_robot_0 = Robot(0, Point(0, 0), Vector(0, 0), Angle::zero(),
Expand All @@ -70,7 +98,7 @@ TEST(FindAllPasserReceiverPairsTest, all_passes_blocked)
AngularVelocity::zero(), Timestamp::fromSeconds(0));

// Blocks the pass from robot 0 to robot 1
Robot enemy_robot_0 = Robot(0, Point(2, 0), Vector(0, 0), Angle::zero(),
Robot enemy_robot_0 = Robot(0, Point(4, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

std::vector<Robot> all_robots{friendly_robot_0, friendly_robot_1, enemy_robot_0};
Expand All @@ -81,6 +109,28 @@ TEST(FindAllPasserReceiverPairsTest, all_passes_blocked)
EXPECT_TRUE(result.empty());
}

TEST(FindAllPasserReceiverPairsTest, chip_pass_not_blocked)
{
Robot friendly_robot_0 = Robot(0, Point(0, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));
Robot friendly_robot_1 = Robot(1, Point(5, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

// Not close enough to robot 1 to block the pass
Robot enemy_robot_0 = Robot(0, Point(2, 0), Vector(0, 0), Angle::zero(),
AngularVelocity::zero(), Timestamp::fromSeconds(0));

std::vector<Robot> all_robots{friendly_robot_0, friendly_robot_1, enemy_robot_0};

auto result =
findAllReceiverPasserPairs({friendly_robot_0}, {friendly_robot_1}, all_robots);

std::map<Robot, std::vector<Robot>, Robot::cmpRobotByID> expected_result = {
std::make_pair(friendly_robot_1, std::vector<Robot>{friendly_robot_0})};

EXPECT_EQ(result, expected_result);
}

TEST(FindAllPasserReceiverPairsTest, receiver_with_multiple_passers)
{
Robot friendly_robot_0 = Robot(0, Point(0, 0), Vector(0, 0), Angle::zero(),
Expand Down Expand Up @@ -152,7 +202,7 @@ TEST(GetNumPassesToRobotTest, one_simple_pass_to_robot_with_no_obstacles)
EXPECT_EQ(passer.value(), friendly_robot_0);
}

// TODO: Re-enable as part of https://github.com/UBC-Thunderbots/Software/issues/642
// TODO: Re-enable as part of +
// TEST(GetNumPassesToRobotTest, two_passes_around_a_single_obstacle)
//{
// Robot friendly_robot_0 = Robot(0, Point(0, 0), Vector(0, 0), Angle::zero(),
Expand Down
Loading