Skip to content
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
66303ec
Merge pull request #1 from UBC-Thunderbots/master
someone2060 Sep 28, 2024
d7f9452
Merge pull request #2 from UBC-Thunderbots/master
someone2060 Oct 4, 2024
00f3753
Refactor `StopTactic` to `HaltTactic`, refactoring variables where ne…
someone2060 Oct 4, 2024
148d72a
Rename `stop_tactic.cpp` and `stop_tactic.h` to `halt_tactic.cpp` and…
someone2060 Oct 5, 2024
629c067
Rename `stop_tactic_test.cpp` to `halt_tactic_test.cpp`
someone2060 Oct 5, 2024
835de96
Rename `stop_fsm` and `stop_fsm_test` to `halt_fsm` and `halt_fsm_tes…
someone2060 Oct 5, 2024
3d7810f
Rename `tactic/stop` folder to `tactic/halt`, renaming addresses wher…
someone2060 Oct 5, 2024
922210f
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 5, 2024
fc27428
Small consistency improvements
someone2060 Oct 5, 2024
12d8ecc
Small consistency improvements
someone2060 Oct 5, 2024
e5f56d7
Merge branch 'master' into master
someone2060 Oct 12, 2024
cca2c0b
Create `example` directory containing all example plays (fsm incomplete)
someone2060 Oct 19, 2024
95aeed1
Create `example` directory containing all example plays (FSM incomplete)
someone2060 Oct 26, 2024
c470919
Copy relevant code from other fsm plays to `example_play` files
someone2060 Oct 26, 2024
82b4961
Merge remote-tracking branch 'origin/exampleplay-to-fsm' into example…
someone2060 Oct 26, 2024
3585ac7
Remove `example_play_fsm_test.cpp`
someone2060 Oct 26, 2024
1d9248d
Implement `example_play_fsm.cpp` and `example_play_fsm.h`
someone2060 Oct 26, 2024
54afbb4
Debug `example_play_fsm.cpp`
someone2060 Oct 28, 2024
b579915
Merge branch 'UBC-Thunderbots:master' into exampleplay-to-fsm
someone2060 Oct 28, 2024
9631d55
comment fix
someone2060 Oct 28, 2024
e6d5f47
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Oct 28, 2024
8d75313
Remove `AIConfig` from example plays
someone2060 Oct 30, 2024
b44573a
Implement suggestions from @williamckha
someone2060 Nov 11, 2024
fb504d2
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Nov 11, 2024
ad79923
Create `example_play_fsm_test.cpp`
someone2060 Nov 11, 2024
de099bc
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Nov 11, 2024
fceadea
temp push
someone2060 Feb 1, 2025
328f774
Merge branch 'exampleplay-to-fsm' of ssh://ssh.github.com:443/someone…
someone2060 Feb 8, 2025
55c6345
(try to) Merge master branch into own branch
someone2060 Feb 8, 2025
201be90
Remove merge conflict in `play/example/BUILD`
someone2060 Feb 8, 2025
1d3c628
Merge branch 'master' of https://github.com/UBC-Thunderbots/Software …
someone2060 Feb 8, 2025
2d30eb1
Resolve `.BUILD` merge conflict
someone2060 Feb 17, 2025
67d1ee6
Adds pytests for example play
GrayHoang Apr 29, 2025
c2998e2
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] Apr 29, 2025
2bb773b
Merge branch 'master' of https://github.com/UBC-Thunderbots/Software …
williamckha May 15, 2025
facfc19
Small fixes
williamckha May 15, 2025
3515714
[pre-commit.ci lite] apply automatic fixes
pre-commit-ci-lite[bot] May 15, 2025
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
13 changes: 13 additions & 0 deletions docs/fsm-diagrams.md
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,19 @@ Terminate:::terminate --> Terminate:::terminate

```

## [ExamplePlayFSM](/src/software/ai/hl/stp/play/example/example_play_fsm.h)

```mermaid

stateDiagram-v2
classDef terminate fill:white,color:black,font-weight:bold
direction LR
[*] --> MoveState
MoveState --> MoveState : <i>moveToPosition</i>
Terminate:::terminate --> Terminate:::terminate

```

## [FreeKickPlayFSM](/src/software/ai/hl/stp/play/free_kick/free_kick_play_fsm.h)

```mermaid
Expand Down
30 changes: 1 addition & 29 deletions src/software/ai/hl/stp/play/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,6 @@ load("@simulated_tests_deps//:requirements.bzl", "requirement")
# "factory" design pattern to work are linked in
# https://www.bfilipek.com/2018/02/static-vars-static-lib.html

cc_library(
name = "example_play",
srcs = ["example_play.cpp"],
hdrs = ["example_play.h"],
deps = [
":play",
"//shared:constants",
"//software/ai/hl/stp/tactic/move:move_tactic",
"//software/logger",
"//software/util/generic_factory",
],
alwayslink = True,
)

cc_library(
name = "kickoff_enemy_play",
srcs = ["kickoff_enemy_play.cpp"],
Expand Down Expand Up @@ -119,7 +105,6 @@ cc_library(
cc_library(
name = "all_plays",
deps = [
":example_play",
":kickoff_enemy_play",
":kickoff_friendly_play",
":shoot_or_chip_play",
Expand All @@ -129,6 +114,7 @@ cc_library(
"//software/ai/hl/stp/play/defense:defense_play",
"//software/ai/hl/stp/play/enemy_ball_placement:enemy_ball_placement_play",
"//software/ai/hl/stp/play/enemy_free_kick:enemy_free_kick_play",
"//software/ai/hl/stp/play/example:example_play",
"//software/ai/hl/stp/play/free_kick:free_kick_play",
"//software/ai/hl/stp/play/halt_play",
"//software/ai/hl/stp/play/hardware_challenge_plays:dribbling_parcour_play",
Expand All @@ -142,20 +128,6 @@ cc_library(
],
)

cc_test(
name = "example_play_test",
srcs = ["example_play_test.cpp"],
deps = [
"//shared/test_util:tbots_gtest_main",
"//software/ai/hl/stp/play:example_play",
"//software/simulated_tests:simulated_er_force_sim_play_test_fixture",
"//software/simulated_tests/validation:validation_function",
"//software/test_util",
"//software/time:duration",
"//software/world",
],
)

cc_test(
name = "kickoff_friendly_play_cpp_test",
srcs = ["kickoff_friendly_play_test.cpp"],
Expand Down
63 changes: 63 additions & 0 deletions src/software/ai/hl/stp/play/example/BUILD
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package(default_visibility = ["//visibility:public"])

load("@simulated_tests_deps//:requirements.bzl", "requirement")

cc_library(
name = "example_play",
srcs = [
"example_play.cpp",
"example_play_fsm.cpp",
],
hdrs = [
"example_play.h",
"example_play_fsm.h",
],
deps = [
"//shared:constants",
"//software/ai/hl/stp/play",
"//software/ai/hl/stp/tactic/move:move_tactic",
"//software/logger",
"//software/util/generic_factory",
],
alwayslink = True,
)

cc_test(
name = "example_play_test",
srcs = ["example_play_test.cpp"],
deps = [
"//shared/test_util:tbots_gtest_main",
"//software/ai/hl/stp/play/example:example_play",
"//software/simulated_tests:simulated_er_force_sim_play_test_fixture",
"//software/simulated_tests/validation:validation_function",
"//software/test_util",
"//software/time:duration",
"//software/world",
],
)

cc_test(
name = "example_play_fsm_test",
srcs = ["example_play_fsm_test.cpp"],
deps = [
":example_play",
"//shared/test_util:tbots_gtest_main",
"//software/test_util",
],
)

py_test(
name = "example_play_test_py",
srcs = ["example_play_test.py"],
main = "example_play_test.py",
# TODO (#2619) Remove tag to run in parallel
tags = [
"exclusive",
],
deps = [
"//software:conftest",
"//software/simulated_tests:speed_threshold_helpers",
"//software/simulated_tests:validation",
requirement("pytest"),
],
)
31 changes: 31 additions & 0 deletions src/software/ai/hl/stp/play/example/example_play.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#include "software/ai/hl/stp/play/example/example_play.h"

#include "shared/constants.h"
#include "software/util/generic_factory/generic_factory.h"

ExamplePlay::ExamplePlay(TbotsProto::AiConfig config)
: Play(config, false), fsm{ExamplePlayFSM{}}, control_params{}
{
}

void ExamplePlay::getNextTactics(TacticCoroutine::push_type &yield,
const WorldPtr &world_ptr)
{
// This function doesn't get called and it will be removed once coroutines are phased
// out
}

void ExamplePlay::updateTactics(const PlayUpdate &play_update)
{
fsm.process_event(ExamplePlayFSM::Update(control_params, play_update));
}

std::vector<std::string> ExamplePlay::getState()
{
std::vector<std::string> state;
state.emplace_back(objectTypeName(*this) + " - " + getCurrentFullStateName(fsm));
return state;
}

// Register this play in the genericFactory
static TGenericFactory<std::string, Play, ExamplePlay, TbotsProto::AiConfig> factory;
26 changes: 26 additions & 0 deletions src/software/ai/hl/stp/play/example/example_play.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#pragma once

#include "software/ai/hl/stp/play/example/example_play_fsm.h"

/**
* An example play that moves the robots in a circle around the ball
*/
class ExamplePlay : public Play
{
public:
/**
* Creates an example play
*
* @param ai_config the play config for this play
*/
ExamplePlay(TbotsProto::AiConfig config);

void getNextTactics(TacticCoroutine::push_type &yield,
const WorldPtr &world_ptr) override;
void updateTactics(const PlayUpdate &play_update) override;
std::vector<std::string> getState() override;

private:
FSM<ExamplePlayFSM> fsm;
ExamplePlayFSM::ControlParams control_params;
};
29 changes: 29 additions & 0 deletions src/software/ai/hl/stp/play/example/example_play_fsm.cpp
Comment thread
GrayHoang marked this conversation as resolved.
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#include "software/ai/hl/stp/play/example/example_play_fsm.h"

ExamplePlayFSM::ExamplePlayFSM() : move_tactics(DIV_A_NUM_ROBOTS)
{
std::generate(move_tactics.begin(), move_tactics.end(),
[]() { return std::make_shared<MoveTactic>(); });
}

void ExamplePlayFSM::moveToPosition(const Update &event)
{
// The angle between each robot spaced out in a circle around the ball
Angle angle_between_robots = Angle::full() / static_cast<double>(move_tactics.size());

for (size_t k = 0; k < move_tactics.size(); k++)
{
move_tactics[k]->updateControlParams(
event.common.world_ptr->ball().position() +
Vector::createFromAngle(angle_between_robots *
static_cast<double>(k + 1)),
(angle_between_robots * static_cast<double>(k + 1)) + Angle::half());
}

// Set the Tactics this Play wants to run, in order of priority.
// If there are fewer robots in play, robots at the end of the list will not be
// assigned
TacticVector result = {};
result.insert(result.end(), move_tactics.begin(), move_tactics.end());
event.common.set_tactics({result});
}
52 changes: 52 additions & 0 deletions src/software/ai/hl/stp/play/example/example_play_fsm.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
#pragma once

#include "proto/parameters.pb.h"
#include "shared/constants.h"
#include "software/ai/hl/stp/play/play.h"
#include "software/ai/hl/stp/tactic/move/move_tactic.h"
#include "software/logger/logger.h"

/**
* An example play that moves the robots in a circle around the ball
*/
struct ExamplePlayFSM
{
class MoveState;

struct ControlParams
{
};

DEFINE_PLAY_UPDATE_STRUCT_WITH_CONTROL_AND_COMMON_PARAMS

/**
* Creates an example play FSM
*/
explicit ExamplePlayFSM();

/**
* Action that moves the robots to certain positions around the ball
*
* @param event the ExamplePlayFSM Update event
*/
void moveToPosition(const Update& event);

auto operator()()
{
using namespace boost::sml;

DEFINE_SML_STATE(MoveState)

DEFINE_SML_EVENT(Update)

DEFINE_SML_ACTION(moveToPosition)

return make_transition_table(
// src_state + event [guard] / action = dest_state
*MoveState_S + Update_E / moveToPosition_A = MoveState_S,
X + Update_E = X);
}

private:
std::vector<std::shared_ptr<MoveTactic>> move_tactics;
};
27 changes: 27 additions & 0 deletions src/software/ai/hl/stp/play/example/example_play_fsm_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "software/ai/hl/stp/play/example/example_play_fsm.h"

#include <gtest/gtest.h>

#include "proto/parameters.pb.h"
#include "software/test_util/equal_within_tolerance.h"
#include "software/test_util/test_util.h"

TEST(ExamplePlayFSMTest, test_transitions)
{
std::shared_ptr<World> world = ::TestUtil::createBlankTestingWorld();
TbotsProto::AiConfig ai_config;

FSM<ExamplePlayFSM> fsm(ExamplePlayFSM{});

EXPECT_TRUE(fsm.is(boost::sml::state<ExamplePlayFSM::MoveState>));

int num_tactics = 6;

fsm.process_event(ExamplePlayFSM::Update(
ExamplePlayFSM::ControlParams{},
PlayUpdate(
world, num_tactics, [](PriorityTacticVector new_tactics) {},
InterPlayCommunication{}, [](InterPlayCommunication comm) {})));

EXPECT_TRUE(fsm.is(boost::sml::state<ExamplePlayFSM::MoveState>));
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

you should also write a FSM test and a pytest for your changes.

Take a look at Grayson's PR on how he does the FSM test: #3398

Comment thread
williamckha marked this conversation as resolved.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Okay some lore...

This is a simulated test. Simulated tests execute your AI changes against a simulator to simulate the world. We have two forms of these tests: a C++ test fixture and a newer Python test fixture. We are in the process of phasing the C++ tests out and replacing them with Python. Could you make a new example_play_test.py? Here's an example of what these look like: https://github.com/UBC-Thunderbots/Software/blob/master/src/software/ai/hl/stp/play/defense/defense_play_test.py

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#include "software/ai/hl/stp/play/example_play.h"
#include "software/ai/hl/stp/play/example/example_play.h"

#include <gtest/gtest.h>

Expand Down
Loading
Loading