Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pacman demo #63

Merged
merged 168 commits into from
Oct 31, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
168 commits
Select commit Hold shift + click to select a range
6e6222e
Draft pacman demo
orzechow Apr 12, 2024
b6138ea
WIP Setup arbitrator pacman demo structure
orzechow May 6, 2024
f861fb5
Update EnTT-Pacman submodule to clean 0a1ce67:
orzechow May 14, 2024
8fe71d7
Use public base image instead of locally built version
ll-nick May 8, 2024
2432031
Pass display device to fix docker display issues
ll-nick May 8, 2024
75a3703
Define main arbitrator class
ll-nick May 8, 2024
453a297
WIP: Copy main routine from EnTT and pass dummy command
ll-nick May 8, 2024
3a9d6f8
Add clang tidy and format to be able to use auto-formatting
ll-nick May 8, 2024
1a755b9
Add environment model and extract entity positions from game engine
ll-nick May 8, 2024
cb9078d
Temporary: Build demo using submodule
ll-nick May 14, 2024
8e8d434
Environment model now stores maze
ll-nick May 14, 2024
0f59a3c
Implement first draft of runAwayFromGhostBehavior and corresponding u…
ll-nick May 14, 2024
16fff70
Add first behavior to main arbitrator class
ll-nick May 14, 2024
5ed8459
Call getCommand from main.cpp
ll-nick May 14, 2024
f2cd6c7
gitignore vscode files
ll-nick May 14, 2024
17c7564
Implement doNothingBehavior
ll-nick May 14, 2024
03a2616
Add defined behaviors to arbitration graph
ll-nick May 14, 2024
fb290ac
Smarten up getCommand of run away behavior a little bit
ll-nick May 14, 2024
ac341ab
Move mock environment into separate header
ll-nick May 14, 2024
98bea39
Define maze in mock environment model and adjust numbers in unit test…
ll-nick May 14, 2024
a90ebd6
Consider walls in run away behavior
ll-nick May 14, 2024
33d6efc
Move possible moves into types header
ll-nick May 14, 2024
85a7ec2
Implement astar and use it as distance function inside run away behavior
ll-nick May 14, 2024
0997172
Replace submodule with installed pacman library
ll-nick May 24, 2024
aff5a16
Name executable target _exe (analogous to EnTT_Pacman).
ll-nick May 24, 2024
5a0bd1e
Create separate docker stages for demo and tutorial
ll-nick May 24, 2024
99ad3b9
Add documentation
ll-nick May 24, 2024
8fac205
Refactor main.cpp to keep focus on the good stuff.
ll-nick May 24, 2024
aeb5776
Add PR review feedback
ll-nick May 29, 2024
9707235
Replace closestGhost{Distance,Position} by closestGhost and cache res…
ll-nick Jun 3, 2024
f1cfcad
Implement MazeAdapter
ll-nick Jun 3, 2024
04ff357
Cache computed A* distance
ll-nick Jun 4, 2024
203cff1
Move astar and pacman wrapper to separate namespace
ll-nick Jun 4, 2024
cb8309f
Merge pull request #9 from KIT-MRT/entt_interface
ll-nick Jun 4, 2024
ad90ffb
Implement maze wrapper class and use it instead of the EnTT MazeState
ll-nick Jun 10, 2024
a4bf8db
Move tunnel logic to separate function
ll-nick Jun 10, 2024
df3bdd6
Move heuristic computation into separate function
ll-nick Jun 10, 2024
ad52b47
Add test for cached A* distance
ll-nick Jun 10, 2024
0309c99
Simplify PacmanWrapper constructor using factory functions
ll-nick Jun 13, 2024
65b4bb9
q ends the demo, space pauses it
ll-nick Jun 13, 2024
bb1d4cd
<ESC> now also quits the game
ll-nick Jun 17, 2024
0f6f455
Merge pull request #15 from KIT-MRT/add_pause_by_keypress
ll-nick Jun 17, 2024
99ae8dd
Use [] operator for maze access
ll-nick Jun 17, 2024
a516ed7
Use std::clock in unit test
ll-nick Jun 17, 2024
7137324
Generalize tunnels using generically wrapped position
ll-nick Jun 17, 2024
812eef1
Merge pull request #14 from KIT-MRT/add_maze_wrapper
ll-nick Jun 17, 2024
2b71c2b
Fix linter warning about alias naming convention
ll-nick Jul 2, 2024
fcc910b
Remove outdated clang-tidy option
ll-nick Jul 2, 2024
e8e3a3a
Extract whether or not ghosts are scared from game
ll-nick Jul 2, 2024
a5caef6
Add first version of chase ghost behavior
ll-nick Jul 2, 2024
6754661
Add entities struct
ll-nick Jul 3, 2024
755f324
Remove positionStore and update tests accordingly
ll-nick Jul 3, 2024
bd8b329
Fix distance computation and corresponding tests
ll-nick Jul 3, 2024
e11162f
Move Entities struct to entities header (duh) and and scaredGhosts() …
ll-nick Jul 3, 2024
135cb0b
Compute distance to closest scared ghost and set invoc condition for …
ll-nick Jul 3, 2024
7128072
Return ghost (not just position) from distance calculations. Consider…
ll-nick Jul 3, 2024
bc65aff
Test driven development (once I move this commit in an interactive re…
ll-nick Jul 3, 2024
28cb32a
Apply suggestions from code review
ll-nick Jul 9, 2024
f58d801
push_back instead of erase to filter scared ghosts
ll-nick Jul 9, 2024
f81066f
Add minimum distance to chase ghost invoc condition
ll-nick Jul 9, 2024
38bb0f8
Fix astar crash caused by virtual tunnel position
ll-nick Jul 9, 2024
de20640
Consider tunnel in the start cell heuristic as well
ll-nick Jul 9, 2024
9044207
Merge pull request #18 from KIT-MRT/fix_astar_virtual_position
ll-nick Jul 9, 2024
ec998ec
Merge pull request #16 from KIT-MRT/chase_ghost_behavior
ll-nick Jul 9, 2024
baced16
Implement random walk behavior and corresponding unit test
ll-nick Jul 9, 2024
153608d
Add random walk behavior to arbitration graph
ll-nick Jul 9, 2024
15ac9ad
Fix linter warnings
ll-nick Jul 10, 2024
d4d2066
Consistently setup behavior parameters
ll-nick Jul 10, 2024
8ed4c95
Replace direction with path in command struct
ll-nick Jul 11, 2024
adff121
Command constructor is now marked explicit
ll-nick Jul 11, 2024
e350212
Add interface to return next direction to fix tests
ll-nick Jul 11, 2024
04ba976
Fix linter warnings
ll-nick Jul 11, 2024
c835f8f
Rename distance to manhattanDistance to prevent confusion with euclid…
ll-nick Jul 11, 2024
ca588e2
Apply suggestions from code review
ll-nick Jul 22, 2024
fd866db
Merge pull request #19 from KIT-MRT/random_walk_behavior
ll-nick Jul 22, 2024
5caaee8
Apply suggestions from code review
ll-nick Jul 22, 2024
ffc1486
Merge pull request #30 from KIT-MRT/add_path_interface
ll-nick Jul 22, 2024
3592d22
Rename files
ll-nick Jul 11, 2024
6f605fe
Rename the DoNothingBehavior to StayInPlaceBehavior in the code
ll-nick Jul 11, 2024
7dd6d4c
Store direction in entity class
ll-nick Jul 11, 2024
e380d99
Add direction interface to env model and mock env model
ll-nick Jul 11, 2024
0e2a8e2
Implement the actual stay in place behavior
ll-nick Jul 11, 2024
9e540ca
Merge pull request #32 from KIT-MRT/stay_in_place_behavior
ll-nick Aug 1, 2024
268b2c8
Rename RunAwayFromGhost to AvoidGhost in code
ll-nick Jul 22, 2024
2c5bb71
Rename files
ll-nick Jul 22, 2024
286b418
Fix unit test
ll-nick Aug 1, 2024
5bfdb56
Merge pull request #34 from KIT-MRT/rename_avoid_ghost_behavior
ll-nick Aug 1, 2024
8c8c41f
Create separate tileType enum and use it in maze class
ll-nick Jul 23, 2024
67274d2
Use type enum inside cell class replacing the isWall bool
ll-nick Jul 23, 2024
431ae46
Add interface to compute the shortest path on top of it's distance
ll-nick Jul 23, 2024
1e7d138
Add astar interface to compute distance to closest dot
ll-nick Jul 23, 2024
a8296cd
Continuously update maze
ll-nick Jul 23, 2024
22de078
Fix bug where no path was found due to the order of the game logic co…
ll-nick Jul 23, 2024
e79f071
Add eatClosestDotBehavior
ll-nick Jul 23, 2024
2cdd067
Rename manhattanDistance to mazeDistance
ll-nick Jul 23, 2024
d649a28
Generalize the expandCell function by passing a heuristic function
ll-nick Jul 23, 2024
60d9e04
Fix file name typo
ll-nick Jul 25, 2024
e7ec811
Apply suggestions from code review
ll-nick Sep 24, 2024
e43d8a2
AStar returns optional to clearly indicate whether path was found
ll-nick Sep 24, 2024
980303a
Merge pull request #35 from KIT-MRT/eat_closest_dot_behavior
ll-nick Sep 24, 2024
0cdc8fa
Generalize mazeAdapter to be reused in clustering algorithm
ll-nick Jul 24, 2024
1fb7348
Move positionConsideringTunnel into maze class
ll-nick Jul 25, 2024
64e7719
Add ClusterFinder class
ll-nick Jul 25, 2024
ea75033
Add and compute center for each cluster
ll-nick Jul 25, 2024
c0fd77d
Find clusters during init and use getter function
ll-nick Jul 25, 2024
bf3ced5
Use Positions alias
ll-nick Jul 25, 2024
529685b
rename getter functions to clarify that we are talking about dot clus…
ll-nick Jul 25, 2024
3e89d74
Add clusterFinder to environment model
ll-nick Jul 25, 2024
529558d
Power pellets can be part of a cluster
ll-nick Jul 25, 2024
4876ea5
Return the full clusters vector instead of just the cluster centers
ll-nick Jul 25, 2024
46536c2
Add convenience function to determine whether given position is withi…
ll-nick Jul 25, 2024
ce90279
Add another astar interface to the env model
orzechow Oct 4, 2024
52966c2
Add changeDotClusterBehavior
orzechow Oct 4, 2024
f199a48
Bug fix: Fix out of range error in run away and chase ghost behaviors
ll-nick Jul 25, 2024
b91d969
Add changeDotClusterBehavior to pacmanAgent
orzechow Oct 4, 2024
704d91b
Add documentation and tidy up
ll-nick Jul 25, 2024
063ae1e
Use std::optional for A* path return types
orzechow Oct 4, 2024
88d2e45
Apply suggestions from code review
ll-nick Oct 7, 2024
5a6118b
Move behavior implementation out of header
ll-nick Oct 7, 2024
0da94db
Remove non-obvious abbreviation from variable name
ll-nick Oct 7, 2024
c783b60
Generalize unit test to not assume a given order of clusters
ll-nick Oct 7, 2024
bcf1f2d
Merge pull request #36 from KIT-MRT/change_dot_cluster_behavior
ll-nick Oct 7, 2024
1409deb
More convenience functions passed through the environment model
ll-nick Jul 25, 2024
f4c371b
Add a Move constructor using a Direction
ll-nick Jul 25, 2024
ec33e97
Add costEstimator
ll-nick Jul 25, 2024
9c5a3e6
Use costArbitrator to switch between the eat dot strategies
orzechow Oct 4, 2024
b2a6f92
Add simple unit test
ll-nick Jul 25, 2024
4e48b08
Add documentation
ll-nick Jul 25, 2024
6202876
Remove unused includes
orzechow Oct 4, 2024
f1642af
Apply suggestions from code review
ll-nick Oct 7, 2024
8cc4678
Handle 0 dots in cost function
ll-nick Oct 7, 2024
e48d8ba
The "absolute Path" no longer contains the current position
ll-nick Oct 7, 2024
0081abd
Some naming suggestions from the code review
ll-nick Oct 7, 2024
dba62df
Moved utility out of cost estimator
ll-nick Oct 7, 2024
9bdfeb7
Merge pull request #38 from KIT-MRT/cost_estimator
ll-nick Oct 7, 2024
e739fb6
Yet another function passed through the environment model
ll-nick Jul 25, 2024
4a8801e
Add verifier
ll-nick Jul 25, 2024
7a7a7e3
Use verifier in arbitrators
orzechow Oct 4, 2024
91e2741
Make stayInPlace a fallback behavior
orzechow Oct 4, 2024
d014631
Remove Direction::LAST as it is no longer required
ll-nick Jul 25, 2024
cf1349e
Add basic test for verification
ll-nick Oct 7, 2024
158389e
Add test for verification within priority arbitrator
ll-nick Oct 7, 2024
7e5180e
Bug fix: Handle Direction::none
ll-nick Oct 8, 2024
8210e8b
Merge pull request #40 from KIT-MRT/verifier
ll-nick Oct 8, 2024
31099d8
Rename RandomWalkBehavior to MoveRandomly
ll-nick Oct 8, 2024
bd18c91
Rename files
ll-nick Oct 8, 2024
19ebf85
Remove rebase artifact
ll-nick Oct 8, 2024
7eb3499
Merge pull request #55 from KIT-MRT/raname_move_randomly_behavior
ll-nick Oct 8, 2024
125cf70
Move toAbsolutPath into EnvironmentModel
ll-nick Oct 22, 2024
b6b193c
Pass environmentModel to PacmanAgent
ll-nick Oct 22, 2024
dbd9a79
Render the path as blended green tiles
ll-nick Oct 22, 2024
c652ea8
Make path toggleable, default is off
ll-nick Oct 22, 2024
e4e7c79
Merge branch 'main' into pacman-demo
orzechow Oct 29, 2024
c75f358
Merge pull request #56 from KIT-MRT/render_path
ll-nick Oct 29, 2024
82b3f11
Use explicit versions when building docker images
orzechow Oct 29, 2024
bdd22a4
Merge docker-compose.yaml with docker-compose.devel.yaml
orzechow Oct 29, 2024
ffdc8f6
Build demo with more threads
orzechow Oct 29, 2024
68c648d
Avoid copying the whole repo into the docker image
orzechow Oct 28, 2024
233d800
Merge pull request #64 from KIT-MRT/improve_docker
orzechow Oct 30, 2024
882d5b6
Make sure to run only the demo service on docker compose up
orzechow Oct 30, 2024
92c7157
Use cropped pacman screenshot in Readme
orzechow Oct 30, 2024
4d333c0
Improve install and devel section of Readme
orzechow Oct 30, 2024
3c0352d
Add functionality teaser and brief arbitrator explanation to Readme
orzechow Oct 30, 2024
c16ef52
Apply review suggestion by @ll-nick to Readme
orzechow Oct 30, 2024
f4244a8
Update README.md
orzechow Oct 30, 2024
a45bea0
Improve language of feature list a bit
orzechow Oct 30, 2024
e947286
Remove the demo Readme (it is addressed in the main Readme)
orzechow Oct 31, 2024
729b1fe
Explain the docker compose profile in demo/docker-compose.yaml
orzechow Oct 31, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,3 @@ _site/
.bundle/
vendor/
Gemfile.lock

Empty file added .gitmodules
Empty file.
6 changes: 5 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ RUN git clone https://github.com/KIT-MRT/util_caching.git /tmp/util_caching && \


# Install arbitration_graphs
COPY . /tmp/arbitration_graphs
COPY CMakeLists.txt /tmp/arbitration_graphs/
COPY cmake /tmp/arbitration_graphs/cmake
COPY include /tmp/arbitration_graphs/include
COPY test /tmp/arbitration_graphs/test

RUN mkdir /tmp/arbitration_graphs/build && \
cd /tmp/arbitration_graphs/build && \
cmake .. && \
Expand Down
90 changes: 69 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,43 +2,83 @@

[![License](https://img.shields.io/github/license/KIT-MRT/arbitration_graphs)](./LICENSE)

Arbitration graphs combine simple atomic behavior components into more complex behaviors for decision-making and behavior generation
**Hierarchical behavior models for complex decision-making and behavior generation in robotics!**
orzechow marked this conversation as resolved.
Show resolved Hide resolved

<!--
TODO: add example arbitration graph from robotics (with POMDP, RL methods)
<img
src="./docs/assets/img/pacman_arbitrator_safe.svg"
alt="Example arbitration graph from robotics"
style="margin:10px; width: 50%"
align="right"
/>
-->

- 🌱 **Bottom-up**
Combine simple atomic behavior components to generate complex behaviors.
- 🧩 **Functional decomposition**
Behavior components address *How to do it?* and *Can we do it?*, while Arbitrators decide *What to do?*
- 🧠 **Meta-framework**
Integrate diverse methods in one decision-making framework. Why not combine optimization-based planning, probabilistic approaches (POMDPs), and machine learning (RL)? Use any approach where it performs best!
- 📈 **Scalability**
Stack behavior components in arbitrators to create hierarchical behavior models.
- 🛠️ **Maintainability**
Add new behaviors without having to touch existing ones – did we mention strict modularity and functional decomposition?
- 💡 **Transparency**
Easily follow and understand the decision-making process.
- 🛡️ **Behavior Verification**
Use tightly integrated verifiers to ensure that only safe and valid behavior commands are executed.
- 🪂 **Graceful Degradation**
Your behavior is unreliable or unsafe? Arbitrators will gracefully fall back to the next-best option.


## Demo

We provide a demo of this 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:

## Demonstration
```bash
git clone https://github.com/KIT-MRT/arbitration_graphs.git
cd arbitration_graphs/demo
docker compose up
```

We are currently working on a demonstration of this library using Pac-Man as an example application.
### Explanation

You will see the *Pacman Agent* arbitrator selecting between five behavior options (by priority).
The *Eat Dots* option is itself an arbitrator with two sub-behaviors (selecting by expected benefit).

In this scene,
- the *Chase Ghost* and *Avoid Ghost* behaviors are not applicable (no ghosts in close vicinity) → grey background,
- the *Eat Closest Dot* and *Move Randomly* behavior failed verification (our verification showcase) → red background,
- thus, the least-prioritized *Stay in Place* behavior is being executed → green background.

<p align="center">
<img src="docs/assets/img/pacman_scenario.png" width="400" />
<img src="docs/assets/img/pacman_scenario_cropped.png" width="300" />
</p>
<p align="center">
<img src="docs/assets/img/pacman_arbitrator_safe.svg" width="500" />
</p>

Feel free to take a look at the work in progress in the [pacman-demo branch](https://github.com/KIT-MRT/arbitration_graphs/tree/pacman-demo).

## Installation
We will shortly add an [arbitration graph GUI](https://github.com/KIT-MRT/arbitration_graphs/pull/10) and a [tutorial](https://github.com/KIT-MRT/arbitration_graphs/pull/51) based on this demo – stay tuned!

First, clone this repository:

```bash
git clone https://github.com/KIT-MRT/arbitration_graphs.git
cd arbitration_graphs
```
## Installation

From easy to advanced:

### Using Docker image

We provide a [`Dockerfile`](./Dockerfile) with the library already installed globally.

In the source directory, build and run the docker image with `docker compose`:
We provide a Docker image with the library already installed globally.

```bash
docker compose build
docker compose run --rm arbitration_graphs
docker pull ghcr.io/kit-mrt/arbitration_graphs
```

The library is installed in the Docker image under `/usr/local/include/arbitration_graphs/` and `/usr/local/lib/cmake/arbitration_graphs/`.
The library is located under `/usr/local/include/arbitration_graphs/` and `/usr/local/lib/cmake/arbitration_graphs/`.
So, it can be easily loaded with CMake:

```cmake
Expand All @@ -56,6 +96,13 @@ First make sure all dependencies are installed:

See also the [`Dockerfile`](./Dockerfile) for how to install these packages under Debian or Ubuntu.

Now, clone the repository:

```bash
git clone https://github.com/KIT-MRT/arbitration_graphs.git
cd arbitration_graphs
```

Compile and install the project with CMake:

```bash
Expand All @@ -71,12 +118,13 @@ sudo cmake --install .

### Using Docker image

Follow the steps above to setup the Docker image.
Then, run the development image.
Clone the repository and run the development image

```bash
docker compose -f docker-compose.devel.yaml build
docker compose -f docker-compose.devel.yaml run --rm arbitration_graphs_devel
git clone https://github.com/KIT-MRT/arbitration_graphs.git
cd arbitration_graphs
docker compose build
docker compose run --rm arbitration_graphs_devel
```

This mounts the source into the container's `/home/blinky/arbitration_graphs` folder.
Expand Down
92 changes: 92 additions & 0 deletions demo/.clang-format
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
Language: Cpp
BasedOnStyle: LLVM
AccessModifierOffset: -4
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
AllowAllParametersOfDeclarationOnNextLine: true
AllowShortBlocksOnASingleLine: Never
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: None
AllowShortIfStatementsOnASingleLine: Never
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false
BinPackParameters: false
BraceWrapping:
AfterClass: false
AfterControlStatement: Never
AfterEnum: false
AfterFunction: false
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Attach
BreakBeforeTernaryOperators: true
BreakConstructorInitializersBeforeComma: false
ColumnLimit: 120
CommentPragmas: '^ IWYU pragma:'
ConstructorInitializerAllOnOneLineOrOnePerLine: false
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 4
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
ExperimentalAutoDetectBinPacking: false
ForEachMacros: [ foreach, Q_FOREACH, BOOST_FOREACH ]
IncludeCategories:
- Regex: '^<.*\/.*\/.*>'
Priority: 3
- Regex: '^<.*\/.*>'
Priority: 2
- Regex: '^<.*>'
Priority: 1
- Regex: '^".*\/.*\/.*"'
Priority: 6
- Regex: '^".*\/.*"'
Priority: 5
- Regex: '^".*"'
Priority: 4
- Regex: '.*'
Priority: 7
IndentCaseLabels: false
IndentWidth: 4
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MacroBlockBegin: ''
MacroBlockEnd: ''
MaxEmptyLinesToKeep: 2
NamespaceIndentation: None
PenaltyBreakBeforeFirstCallParameter: 19
PenaltyBreakComment: 300
PenaltyBreakFirstLessLess: 120
PenaltyBreakString: 1000
PenaltyExcessCharacter: 1000000
PenaltyReturnTypeOnItsOwnLine: 2000
PointerAlignment: Left
ReflowComments: true
SortIncludes: true
SpaceAfterCStyleCast: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeParens: ControlStatements
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInContainerLiterals: true
SpacesInCStyleCastParentheses: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
Standard: Latest
TabWidth: 4
UseTab: Never
Loading