# The Agnostic Behavior Tree package of the YASE framework This package contains the simulator agnostic behavior tree implementation. It can be used for for modular, simulator agnostic and deterministic simulation and scenario execution. Behavior Trees allow to build up any tree structure to represent the behavior to execute such as a [scenario or a full simulation setup](https://ieeexplore.ieee.org/document/9625405). Since the agnostic behavior tree allows data management and scheduling of tasks, it can be seen as a full [simulation kernel](https://ieeexplore.ieee.org/document/9162620).  ## Version 0.9.0 (== pre v1.0.0) The current version is considered as the pre version of the v1.0.0. **The package is considered as API stable**, however a grace period is given for external feedback which may break the API stability. ## Architecture ### Behavior Nodes In Behavior Trees, there exist three major node types: Composites, Decorators and Actions. - `ActionNode`: Action nodes are nodes, which perform actual tasks in the simulator, such as a `ChangeLane` or `FollowLane`. - `DecoratorNode`: Decorators allow to modify the behavior of other nodes. As an example, the `ChangeLane` behavior can be decorated with an `AdjacentLaneFree` condition decorator. This would prevent the execution of the `ChangeLane` in situations in which the `ChangeLane` not possible. - `CompositeNode`: Composites allow to compose multiple other behaviors into a greater behavior. As an example a `Sequence` composite may combine a `FollowLane` after a `ChangeLane` in sequential manner.  ### Scoped BlackBoard Container Often it is necessary to share data among several nodes within the tree. For this purpose the behavior nodes contain a scoped blackboard container to declare and look up data. The following example demonstrates how two symbols (`veh_1` and `veh_2`) are declared at a certain node. This can then be accessed by the nodes of the subtree, such as the `ChangeLane` nodes, which requires access.  ### Extensions For the behavior tree usage within specific simulation tools it is often necessary to add further custom methods to nodes. Such functionality can be added via composition with the Extension template. In the unit test "test_extension.cpp" it is exemplary shown how a custom method `serializeToFormatXyz()` can be added to all nodes. ## Types of Behavior Nodes ### Actions Actions are defined for the specific use case and simulation environment. Therefore predefined actions are not part of this simulator agnostic package. The existing utility actions are only for the purpose of unit testing. ### Decorators The package already provides some generic decorators which can be used across all implementations. - `ConstraintNode`: Checks a generic condition and ensures it is true \[at beginning / during execution / after execution\]. If the condition fails, the behavior node returns `kFailure`. - `DataDeclarationNode`: Decorator which sole purpose is to allow easy data declaration in the blackboard without a need to write an own node. - `DataProxyNode`: Decorator which allows to remap & restrict available blackboard data for the subtree. - `InverterNode`: Inverts the returned execution node status of the child node. `NodeStatus::kFailure` becomes `NodeStatus::kSuccess` and vice versa. `NodeStatus::kRunning` stays the same. - `RepeatNode`: This decorator repeats the child behavior N times. Once the child behavior returns `NodeStatus::kSuccess`, it is terminated and initialized again so the behavior is reset again. - `ServiceNode`: Allows to add generic services. Services are can calculate services like `UpdateLanePositions` and provide them via the blackboard for all nodes in the subtree. - `StartAt`: Delays the execution of the subtree until a generic condition returns true. Is for example useful to write trigger engines. - `StopAt`: Interrupts the execution of the subtree until a generic condition returns true independent if the child node is finished yet. ### Composites The package provides three base composites: - `Sequence`: This composite allows to execute behaviors in sequence, e.g. a `FollowLane` after a `ChangeLane`. - `Parallel`: This composite allows the parallel execution of behaviors, e.g. two vehicles follow a lane in parallel. - `Selector`: This composite allows the situation based, event based or interruption based execution of behavior. Example: A `selector` can first try a `ChangeLane`, but if this is not possible, it will perform a `FollowLane` behavior instead. ## Build and run tests ### Dependencies Tested with following versions, may work with lower version numbers: - make/4.2.1 - cmake/3.1 - gtest/1.8.1 ### How to build Create a subfolder "build" and build it: ```shell mkdir build && cd build cmake ../your/path/to/agnostic_behavior_tree && make && ./agnostic_behavior_tree_test ``` ## Usage ### Tips on how to use - Use predefined composites/ decorators as much as possible - Relying on them reduces compatibility problems with future versions in a great extent. - Always check if the node state is completely reset with an `onInit()` call. - Within a decorator, ensure that the `onInit()` call is passed to the child. ## Other References The following references provide deeper understanding of BehaviorTrees, which are the state of the art for behavior modeling in the gaming/ robotic industry. - [Behavior Tree Starter Kit](https://www.gameaipro.com/GameAIPro/GameAIPro_Chapter06_The_Behavior_Tree_Starter_Kit.pdf) - [Behavior Trees in Robotics and AI: An Introduction](https://arxiv.org/abs/1709.00084) - [Other good C++ implementation for Robotics](https://www.behaviortree.dev/) - [Unreal Engine Behavior Tree documentation](https://docs.unrealengine.com/en-US/InteractiveExperiences/ArtificialIntelligence/BehaviorTrees/index.html) - [Paper on scenario/simulation setup with yase behavior tree](https://ieeexplore.ieee.org/document/9625405) - [Simulation kernel](https://ieeexplore.ieee.org/document/9162620)