狀態機發展至今,其實傳統的FSM應用場合其實并不多了,他雖然可以解決確定性的問題,但是他無法解決軟件重復的問題,層次式狀態機HSM就是為解決這個問題而提出來的,層次式狀態機HSM = 有限狀態機FSM(狀態機技術) + 面向對象(復用技術),這就是我理解的層次式狀態機的本質。
層次式狀態機相比于有限狀態機,在狀態轉換方面復雜了很多,因為他有了子狀態和父狀態的概念,曾經的FSM,其實也可以看做是一種特殊的層次式狀態機,也就是他們擁有共同的父狀態,這種情況下,從一個狀態轉換到另一個狀態的步驟是固定的,但是一旦兩人不再同一個狀態層次,問題就變得復雜了很多。
當然也帶來了很多的好處,比如當前的子狀態機中,并不需要對每一個需要響應的事件進行動作的處理,假如很多擁有相同的父狀態的子狀態,都需要對同一個事件作出相同的響應,這時候只需要在父狀態中統一處理一次就可以了,也就是所有的子狀態都繼承了父狀態的事件處理,這種在狀態機里面會有一個新的名字,行為繼承。
層次式狀態機的實現相對來講是比較復雜的,所有的事件觸發,狀態轉換都和自身的層相關,以狀態轉換為例,他需要實現以下轉換,整個轉換的過程無疑是很復雜的,但是沒必要深入把他搞懂,了解就可以了。如下:
層次式事件處理器被設計出來就是為了解決這些麻煩的轉換算法,假如你不需要再造一個處理器(輪子),可以忽略這一部分算法,直接應用就可以,也就是核心是如何使用層次式狀態機來設計我們的程序,要達到這一目的,你就必要掌握給定一個狀態模型,任何一個觸發導致的事件動作或者狀態轉換的先后順序及執行的流程(路徑),掌握了這些,你基本上就掌握了層次式狀態機的核心規則,基于這個核心規則,你可以設計自己的層次式狀態機,并用于實際的項目中。
掌握一項技能最好的方式就是通過實戰,其實針對狀態機運行規則這塊,官方提供了一個可以玩的例程,不需要嵌入式硬件的支持,我們就可以實戰,通過這個例程基本上囊括了一個層次式狀態機所有可能出現的轉換的情況,掌握了他,你也就掌握了層次式狀態機的運行規則,廢話不多說,直接上例程,先看一下,用于驗證層次式狀態執行的這個例程的狀態圖,如下:
看著還是比較復雜的,接下來,我們直接讓這個應用程序跑起來,看看初始化完成以后他停在哪,執行了哪些操作。
執行過程:首先完成TopInit頂層初始化,然后觸發了一個TRAN轉換,這個轉換的最終目標是S2,但是S2并不是一個最終的子狀態,S2要向最終的子狀態過渡,首先要進入S2狀態,首先要執行S1-ENTRY,然后執行S2-ENTRY,然后發現執行S2-INIT,INIT觸發狀態轉換,執行S21-ENTRY ,S211-ENTRY,完成最終轉換。
這里要注意幾點:
第一、并不是所有的狀態都要有INIT事件處理,但是如果該狀態不是最終子狀態,則需要一個INIT。
第二、并不是的INIT在觸發轉換以后都會執行,只有當觸發轉換是某個超狀態時,并且完成了到達該超狀態的進入動作以后,停留在了該超狀態,因為超狀態不能作為最終的根,所以需要觸發INIT來完成到最終的根的轉換。
第三、系統的狀態永遠都是停留在最終的某個子狀態,例如上面的S211,當有信號發送給當前狀態時,可能并沒有對應的事件相應的處理,這時候他會遞歸到其上一層也就是Q_SUPER的狀態,查找是否有相應的處理響應,如果沒有就一直往上找,直到找到為止,如果到了HSMTOP層還是沒有,整個信號也就被忽略掉了。
第四、兩個狀態要進行轉換,首先要找到兩個狀態的最小的共同超狀態(有點類似于數學里面那個最小公因數)。然后從源狀態一路退出至最小共同超狀態,然后再沿著最小共同超狀態這條路,一路進入到目標狀態,執行完這個過程狀態轉換完成。
繼續我們的應用例程,當前狀態處于S211,這個時候,我們按下鍵盤的F鍵,觸發f事件,來分析一下系統將會作出什么樣的反應,根據我們上述總結的幾點:
1. 當前處于S211的狀態,查找其狀態或者其超狀態是否有對應的信號響應,根據狀態圖可以看到,其響應為S2狀態,響應動作為狀態轉換,目標狀態位s11。
2.開始執行源狀態S211---->S11目標狀態的轉換,先查找其最小共同超狀態,我們看狀態圖一眼就能看出來,但是程序上算法查找還是比較復雜的,這里看圖說話,最小共同超狀態為S狀態。
3.從源狀態一路退出至S,s211-EXIT;s21-EXIT;s2-EXIT;
4.從S一路進入至S11,s1-ENTRY;s11-ENTRY;
真實的執行結果如下:
帶有內置參數的事件處理,兩次執行相同的事件可能會返回不同的執行路徑,現象如下:
S11內部處理的代碼如下:
超狀態S1的相關內部代碼如下:
這個可以嘗試自己分析一下,根據代碼和狀態圖,分析一下為什么會有兩種不同的輸出。
除此之外還有很多的事件信號可以被觸發,例如下面:
感興趣可以自己下載源碼跑起來,自己操作和分析,需要源碼的話也可以留言,留下郵箱,我打包發給大家。看到這里HSM的變換流程就基本差不多了。