Robot Behavior Tree Demo
This is a demo of a behavior tree for a robot. It has no practical use for Vultron, rather it's an introduction to how to use the behavior tree framework we've built.
We're providing this as an example to show how to build a behavior tree that can be used to implement some context-aware behavior.
Behaviors
The robot has a number of behaviors:
- If the ball is in the bin, it will stop.
 - If the ball is in the robot's grasp and it is near the bin, it will put it in the bin.
 - If the ball is in the robot's grasp and it is not near the bin, it will move toward the bin.
 - If the ball is nearby, it will try to pick it up (and sometimes fail)
 - If the ball is not nearby, it will move toward the ball.
 - If the ball is not found, it will search for it.
 - If it fails to complete its task, it will ask for help.
 
The Behavior Tree
The tree structure is shown below.
graph LR
  Robot_1["? Robot"]
  BallPlaced_2(["#11052; BallPlaced"])
  Robot_1 --> BallPlaced_2
  MainSequence_3["→ MainSequence"]
  Robot_1 --> MainSequence_3
  EnsureBallFound_4["? EnsureBallFound"]
  MainSequence_3 --> EnsureBallFound_4
  BallFound_5(["#11052; BallFound"])
  EnsureBallFound_4 --> BallFound_5
  FindBall_6["→ FindBall"]
  EnsureBallFound_4 --> FindBall_6
  UsuallySucceed_7["#127922; UsuallySucceed"]
  FindBall_6 --> UsuallySucceed_7
  SetBallFound_8["#9648; SetBallFound"]
  FindBall_6 --> SetBallFound_8
  EnsureBallClose_9["? EnsureBallClose"]
  MainSequence_3 --> EnsureBallClose_9
  BallClose_10(["#11052; BallClose"])
  EnsureBallClose_9 --> BallClose_10
  ApproachBall_11["→ ApproachBall"]
  EnsureBallClose_9 --> ApproachBall_11
  UsuallySucceed_12["#127922; UsuallySucceed"]
  ApproachBall_11 --> UsuallySucceed_12
  SetBallClose_13["#9648; SetBallClose"]
  ApproachBall_11 --> SetBallClose_13
  EnsureBallGrasped_14["? EnsureBallGrasped"]
  MainSequence_3 --> EnsureBallGrasped_14
  BallGrasped_15(["#11052; BallGrasped"])
  EnsureBallGrasped_14 --> BallGrasped_15
  GraspBall_16["→ GraspBall"]
  EnsureBallGrasped_14 --> GraspBall_16
  OftenFail_17["#127922; OftenFail"]
  GraspBall_16 --> OftenFail_17
  SetBallGrasped_18["#9648; SetBallGrasped"]
  GraspBall_16 --> SetBallGrasped_18
  EnsureBinClose_19["? EnsureBinClose"]
  MainSequence_3 --> EnsureBinClose_19
  BinClose_20(["#11052; BinClose"])
  EnsureBinClose_19 --> BinClose_20
  ApproachBin_21["→ ApproachBin"]
  EnsureBinClose_19 --> ApproachBin_21
  UsuallySucceed_22["#127922; UsuallySucceed"]
  ApproachBin_21 --> UsuallySucceed_22
  SetBinClose_23["#9648; SetBinClose"]
  ApproachBin_21 --> SetBinClose_23
  EnsureBallPlaced_24["? EnsureBallPlaced"]
  MainSequence_3 --> EnsureBallPlaced_24
  BallPlaced_25(["#11052; BallPlaced"])
  EnsureBallPlaced_24 --> BallPlaced_25
  PlaceBall_26["→ PlaceBall"]
  EnsureBallPlaced_24 --> PlaceBall_26
  UsuallySucceed_27["#127922; UsuallySucceed"]
  PlaceBall_26 --> UsuallySucceed_27
  SetBallPlaced_28["#9648; SetBallPlaced"]
  PlaceBall_26 --> SetBallPlaced_28
  MaybeAskForHelp_29["→ MaybeAskForHelp"]
  Robot_1 --> MaybeAskForHelp_29
  TimeToAskForHelp_30(["#11052; TimeToAskForHelp"])
  MaybeAskForHelp_29 --> TimeToAskForHelp_30
  AskForHelp_31["#9648; AskForHelp"]
  MaybeAskForHelp_29 --> AskForHelp_31
Legend:
| Symbol | Meaning | 
|---|---|
| ? | FallbackNode | 
| → | SequenceNode | 
| ⇅ | Invert | 
| ▰ | ActionNode | 
| ⬬ | ConditionNode | 
| 🎲 | Fuzzer node (randomly succeeds or fails some percentage of the time) | 
Demo Output
Example
 # if vultron package is installed
# run the demo
$ vultrabot --robot
# print the tree and exit
$ vultrabot --robot --print-tree
# if vultron package is not installed
python -m vultron.bt.base.demo.robot
When the tree is run, it will look something like this:
(?) ?_Robot_1
 | (c) c_BallPlaced_2
 |  | = FAILURE
 | (>) >_MainSequence_3
 |  | (?) ?_EnsureBallFound_4
 |  |  | (c) c_BallFound_5
 |  |  |  | = FAILURE
 |  |  | (>) >_FindBall_6
 |  |  |  | (z) z_UsuallySucceed_7
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBallFound_8
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallClose_9
 |  |  | (c) c_BallClose_10
 |  |  |  | = FAILURE
 |  |  | (>) >_ApproachBall_11
 |  |  |  | (z) z_UsuallySucceed_12
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBallClose_13
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallGrasped_14
 |  |  | (c) c_BallGrasped_15
 |  |  |  | = FAILURE
 |  |  | (>) >_GraspBall_16
 |  |  |  | (z) z_OftenFail_17
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBallGrasped_18
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBinClose_19
 |  |  | (c) c_BinClose_20
 |  |  |  | = FAILURE
 |  |  | (>) >_ApproachBin_21
 |  |  |  | (z) z_UsuallySucceed_22
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBinClose_23
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallPlaced_24
 |  |  | (c) c_BallPlaced_25
 |  |  |  | = FAILURE
 |  |  | (>) >_PlaceBall_26
 |  |  |  | (z) z_UsuallySucceed_27
 |  |  |  |  | = FAILURE
 |  |  |  | = FAILURE
 |  |  | = FAILURE
 |  | = FAILURE
 | (>) >_MaybeAskForHelp_29
 |  | (c) c_TimeToAskForHelp_30
 |  |  | = FAILURE
 |  | = FAILURE
 | = FAILURE
The ball was knocked out of the robot's grasp!
(?) ?_Robot_1
 | (c) c_BallPlaced_2
 |  | = FAILURE
 | (>) >_MainSequence_3
 |  | (?) ?_EnsureBallFound_4
 |  |  | (c) c_BallFound_5
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallClose_9
 |  |  | (c) c_BallClose_10
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallGrasped_14
 |  |  | (c) c_BallGrasped_15
 |  |  |  | = FAILURE
 |  |  | (>) >_GraspBall_16
 |  |  |  | (z) z_OftenFail_17
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBallGrasped_18
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBinClose_19
 |  |  | (c) c_BinClose_20
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallPlaced_24
 |  |  | (c) c_BallPlaced_25
 |  |  |  | = FAILURE
 |  |  | (>) >_PlaceBall_26
 |  |  |  | (z) z_UsuallySucceed_27
 |  |  |  |  | = FAILURE
 |  |  |  | = FAILURE
 |  |  | = FAILURE
 |  | = FAILURE
 | (>) >_MaybeAskForHelp_29
 |  | (c) c_TimeToAskForHelp_30
 |  |  | = FAILURE
 |  | = FAILURE
 | = FAILURE
(?) ?_Robot_1
 | (c) c_BallPlaced_2
 |  | = FAILURE
 | (>) >_MainSequence_3
 |  | (?) ?_EnsureBallFound_4
 |  |  | (c) c_BallFound_5
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallClose_9
 |  |  | (c) c_BallClose_10
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallGrasped_14
 |  |  | (c) c_BallGrasped_15
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBinClose_19
 |  |  | (c) c_BinClose_20
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | (?) ?_EnsureBallPlaced_24
 |  |  | (c) c_BallPlaced_25
 |  |  |  | = FAILURE
 |  |  | (>) >_PlaceBall_26
 |  |  |  | (z) z_UsuallySucceed_27
 |  |  |  |  | = SUCCESS
 |  |  |  | (a) a_SetBallPlaced_28
 |  |  |  |  | = SUCCESS
 |  |  |  | = SUCCESS
 |  |  | = SUCCESS
 |  | = SUCCESS
 | = SUCCESS
Robot completed its mission in 3 ticks.
Demo Code
            vultron.bt.base.demo.robot
    This module demonstrates a simple robot behavior tree. The robot has a number of tasks it must perform in order to complete its mission. The robot must find a ball, approach the ball, grasp the ball, approach the bin, and place the ball in the bin. If any of these tasks fail, the robot must ask for help.
Oh, and the first time the robot picks up the ball, we knock it out of the robot's grasp, because we're mean like that.
The implementation also shows how to use the included bt tree fuzzer to exercise the bt tree.
            ask_for_help(obj)
    Records that the robot has asked for help
Source code in vultron/bt/base/demo/robot.py
              267 268 269 270 271  |  | 
            ball_close(obj)
    Checks whether the ball is close
Source code in vultron/bt/base/demo/robot.py
              176 177 178  |  | 
            ball_found(obj)
    Checks whether the ball is found
Source code in vultron/bt/base/demo/robot.py
              236 237 238  |  | 
            ball_grasped(obj)
    Checks whether the ball is grasped
Source code in vultron/bt/base/demo/robot.py
              137 138 139  |  | 
            ball_placed(obj)
    Checks whether the ball is placed in the bin
Source code in vultron/bt/base/demo/robot.py
              58 59 60  |  | 
            bin_close(obj)
    Checks whether the bin is close
Source code in vultron/bt/base/demo/robot.py
              98 99 100  |  | 
            set_ball_close(obj)
    Records that the ball is close
Source code in vultron/bt/base/demo/robot.py
              187 188 189 190  |  | 
            set_ball_found(obj)
    Records that the ball has been found
Source code in vultron/bt/base/demo/robot.py
              216 217 218 219  |  | 
            set_ball_grasped(obj)
    Records that the ball has been grasped
Source code in vultron/bt/base/demo/robot.py
              148 149 150 151  |  | 
            set_ball_placed(obj)
    Records that the ball has been placed in the bin
Source code in vultron/bt/base/demo/robot.py
              69 70 71 72  |  | 
            set_bin_close(obj)
    Records that the bin is close
Source code in vultron/bt/base/demo/robot.py
              109 110 111 112  |  | 
            time_to_ask_for_help(obj)
    Checks if it is time to ask for help
Source code in vultron/bt/base/demo/robot.py
              256 257 258  |  |