From a21e5f7c9fd13370a99be8166918f288d257c3b7 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 4 Oct 2024 16:03:17 +0200
Subject: [PATCH 01/48] Try adding subpages to the website
---
docs/Tutorial.md | 4 ++++
1 file changed, 4 insertions(+)
create mode 100644 docs/Tutorial.md
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
new file mode 100644
index 00000000..ef2956a7
--- /dev/null
+++ b/docs/Tutorial.md
@@ -0,0 +1,4 @@
+# Arbitration Graphs Tutorial
+
+Let's write an agent for the famous PacMan game using Arbitration Graphs đšī¸
+
From 7cab87ac4f2fd03cf84610edfd745f0ad97e8869 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Tue, 8 Oct 2024 16:37:35 +0200
Subject: [PATCH 02/48] Add a first outline for the tutorial website
---
docs/Tutorial.md | 21 ++++++++++++++++++++
docs/tasks/1_implement_behavior_component.md | 12 +++++++++++
docs/tasks/2_extend_arbitration_graph.md | 15 ++++++++++++++
docs/tasks/3_add_more_behaviors.md | 15 ++++++++++++++
docs/tasks/4_nested_arbitrators.md | 15 ++++++++++++++
docs/tasks/5_cost_arbitration.md | 12 +++++++++++
6 files changed, 90 insertions(+)
create mode 100644 docs/tasks/1_implement_behavior_component.md
create mode 100644 docs/tasks/2_extend_arbitration_graph.md
create mode 100644 docs/tasks/3_add_more_behaviors.md
create mode 100644 docs/tasks/4_nested_arbitrators.md
create mode 100644 docs/tasks/5_cost_arbitration.md
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index ef2956a7..7769ead3 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -2,3 +2,24 @@
Let's write an agent for the famous PacMan game using Arbitration Graphs đšī¸
+## Introduction
+- [ ] What to find where in the repo?
+- [ ] What is the goal of the tutorial?
+
+## Tasks
+
+1. [Implement your first behavior component](./tasks/1_implement_behavior_component.md)
+2. [Extend the arbitration graph with that behavior](./tasks/2_extend_arbitration_graph.md)
+3. [Add even more behavior components](./tasks/3_add_more_behaviors.md)
+4. [Learn about nested arbitration graphs](./tasks/4_nested_arbitrators.md)
+5. [Arbitrate based on predicted utility](./tasks/5_cost_arbitration.md)
+
+
+- [ ] Finish chase ghost finish so that is passes unit tests by re-implementing some removed part, e.g. getCommand
+- [ ] Integrate chase ghost into priority arbitrator
+- [ ] Integrate eat closest dot behavior
+- [ ] Integrate eat dot arbitrator as random arbitrator
+- [ ] Replace arbitrator from previous step with cost arbitrator, finish cost estimator
+
+## General TODOs
+- [ ] Add a bit of an explanation about arbitration graphs to top-level readme
\ No newline at end of file
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
new file mode 100644
index 00000000..15c8eb61
--- /dev/null
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -0,0 +1,12 @@
+---
+title: "Task 1: Implement a Behavior Component"
+description: Implement your first getCommand function, such that the ChaseGhost behavior component passes its unit tests.
+---
+
+# Chase Ghost
+
+
+---
+[Tutorial Home](../Tutorial.md)
+|
+[Next task â](2_extend_arbitration_graph.md)
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
new file mode 100644
index 00000000..0234078e
--- /dev/null
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -0,0 +1,15 @@
+---
+title: "Task 2: Extend the Arbitration Graph"
+description: Extend the arbitration graph with the ChaseGhost behavior component.
+---
+
+# Chase Ghost
+
+
+
+---
+[â Previous task](1_implement_behavior_component.md)
+|
+[Tutorial Home](../Tutorial.md)
+|
+[Next task â](3_add_more_behaviors.md)
\ No newline at end of file
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
new file mode 100644
index 00000000..5412b5c8
--- /dev/null
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -0,0 +1,15 @@
+---
+title: "Task 3: Even more behavior components"
+description: Integrate the EatClosestDot behavior component into the arbitration graph.
+---
+
+# Eat Closest Dot
+
+
+
+---
+[â Previous task](2_extend_arbitration_graph.md)
+|
+[Tutorial Home](../Tutorial.md)
+|
+[Next task â](4_nested_arbitrators.md)
\ No newline at end of file
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
new file mode 100644
index 00000000..faf625ea
--- /dev/null
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -0,0 +1,15 @@
+---
+title: "Task 4: Nested arbitration graphs"
+description: Integrate a long-term behavior and add another layer to the arbitration graph
+---
+
+# Nesting
+
+
+
+---
+[â Previous task](3_add_more_behaviors.md)
+|
+[Tutorial Home](../Tutorial.md)
+|
+[Next task â](5_cost_arbitration.md)
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
new file mode 100644
index 00000000..d50951d8
--- /dev/null
+++ b/docs/tasks/5_cost_arbitration.md
@@ -0,0 +1,12 @@
+---
+title: "Task 5: Arbitrate based on predicted utility"
+description: Learn how the cost arbitrator can help you to arbitrate between behaviors based on their expected cost/utility.
+---
+
+# Cost Arbitrator
+
+
+---
+[â Previous task](4_nested_arbitrators.md)
+|
+[Tutorial Home](../Tutorial.md)
\ No newline at end of file
From f351c8d281b917396c7f03884acb258e91165730 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Fri, 18 Oct 2024 20:28:16 +0200
Subject: [PATCH 03/48] Write the main landing page of the tutorial
.
---
docs/Tutorial.md | 84 ++++++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 81 insertions(+), 3 deletions(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index 7769ead3..49608215 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -2,12 +2,90 @@
Let's write an agent for the famous PacMan game using Arbitration Graphs đšī¸
+**TL;DR**: Find links to the individual tasks at the bottom of this page.
+
## Introduction
-- [ ] What to find where in the repo?
-- [ ] What is the goal of the tutorial?
+
+
+### Goal
+
+The goal of this tutorial is to help you understand how to use the Arbitration Graphs library.
+To keep things interesting, we will re-implement some parts of our PacMan demo.
+
+We'll start by looking into the implementation of a single behavior component
+ and then learn how to integrate it into an arbitration graph using a simple priority arbitrator.
+
+Next, we'll start adding more and more behavior components to the graph and learn about other aspects of the library
+ such as cost arbitrators, nested structures and verification.
+
+The tutorial is structured into several tasks that are meant to be completed in order.
+
+### What to find where
+
+Let's take a look at the structure and content of the `arbitration_graphs/demo` directory.
+All header files can be found in the `include/demo/` directory with corresponding implementation files in the `src/` directory.
+The entire demo is thoroughly tested using the unit tests you'll find in the `test/` directory.
+
+Each behavior component is implemented in a separate `_behavior.hpp` file as a class inheriting from the abstract `Behavior` class.
+
+Next, there is `environment_model.hpp`.
+You guessed it, it contains the environment model for the arbitration graph.
+In it, we store things like current positions of PacMan and the ghosts, the maze, several utility functions
+ and other things required by the behavior components.
+
+Finally, in `pacman_agent.hpp`, the behavior components are assembled into an arbitration graph.
+It's also where you'll spend most of your time during this tutorial.
+
+If you are interested in how the demo works in detail,
+ you'll find additional code not directly relevant to the tutorial in the `include/utils/` directory
+
+### Development Environment
+
+The easiest way to get started is to use the provided docker setup.
+
+Start by checking out the `tutorial` branch where we have removed some parts
+ of the demo implementation for the purpose of this tutorial.
+```bash
+git checkout tutorial
+```
+
+To be dropped into an interactive shell with all required dependencies installed
+ and the current directory mounted, run
+```bash
+cd arbitration_graphs/demo
+docker compose run --rm tutorial
+```
+
+You can then create a build directory and run CMake to build the project.
+You should enable the `BUILD_TESTS` option to build the unit tests as well.
+
+```bash
+cd /home/blinky/demo
+mkdir -p arbitration_graphs/demo/build
+cd arbitration_graphs/demo/build
+cmake -DBUILD_TESTS=true ..
+cmake --build .
+```
+
+You can then run the demo with
+```bash
+./arbitration_graphs_pacman_demo_exe
+```
+
+You'll also find the individual unit executables in this directory.
+To execute them all at once, run
+```bash
+find -executable -type f -name '*-gtest-*' -exec {} \;
+```
+
+We'll leave the setup of your favorite IDE up to you
+ though most modern IDEs should support attaching to a running docker container.
+
## Tasks
+With the basics out of the way, let's work through the tasks.
+
1. [Implement your first behavior component](./tasks/1_implement_behavior_component.md)
2. [Extend the arbitration graph with that behavior](./tasks/2_extend_arbitration_graph.md)
3. [Add even more behavior components](./tasks/3_add_more_behaviors.md)
@@ -22,4 +100,4 @@ Let's write an agent for the famous PacMan game using Arbitration Graphs đšī¸
- [ ] Replace arbitrator from previous step with cost arbitrator, finish cost estimator
## General TODOs
-- [ ] Add a bit of an explanation about arbitration graphs to top-level readme
\ No newline at end of file
+- [ ] Add a bit of an explanation about arbitration graphs to top-level readme
From 354d79a21ea2f39b23d3edcd8dc1a89a7f7967a3 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Fri, 18 Oct 2024 20:28:38 +0200
Subject: [PATCH 04/48] Add the description for the first task of the tutorial
---
docs/tasks/1_implement_behavior_component.md | 35 +++++++++++++++++++-
1 file changed, 34 insertions(+), 1 deletion(-)
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
index 15c8eb61..82ea1e34 100644
--- a/docs/tasks/1_implement_behavior_component.md
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -1,10 +1,43 @@
---
title: "Task 1: Implement a Behavior Component"
-description: Implement your first getCommand function, such that the ChaseGhost behavior component passes its unit tests.
+description: Implement your first checkInvocationCondition and getCommand function, such that the ChaseGhost behavior component passes its unit tests.
---
# Chase Ghost
+## Context
+
+Before we start building our arbitration graph, we want to take a closer look into behavior components.
+Don't worry, most of the behavior components are already implemented for you
+ but we want to make sure you have an idea of how they work.
+
+With the current state of the arbitration graph, PacMan will just move around randomly until a ghost gets too close.
+That's great and all but if we ate a power pellet, we want to chase the ghosts to eat them for extra points.
+
+To do this, we need to implement the `ChaseGhost` behavior component.
+It essentially does the exact opposite of the `AvoidGhost` behavior component
+ but is only applicable when PacMan ate a power pellet.
+We can ensure that's always the case using the behavior's invocation condition.
+
+But wait - the current implementation of the invocation condition is not complete.
+It should only be applicable if there is one of these tasty ghosts close by.
+
+Once that's out of the way, we'll take a closer look at the `getCommand` function which is missing some core logic right now.
+
+## Goal
+
+Finish the implementation of the `checkInvocationCondition` and `getCommand` functions
+ of the `ChaseGhost` behavior component such that it passes its unit tests.
+
+## Instructions
+
+- Open the implementation of the `ChaseGhost` behavior component in `src/chase_ghost_behavior.cpp`.
+- The `checkInvocationCondition` function is already implemented but does not check for the presence of a ghost.
+- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::checkInvocationCondition` if you need inspiration.
+- The `getCommand` function is partially implemented but the core logic is missing.
+- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::getCommand` if you need inspiration.
+- Compile and run the unit tests for the `ChaseGhost` behavior component to verify that your implementation is correct.
+
---
[Tutorial Home](../Tutorial.md)
From 72585c3f1e1d6895e914e646e8e9e33065921272 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Tue, 22 Oct 2024 16:33:50 +0200
Subject: [PATCH 05/48] Add the second task
---
docs/tasks/2_extend_arbitration_graph.md | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index 0234078e..84b09546 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -5,6 +5,26 @@ description: Extend the arbitration graph with the ChaseGhost behavior component
# Chase Ghost
+## Context
+
+With our next behavior component ready to go, we need to think about integrating it into our arbitration graph.
+
+For this purpose, we need to modify the `PacmanAgent` class to include the `ChaseGhost` behavior component we implemented in the previous task.
+Integrating a new behavior component into the arbitration graph is as simple as instantiating it and adding it as a new option to one of the arbitrators.
+Since right now there is just one arbitrator - a priority arbitrator - the choice is simple.
+We just need to worry about the order in which the options are assigned to the arbitrator.
+Should chasing a ghost have a higher priority than avoiding a ghost or vice versa?
+
+## Goal
+
+Integrate the `ChaseGhost` behavior component into the arbitration graph defined in the `PacmanAgent` class.
+
+## Instructions
+
+- Take a look at how the other behavior components are defined in `include/demo/pacman_agent.hpp`.
+- Add the `ChaseGhost` behavior component as a new member of the `PacmanAgent` class and initialize it in the constructor.
+- Add a new option to the priority arbitrator.
+- Run the game, take a look at the new arbitration graph and observe how PacMan behaves.
---
@@ -12,4 +32,4 @@ description: Extend the arbitration graph with the ChaseGhost behavior component
|
[Tutorial Home](../Tutorial.md)
|
-[Next task â](3_add_more_behaviors.md)
\ No newline at end of file
+[Next task â](3_add_more_behaviors.md)
From bc034231837d7d0a80e61bae80e12b7cd4d354e2 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Tue, 22 Oct 2024 16:40:17 +0200
Subject: [PATCH 06/48] Add the third task
---
docs/tasks/3_add_more_behaviors.md | 22 +++++++++++++++++++++-
1 file changed, 21 insertions(+), 1 deletion(-)
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
index 5412b5c8..08b829a0 100644
--- a/docs/tasks/3_add_more_behaviors.md
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -5,6 +5,26 @@ description: Integrate the EatClosestDot behavior component into the arbitration
# Eat Closest Dot
+## Context
+
+So far, we have not looked into a behavior component that handles the most important aspect of the game: eating dots.
+So now is a good a time as any to further extend our arbitration graph with the `EatClosestDot` behavior component.
+
+We don't want to bore you with the details of planning a path through a PacMan maze, so we have already implemented that for you.
+You just need to integrate it into the arbitration graph, very similarly to the last task.
+
+We'll keep it simple and just add it as another option to the priority arbitrator.
+Arbitration graphs can be nested of course, but we'll save that for the next task.
+
+## Goal
+
+Integrate the `EatClosestDot` behavior component into the arbitration graph defined in the `PacmanAgent` class.
+
+## Instructions
+
+- Integrate the new component just like you did in the last task.
+- Start the game and see how PacMan stop wandering around aimlessly and starts eating dots.
+
---
@@ -12,4 +32,4 @@ description: Integrate the EatClosestDot behavior component into the arbitration
|
[Tutorial Home](../Tutorial.md)
|
-[Next task â](4_nested_arbitrators.md)
\ No newline at end of file
+[Next task â](4_nested_arbitrators.md)
From 777ff67a2e776e77ae0a2e639e4fde114b029f6d Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Tue, 22 Oct 2024 16:47:43 +0200
Subject: [PATCH 07/48] Add the fourth task
---
docs/tasks/4_nested_arbitrators.md | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
index faf625ea..42577cd2 100644
--- a/docs/tasks/4_nested_arbitrators.md
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -5,6 +5,30 @@ description: Integrate a long-term behavior and add another layer to the arbitra
# Nesting
+## Context
+
+We have now implemented a few behavior components and integrated them into the arbitration graph.
+So far, all behavior components are children of the root arbitrator.
+
+Let's make things a bit more interesting by adding a long-term behavior component that's also about eating dots.
+The `ChangeDotCluster` behavior will move to an area in the maze where there is a higher density of dots.
+
+For now, we'll just decide between the two dot eating strategies using chance.
+We can achieve that by adding them to a random arbitrator which is then added as an option to the root arbitrator.
+
+There are more sophisticated ways to decide between behavior components, we'll cover those in the next task.
+
+## Goal
+
+Add the `EatClosestDot` and `ChangeDotCluster` behavior components to a random arbitrator nested within the root arbitrator.
+
+## Instructions
+
+- Add the `ChangeDotCluster` behavior component as a new member of the `PacmanAgent` class and initialize it in the constructor.
+- Add a random arbitrator as a new member of the `PacmanAgent` class, analogous to the priority arbitrator.
+- Add the `EatClosestDot` and `ChangeDotCluster` behavior components as options to the random arbitrator.
+- Add the random arbitrator as an option to the root arbitrator.
+- Run the game and observe how PacMan behaves.
---
From 7736b5148b1025fe262e08eba211c293c23dd878 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Thu, 24 Oct 2024 10:19:57 +0200
Subject: [PATCH 08/48] Add the fifth task
---
docs/Tutorial.md | 2 ++
docs/tasks/5_cost_arbitration.md | 29 ++++++++++++++++++++++++++++-
2 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index 49608215..ef5f14e5 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -33,6 +33,8 @@ You guessed it, it contains the environment model for the arbitration graph.
In it, we store things like current positions of PacMan and the ghosts, the maze, several utility functions
and other things required by the behavior components.
+The `cost_estimator.hpp` file will be relevant for a later task when we cover cost arbitrators.
+
Finally, in `pacman_agent.hpp`, the behavior components are assembled into an arbitration graph.
It's also where you'll spend most of your time during this tutorial.
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index d50951d8..8c95ee59 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -5,8 +5,35 @@ description: Learn how the cost arbitrator can help you to arbitrate between beh
# Cost Arbitrator
+## Context
+
+The `EatDot` arbitrator we added in the previous task decides between the two dot eating strategies randomly.
+That's obviously not the greatest idea.
+There must be a better way.
+
+Turns out, there is!
+There is another type of arbitrator that might be more suitable for this task: the cost arbitrator.
+
+As the name suggests, the cost arbitrator computes a cost for each command received from its children and selects the one with the lowest cost.
+We need some kind of cost function for this, which we will implement in the `CostEstimator` class.
+
+The idea is to reward a planned path that contains lots of dots while also moving into an area with a high dot density.
+We prepared the general structure of the `CostEstimator` class for you, you just need to fill in the blanks.
+
+Let's get started!
+
+## Goal
+
+Finish the implementation of the `CostEstimator` and replace the random arbitrator with a cost arbitrator.
+
+## Instructions
+
+- In `cost_estimator.cpp`, fill in the blanks to compute `nDots` and `nCells`.
+- Add an instance of the `CostEstimator` to the `PacmanAgent` class and initialize it in the constructor.
+- Replace the random arbitrator with a cost arbitrator in the `PacmanAgent` class. Pass the `CostEstimator` instance to the `addOption` method.
+
---
[â Previous task](4_nested_arbitrators.md)
|
-[Tutorial Home](../Tutorial.md)
\ No newline at end of file
+[Tutorial Home](../Tutorial.md)
From 9d45ee38a1561e9cdb1da6be030abc0e9bf77220 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Thu, 24 Oct 2024 14:21:21 +0200
Subject: [PATCH 09/48] Add the sixth task
---
docs/Tutorial.md | 2 +
docs/tasks/5_cost_arbitration.md | 2 +
docs/tasks/6_verification.md | 67 ++++++++++++++++++++++++++++++++
3 files changed, 71 insertions(+)
create mode 100644 docs/tasks/6_verification.md
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index ef5f14e5..c7d42ac4 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -35,6 +35,8 @@ In it, we store things like current positions of PacMan and the ghosts, the maze
The `cost_estimator.hpp` file will be relevant for a later task when we cover cost arbitrators.
+Similarly, the `verifier.hpp` file will be used to add a verification layer to the arbitration graph near the end of the tutorial.
+
Finally, in `pacman_agent.hpp`, the behavior components are assembled into an arbitration graph.
It's also where you'll spend most of your time during this tutorial.
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index 8c95ee59..ecc70201 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -37,3 +37,5 @@ Finish the implementation of the `CostEstimator` and replace the random arbitrat
[â Previous task](4_nested_arbitrators.md)
|
[Tutorial Home](../Tutorial.md)
+|
+[Next task â](6_verification.md)
diff --git a/docs/tasks/6_verification.md b/docs/tasks/6_verification.md
new file mode 100644
index 00000000..0fc10efa
--- /dev/null
+++ b/docs/tasks/6_verification.md
@@ -0,0 +1,67 @@
+---
+title: "Task 6: Better safe than sorry"
+description: Execute only safe commands and add a fallback strategy.
+---
+
+# Verification and Fallback Layers
+
+## Context
+
+The arbitration graph is now complete and PacMan is eating dots like a pro.
+But there is one last topic we want to talk about: safety and robustness.
+
+Depending on your application, you might be interested in only executing commands that you know fulfill certain criteria.
+The concrete requirements depend on your application and could be anything from physical constraints to safety requirements.
+In our case, we only want to execute commands where PacMan does not run into walls.
+
+We can ensure that commands obey these requirements by adding a verifier to the arbitrators.
+The arbitrator will then run the verification step and only choose commands that pass this step.
+
+The leads us to another issue.
+What to do if the command we wanted to execute does not pass the verification step?
+
+Glad you asked!
+The first and thing that will happen without us doing anything is that the arbitrator will just choose the next best option.
+E.g., if the `EatClosestDot` is not safe, the `EatDot` arbitrator could just pass the `ChangeDotCluster` command to the root arbitrator
+ assuming the latter is both applicable and does itself pass verification.
+
+If that's not the case, we can think about adding additional behavior components as fallback layers to enable graceful degradation of the system.
+The first one is already there: `MoveRandomly` is something we probably don't really want to do under normal circumstances.
+But if we run out of ideas, it is still a valid option.
+It might also give our main behavior components a chance to recover or to solve deadlock situations.
+
+Finally, it is a good idea to add a last resort fallback layer.
+This behavior component should be a simple implementation that is always applicable and does not require a lot of context knowledge.
+If the system is in a failing state, the latter might not be available.
+We can mark behavior components as last resort fallback layers which will lead to these components not having to pass verification.
+After all, they are our last straw and it's better to execute that than to do nothing.
+
+In our case, we will add a `StayInPlace` behavior component.
+PacMan is not actually able to stop, so he will just keep moving back and forth.
+Probably not an ideal strategy to win the game but we can be sure to have a comprehensible command at all times.
+Also, PacMan will never run into a wall with this behavior component.
+
+Phew, that was long read. Time to get our hands dirty!
+
+
+## Goal
+
+Finish the implementation of the `Verifier` class and have the existing arbitrators use it.
+Add the `MoveRandomly` behavior component as a last resort fallback layer.
+
+## Instructions
+
+- In `verifier.cpp`, finish the implementation of the `Verifier::analyze` method.
+- Add an instance of the `Verifier` to the `PacmanAgent` class and initialize it in the constructor.
+- Pass the `Verifier` instance to the constructors of the arbitrators.
+ (Hint: You'll need to adjust the template parameters of the arbitrators.)
+- Add the `MoveRandomly` behavior component analogously to the other behavior components.
+- Mark the `MoveRandomly` behavior component as a last resort fallback layer.
+- Try breaking a behavior component on purpose and see how the system reacts.
+ (Try throwing an exception in the `getCommand` method of a behavior component or returning a command that will lead to a collision with a wall.)
+
+
+---
+[â Previous task](5_cost_arbitration.md)
+|
+[Tutorial Home](../Tutorial.md)
From d0d4047c8091256ddfe56ec0c9cc7c1ceefe583f Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Thu, 24 Oct 2024 15:46:00 +0200
Subject: [PATCH 10/48] Add solutions to all tasks
---
docs/tasks/1_implement_behavior_component.md | 56 +++++++++++++
docs/tasks/2_extend_arbitration_graph.md | 35 +++++++++
docs/tasks/3_add_more_behaviors.md | 37 +++++++++
docs/tasks/4_nested_arbitrators.md | 56 +++++++++++++
docs/tasks/5_cost_arbitration.md | 83 ++++++++++++++++++++
docs/tasks/6_verification.md | 80 +++++++++++++++++++
6 files changed, 347 insertions(+)
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
index 82ea1e34..6ba2c9e0 100644
--- a/docs/tasks/1_implement_behavior_component.md
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -38,6 +38,62 @@ Finish the implementation of the `checkInvocationCondition` and `getCommand` fun
- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::getCommand` if you need inspiration.
- Compile and run the unit tests for the `ChaseGhost` behavior component to verify that your implementation is correct.
+## Solution
+
+
+Click here to expand the solution
+
+Fix the invocation condition in `src/chase_ghost_behavior.cpp`:
+```cpp
+bool ChaseGhostBehavior::checkInvocationCondition(const Time& time) const {
+ return environmentModel_->closestScaredGhost(time).has_value() &&
+ environmentModel_->closestScaredGhost(time)->ghost.scaredCountdown > parameters_.minScaredTicksLeft &&
+ environmentModel_->closestScaredGhost(time)->distance < parameters_.invocationMinDistance; // Only applicable if a ghost is close by
+}
+```
+
+Add the missing pice of the getCommand function in `src/chase_ghost_behavior.cpp`:
+```cpp
+Command ChaseGhostBehavior::getCommand(const Time& time) {
+ auto pacmanPosition = environmentModel_->pacmanPosition();
+
+ auto closestScaredGhost = environmentModel_->closestScaredGhost(time);
+ if (!closestScaredGhost) {
+ throw std::runtime_error("Can not compute command to chase ghost because there are no scared ghosts.");
+ }
+
+ auto ghostPosition = closestScaredGhost->ghost.position;
+
+ std::optional direction;
+
+ // Add this part:
+ // Chose the direction moving pacman towards the closest scared ghost
+ double minDistance = std::numeric_limits::max();
+ for (const auto& move : Move::possibleMoves()) {
+ auto nextPosition = environmentModel_->positionConsideringTunnel(pacmanPosition + move.deltaPosition);
+
+ if (environmentModel_->isWall(nextPosition)) {
+ continue;
+ }
+
+ // Chose the direction moving pacman towards the closest scared ghost (considering ghost movement)
+ auto nextDistance = environmentModel_->mazeDistance(nextPosition, ghostPosition);
+ if (nextDistance < minDistance) {
+ direction = move.direction;
+ minDistance = nextDistance;
+ }
+ }
+
+ if (!direction) {
+ throw std::runtime_error("Failed to compute direction to chase the closest ghost.");
+ }
+
+ return Command{direction.value()};
+}
+
+```
+
+
---
[Tutorial Home](../Tutorial.md)
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index 84b09546..99c28ff8 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -26,6 +26,41 @@ Integrate the `ChaseGhost` behavior component into the arbitration graph defined
- Add a new option to the priority arbitrator.
- Run the game, take a look at the new arbitration graph and observe how PacMan behaves.
+## Solution
+
+
+Click here to expand the solution
+
+Include the header of the `ChaseGhost` behavior component in `include/demo/pacman_agent.hpp`:
+```cpp
+#include "chase_ghost_behavior.hpp"
+```
+
+Add the `ChaseGhost` behavior component as a new member of the `PacmanAgent` class:
+```cpp
+private:
+ ChaseGhostBehavior::Ptr chaseGhostBehavior_;
+```
+
+In the constructor of the `PacmanAgent` class, initialize the `ChaseGhost` behavior component and add it to the priority arbitrator:
+```cpp
+explicit PacmanAgent(const entt::Game& game)
+ : parameters_{}, environmentModel_{std::make_shared(game)} {
+
+ avoidGhostBehavior_ = std::make_shared(environmentModel_, parameters_.avoidGhostBehavior);
+ // Initialize the ChaseGhost behavior component
+ chaseGhostBehavior_ = std::make_shared(environmentModel_, parameters_.chaseGhostBehavior);
+ moveRandomlyBehavior_ = std::make_shared(parameters_.moveRandomlyBehavior);
+
+ rootArbitrator_ = std::make_shared("Pacman");
+ // Add the ChaseGhost behavior component to the priority arbitrator (before the AvoidGhost behavior component!)
+ rootArbitrator_->addOption(chaseGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(avoidGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(moveRandomlyBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+}
+```
+
+
---
[â Previous task](1_implement_behavior_component.md)
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
index 08b829a0..6e5d8d88 100644
--- a/docs/tasks/3_add_more_behaviors.md
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -25,6 +25,43 @@ Integrate the `EatClosestDot` behavior component into the arbitration graph defi
- Integrate the new component just like you did in the last task.
- Start the game and see how PacMan stop wandering around aimlessly and starts eating dots.
+## Solution
+
+
+Click here to expand the solution
+
+Include the header of the `EatClosestDot` behavior component in `include/demo/pacman_agent.hpp`:
+```cpp
+#include "eat_closest_dot_behavior.hpp"
+```
+
+Add the `ChaseGhost` behavior component as a new member of the `PacmanAgent` class:
+```cpp
+private:
+ EatClosestDotBehavior::Ptr eatClosestDotBehavior_;
+```
+
+In the constructor of the `PacmanAgent` class, initialize the `ChaseGhost` behavior component and add it to the priority arbitrator:
+```cpp
+explicit PacmanAgent(const entt::Game& game)
+ : parameters_{}, environmentModel_{std::make_shared(game)} {
+
+ avoidGhostBehavior_ = std::make_shared(environmentModel_, parameters_.avoidGhostBehavior);
+ chaseGhostBehavior_ = std::make_shared(environmentModel_, parameters_.chaseGhostBehavior);
+ // Initialize the EatClosestDot behavior component
+ eatClosestDotBehavior_ = std::make_shared(environmentModel_);
+ moveRandomlyBehavior_ = std::make_shared(parameters_.moveRandomlyBehavior);
+
+ rootArbitrator_ = std::make_shared("Pacman");
+ rootArbitrator_->addOption(chaseGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(avoidGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ // Add the EatClosestDot behavior component to the priority arbitrator (after the ghost behavior components!)
+ rootArbitrator_->addOption(eatClosestDotBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(moveRandomlyBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+}
+```
+
+
---
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
index 42577cd2..d4d114e8 100644
--- a/docs/tasks/4_nested_arbitrators.md
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -30,6 +30,62 @@ Add the `EatClosestDot` and `ChangeDotCluster` behavior components to a random a
- Add the random arbitrator as an option to the root arbitrator.
- Run the game and observe how PacMan behaves.
+## Solution
+
+
+Click here to expand the solution
+
+Include the header of the `ChangeDotCluster` behavior component and the random arbitrator in `include/demo/pacman_agent.hpp`:
+```cpp
+#include
+
+#include "change_dot_cluster_behavior.hpp"
+```
+
+For easier to read code, add the following alias near the top of the class definition:
+```cpp
+using RandomArbitrator = arbitration_graphs::RandomArbitrator;
+```
+
+Add the `ChangeDotCluster` behavior component and the `RandomArbitrator` as a new members of the `PacmanAgent` class:
+```cpp
+private:
+ ChangeDotClusterBehavior::Ptr changeDotClusterBehavior_;
+
+ RandomArbitrator::Ptr eatDotsArbitrator_;
+```
+
+In the constructor of the `PacmanAgent` class, initialize the `ChangeDotCluster` behavior component and the `RandomArbitrator`:
+Add the `EatClosestDot` and `ChangeDotCluster` behavior components as options to the random arbitrator.
+Finally, add the random arbitrator as an option to the root arbitrator:
+```cpp
+explicit PacmanAgent(const entt::Game& game)
+ : parameters_{}, environmentModel_{std::make_shared(game)} {
+
+ avoidGhostBehavior_ = std::make_shared(environmentModel_, parameters_.avoidGhostBehavior);
+ // Initialize the ChangeDotCluster behavior component
+ changeDotClusterBehavior_ = std::make_shared(environmentModel_);
+ chaseGhostBehavior_ = std::make_shared(environmentModel_, parameters_.chaseGhostBehavior);
+ eatClosestDotBehavior_ = std::make_shared(environmentModel_);
+ moveRandomlyBehavior_ = std::make_shared(parameters_.moveRandomlyBehavior);
+
+ // Initialize the random arbitrator and add the EatClosestDot and ChangeDotCluster behavior components as options
+ eatDotsArbitrator_ = std::make_shared("EatDots");
+ eatDotsArbitrator_->addOption( changeDotClusterBehavior_, RandomArbitrator::Option::Flags::INTERRUPTABLE);
+ eatDotsArbitrator_->addOption( eatClosestDotBehavior_, RandomArbitrator::Option::Flags::INTERRUPTABLE);
+
+ rootArbitrator_ = std::make_shared("Pacman");
+ rootArbitrator_->addOption(chaseGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(avoidGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ // The EatDot arbitrator is itself an option of the root arbitrator
+ rootArbitrator_->addOption(eatDotsArbitrator_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(moveRandomlyBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+}
+```
+
+
+
+
---
[â Previous task](3_add_more_behaviors.md)
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index ecc70201..65dc7438 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -32,6 +32,89 @@ Finish the implementation of the `CostEstimator` and replace the random arbitrat
- Add an instance of the `CostEstimator` to the `PacmanAgent` class and initialize it in the constructor.
- Replace the random arbitrator with a cost arbitrator in the `PacmanAgent` class. Pass the `CostEstimator` instance to the `addOption` method.
+## Solution
+
+
+Click here to expand the solution
+
+Finish the implementation of the `CostEstimator` class in `cost_estimator.cpp`:
+```cpp
+double CostEstimator::estimateCost(const Command& command, bool /*isActive*/) {
+ Positions absolutePath = utils::toAbsolutePath(command.path, environmentModel_);
+
+ // Compute the number of dots along the path and in the neighborhood of the path end using helper functions
+ const int nDotsAlongPath = utils::dotsAlongPath(absolutePath, environmentModel_);
+ const int nDotsInRadius =
+ utils::dotsInRadius(absolutePath.back(), environmentModel_, parameters_.pathEndNeighborhoodRadius);
+ const int nDots = nDotsAlongPath + nDotsInRadius;
+
+ if (nDots == 0) {
+ return std::numeric_limits::max();
+ }
+
+ // Compute the size of the path and the neighborhood of the path end
+ const int pathLength = static_cast(absolutePath.size());
+ const int neighborhoodSize = static_cast(std::pow(2 * parameters_.pathEndNeighborhoodRadius + 1, 2));
+ const int nCells = pathLength + neighborhoodSize;
+
+ // We can define a cost as the inverse of a benefit.
+ // Our benefit is a dot density (number of dots / number of examined cells)
+ return static_cast(nCells) / nDots;
+}
+```
+
+Replace the include of the random arbitrator with the cost arbitrator in `include/demo/pacman_agent.hpp`.
+Also, include `cost_estimator.hpp`:
+```cpp
+#include
+
+#include "cost_estimator.hpp"
+```
+
+Change the type of the `eatDotsArbitrator_` member in the `PacmanAgent` class to `CostArbitrator` and add an instance of the `CostEstimator`:
+```cpp
+private:
+ CostArbitrator::Ptr eatDotsArbitrator_;
+
+ CostEstimator::Ptr costEstimator_;
+```
+
+As always, the magic happens in the constructor of the `PacmanAgent` class.
+Instantiate the cost estimator and pass it in the `addOption` calls:
+```cpp
+explicit PacmanAgent(const entt::Game& game)
+ : parameters_{}, environmentModel_{std::make_shared(game)} {
+
+ avoidGhostBehavior_ = std::make_shared(environmentModel_, parameters_.avoidGhostBehavior);
+ changeDotClusterBehavior_ = std::make_shared(environmentModel_);
+ chaseGhostBehavior_ = std::make_shared(environmentModel_, parameters_.chaseGhostBehavior);
+ eatClosestDotBehavior_ = std::make_shared(environmentModel_);
+ moveRandomlyBehavior_ = std::make_shared(parameters_.moveRandomlyBehavior);
+
+ // This is now a cost arbitrator
+ eatDotsArbitrator_ = std::make_shared("EatDots");
+ // Construct the cost estimator
+ costEstimator_ = std::make_shared(environmentModel_, parameters_.costEstimator);
+ // Add the ChangeDotCluster and EatClosestDot behavior components as options to the
+ // cost arbitrator while also passing the cost estimator
+ eatDotsArbitrator_->addOption(
+ changeDotClusterBehavior_, CostArbitrator::Option::Flags::INTERRUPTABLE, costEstimator_);
+ eatDotsArbitrator_->addOption(
+ eatClosestDotBehavior_, CostArbitrator::Option::Flags::INTERRUPTABLE, costEstimator_);
+
+ rootArbitrator_ = std::make_shared("Pacman");
+ rootArbitrator_->addOption(chaseGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(avoidGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(eatDotsArbitrator_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(moveRandomlyBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(stayInPlaceBehavior_,
+ PriorityArbitrator::Option::Flags::INTERRUPTABLE |
+ PriorityArbitrator::Option::FALLBACK);
+}
+```
+
+
+
---
[â Previous task](4_nested_arbitrators.md)
diff --git a/docs/tasks/6_verification.md b/docs/tasks/6_verification.md
index 0fc10efa..432a9f0b 100644
--- a/docs/tasks/6_verification.md
+++ b/docs/tasks/6_verification.md
@@ -60,6 +60,86 @@ Add the `MoveRandomly` behavior component as a last resort fallback layer.
- Try breaking a behavior component on purpose and see how the system reacts.
(Try throwing an exception in the `getCommand` method of a behavior component or returning a command that will lead to a collision with a wall.)
+## Solution
+
+
+Click here to expand the solution
+
+In the `Verifier::analyze` method (in `include/demo/verifier.hpp`), we simply check if the command would lead to an invalid position:
+```cpp
+VerificationResult analyze(const Time /*time*/, const Command& command) const {
+ Move nextMove = Move{command.path.front()};
+ Position nextPosition = environmentModel_->pacmanPosition() + nextMove.deltaPosition;
+
+ // The command is considered safe if the next position is in bounds and not a wall
+ if (environmentModel_->isPassableCell(nextPosition)) {
+ return VerificationResult{true};
+ }
+
+ return VerificationResult{false};
+}
+```
+
+Include the verifier header you just implemented, in `include/demo/pacman_agent.hpp`.
+Also, include `stay_in_place_behavior.hpp`.
+```cpp
+#include "stay_in_place_behavior.hpp"
+#include "verifier.hpp"
+```
+
+Adjust the template parameters in the alias definitions to contain the verifier types:
+```cpp
+public:
+ using CostArbitrator = arbitration_graphs::CostArbitrator;
+ using PriorityArbitrator = arbitration_graphs::PriorityArbitrator;
+```
+
+Add the verifier and the fallback behavior component as members of the `PacmanAgent` class:
+```cpp
+private:
+ StayInPlaceBehavior::Ptr stayInPlaceBehavior_;
+
+ Verifier verifier_;
+```
+
+In the constructor of the `PacmanAgent` class, initialize the verifier and the `StayInPlace` behavior component.
+Make sure to also pass the verifier to the arbitrator constructors:
+```cpp
+ explicit PacmanAgent(const entt::Game& game)
+ : parameters_{},
+ environmentModel_{std::make_shared(game)},
+ verifier_{environmentModel_} // We can initialize the verifier in the member initializer list {
+
+ avoidGhostBehavior_ = std::make_shared(environmentModel_, parameters_.avoidGhostBehavior);
+ changeDotClusterBehavior_ = std::make_shared(environmentModel_);
+ chaseGhostBehavior_ = std::make_shared(environmentModel_, parameters_.chaseGhostBehavior);
+ eatClosestDotBehavior_ = std::make_shared(environmentModel_);
+ moveRandomlyBehavior_ = std::make_shared(parameters_.moveRandomlyBehavior);
+ // Initialize the StayInPlace behavior component
+ stayInPlaceBehavior_ = std::make_shared(environmentModel_);
+
+ // Pass the verifier instance to the cost arbitrator
+ eatDotsArbitrator_ = std::make_shared("EatDots", verifier_);
+ costEstimator_ = std::make_shared(environmentModel_, parameters_.costEstimator);
+ eatDotsArbitrator_->addOption(
+ changeDotClusterBehavior_, CostArbitrator::Option::Flags::INTERRUPTABLE, costEstimator_);
+ eatDotsArbitrator_->addOption(
+ eatClosestDotBehavior_, CostArbitrator::Option::Flags::INTERRUPTABLE, costEstimator_);
+
+ // Pass the verifier instance to the priority arbitrator
+ rootArbitrator_ = std::make_shared("Pacman", verifier_);
+ rootArbitrator_->addOption(chaseGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(avoidGhostBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(eatDotsArbitrator_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ rootArbitrator_->addOption(moveRandomlyBehavior_, PriorityArbitrator::Option::Flags::INTERRUPTABLE);
+ // Add the StayInPlace behavior component. Mark it as a last resort fallback layer using the FALLBACK flag.
+ rootArbitrator_->addOption(stayInPlaceBehavior_,
+ PriorityArbitrator::Option::Flags::INTERRUPTABLE |
+ PriorityArbitrator::Option::FALLBACK);
+ }
+```
+
+
---
[â Previous task](5_cost_arbitration.md)
From f168d1ea9a7ea1187e5201a3b322367edf5f75ec Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Thu, 24 Oct 2024 15:54:03 +0200
Subject: [PATCH 11/48] Add hint about adding parameters to the main parameter
struct
---
docs/tasks/2_extend_arbitration_graph.md | 11 +++++++++++
docs/tasks/5_cost_arbitration.md | 13 +++++++++++++
2 files changed, 24 insertions(+)
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index 99c28ff8..4d7b6e38 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -23,6 +23,7 @@ Integrate the `ChaseGhost` behavior component into the arbitration graph defined
- Take a look at how the other behavior components are defined in `include/demo/pacman_agent.hpp`.
- Add the `ChaseGhost` behavior component as a new member of the `PacmanAgent` class and initialize it in the constructor.
+- Extend the `PacmanAgent` parameter struct to include the parameters for the `ChaseGhost` behavior component.
- Add a new option to the priority arbitrator.
- Run the game, take a look at the new arbitration graph and observe how PacMan behaves.
@@ -42,6 +43,16 @@ private:
ChaseGhostBehavior::Ptr chaseGhostBehavior_;
```
+Extend the `PacmanAgent` parameter struct to include the parameters for the `ChaseGhost` behavior component:
+```cpp
+struct Parameters {
+ AvoidGhostBehavior::Parameters avoidGhostBehavior;
+ // Add the parameters for the ChaseGhost behavior component
+ ChaseGhostBehavior::Parameters chaseGhostBehavior;
+ MoveRandomlyBehavior::Parameters moveRandomlyBehavior;
+};
+```
+
In the constructor of the `PacmanAgent` class, initialize the `ChaseGhost` behavior component and add it to the priority arbitrator:
```cpp
explicit PacmanAgent(const entt::Game& game)
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index 65dc7438..28debff1 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -30,6 +30,7 @@ Finish the implementation of the `CostEstimator` and replace the random arbitrat
- In `cost_estimator.cpp`, fill in the blanks to compute `nDots` and `nCells`.
- Add an instance of the `CostEstimator` to the `PacmanAgent` class and initialize it in the constructor.
+ Don't forget to include the necessary headers and extend the parameter struct with the parameters for the `CostEstimator`.
- Replace the random arbitrator with a cost arbitrator in the `PacmanAgent` class. Pass the `CostEstimator` instance to the `addOption` method.
## Solution
@@ -79,6 +80,18 @@ private:
CostEstimator::Ptr costEstimator_;
```
+Extend the `Parameters` struct to contain the parameters for the `CostEstimator`:
+```cpp
+struct Parameters {
+ AvoidGhostBehavior::Parameters avoidGhostBehavior;
+ ChaseGhostBehavior::Parameters chaseGhostBehavior;
+ MoveRandomlyBehavior::Parameters moveRandomlyBehavior;
+
+ // Add the parameters for the CostEstimator
+ CostEstimator::Parameters costEstimator;
+};
+```
+
As always, the magic happens in the constructor of the `PacmanAgent` class.
Instantiate the cost estimator and pass it in the `addOption` calls:
```cpp
From efcd1b4179dfa67b4bbb09780a28417d583570e5 Mon Sep 17 00:00:00 2001
From: Nick Le Large
Date: Thu, 24 Oct 2024 16:08:37 +0200
Subject: [PATCH 12/48] Remove todos from the tutorial landing page
---
docs/Tutorial.md | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index c7d42ac4..a836d604 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -96,12 +96,3 @@ With the basics out of the way, let's work through the tasks.
4. [Learn about nested arbitration graphs](./tasks/4_nested_arbitrators.md)
5. [Arbitrate based on predicted utility](./tasks/5_cost_arbitration.md)
-
-- [ ] Finish chase ghost finish so that is passes unit tests by re-implementing some removed part, e.g. getCommand
-- [ ] Integrate chase ghost into priority arbitrator
-- [ ] Integrate eat closest dot behavior
-- [ ] Integrate eat dot arbitrator as random arbitrator
-- [ ] Replace arbitrator from previous step with cost arbitrator, finish cost estimator
-
-## General TODOs
-- [ ] Add a bit of an explanation about arbitration graphs to top-level readme
From 42b8f3cda18bc27708ad4bb89a581b663db97b10 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Sun, 10 Nov 2024 08:20:02 +0100
Subject: [PATCH 13/48] Link to the tutorial from main Readme
---
README.md | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/README.md b/README.md
index 73fcdd57..96128e58 100644
--- a/README.md
+++ b/README.md
@@ -72,7 +72,18 @@ In this scene,
-We will shortly add a [tutorial](https://github.com/KIT-MRT/arbitration_graphs/pull/51) based on this demo â stay tuned!
+## Tutorial
+
+Follow our [Tutorial](./docs/Tutorial.md) and learn how to use the Arbitration Graphs library!
+It's based on this demo and guides you through all important concepts:
+
+0. [Introduction â start here!](./docs/Tutorial.md)
+1. [Implement your first behavior component](./docs/tasks/1_implement_behavior_component.md)
+2. [Extend the arbitration graph with that behavior](./docs/tasks/2_extend_arbitration_graph.md)
+3. [Add even more behavior components](./docs/tasks/3_add_more_behaviors.md)
+4. [Learn about nested arbitration graphs](./docs/tasks/4_nested_arbitrators.md)
+5. [Arbitrate based on predicted utility](./docs/tasks/5_cost_arbitration.md)
+6. [Verify commands and add a fallback strategy](./docs/tasks/6_verification.md)
## Installation
From 339468f2c6a9e1ea8f26b3c23d42b2d8767f572c Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Sun, 10 Nov 2024 08:26:48 +0100
Subject: [PATCH 14/48] Rename demo executable to
arbitration_graphs_pacman_demo
---
demo/CMakeLists.txt | 16 ++++++++--------
demo/Dockerfile | 2 +-
demo/test/CMakeLists.txt | 2 +-
docs/Tutorial.md | 2 +-
4 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt
index bbdc0040..f409eb7a 100644
--- a/demo/CMakeLists.txt
+++ b/demo/CMakeLists.txt
@@ -59,7 +59,7 @@ find_package(Yaml-cpp REQUIRED)
## Build ##
###########
-add_library(${PROJECT_NAME} SHARED
+add_library(${PROJECT_NAME}_lib SHARED
src/astar.cpp
src/avoid_ghost_behavior.cpp
src/change_dot_cluster_behavior.cpp
@@ -71,11 +71,11 @@ add_library(${PROJECT_NAME} SHARED
src/move_randomly_behavior.cpp
src/utils.cpp
)
-target_include_directories(${PROJECT_NAME} PRIVATE
+target_include_directories(${PROJECT_NAME}_lib PRIVATE
include
${SDL2_INCLUDE_DIR}
)
-target_link_libraries(${PROJECT_NAME} PUBLIC
+target_link_libraries(${PROJECT_NAME}_lib PUBLIC
arbitration_graphs
glog::glog
@@ -86,16 +86,16 @@ target_link_libraries(${PROJECT_NAME} PUBLIC
${SDL2_LIBRARY}
)
-add_executable(${PROJECT_NAME}_exe
+add_executable(${PROJECT_NAME}
src/main.cpp
src/pacman_wrapper.cpp
)
-target_include_directories(${PROJECT_NAME}_exe PRIVATE
+target_include_directories(${PROJECT_NAME} PRIVATE
include
${SDL2_INCLUDE_DIR}
)
-target_link_libraries(${PROJECT_NAME}_exe PRIVATE
- ${PROJECT_NAME}
+target_link_libraries(${PROJECT_NAME} PRIVATE
+ ${PROJECT_NAME}_lib
)
@@ -133,7 +133,7 @@ endif()
## Install ##
#############
-install(TARGETS ${PROJECT_NAME} ${PROJECT_NAME}_exe
+install(TARGETS ${PROJECT_NAME}_lib ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
COMPONENT demo
LIBRARY DESTINATION lib COMPONENT Runtime
diff --git a/demo/Dockerfile b/demo/Dockerfile
index 2f9e68ba..89018980 100644
--- a/demo/Dockerfile
+++ b/demo/Dockerfile
@@ -61,5 +61,5 @@ WORKDIR /home/blinky/demo/build
RUN cmake -DCMAKE_BUILD_TYPE=Release .. && \
cmake --build . -j8
-CMD ["bash", "-c", "/home/blinky/.motd && /home/blinky/demo/build/arbitration_graphs_pacman_demo_exe"]
+CMD ["bash", "-c", "/home/blinky/.motd && /home/blinky/demo/build/arbitration_graphs_pacman_demo"]
diff --git a/demo/test/CMakeLists.txt b/demo/test/CMakeLists.txt
index 14e4cece..30f3ee05 100644
--- a/demo/test/CMakeLists.txt
+++ b/demo/test/CMakeLists.txt
@@ -88,7 +88,7 @@ if(GTEST_FOUND)
target_link_libraries(${TEST_TARGET_NAME} PUBLIC
${GTEST_BOTH_LIBRARIES}
pthread
- arbitration_graphs_pacman_demo
+ arbitration_graphs_pacman_demo_lib
arbitration_graphs
EnTT_Pacman
util_caching
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index a836d604..c2fbf9e1 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -73,7 +73,7 @@ cmake --build .
You can then run the demo with
```bash
-./arbitration_graphs_pacman_demo_exe
+./arbitration_graphs_pacman_demo
```
You'll also find the individual unit executables in this directory.
From f2f775abbaa684a0c8b5e7e0abe0ac08ee0b86f2 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Sun, 10 Nov 2024 08:51:37 +0100
Subject: [PATCH 15/48] Tune tutorial introduction
---
docs/Tutorial.md | 21 +++++++++++++++------
1 file changed, 15 insertions(+), 6 deletions(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index c2fbf9e1..6c00087d 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -2,7 +2,7 @@
Let's write an agent for the famous PacMan game using Arbitration Graphs đšī¸
-**TL;DR**: Find links to the individual tasks at the bottom of this page.
+**TL;DR:** Find links to the individual tasks at the bottom of this page.
## Introduction
@@ -22,11 +22,20 @@ The tutorial is structured into several tasks that are meant to be completed in
### What to find where
-Let's take a look at the structure and content of the `arbitration_graphs/demo` directory.
-All header files can be found in the `include/demo/` directory with corresponding implementation files in the `src/` directory.
+Let's take a look at the structure and content of the `arbitration_graphs/demo/` directory.
+
+```
+demo
+âââ include
+âââ src
+âââ test
+âââ âĻ
+```
+
+All header files can be found in the `include/` directory with corresponding implementation files in the `src/` directory.
The entire demo is thoroughly tested using the unit tests you'll find in the `test/` directory.
-Each behavior component is implemented in a separate `_behavior.hpp` file as a class inheriting from the abstract `Behavior` class.
+Each behavior component is implemented in a separate `_behavior.hpp` file as a class inheriting from the abstract `Behavior` class.
Next, there is `environment_model.hpp`.
You guessed it, it contains the environment model for the arbitration graph.
@@ -50,10 +59,10 @@ The easiest way to get started is to use the provided docker setup.
Start by checking out the `tutorial` branch where we have removed some parts
of the demo implementation for the purpose of this tutorial.
```bash
-git checkout tutorial
+git clone --branch tutorial https://github.com/KIT-MRT/arbitration_graphs.git
```
-To be dropped into an interactive shell with all required dependencies installed
+To start an interactive shell in the docker container with all required dependencies installed
and the current directory mounted, run
```bash
cd arbitration_graphs/demo
From 6e150df9d883452eefd1c59faf731e27029f6f11 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Sun, 10 Nov 2024 08:51:53 +0100
Subject: [PATCH 16/48] Add crosslinks and missing link to tutorial
introduction
---
docs/Tutorial.md | 6 +++---
docs/tasks/2_extend_arbitration_graph.md | 2 +-
docs/tasks/3_add_more_behaviors.md | 6 +++---
docs/tasks/4_nested_arbitrators.md | 2 +-
docs/tasks/5_cost_arbitration.md | 2 +-
5 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index 6c00087d..9fb742e1 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -42,9 +42,9 @@ You guessed it, it contains the environment model for the arbitration graph.
In it, we store things like current positions of PacMan and the ghosts, the maze, several utility functions
and other things required by the behavior components.
-The `cost_estimator.hpp` file will be relevant for a later task when we cover cost arbitrators.
+The `cost_estimator.hpp` file will be relevant for a later task when we cover [cost arbitrators](./tasks/5_cost_arbitration.md).
-Similarly, the `verifier.hpp` file will be used to add a verification layer to the arbitration graph near the end of the tutorial.
+Similarly, the `verifier.hpp` file will be used to add a verification layer to the arbitration graph [near the end](./tasks/6_verification.md) of the tutorial.
Finally, in `pacman_agent.hpp`, the behavior components are assembled into an arbitration graph.
It's also where you'll spend most of your time during this tutorial.
@@ -104,4 +104,4 @@ With the basics out of the way, let's work through the tasks.
3. [Add even more behavior components](./tasks/3_add_more_behaviors.md)
4. [Learn about nested arbitration graphs](./tasks/4_nested_arbitrators.md)
5. [Arbitrate based on predicted utility](./tasks/5_cost_arbitration.md)
-
+6. [Verify commands and add a fallback strategy](./tasks/6_verification.md)
\ No newline at end of file
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index 4d7b6e38..d700472c 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -9,7 +9,7 @@ description: Extend the arbitration graph with the ChaseGhost behavior component
With our next behavior component ready to go, we need to think about integrating it into our arbitration graph.
-For this purpose, we need to modify the `PacmanAgent` class to include the `ChaseGhost` behavior component we implemented in the previous task.
+For this purpose, we need to modify the `PacmanAgent` class to include the `ChaseGhost` behavior component we implemented in the [previous task](1_implement_behavior_component.md).
Integrating a new behavior component into the arbitration graph is as simple as instantiating it and adding it as a new option to one of the arbitrators.
Since right now there is just one arbitrator - a priority arbitrator - the choice is simple.
We just need to worry about the order in which the options are assigned to the arbitrator.
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
index 6e5d8d88..1e886589 100644
--- a/docs/tasks/3_add_more_behaviors.md
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -11,10 +11,10 @@ So far, we have not looked into a behavior component that handles the most impor
So now is a good a time as any to further extend our arbitration graph with the `EatClosestDot` behavior component.
We don't want to bore you with the details of planning a path through a PacMan maze, so we have already implemented that for you.
-You just need to integrate it into the arbitration graph, very similarly to the last task.
+You just need to integrate it into the arbitration graph, very similarly to the [previous task](2_extend_arbitration_graph.md).
We'll keep it simple and just add it as another option to the priority arbitrator.
-Arbitration graphs can be nested of course, but we'll save that for the next task.
+Arbitration graphs can be nested of course, but we'll save that for the [next task](4_nested_arbitrators.md).
## Goal
@@ -22,7 +22,7 @@ Integrate the `EatClosestDot` behavior component into the arbitration graph defi
## Instructions
-- Integrate the new component just like you did in the last task.
+- Integrate the new component just like you did in the [previous task](2_extend_arbitration_graph.md).
- Start the game and see how PacMan stop wandering around aimlessly and starts eating dots.
## Solution
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
index d4d114e8..39e8b81b 100644
--- a/docs/tasks/4_nested_arbitrators.md
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -16,7 +16,7 @@ The `ChangeDotCluster` behavior will move to an area in the maze where there is
For now, we'll just decide between the two dot eating strategies using chance.
We can achieve that by adding them to a random arbitrator which is then added as an option to the root arbitrator.
-There are more sophisticated ways to decide between behavior components, we'll cover those in the next task.
+There are more sophisticated ways to decide between behavior components, we'll cover those in the [next task](5_cost_arbitration.md).
## Goal
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index 28debff1..b846cdd1 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -7,7 +7,7 @@ description: Learn how the cost arbitrator can help you to arbitrate between beh
## Context
-The `EatDot` arbitrator we added in the previous task decides between the two dot eating strategies randomly.
+The `EatDot` arbitrator we added in the [previous task](4_nested_arbitrators.md) decides between the two dot eating strategies randomly.
That's obviously not the greatest idea.
There must be a better way.
From b01eb3d53af5131c258e80cb9a37f2e86dbde3c5 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Sun, 10 Nov 2024 08:52:12 +0100
Subject: [PATCH 17/48] Improve compile and run commands in tutorial
introduction
---
docs/Tutorial.md | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/docs/Tutorial.md b/docs/Tutorial.md
index 9fb742e1..47566fd5 100644
--- a/docs/Tutorial.md
+++ b/docs/Tutorial.md
@@ -74,10 +74,10 @@ You should enable the `BUILD_TESTS` option to build the unit tests as well.
```bash
cd /home/blinky/demo
-mkdir -p arbitration_graphs/demo/build
-cd arbitration_graphs/demo/build
+mkdir build
+cd build
cmake -DBUILD_TESTS=true ..
-cmake --build .
+cmake --build . -j9
```
You can then run the demo with
@@ -88,7 +88,7 @@ You can then run the demo with
You'll also find the individual unit executables in this directory.
To execute them all at once, run
```bash
-find -executable -type f -name '*-gtest-*' -exec {} \;
+cmake --build . --target test
```
We'll leave the setup of your favorite IDE up to you
From 72edc1eda809a7e67b5b1d54df7e1a032f3b4059 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 17:05:32 +0100
Subject: [PATCH 18/48] Add a short Readme for the Demo (in case it's opened as
top-level dir in an IDE)
---
demo/README.md | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
create mode 100644 demo/README.md
diff --git a/demo/README.md b/demo/README.md
new file mode 100644
index 00000000..834175e3
--- /dev/null
+++ b/demo/README.md
@@ -0,0 +1,20 @@
+# Arbitration Graphs Demo and Tutorial
+
+This is a demo of the [arbitration_graphs](https://github.com/KIT-MRT/arbitration_graphs) library using Pac-Man as an example application.
+The arbitration graph controls Pac-Man on its journey to collect tasty dots đŦ
+
+Run the demo with:
+
+```bash
+git clone https://github.com/KIT-MRT/arbitration_graphs.git
+cd arbitration_graphs/demo
+docker compose up
+```
+
+Open the GUI with your favorite browser:
+[http://0.0.0.0:8080](http://0.0.0.0:8080)
+
+
+## Tutorial
+
+If you're here for the tutorial, follow the instructions on our [Tutorial GitHub Page](https://kit-mrt.github.io/arbitration_graphs/docs/Tutorial.md).
\ No newline at end of file
From 92d524517225c82e2a532f697434429ec0f71219 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 16:22:18 +0100
Subject: [PATCH 19/48] Move tutorial Docker service to own compose file again
This is due to VSCode not supporting docker profiles (yet?).
Thus we have issues setting up a nice DevContainer that doesn't start the demo as well.
---
demo/docker-compose.tutorial.yaml | 13 +++++++++++++
demo/docker-compose.yaml | 13 +++----------
2 files changed, 16 insertions(+), 10 deletions(-)
create mode 100644 demo/docker-compose.tutorial.yaml
diff --git a/demo/docker-compose.tutorial.yaml b/demo/docker-compose.tutorial.yaml
new file mode 100644
index 00000000..8bf2b966
--- /dev/null
+++ b/demo/docker-compose.tutorial.yaml
@@ -0,0 +1,13 @@
+services:
+ tutorial:
+ image: ghcr.io/kit-mrt/arbitration_graphs_pacman_tutorial:$VERSION
+ env_file: .env
+ ports:
+ - "8080:8080"
+ volumes:
+ - .:/home/blinky/demo
+ - $HOME/.Xauthority:/home/blinky/.Xauthority
+ - /tmp/.X11-unix:/tmp/.X11-unix
+ environment:
+ - DISPLAY=$DISPLAY
+
diff --git a/demo/docker-compose.yaml b/demo/docker-compose.yaml
index f18bde66..f7193356 100644
--- a/demo/docker-compose.yaml
+++ b/demo/docker-compose.yaml
@@ -1,15 +1,8 @@
services:
tutorial:
- image: ghcr.io/kit-mrt/arbitration_graphs_pacman_tutorial:$VERSION
- env_file: .env
- ports:
- - "8080:8080"
- volumes:
- - .:/home/blinky/demo
- - $HOME/.Xauthority:/home/blinky/.Xauthority
- - /tmp/.X11-unix:/tmp/.X11-unix
- environment:
- - DISPLAY=$DISPLAY
+ extends:
+ file: docker-compose.tutorial.yaml
+ service: tutorial
#
# This makes sure `docker compose up` only runs the demo service
# Use `docker compose run --rm --service-ports tutorial` to run the tutorial
From 0d13c078803f33a49626b7b35be94ebb9c6bd6df Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 16:29:43 +0100
Subject: [PATCH 20/48] Add a VSCode DevContainer for the tutorial
---
demo/.devcontainer/.zshrc | 89 +++++++++++++++++++++++++++
demo/.devcontainer/Dockerfile | 25 ++++++++
demo/.devcontainer/devcontainer.json | 44 +++++++++++++
demo/.devcontainer/docker-compose.yml | 13 ++++
demo/.vscode/launch.json | 18 ++++++
demo/.vscode/tasks.json | 39 ++++++++++++
demo/README.md | 13 +++-
7 files changed, 240 insertions(+), 1 deletion(-)
create mode 100644 demo/.devcontainer/.zshrc
create mode 100644 demo/.devcontainer/Dockerfile
create mode 100644 demo/.devcontainer/devcontainer.json
create mode 100644 demo/.devcontainer/docker-compose.yml
create mode 100644 demo/.vscode/launch.json
create mode 100644 demo/.vscode/tasks.json
diff --git a/demo/.devcontainer/.zshrc b/demo/.devcontainer/.zshrc
new file mode 100644
index 00000000..5875b839
--- /dev/null
+++ b/demo/.devcontainer/.zshrc
@@ -0,0 +1,89 @@
+# >>> reference: https://carlosneto.dev/blog/2024/2024-02-08-starship-zsh/
+
+# list files with details
+alias ll="ls -larht"
+
+
+# set the locale of the shell
+export LANG="en_US.UTF-8"
+
+# define VSCode as the default text editor
+export EDITOR="code -w"
+
+# specify characters considered as word boundaries for command line navigation
+export WORDCHARS=""
+
+# set the location and filename of the history file
+export HISTFILE="$HOME/.zsh_history"
+
+# set the maximum number of lines to be saved in the history file
+export HISTSIZE="100000"
+export SAVEHIST="$HISTSIZE"
+
+# disable CTRL + S and CTRL + Q
+stty -ixon
+
+# enable comments "#" expressions in the prompt shell
+setopt INTERACTIVE_COMMENTS
+
+# append new history entries to the history file
+setopt APPEND_HISTORY
+
+# save each command to the history file as soon as it is executed
+setopt INC_APPEND_HISTORY
+
+# ignore recording duplicate consecutive commands in the history
+setopt HIST_IGNORE_DUPS
+
+# ignore commands that start with a space in the history
+setopt HIST_IGNORE_SPACE
+
+# >>> bindkey tip: to discovery the code of your keys, execute "$ cat -v" and press the key, the code will be printed in your shell.
+
+# use the ZLE (zsh line editor) in emacs mode. Useful to move the cursor in large commands
+bindkey -e
+
+# navigate words using Ctrl + arrow keys
+# >>> CRTL + right arrow | CRTL + left arrow
+bindkey "^[[1;5C" forward-word
+bindkey "^[[1;5D" backward-word
+
+# macosx override
+if [[ "$OSTYPE" == "darwin"* ]]; then
+ # >>> OPT + right arrow | OPT + left arrow
+ bindkey "^[^[[C" forward-word
+ bindkey "^[^[[D" backward-word
+fi
+
+# search history using Up and Down keys
+# >>> up arrow | down arrow
+bindkey "^[[A" history-beginning-search-backward
+bindkey "^[[B" history-beginning-search-forward
+
+# jump to the start and end of the command line
+# >>> CTRL + A | CTRL + E
+bindkey "^A" beginning-of-line
+bindkey "^E" end-of-line
+# >>> Home | End
+bindkey "^[[H" beginning-of-line
+bindkey "^[[F" end-of-line
+
+# navigate menu for command output
+zstyle ':completion:*:*:*:*:*' menu select
+bindkey '^[[Z' reverse-menu-complete
+
+# delete characters using the "delete" key
+bindkey "^[[3~" delete-char
+
+
+# >>> load ZSH plugin
+
+# enable kubectl plugin autocompletion
+autoload -Uz compinit
+compinit
+
+
+# start Starship prompt
+eval "$(starship init zsh)"
+
+source /home/blinky/.motd
\ No newline at end of file
diff --git a/demo/.devcontainer/Dockerfile b/demo/.devcontainer/Dockerfile
new file mode 100644
index 00000000..72ca2e1a
--- /dev/null
+++ b/demo/.devcontainer/Dockerfile
@@ -0,0 +1,25 @@
+ARG VERSION=latest
+
+FROM ghcr.io/kit-mrt/arbitration_graphs_pacman_tutorial:$VERSION
+
+USER root
+
+# Install clangd for the VSCode extension to work out of the box
+# Install zsh and tig as modern dev tools
+RUN apt-get update && \
+ apt-get install -y --no-install-recommends \
+ clangd \
+ curl \
+ tig \
+ zsh && \
+ apt-get clean
+
+# Install and use starship terminal prompt
+RUN curl https://starship.rs/install.sh > /tmp/starship_install.sh && \
+ chmod +x /tmp/starship_install.sh && \
+ /tmp/starship_install.sh -y && \
+ rm /tmp/starship_install.sh
+
+COPY .devcontainer/.zshrc /home/blinky/.zshrc
+
+USER blinky
diff --git a/demo/.devcontainer/devcontainer.json b/demo/.devcontainer/devcontainer.json
new file mode 100644
index 00000000..d83ac6f0
--- /dev/null
+++ b/demo/.devcontainer/devcontainer.json
@@ -0,0 +1,44 @@
+// For format details, see https://aka.ms/devcontainer.json. For config options, see the
+// README at: https://github.com/devcontainers/templates/tree/main/src/docker-existing-docker-compose
+{
+ "name": "Arbitration Graphs Tutorial",
+
+ // Update the 'dockerComposeFile' list if you have more compose files or use different names.
+ // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make.
+ "dockerComposeFile": [
+ "../docker-compose.tutorial.yaml",
+ "docker-compose.yml"
+ ],
+
+ // The 'service' property is the name of the service for the container that VS Code should
+ // use. Update this value and .devcontainer/docker-compose.yml to the real service name.
+ "service": "tutorial",
+
+ // The optional 'workspaceFolder' property is the path VS Code should open by default when
+ // connected. This is typically a file mount in .devcontainer/docker-compose.yml
+ "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}",
+ "customizations": {
+ "vscode": {
+ // Install some useful VSCode C++ extensions
+ "extensions": [
+ "llvm-vs-code-extensions.vscode-clangd",
+ "vadimcn.vscode-lldb",
+ "matepek.vscode-catch2-test-adapter",
+ "twxs.cmake"
+ ],
+ "settings": {
+ // Use zsh as default terminal
+ "terminal.integrated.profiles.linux": {
+ "zsh": {
+ "path": "/bin/zsh",
+ "args": ["-l", "-i"]
+ }
+ },
+ "terminal.integrated.defaultProfile.linux": "zsh",
+
+ // Use system installation of clangd
+ "clangd.path": "clangd"
+ }
+ }
+ }
+}
diff --git a/demo/.devcontainer/docker-compose.yml b/demo/.devcontainer/docker-compose.yml
new file mode 100644
index 00000000..77fba341
--- /dev/null
+++ b/demo/.devcontainer/docker-compose.yml
@@ -0,0 +1,13 @@
+version: '3.8'
+services:
+ tutorial:
+ build:
+ context: .
+ dockerfile: .devcontainer/Dockerfile
+
+ volumes:
+ - ..:/workspaces:cached
+
+ # Overrides default command so things don't shut down after the process ends.
+ command: sleep infinity
+
diff --git a/demo/.vscode/launch.json b/demo/.vscode/launch.json
new file mode 100644
index 00000000..df67280a
--- /dev/null
+++ b/demo/.vscode/launch.json
@@ -0,0 +1,18 @@
+{
+ // Use IntelliSense to learn about possible attributes.
+ // Hover to view descriptions of existing attributes.
+ // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
+ "version": "0.2.0",
+ "configurations": [
+ {
+ "type": "lldb",
+ "request": "launch",
+ "name": "Debug Pacman Demo",
+ "program": "${workspaceFolder}/build/arbitration_graphs_pacman_demo",
+ "args": [],
+ "cwd": "${workspaceFolder}",
+ "initCommands":["settings set target.disable-aslr false"],
+ "console": "integratedTerminal"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/demo/.vscode/tasks.json b/demo/.vscode/tasks.json
new file mode 100644
index 00000000..d1bb4811
--- /dev/null
+++ b/demo/.vscode/tasks.json
@@ -0,0 +1,39 @@
+{
+ // See https://go.microsoft.com/fwlink/?LinkId=733558
+ // for the documentation about the tasks.json format
+ "version": "2.0.0",
+ "tasks": [
+ {
+ "label": "Create build folder",
+ "type": "shell",
+ "command": "mkdir -p ${workspaceFolder}/build"
+ },
+ {
+ "label": "Configure debug build",
+ "type": "shell",
+ "command": "cmake -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTS=true -S ${workspaceFolder} -B ${workspaceFolder}/build"
+ },
+ {
+ "label": "CMake build for debug",
+ "dependsOn": ["Create build folder", "Configure debug build"],
+ "type": "shell",
+ "command": "cmake --build ${workspaceFolder}/build -j9",
+ "group": {
+ "kind": "build",
+ "isDefault": true
+ }
+ },
+ {
+ "label": "Configure release build",
+ "dependsOn": ["Create build folder"],
+ "type": "shell",
+ "command": "cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_TESTS=true -S ${workspaceFolder} -B ${workspaceFolder}/build"
+ },
+ {
+ "label": "CMake build for release",
+ "dependsOn": ["Create build folder", "Configure release build"],
+ "type": "shell",
+ "command": "cmake --build ${workspaceFolder}/build -j9"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/demo/README.md b/demo/README.md
index 834175e3..03a3f39b 100644
--- a/demo/README.md
+++ b/demo/README.md
@@ -17,4 +17,15 @@ Open the GUI with your favorite browser:
## Tutorial
-If you're here for the tutorial, follow the instructions on our [Tutorial GitHub Page](https://kit-mrt.github.io/arbitration_graphs/docs/Tutorial.md).
\ No newline at end of file
+If you're here for the tutorial, follow the instructions on our [Tutorial GitHub Page](https://kit-mrt.github.io/arbitration_graphs/docs/Tutorial.md).
+
+For a smooth out-of-the-box experience, we recommend using [Visual Studio Code](https://code.visualstudio.com/) with our DevContainer setup.
+
+- Open this folder in VSCode
+- Build and open the Dev Container by running this [command](https://code.visualstudio.com/docs/getstarted/userinterface#_command-palette) (use `Ctrl+Shift+P`):
+ `Dev Containers: Reopen in Container`
+- Enjoy a full-blown IDE with code-completion, code-navigation etc.
+ - Compile via `Ctrl+Shift+B`
+ - View, run and debug unit tests via [Testing](https://code.visualstudio.com/docs/editor/testing) sidebar
+ - Debug the PacMan Demo via [Run and Debug](https://code.visualstudio.com/docs/editor/debugging) sidebar
+ - Debug with breakpoints etc.
\ No newline at end of file
From a6034beb14337c39e771626bb6c83aa6eea2b548 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 17:50:28 +0100
Subject: [PATCH 21/48] Use subtitles as short site introduction text
---
docs/tasks/1_implement_behavior_component.md | 4 +++-
docs/tasks/2_extend_arbitration_graph.md | 2 ++
docs/tasks/3_add_more_behaviors.md | 2 ++
docs/tasks/4_nested_arbitrators.md | 2 ++
docs/tasks/5_cost_arbitration.md | 2 ++
docs/tasks/6_verification.md | 2 ++
6 files changed, 13 insertions(+), 1 deletion(-)
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
index 6ba2c9e0..df1bb0d6 100644
--- a/docs/tasks/1_implement_behavior_component.md
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -1,10 +1,12 @@
---
title: "Task 1: Implement a Behavior Component"
-description: Implement your first checkInvocationCondition and getCommand function, such that the ChaseGhost behavior component passes its unit tests.
+description: Implement your first invocation condition and command function, such that the ChaseGhost behavior component passes its unit tests.
---
# Chase Ghost
+Implement your first `checkInvocationCondition` and `getCommand` function, such that the ChaseGhost behavior component passes its unit tests.
+
## Context
Before we start building our arbitration graph, we want to take a closer look into behavior components.
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index d700472c..81527783 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -5,6 +5,8 @@ description: Extend the arbitration graph with the ChaseGhost behavior component
# Chase Ghost
+Extend the arbitration graph with the ChaseGhost behavior component
+
## Context
With our next behavior component ready to go, we need to think about integrating it into our arbitration graph.
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
index 1e886589..bfdcc9fe 100644
--- a/docs/tasks/3_add_more_behaviors.md
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -5,6 +5,8 @@ description: Integrate the EatClosestDot behavior component into the arbitration
# Eat Closest Dot
+Integrate the EatClosestDot behavior component into the arbitration graph.
+
## Context
So far, we have not looked into a behavior component that handles the most important aspect of the game: eating dots.
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
index 39e8b81b..cae0402e 100644
--- a/docs/tasks/4_nested_arbitrators.md
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -5,6 +5,8 @@ description: Integrate a long-term behavior and add another layer to the arbitra
# Nesting
+Integrate a long-term behavior and add another layer to the arbitration graph.
+
## Context
We have now implemented a few behavior components and integrated them into the arbitration graph.
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index b846cdd1..d87b4fe1 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -5,6 +5,8 @@ description: Learn how the cost arbitrator can help you to arbitrate between beh
# Cost Arbitrator
+Learn how the cost arbitrator can help you to arbitrate between behaviors based on their expected cost/utility.
+
## Context
The `EatDot` arbitrator we added in the [previous task](4_nested_arbitrators.md) decides between the two dot eating strategies randomly.
diff --git a/docs/tasks/6_verification.md b/docs/tasks/6_verification.md
index 432a9f0b..6c871fcc 100644
--- a/docs/tasks/6_verification.md
+++ b/docs/tasks/6_verification.md
@@ -5,6 +5,8 @@ description: Execute only safe commands and add a fallback strategy.
# Verification and Fallback Layers
+Execute only safe commands and add a fallback strategy.
+
## Context
The arbitration graph is now complete and PacMan is eating dots like a pro.
From 87eaf07ac29048ef09fcf643a10897dc5dd84f27 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 17:53:14 +0100
Subject: [PATCH 22/48] Add brackets to all function names for better
readability
---
docs/tasks/1_implement_behavior_component.md | 16 ++++++++--------
docs/tasks/5_cost_arbitration.md | 2 +-
docs/tasks/6_verification.md | 6 +++---
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
index df1bb0d6..a674beda 100644
--- a/docs/tasks/1_implement_behavior_component.md
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -5,7 +5,7 @@ description: Implement your first invocation condition and command function, suc
# Chase Ghost
-Implement your first `checkInvocationCondition` and `getCommand` function, such that the ChaseGhost behavior component passes its unit tests.
+Implement your first `checkInvocationCondition()` and `getCommand()` function, such that the ChaseGhost behavior component passes its unit tests.
## Context
@@ -24,20 +24,20 @@ We can ensure that's always the case using the behavior's invocation condition.
But wait - the current implementation of the invocation condition is not complete.
It should only be applicable if there is one of these tasty ghosts close by.
-Once that's out of the way, we'll take a closer look at the `getCommand` function which is missing some core logic right now.
+Once that's out of the way, we'll take a closer look at the `getCommand()` function which is missing some core logic right now.
## Goal
-Finish the implementation of the `checkInvocationCondition` and `getCommand` functions
+Finish the implementation of the `checkInvocationCondition()` and `getCommand()` functions
of the `ChaseGhost` behavior component such that it passes its unit tests.
## Instructions
- Open the implementation of the `ChaseGhost` behavior component in `src/chase_ghost_behavior.cpp`.
-- The `checkInvocationCondition` function is already implemented but does not check for the presence of a ghost.
-- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::checkInvocationCondition` if you need inspiration.
-- The `getCommand` function is partially implemented but the core logic is missing.
-- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::getCommand` if you need inspiration.
+- The `checkInvocationCondition()` function is already implemented but does not check for the presence of a ghost.
+- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::checkInvocationCondition()` if you need inspiration.
+- The `getCommand()` function is partially implemented but the core logic is missing.
+- Implement the missing piece. Take a look at the implementation of `AvoidGhostBehavior::getCommand()` if you need inspiration.
- Compile and run the unit tests for the `ChaseGhost` behavior component to verify that your implementation is correct.
## Solution
@@ -54,7 +54,7 @@ bool ChaseGhostBehavior::checkInvocationCondition(const Time& time) const {
}
```
-Add the missing pice of the getCommand function in `src/chase_ghost_behavior.cpp`:
+Add the missing piece of the `getCommand()` function in `src/chase_ghost_behavior.cpp`:
```cpp
Command ChaseGhostBehavior::getCommand(const Time& time) {
auto pacmanPosition = environmentModel_->pacmanPosition();
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index d87b4fe1..cbd77978 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -33,7 +33,7 @@ Finish the implementation of the `CostEstimator` and replace the random arbitrat
- In `cost_estimator.cpp`, fill in the blanks to compute `nDots` and `nCells`.
- Add an instance of the `CostEstimator` to the `PacmanAgent` class and initialize it in the constructor.
Don't forget to include the necessary headers and extend the parameter struct with the parameters for the `CostEstimator`.
-- Replace the random arbitrator with a cost arbitrator in the `PacmanAgent` class. Pass the `CostEstimator` instance to the `addOption` method.
+- Replace the random arbitrator with a cost arbitrator in the `PacmanAgent` class. Pass the `CostEstimator` instance to the `addOption()` method.
## Solution
diff --git a/docs/tasks/6_verification.md b/docs/tasks/6_verification.md
index 6c871fcc..76960b1c 100644
--- a/docs/tasks/6_verification.md
+++ b/docs/tasks/6_verification.md
@@ -53,21 +53,21 @@ Add the `MoveRandomly` behavior component as a last resort fallback layer.
## Instructions
-- In `verifier.cpp`, finish the implementation of the `Verifier::analyze` method.
+- In `verifier.cpp`, finish the implementation of the `Verifier::analyze()` method.
- Add an instance of the `Verifier` to the `PacmanAgent` class and initialize it in the constructor.
- Pass the `Verifier` instance to the constructors of the arbitrators.
(Hint: You'll need to adjust the template parameters of the arbitrators.)
- Add the `MoveRandomly` behavior component analogously to the other behavior components.
- Mark the `MoveRandomly` behavior component as a last resort fallback layer.
- Try breaking a behavior component on purpose and see how the system reacts.
- (Try throwing an exception in the `getCommand` method of a behavior component or returning a command that will lead to a collision with a wall.)
+ (Try throwing an exception in the `getCommand()` method of a behavior component or returning a command that will lead to a collision with a wall.)
## Solution
Click here to expand the solution
-In the `Verifier::analyze` method (in `include/demo/verifier.hpp`), we simply check if the command would lead to an invalid position:
+In the `Verifier::analyze()` method (in `include/demo/verifier.hpp`), we simply check if the command would lead to an invalid position:
```cpp
VerificationResult analyze(const Time /*time*/, const Command& command) const {
Move nextMove = Move{command.path.front()};
From 7741a909800b1109fd52bfed2bd6c5e6173575b2 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 18:07:06 +0100
Subject: [PATCH 23/48] Use title for task heading and keep tutorial page
banner consistent
---
docs/tasks/1_implement_behavior_component.md | 5 ++---
docs/tasks/2_extend_arbitration_graph.md | 7 +++----
docs/tasks/3_add_more_behaviors.md | 7 +++----
docs/tasks/4_nested_arbitrators.md | 5 ++---
docs/tasks/5_cost_arbitration.md | 5 ++---
docs/tasks/6_verification.md | 5 ++---
6 files changed, 14 insertions(+), 20 deletions(-)
diff --git a/docs/tasks/1_implement_behavior_component.md b/docs/tasks/1_implement_behavior_component.md
index a674beda..dcd4e0ba 100644
--- a/docs/tasks/1_implement_behavior_component.md
+++ b/docs/tasks/1_implement_behavior_component.md
@@ -1,9 +1,8 @@
---
-title: "Task 1: Implement a Behavior Component"
-description: Implement your first invocation condition and command function, such that the ChaseGhost behavior component passes its unit tests.
+title: "Arbitration Graphs Tutorial"
---
-# Chase Ghost
+# Task 1: Implement a Behavior Component
Implement your first `checkInvocationCondition()` and `getCommand()` function, such that the ChaseGhost behavior component passes its unit tests.
diff --git a/docs/tasks/2_extend_arbitration_graph.md b/docs/tasks/2_extend_arbitration_graph.md
index 81527783..9f8d99cc 100644
--- a/docs/tasks/2_extend_arbitration_graph.md
+++ b/docs/tasks/2_extend_arbitration_graph.md
@@ -1,11 +1,10 @@
---
-title: "Task 2: Extend the Arbitration Graph"
-description: Extend the arbitration graph with the ChaseGhost behavior component.
+title: "Arbitration Graphs Tutorial"
---
-# Chase Ghost
+# Task 2: Extend the Arbitration Graph
-Extend the arbitration graph with the ChaseGhost behavior component
+Extend the arbitration graph with the `ChaseGhost` behavior component.
## Context
diff --git a/docs/tasks/3_add_more_behaviors.md b/docs/tasks/3_add_more_behaviors.md
index bfdcc9fe..5f9e4686 100644
--- a/docs/tasks/3_add_more_behaviors.md
+++ b/docs/tasks/3_add_more_behaviors.md
@@ -1,11 +1,10 @@
---
-title: "Task 3: Even more behavior components"
-description: Integrate the EatClosestDot behavior component into the arbitration graph.
+title: "Arbitration Graphs Tutorial"
---
-# Eat Closest Dot
+# Task 3: Even more behavior components
-Integrate the EatClosestDot behavior component into the arbitration graph.
+Integrate the `EatClosestDot` behavior component into the arbitration graph.
## Context
diff --git a/docs/tasks/4_nested_arbitrators.md b/docs/tasks/4_nested_arbitrators.md
index cae0402e..8bc0cf18 100644
--- a/docs/tasks/4_nested_arbitrators.md
+++ b/docs/tasks/4_nested_arbitrators.md
@@ -1,9 +1,8 @@
---
-title: "Task 4: Nested arbitration graphs"
-description: Integrate a long-term behavior and add another layer to the arbitration graph
+title: "Arbitration Graphs Tutorial"
---
-# Nesting
+# Task 4: Nested arbitration graphs
Integrate a long-term behavior and add another layer to the arbitration graph.
diff --git a/docs/tasks/5_cost_arbitration.md b/docs/tasks/5_cost_arbitration.md
index cbd77978..a0e9bd91 100644
--- a/docs/tasks/5_cost_arbitration.md
+++ b/docs/tasks/5_cost_arbitration.md
@@ -1,9 +1,8 @@
---
-title: "Task 5: Arbitrate based on predicted utility"
-description: Learn how the cost arbitrator can help you to arbitrate between behaviors based on their expected cost/utility.
+title: "Arbitration Graphs Tutorial"
---
-# Cost Arbitrator
+# Task 5: Arbitrate based on predicted utility
Learn how the cost arbitrator can help you to arbitrate between behaviors based on their expected cost/utility.
diff --git a/docs/tasks/6_verification.md b/docs/tasks/6_verification.md
index 76960b1c..debbab4a 100644
--- a/docs/tasks/6_verification.md
+++ b/docs/tasks/6_verification.md
@@ -1,9 +1,8 @@
---
-title: "Task 6: Better safe than sorry"
-description: Execute only safe commands and add a fallback strategy.
+title: "Arbitration Graphs Tutorial"
---
-# Verification and Fallback Layers
+# Task 6: Better safe than sorry
Execute only safe commands and add a fallback strategy.
From d5bd4e8f452995f2dcccc0054adec9fde0877e5d Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 18:43:04 +0100
Subject: [PATCH 24/48] Add a auto-generated sitemap.xml
---
docs/_layouts/default.html | 5 +++-
docs/sitemap.xml | 59 ++++++++++++++++++++++++++++++++++++++
2 files changed, 63 insertions(+), 1 deletion(-)
create mode 100644 docs/sitemap.xml
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
index fcd768c7..0774783d 100644
--- a/docs/_layouts/default.html
+++ b/docs/_layouts/default.html
@@ -44,8 +44,11 @@
{{ page.description | default: site.description | de
Cayman theme,
using
allejo/jekyll-toc and
+
snippets from
- Bram.us
+ Bram.us
+ as well as
+ David Ensinger
â¤ī¸
diff --git a/docs/sitemap.xml b/docs/sitemap.xml
new file mode 100644
index 00000000..82c99f38
--- /dev/null
+++ b/docs/sitemap.xml
@@ -0,0 +1,59 @@
+---
+layout: null
+sitemap:
+ exclude: 'yes'
+permalink: /sitemap.xml
+---
+
+
+ {% for post in site.posts %}
+ {% assign file_ext = post.url | split: '.' | last %}
+ {% if post.published != false and file_ext != 'css' %}
+
+ {{ site.url }}{{ post.url }}
+ {% if post.sitemap.lastmod %}
+ {{ post.sitemap.lastmod | date: "%Y-%m-%d" }}
+ {% elsif post.date %}
+ {{ post.date | date_to_xmlschema }}
+ {% else %}
+ {{ site.time | date_to_xmlschema }}
+ {% endif %}
+ {% if post.sitemap.changefreq %}
+ {{ post.sitemap.changefreq }}
+ {% else %}
+ monthly
+ {% endif %}
+ {% if post.sitemap.priority %}
+ {{ post.sitemap.priority }}
+ {% else %}
+ 0.5
+ {% endif %}
+
+ {% endif %}
+ {% endfor %}
+ {% for page in site.pages %}
+ {% assign file_ext = page.url | split: '.' | last %}
+ {% if page.sitemap.exclude != "yes" and file_ext != 'css' %}
+
+ {{ site.url }}{{ page.url | remove: "index.html" }}
+ {% if page.sitemap.lastmod %}
+ {{ page.sitemap.lastmod | date: "%Y-%m-%d" }}
+ {% elsif page.date %}
+ {{ page.date | date_to_xmlschema }}
+ {% else %}
+ {{ site.time | date_to_xmlschema }}
+ {% endif %}
+ {% if page.sitemap.changefreq %}
+ {{ page.sitemap.changefreq }}
+ {% else %}
+ monthly
+ {% endif %}
+ {% if page.sitemap.priority %}
+ {{ page.sitemap.priority }}
+ {% else %}
+ 0.3
+ {% endif %}
+
+ {% endif %}
+ {% endfor %}
+
\ No newline at end of file
From a439b3c8efa427fbb784b6d55b5239e833293ced Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 19:24:13 +0100
Subject: [PATCH 25/48] Fix warning about missing toc.css file (it's compiled
into the main style.css)
---
docs/_includes/head-custom.html | 1 -
1 file changed, 1 deletion(-)
diff --git a/docs/_includes/head-custom.html b/docs/_includes/head-custom.html
index 4a2e9169..7f8b0918 100644
--- a/docs/_includes/head-custom.html
+++ b/docs/_includes/head-custom.html
@@ -1,4 +1,3 @@
-
\ No newline at end of file
From a4caac8fdfdfa64a684ae2b14b3d0a1bda64e88e Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Mon, 18 Nov 2024 12:09:12 +0100
Subject: [PATCH 26/48] Tune font size of inline code
---
docs/assets/_sass/fonts.scss | 1 +
1 file changed, 1 insertion(+)
diff --git a/docs/assets/_sass/fonts.scss b/docs/assets/_sass/fonts.scss
index 57d04fb5..f05e8f4f 100644
--- a/docs/assets/_sass/fonts.scss
+++ b/docs/assets/_sass/fonts.scss
@@ -28,6 +28,7 @@ body {
code {
font-family: "Source Code Pro", Consolas, "Liberation Mono", Menlo, Courier, monospace;
+ font-size: 0.85rem;
}
pre {
From 3375912f74ae0ea4644d65b9b2d2eb948a4ffd27 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Mon, 18 Nov 2024 12:09:29 +0100
Subject: [PATCH 27/48] Define navigation text colors in variables.scss
---
docs/assets/_sass/toc.scss | 6 +++---
docs/assets/_sass/variables.scss | 5 +++++
2 files changed, 8 insertions(+), 3 deletions(-)
diff --git a/docs/assets/_sass/toc.scss b/docs/assets/_sass/toc.scss
index 0eb87b26..1ee23572 100644
--- a/docs/assets/_sass/toc.scss
+++ b/docs/assets/_sass/toc.scss
@@ -43,7 +43,7 @@ html {
// ScrollSpy active styles (see toc.js tab for activation)
.section-nav li.active>a {
- color: #333;
+ color: $nav-text-active-color;
font-weight: 500;
}
@@ -56,13 +56,13 @@ html {
text-decoration: none;
display: block;
padding: .125rem 0;
- color: #ccc;
+ color: $nav-text-color;
transition: all 50ms ease-in-out;
/* đĄ This small transition makes setting of the active state smooth */
}
.section-nav a:hover,
.section-nav a:focus {
- color: #666;
+ color: $nav-text-focus-color;
}
}
\ No newline at end of file
diff --git a/docs/assets/_sass/variables.scss b/docs/assets/_sass/variables.scss
index 1f12ce6b..cc625fe8 100644
--- a/docs/assets/_sass/variables.scss
+++ b/docs/assets/_sass/variables.scss
@@ -2,6 +2,11 @@
$large-breakpoint: 64em !default;
$medium-breakpoint: 42em !default;
+// Navigation
+$nav-text-color: #ccc !default;
+$nav-text-active-color: #333 !default;
+$nav-text-focus-color: #666 !default;
+
// Headers
$header-heading-color: #fff !default;
$header-bg-color: #008383 !default;
From eb3be89c8161e6ad95bb46abdd82178eed02b1e4 Mon Sep 17 00:00:00 2001
From: Piotr Spieker
Date: Fri, 15 Nov 2024 19:27:17 +0100
Subject: [PATCH 28/48] Add menu to tutorial pages
---
docs/_layouts/default.html | 34 ++++++++++++++
docs/assets/_sass/toc.scss | 49 +++++++++++++++-----
docs/assets/_sass/variables.scss | 2 +
docs/assets/css/style.scss | 4 ++
docs/tasks/1_implement_behavior_component.md | 1 +
docs/tasks/2_extend_arbitration_graph.md | 1 +
docs/tasks/3_add_more_behaviors.md | 1 +
docs/tasks/4_nested_arbitrators.md | 1 +
docs/tasks/5_cost_arbitration.md | 1 +
docs/tasks/6_verification.md | 1 +
10 files changed, 84 insertions(+), 11 deletions(-)
diff --git a/docs/_layouts/default.html b/docs/_layouts/default.html
index 0774783d..e52daeb1 100644
--- a/docs/_layouts/default.html
+++ b/docs/_layouts/default.html
@@ -32,6 +32,40 @@
{{ page.description | default: site.description | de