行為樹是用於計算機科學,機器人技術,控制系統和視頻遊戲中的計劃執行的數學模型。它們以模塊化方式描述了有限任務集之間的切換。他們的優勢在於能夠創建由簡單任務組成的非常複雜的任務,而無需擔心如何執行簡單任務。行為樹與分層狀態機有一些相似之處,主要區別在於行為的主要構建塊是任務而不是狀態。
行為樹的背景
在遊戲行業發展
- 非玩家角色(NPC)
為什麼要BT? - 模塊化
- 啟用代碼重用
- 功能增量設計
- 高效測試
模塊化->機器人
行為樹的概念
A directed tree
- root
- control flow nodes
- sequence node
- fallback node
- parallel node
- execution nodes
- action node
- condition node
- decorator node
- node status
- succeed
- fail
- running
BT VS FSM
不同於FSM的轉換狀態再執行相對應的動作,行為樹是利用邏輯和分類處理的方式進行篩選後再進行動作。
以穿越顏色方框為例
在上幾篇中我們說了怎麼利用openCV去判斷顏色及用ROS或是FSM的方式去飛越單一顏色的方框
那問題來了,如果在飛行的任務中有不同顏色的方框呢?
空拍機在第一個方框穿越後要判斷自己是不是已經穿越,有可能在狀態機上它跑了,穿越了,但是在實際情況下,卻沒有成功穿越
那空拍機要怎麼判斷自己是不是已經穿越,並開始穿越第二種顏色的方框呢?
在行為樹上穿越紅色和藍色的方框
用行為樹的方式,加入了三個不同的判斷
- RedNotFinish
- BlueNotFinish
- isNotCenter
利用行為樹來判斷空拍機自己的狀態以及要處理的動作
- PassAndSwitch
- PassAndLand
- FixedPose
從而可以令空拍機在執行任務更為準確
以下為行為樹上穿越紅色和藍色的方框的程式
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from behave import *
class bt_mission:
# common member
center = [480, 320]
rec_center = [478, 315]
isContinue = True
x = 0
y = 0
z = 0.0
# Now_color
color = "blue"
def __init__(self):
self.tree = (
self.BlueNotFinish >> (self.isNotCenter | self.PassAndSwitch) >> self.FixedPose
|self.RedNotFinish >> (self.isNotCenter | self.PassAndLand) >> self.FixedPose
)
@condition
def BlueNotFinish(self):
print("condition: BlueNotFinish")
return bt_mission.color == "blue"
@condition
def RedNotFinish(self):
print("condition: RedNotFinish")
return bt_mission.color == "red"
@condition
def isNotCenter(self):
print("condition: isNotCenter")
return abs(bt_mission.rec_center[0] - bt_mission.center[0]) > 30 or abs(bt_mission.rec_center[1] - bt_mission.center[1]) > 30
@action
def PassAndSwitch(self):
print("action: PassAndSwitch")
@action
def PassAndLand(self):
print("action: PassAndLand")
@action
def FixedPose(self):
print("action: FixedPose")
def run(self):
while True:
if bt_mission.isContinue == False:
break
bb = self.tree.blackboard(1)
state = bb.tick()
print("state = %s\n" % state)
while state == RUNNING:
state = bb.tick()
print ("state = %s\n" % state)
assert state == SUCCESS or state == FAILURE
def main():
print("start...")
btCm_n = bt_mission()
#time.sleep(3)
try:
btCm_n.run()
except KeyboardInterrupt:
print("Shutting down ROS Image feature detector module")
if __name__ == "__main__":
main()
一周的開發者寫作松正式要結束了,謝謝大家一周的支持。