Evonne 研究室

行為樹 BT vs. 有限狀態機 FSM

在知道行為樹以及有限狀態機之前,我寫的軟體或網頁對於程式條件的判斷都是以 if-else、for loop、switch case 撰寫,行為樹只有以前資料探勘有學習過類似的概念。

在政大修習自主行動機器人導論這門課,有幸接觸到行為樹和有限狀態機的理念和實作,打開了一些新世界,所以順便記錄下來分享。

什麼是Behavior Tree?

  • 行為樹 (BT) 是一種在自主代理中構建不同任務之間切換的方法,例如:計算機遊戲中的機器人或虛擬實體。
  • 在圖 (a) 中可以看到一個 BT 執行拾取 (Pick) 和放置 (Place) 任務的範例。BT 是一種可以有效地建立複雜系統的方法,而這些系統既是模塊化又是可以相互互動的。
  • BT 的屬性在許多應用中都非常重要,這讓 BT 從計算機遊戲編程擴展到 AI 和機器人技術的許多分支。
  • BT 的優點 (Advantage)
    • Modularity
    • Hierarchy
    • Reusable
    • Reactivity
    • Expressive
  • BT 的缺點 (Disadvantage)
    • BT tools are less mature.
    • Sometimes a feed-forward execution is just fine.
    • Checking all the conditions can be expensive.
Simple BT example

BT 節點類別介紹

BT 範例

BT 範例1 – Robot放球到籃子中

Ticks’ traversal while the robot is approaching the bin

BT 範例2 – Robot放球到籃子中

Ticks traversal while the robot is approaching the ball again (because it was removed from the hand)

BT Control Flow Nodes with Memory

Relation between memory and memory-less BT nodes

什麼是FSM?

有限狀態機全名是 Finite-State Machine 維基百科詳解

  • 亦可稱為有限狀態自動機 finite-state automaton
  • “有限”狀態機,表示在“有限”個狀態中進行狀態之間的轉移和動作
  • 優點是:通用結構、直覺且容易理解、容易實作
  • 舉個簡單的例子 (右圖):判斷輸入字串是否有2個1
    • 起始狀態:S0
    • 接受(終點)狀態:S3
條件 \ 當前狀態S0S1S2S3
Input 0S1S1S2
Input 1S2S2S3

FSM的分類

1. 當成接受 / 辨識器 (Σ,S,s0,F…)

  • 產生二元輸出(Yes or No)來表示是否被機器接受。當所有輸入被處理後,如果當前狀態是接受狀態,則輸入被接受,否則被拒絕。
  • Input:字元 (不使用動作)
  • Ex:正規語言

2. 當成變換器 (Σ,S,s0,F…)

  • 基於輸入和 / 或狀態產生輸出。
  • 應用於控制。
  • Ex:電梯門控制

FSM 實作範例 – 紅綠燈跳轉

條件 \ 當前狀態GRY
等待時間 10sR
等待時間 30sG
等待時間 50sY
from statemachine import StateMachine, State
class TrafficLightMachine(StateMachine): # 建立狀態機
    # 狀態
    green = State('Green', initial = True)
    yellow = State('Yellow')
    red = State('Red')
    # 移轉鏈
    slowdown = green.to(yellow)
    stop = yellow.to(red)
    go = red.to(green)

# first
traffic_light = TrafficLightMachine() # 初始化
print("now state: ", traffic_light.current_state)
print("is green: ", traffic_light.is_green)
print("is yellow: ", traffic_light.is_yellow)
print("is red: ", traffic_light.is_red)

print( [s.identifier for s in traffic_light.states] )
print( [t.identifier for t in traffic_light.transitions] )

執行結果

在綠燈下做 slowdown

未定義的轉移 → 在綠燈下做stop

進行轉移時執行行為

class TrafficLightMachine(StateMachine): # 建立狀態機
    # 狀態
    green = State('Green', initial = True)
    yellow = State('Yellow')
    red = State('Red')
    # 移轉鏈
    slowdown = green.to(yellow)
    stop = yellow.to(red)
    go = red.to(green)
    # 進行轉移時執行行為
    def on_slowdown(self):
        print('YELLOW!')
    def on_stop(self):
        print('RED!')
    def on_go(self):
        print('GREEN!')

執行結果

進入狀態時執行動作

class TrafficLightMachine(StateMachine): 
    green = State('Green', initial = True)
    yellow = State('Yellow')
    red = State('Red')

    cycle = green.to(yellow) | yellow.to(red) | red.to(green)
    #進入狀態時執行動作
    def on_enter_green(self):
        #self.stop()
        time.sleep(50)
    def on_enter_yellow(self):
        #self.go()
        time.sleep(10)
    def on_enter_red(self):
        #self.slowdown()
        time.sleep(30)
    def slow(self):
        print("now state: ", self.current_state)
        print("is green: ", self.is_green)
        print("is yellow: ", self.is_yellow)
        print("is red: ", self.is_red)

執行結果

行為樹 BT vs. 有限狀態機 FSM

雖然 BT 跟 FSM 都可以做流程控制,不過近幾年的趨勢是什麼呢?

目前主流認為FSM的”單向控制轉移”是個明顯的缺陷。
在FSM的狀態轉換上是單向控制轉移的,但一個好的系統之間是不同的組件之間進行許多轉換。
在FSM如果刪除了一個組件,則經過的每個組件都必須重新修訂,BT則是使用雙向控制傳輸。

因此 BT 在遊戲產業中得到了發展,在NPC的控制結構中增加模組性。關鍵是因為code可以重複使用並且增加功能設計和高效測試。
以前主要是用 FSM,現在 BT 則成為了取代的方案。

(加碼探討) 行為樹 BT vs. 決策樹 DT

Decision Tree vs. Behavior Tree

可以看出左邊的決策樹是從“上到下”最後到達端點葉(leaves)的情況,而右側的行為樹是有狀態的,並且會根據當前上下文隨時間從葉子移動到葉子。

這樣看起來,行為樹其實更像狀態機一些。