Skip to content
Open
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
35 changes: 9 additions & 26 deletions docs/fsm-diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,23 +298,6 @@ Terminate:::terminate --> Terminate:::terminate : <i>SET_STOP_PRIMITIVE_ACTION</

```

## [ChipFSM](/src/software/ai/hl/stp/tactic/chip/chip_fsm.h)

```mermaid

stateDiagram-v2
classDef terminate fill:white,color:black,font-weight:bold
direction LR
[*] --> GetBehindBallFSM
GetBehindBallFSM --> GetBehindBallFSM : <i>updateGetBehindBall</i>
GetBehindBallFSM --> ChipState
ChipState --> GetBehindBallFSM : [shouldRealignWithBall]\n<i>updateGetBehindBall</i>
ChipState --> ChipState : [!ballChicked]\n<i>updateChip</i>
ChipState --> Terminate:::terminate : [ballChicked]\n<i>SET_STOP_PRIMITIVE_ACTION</i>
Terminate:::terminate --> Terminate:::terminate : <i>SET_STOP_PRIMITIVE_ACTION</i>

```

## [CreaseDefenderFSM](/src/software/ai/hl/stp/tactic/crease_defender/crease_defender_fsm.h)

```mermaid
Expand Down Expand Up @@ -429,7 +412,7 @@ Terminate:::terminate --> Terminate:::terminate : <i>SET_STOP_PRIMITIVE_ACTION</

```

## [KickFSM](/src/software/ai/hl/stp/tactic/kick/kick_fsm.h)
## [KickOrChipFSM](/src/software/ai/hl/stp/tactic/kick_or_chip/kick_or_chip_fsm.h)

```mermaid

Expand All @@ -438,10 +421,10 @@ classDef terminate fill:white,color:black,font-weight:bold
direction LR
[*] --> GetBehindBallFSM
GetBehindBallFSM --> GetBehindBallFSM : <i>updateGetBehindBall</i>
GetBehindBallFSM --> KickState
KickState --> GetBehindBallFSM : [shouldRealignWithBall]\n<i>updateGetBehindBall</i>
KickState --> KickState : [!ballChicked]\n<i>updateKick</i>
KickState --> Terminate:::terminate : [ballChicked]\n<i>SET_STOP_PRIMITIVE_ACTION</i>
GetBehindBallFSM --> KickOrChipState
KickOrChipState --> GetBehindBallFSM : [shouldRealignWithBall]\n<i>updateGetBehindBall</i>
KickOrChipState --> KickOrChipState : [!ballChicked]\n<i>kickOrChipBall</i>
KickOrChipState --> Terminate:::terminate : [ballChicked]\n<i>SET_STOP_PRIMITIVE_ACTION</i>
Terminate:::terminate --> Terminate:::terminate : <i>SET_STOP_PRIMITIVE_ACTION</i>

```
Expand Down Expand Up @@ -489,11 +472,11 @@ classDef terminate fill:white,color:black,font-weight:bold
direction LR
[*] --> DribbleFSM
DribbleFSM --> DribbleFSM : [!takePenaltyShot]\n<i>updateApproachKeeper</i>
DribbleFSM --> KickFSM : [timeOutApproach]\n<i>shoot</i>
DribbleFSM --> KickOrChipFSM : [timeOutApproach]\n<i>shoot</i>
DribbleFSM --> DribbleFSM : <i>adjustOrientationForShot</i>
DribbleFSM --> KickFSM
KickFSM --> KickFSM : <i>shoot</i>
KickFSM --> Terminate:::terminate
DribbleFSM --> KickOrChipFSM
KickOrChipFSM --> KickOrChipFSM : <i>shoot</i>
KickOrChipFSM --> Terminate:::terminate
Terminate:::terminate --> Terminate:::terminate : <i>SET_STOP_PRIMITIVE_ACTION</i>

```
Expand Down
34 changes: 12 additions & 22 deletions src/proto/tactic.proto
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,14 @@ message AssignedTacticPlayControlParams

message Tactic
{
reserved 2, 7;
oneof tactic
{
AttackerTactic attacker = 1;
ChipTactic chip = 2;
CreaseDefenderTactic crease_defender = 3;
DribbleTactic dribble = 4;
GetBehindBallTactic get_behind_ball = 5;
GoalieTactic goalie = 6;
KickTactic kick = 7;
MoveGoalieToGoalLineTactic move_goalie_to_goal_line = 8;
MoveTactic move = 9;
PenaltyKickTactic penalty_kick = 10;
Expand All @@ -30,6 +29,7 @@ message Tactic
ShadowEnemyTactic shadow_enemy = 13;
HaltTactic halt = 14;
PassDefenderTactic pass_defender = 15;
KickOrChipTactic kick_or_chip = 16;
}
}

Expand All @@ -44,16 +44,6 @@ message AttackerTactic
optional Point chip_target = 3;
}

message ChipTactic
{
// The location where the chip will be taken from
required Point chip_origin = 1;
// The direction the Robot will chip in
required Angle chip_direction = 2;
// The distance the robot will chip to
required double chip_distance_meters = 3;
}

enum CreaseDefenderAlignment
{
LEFT = 0;
Expand Down Expand Up @@ -106,16 +96,6 @@ message GoalieTactic
required MaxAllowedSpeedMode max_allowed_speed_mode = 1;
}

message KickTactic
{
// The location where the kick will be taken from
required Point kick_origin = 1;
// The direction the Robot will kick in
required Angle kick_direction = 2;
// How fast the Robot will kick the ball in meters per second
required double kick_speed_meters_per_second = 3;
}

message MoveGoalieToGoalLineTactic {}

message MoveTactic
Expand Down Expand Up @@ -177,3 +157,13 @@ message ShadowEnemyTactic
}

message HaltTactic {}

message KickOrChipTactic
{
// The location where the kick or chip will be taken from
required Point kick_or_chip_origin = 1;
// The direction the Robot will kick or chip in
required Angle kick_or_chip_direction = 2;
// How the robot will chip or kick the ball
required AutoChipOrKick auto_chip_or_kick = 3;
}
2 changes: 1 addition & 1 deletion src/software/ai/hl/stp/play/free_kick/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ cc_library(
"//software/ai/evaluation:possession",
"//software/ai/hl/stp/play",
"//software/ai/hl/stp/play/defense:defense_play",
"//software/ai/hl/stp/tactic/chip:chip_tactic",
"//software/ai/hl/stp/tactic/crease_defender:crease_defender_tactic",
"//software/ai/hl/stp/tactic/goalie:goalie_tactic",
"//software/ai/hl/stp/tactic/kick_or_chip:kick_or_chip_tactic",
"//software/ai/hl/stp/tactic/move:move_tactic",
"//software/ai/hl/stp/tactic/receiver:receiver_tactic",
"//software/ai/passing:eighteen_zone_pitch_division",
Expand Down
31 changes: 17 additions & 14 deletions src/software/ai/hl/stp/play/free_kick/free_kick_play_fsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ FreeKickPlayFSM::FreeKickPlayFSM(
std::shared_ptr<const TbotsProto::AiConfig> ai_config_ptr)
: PlayFSM<FreeKickPlayFSM>(ai_config_ptr),
align_to_ball_tactic(std::make_shared<MoveTactic>(ai_config_ptr)),
shoot_tactic(std::make_shared<KickTactic>(ai_config_ptr)),
chip_tactic(std::make_shared<ChipTactic>(ai_config_ptr)),
passer_tactic(std::make_shared<KickTactic>(ai_config_ptr)),
kick_or_chip_tactic(std::make_shared<KickOrChipTactic>(ai_config_ptr)),
passer_tactic(std::make_shared<KickOrChipTactic>(ai_config_ptr)),
receiver_tactic(std::make_shared<ReceiverTactic>(ai_config_ptr)),
receiver_positioning_tactics({std::make_shared<MoveTactic>(ai_config_ptr),
std::make_shared<MoveTactic>(ai_config_ptr)}),
Expand Down Expand Up @@ -146,12 +145,14 @@ void FreeKickPlayFSM::shootBall(const Update &event)
LOG(INFO) << "Shooting ball.";
PriorityTacticVector tactics_to_run = {{}};

Point ball_pos = event.common.world_ptr->ball().position();
Point ball_pos = event.common.world_ptr->ball().position();
AutoChipOrKick auto_chip_or_kick = {AutoChipOrKickMode::AUTOKICK,
BALL_MAX_SPEED_METERS_PER_SECOND};

shoot_tactic->updateControlParams(
kick_or_chip_tactic->updateControlParams(
ball_pos, (shot->getPointToShootAt() - ball_pos).orientation(),
BALL_MAX_SPEED_METERS_PER_SECOND);
tactics_to_run[0].emplace_back(shoot_tactic);
auto_chip_or_kick);
tactics_to_run[0].emplace_back(kick_or_chip_tactic);

event.common.set_tactics(tactics_to_run);
}
Expand Down Expand Up @@ -200,9 +201,10 @@ void FreeKickPlayFSM::chipBall(const Update &event)
}
}

chip_tactic->updateControlParams(event.common.world_ptr->ball().position(),
chip_target);
tactics_to_run[0].emplace_back(chip_tactic);
AutoChipOrKick auto_chip_or_kick = {AutoChipOrKickMode::AUTOCHIP,
(chip_target - ball_pos).length()};
kick_or_chip_tactic->updateControlParams(ball_pos, chip_target, auto_chip_or_kick);
tactics_to_run[0].emplace_back(kick_or_chip_tactic);

event.common.set_tactics(tactics_to_run);
}
Expand Down Expand Up @@ -288,8 +290,9 @@ void FreeKickPlayFSM::passBall(const Update &event)

Pass pass = best_pass_and_score_so_far.pass;

passer_tactic->updateControlParams(pass.passerPoint(), pass.passerOrientation(),
pass.speed());
passer_tactic->updateControlParams(
pass.passerPoint(), pass.passerOrientation(),
AutoChipOrKick{AutoChipOrKickMode::AUTOKICK, pass.speed()});
receiver_tactic->updateControlParams(pass);
tactics_to_run[0].emplace_back(passer_tactic);
tactics_to_run[0].emplace_back(receiver_tactic);
Expand All @@ -304,7 +307,7 @@ void FreeKickPlayFSM::passBall(const Update &event)

bool FreeKickPlayFSM::shotDone(const Update &event)
{
return shoot_tactic->done();
return kick_or_chip_tactic->done();
}

bool FreeKickPlayFSM::passDone(const FreeKickPlayFSM::Update &event)
Expand All @@ -314,5 +317,5 @@ bool FreeKickPlayFSM::passDone(const FreeKickPlayFSM::Update &event)

bool FreeKickPlayFSM::chipDone(const FreeKickPlayFSM::Update &event)
{
return chip_tactic->done();
return kick_or_chip_tactic->done();
}
8 changes: 3 additions & 5 deletions src/software/ai/hl/stp/play/free_kick/free_kick_play_fsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@
#include "software/ai/evaluation/calc_best_shot.h"
#include "software/ai/hl/stp/play/defense/defense_play.h"
#include "software/ai/hl/stp/play/play.h"
#include "software/ai/hl/stp/tactic/chip/chip_tactic.h"
#include "software/ai/hl/stp/tactic/crease_defender/crease_defender_tactic.h"
#include "software/ai/hl/stp/tactic/kick/kick_tactic.h"
#include "software/ai/hl/stp/tactic/kick_or_chip/kick_or_chip_tactic.h"
#include "software/ai/hl/stp/tactic/move/move_tactic.h"
#include "software/ai/hl/stp/tactic/receiver/receiver_tactic.h"
#include "software/ai/passing/eighteen_zone_pitch_division.h"
Expand Down Expand Up @@ -266,9 +265,8 @@ struct FreeKickPlayFSM : PlayFSM<FreeKickPlayFSM>
private:
std::optional<Shot> shot;
std::shared_ptr<MoveTactic> align_to_ball_tactic;
std::shared_ptr<KickTactic> shoot_tactic;
std::shared_ptr<ChipTactic> chip_tactic;
std::shared_ptr<KickTactic> passer_tactic;
std::shared_ptr<KickOrChipTactic> kick_or_chip_tactic;
std::shared_ptr<KickOrChipTactic> passer_tactic;
std::shared_ptr<ReceiverTactic> receiver_tactic;
std::vector<std::shared_ptr<MoveTactic>> receiver_positioning_tactics;
std::shared_ptr<DefensePlay> defense_play;
Expand Down
146 changes: 146 additions & 0 deletions src/software/ai/hl/stp/play/kickoff_friendly_play.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#include "software/ai/hl/stp/play/kickoff_friendly_play.h"

#include "shared/constants.h"
#include "software/ai/evaluation/enemy_threat.h"
#include "software/ai/hl/stp/tactic/kick_or_chip/kick_or_chip_tactic.h"
#include "software/ai/hl/stp/tactic/move/move_tactic.h"
#include "software/util/generic_factory/generic_factory.h"

KickoffFriendlyPlay::KickoffFriendlyPlay(
std::shared_ptr<const TbotsProto::AiConfig> ai_config_ptr)
: Play(ai_config_ptr, true)
{
}

void KickoffFriendlyPlay::getNextTactics(TacticCoroutine::push_type &yield,
const WorldPtr &world_ptr)
{
// Since we only have 6 robots at the maximum, the number one priority
// is the robot doing the kickoff up front. The goalie is the second most
// important, followed by 3 and 4 setup for offense. 5 and 6 will stay
// back near the goalie just in case the ball quickly returns to the friendly
// side of the field.
//
// +--------------------+--------------------+
// | | |
// | 3 | |
// | | |
// +--+ 5 | +--+
// | | | | |
// | | +-+-+ | |
// |2 | |1 | | |
// | | +-+-+ | |
// | | | | |
// +--+ 6 | +--+
// | | |
// | 4 | |
// | | |
// +--------------------+--------------------+
//
// This is a two part play:
// Part 1: Get into position, but don't touch the ball (ref kickoff)
// Part 2: Chip the ball over the defender (ref normal start)

// the following positions are in the same order as the positions shown above,
// excluding the goalie for part 1 of this play
std::vector<Point> kickoff_setup_positions = {
// Robot 1
Point(world_ptr->field().centerPoint() +
Vector(-world_ptr->field().centerCircleRadius(), 0)),
// Robot 2
// Goalie positions will be handled by the goalie tactic
// Robot 3
Point(
world_ptr->field().centerPoint() +
Vector(-world_ptr->field().centerCircleRadius() - 4 * ROBOT_MAX_RADIUS_METERS,
-1.0 / 3.0 * world_ptr->field().yLength())),
// Robot 4
Point(
world_ptr->field().centerPoint() +
Vector(-world_ptr->field().centerCircleRadius() - 4 * ROBOT_MAX_RADIUS_METERS,
1.0 / 3.0 * world_ptr->field().yLength())),
// Robot 5
Point(world_ptr->field().friendlyGoalpostPos().x() +
world_ptr->field().defenseAreaXLength() + 2 * ROBOT_MAX_RADIUS_METERS,
world_ptr->field().friendlyGoalpostPos().y()),
// Robot 6
Point(world_ptr->field().friendlyGoalpostNeg().x() +
world_ptr->field().defenseAreaXLength() + 2 * ROBOT_MAX_RADIUS_METERS,
world_ptr->field().friendlyGoalpostNeg().y()),
};

// move tactics to use to move to positions defined above
std::vector<std::shared_ptr<MoveTactic>> move_tactics = {
std::make_shared<PrepareKickoffMoveTactic>(ai_config_ptr),
std::make_shared<MoveTactic>(ai_config_ptr),
std::make_shared<MoveTactic>(ai_config_ptr),
std::make_shared<MoveTactic>(ai_config_ptr),
std::make_shared<MoveTactic>(ai_config_ptr)};

// specific tactics
auto kickoff_chip_tactic = std::make_shared<KickoffChipTactic>(ai_config_ptr);

// Part 1: setup state (move to key positions)
while (world_ptr->gameState().isSetupState())
{
auto enemy_threats =
getAllEnemyThreats(world_ptr->field(), world_ptr->friendlyTeam(),
world_ptr->enemyTeam(), world_ptr->ball(), false);

PriorityTacticVector result = {{}};

// set the requirement that Robot 1 must be able to kick and chip
move_tactics.at(0)->mutableRobotCapabilityRequirements() = {
RobotCapability::Kick, RobotCapability::Chip};

// setup 5 kickoff positions in order of priority
for (unsigned i = 0; i < kickoff_setup_positions.size(); i++)
{
move_tactics.at(i)->updateControlParams(kickoff_setup_positions.at(i),
Angle::zero());
result[0].emplace_back(move_tactics.at(i));
}

// yield the Tactics this Play wants to run, in order of priority
yield(result);
}

// Part 2: not normal play, currently ready state (chip the ball)
while (!world_ptr->gameState().isPlaying())
{
auto enemy_threats =
getAllEnemyThreats(world_ptr->field(), world_ptr->friendlyTeam(),
world_ptr->enemyTeam(), world_ptr->ball(), false);

PriorityTacticVector result = {{}};

// TODO (#2612): This needs to be adjusted post field testing, ball needs to land
// exactly in the middle of the enemy field
Point ball_position = world_ptr->ball().position();
Point kick_target = world_ptr->field().centerPoint() +
Vector(world_ptr->field().xLength() / 6, 0);
AutoChipOrKick auto_chip_or_kick = {AutoChipOrKickMode::AUTOCHIP,
(kick_target - ball_position).length()};
kickoff_chip_tactic->updateControlParams(ball_position, kick_target,
auto_chip_or_kick);
result[0].emplace_back(kickoff_chip_tactic);

// the robot at position 0 will be closest to the ball, so positions starting from
// 1 will be assigned to the rest of the robots
for (unsigned i = 1; i < kickoff_setup_positions.size(); i++)
{
move_tactics.at(i)->updateControlParams(kickoff_setup_positions.at(i),
Angle::zero());
result[0].emplace_back(move_tactics.at(i));
}

// yield the Tactics this Play wants to run, in order of priority
yield(result);
}
}


// Register this play in the genericFactory
static TGenericFactory<std::string, Play, KickoffFriendlyPlay,
std::shared_ptr<const TbotsProto::AiConfig>>
factory;
Loading
Loading