Overview

In short, the structure of STP is as followed; Skills are the building blocks of Tactics, Tactics are the building blocks of Roles, Roles are the building blocks of Plays. Every part of STP has there own function which should not overlap and be as short as possible. All decisions are made in the AP or in the Play. AP runs the loop (Algorithm 5) every tick. In this tick, the following happens:

  1. [ApplicationManager] Update theworld to all modules (excluding the play).
  2. [ApplicationManager] Check if current play is valid, if yes skip to step 7, or that the interface changed it, if yes skip to step 6.
  3. [PlayChecker] Get all valid plays.
  4. [PlayEvaluator] Determine the scores of the valid plays.
  5. [PlayDecider] Pick the best scored play.
  6. [ApplicationManager] Change the odd play to the new play.
  7. [ApplicationManager] Update the world to the current play.
  8. [ApplicationManager] Run update of the current play.
  9. [Play] Calculate all the STPInfos.
  10. [Play] Run all Roles updates.
  11. [Role] Run current Tactics.
  12. [Tactic] Run current Skills.
  13. [Skill] Create command for Robot.
  14. [ApplicationManager] Send robot commands.

Background

The goal of STP was to solve the problem of controlling a centralized team of robots to achieve long-term goals. The architecture of this system is designed to be highly versatile in relation to the state of the game. Their vision for STP was to create an AI that would be able to respond to the game state through all levels of individual robot and team control. They suggested 4 challenges that their system should solve:

  • Adaptability/interruptablity within long sequences of commands to respond to unexpected events of the game while sticking to a long-term goal.
  • Respond to the opponents’ team strategies and movements.
  • Reliably behaviour of individual robots.
  • Interchangeable architecture for easy configurations of team play and decision making.

The result was a modular system that split the behaviour of the team and the individual robots into 3 distinct parts, Skill, Tactic, Play. The RTT of 19/20 implemented STP based on the architecture suggested by CMDragons, however made small alterations and filled in the blanks of the suggested architecture to increase modularity of the system. They split up various parts of the system into stand-alone modules. This allows for every part of STP to be simple and compact lines of code that could be adjusted without requiring the re-coding of existing parts of the system. For example, implementing a new part to STP called ’Role’ which is a collection of Tactics and can be reused in every play, separating the role dealer, play evaluation to a new module called Dealer and PlayChecker respectively.

STP starts at the information layer called STPInfo and continues with the bottom layer, skills, and builds up the architecture from there. Every layer has its own clear responsibility and (apart from plays) should be built in a way that it can be reused as building block for the layer directly above. Each element of the layer (the skills, tactics, roles) should be as simple as possible, where if a sequence of any sort could be split, it probably should be split (resulting in less duplicate code).

To communicate through the layers of STP, the structure STPInfo’s was implemented. In this structure, decisions and other computations for STP are stored for each individual role. The STPInfo is sent down to every layer from the play and is unique to that play (a new play means a new STPInfo). STPInfo is unique to a Role and the Play has the collection of STPInfo’s bound to each unique role name.

Flowchart of the working of a skill A skill is an atomic class. As it is the lowest layer of STP, it is the part of the AI that formulates the commands that get sent to the individual robots. It encapsulates a “basic” robot behaviour, like a kick or go-to position. Skills use the structure STPInfo to receive the data the skill needs to execute, like what dribbler speed it should run at or to what coordinates the robot should drive. Basic computations can be done to convert information into the required formation. Skills return Status::Success or Status::Running. They are not allowed to fail, failing would be a result of incorrect constants or too strict margins. If they do not return with a Success, the Skill will simply try again until it does. Note that a skill needs specific inputs, simply calling goToPos without setting a position is useless.

Algorithm 1: Skill::onUpdate()
getSTPinfo;
if STPInfo is complete then
→ Calculate skill info;
→ Generate command
if Skill is done then
→ → return Status::Successful
else
→ → return Status::Running
Requirements of a Skill

The requirements of skill are the following.

  • It must only perform a single task (i.e. rotate, move, shoot)
  • It should not consist of other skills
  • They are not allowed to fail.

Flowchart of the working of a tactic The tactic is a State Machine (SM) of skills, a specific order of multiple skills make one tactic. It moves linearly through the skills, progressing when the skill is successful. Within a tactic the information for the skills are calculated and saved in the STPInfo, however, tactics are not allowed to make decisions.

A tactic can have one of 4 statuses; Success, Running, Waiting or Failure. A tactic is successful if all the skills in the SM have also been successful, Running if one of the skills is still being run, Waiting if the tactic should not end when finishing all skills and Failure if the tactic is no longer valid.

Resetting a tactic will restart the SM to the first skill entry. This is used in situations where instead of failing the tactic, it should restart. For example, when dribbling with the ball, the ball rolls away from the robot, the tactic of dribbling the ball should not fail (and end), but the tactic should go to the ball again and resume.

Failing a tactic is used in situations where the tactic has to end because resetting it so not the solution. For example, when passing the ball, the tactic needs to have the ball, if the ball is lost or stolen the tactic should fail. Failing will allow the AI to make a decision in the play if to restart the play or pick a new play.

A tactic is an ’EndTactic’ if after the success of the tactic it should be repeated. If a tactic is not an ’EndTactic’, the next tactic in the SM will be executed.

Algorithm 2: Tactic::onUpdate()
getSTPinfo;
if STPInfo is complete then
→ run current skill::onUpdate();
if Skills are finished then
→ → if Tactic is not EndTactic then
→ → → return Status::Success
→ → else then
→ → → reset all skills in the tactic
→ → → return Status::Waiting
if Tactic if failing then
→ → return Status::Failure
→ return Status::Running;
Requirements of a Tactic

The requirements of a tactic are the following.

  • It calculates the necessary information for the skills in its SM
  • The calculations should be short
  • It makes no decisions, this should be done in the play

Flowchart of the working of a role The role is a SM of tactics. Similar to the tactics, roles have the same 4 statuses with the same implementations. A STPInfo is given to each unique (by role name) role. If the last tactic of the role is a EndTactic, the role will always keep on running, otherwise the role is successful.

Algorithm 3: Role::update()
getSTPinfo;
if STPInfo is complete then
→ run current tactic::onUpdate();
if Tactics are finished then
→ → return Status::Successful
if Tactic is failing then
→ →Reset tactics;
if is EndTactic then
→ →return Status::Waiting;
→ return Status::Running;
Requirements of a Role
The requirements of a role is that it has a unique role name within the play.

Flowchart of the working of a play The play is where everything of STP comes together. In the play, the play designer is able to pick roles that are needed in that play, define when plays are valid to be played and define when they are failing, calculate or define information for the STPInfo for each role, define what is important for the scoring of the play, define what is important for each role and how to distribute the roles.

The play has a collection of uniquely named roles, which it calls upon to update. For each role, the play contains the calculations for the required information of the STPInfo. This information can include the desired location of the role, the position to shoot at, the enemy robot to defend and every other bit of optional STPInfo that the role, tactic or skill requires to be able to run. Additionally, the play defines what is important for each role so that the dealer is able to efficiently distribute the roles between the robots. If there something needs to happen when a role/tactic fails, the play should contain the decision that needs to be done

Algorithm 4: Play::update()
Clear Role Statuses
Update STPInfo views (Ball, Field);
Calculate Role information;
foreach Role do
→ run Role::update()

The rest of the play is ran from the Application Manager (AP) and its various modules. This includes the decision which play is picked, if the current play is still allowed to be played (with PlayChecker), which are allowed to be played (with PlayDecider) and changing plays.

Algorithm 5: ApplicationManager::runOneLoopCycle()
Get current world from view module;
Update all modules with this ticks world;
if play set by interface then
→ Change play to picked play;
→ Initialize new play;
if current play is not valid to keep then
→ Get all valid plays;
→ Calculate scores of valid plays;
→ Pick highest scoring play;
→ Initialize new play;
run current Play::update();
Requirements of a Play

Requirements of a play:

  • It uses roles with unique names
  • All decisions (all design choices) are made here
  • All information for roles/tactics are defined here.