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 |
|