91视频免费?看_蜜芽MY188精品TV在线观看_国产免费无遮挡在线观看视频_深夜国产_亚洲精品欧洲精品_欧美黑人粗暴多交

程序小白
認證:優質創作者
所在專題目錄 查看專題
【第一章】有限狀態機理論速成筆記
【第二章】HSM層次式狀態機理論(進階版)
【第三章】有限狀態機(FSM)之炸彈項目(實戰1)
【第四章】有限狀態機(FSM)之炸彈項目(實戰2)
【第五章】有限狀態機(FSM)之炸彈項目(實戰3)
【第六章】層次式狀態機HSM = 有限狀態機FSM + 面向對象
作者動態 更多
基于stm32采用PWM驅動伺服控制器學習筆記
05-13 15:25
基于STM32驅動TM1638學習筆記——軟件篇
04-19 12:42
基于TM1638驅動8位數碼管設計分享
02-24 11:26
RT-Thread驅動之路: Studio創建FAL分區⑤
01-02 08:30
RT-Thread驅動之路: Studio 掛載通用SPI flash④
2024-12-23 13:41

【第五章】有限狀態機(FSM)之炸彈項目(實戰3)

     我也不知道你能不能堅持看到這里,我以為的驚喜,可能對你來說是一本天書(是我講的不好),這可能是我最大的遺憾,做技術,痛苦的是無止盡的重復做項目,快樂的是掌握一種新技術,它不能讓你變得富有,只是為你將眼前的大門多推開了一丟丟~!沒有什么能比一句我已經在路上了,更能讓人興奮的。

                                                                                          ———程序小白               

                                                                                                        2020.09.08

      繼續我們的炸彈項目,首先我們要講一下第三種狀態機的構造模式,就是基于面向對象的思想來實現我們的有限狀態機,這里用到的是完全的面向對象,例如在我們的GUI系統中基于事件驅動型設計FSM(現實中可能比這復雜的多,但也算是種一粒種子吧,萬一哪天你真的要搞呢)。這里用到的并不是C語言,因為C語言在實現多態方面會很復雜,不如直接使用C++(C的哥哥),我們先看一下基于面向對象設計的QEP的構架,如下圖:

      BombState是一個類,這是一個抽象類,基于這個類派生出兩個子類,SettingState和TimingState,基于這兩個子類,實例化兩個對象,同時構建我們的Bomb3狀態機類,該類的成員中有BombState類型的成員,實際以指針的方式定義,在狀態機運行時,改變狀態,實際就是改變指針來指向不同的對象, 通過其重載的函數(以多態的形式),來實現不同的狀態處理函數,這種方式利用C++可以很容易的實現,我們并不做過多的討論。

      總結一下:基于面向對象類型的語言(例如C++)來實現狀態機,實際可以做的更簡單,雖然C++學起來并不簡單。

      以上三種方式都稱不上完美,第三種嚴重依賴C++,我們的目的是用C來實現一個通用的QEP,實際上一個通用的QEP集成了以上三種方式的優勢,他的構架來了,如下:

      很重要的題外話:QEP事件處理器是QP構架的一部分,除了他之外,還有QK(內核),QF(框架服務),上圖中我們能看到分為QEP部分,和應用程序部分,也就是如何在我們的應用程序中使用構架服務,主要應用C語言的單繼承,利用繼承,你就可以使用構架的服務。

      接下來進入我們的主題基于通用版QEP實現的QFSM,代碼講解部分我們以QP5.3.1為模板(QP所有的歷史版本都可以從官網下載到),為什么不以QP6.9.0為模板講,并不是因為新的不好,而是新的刪掉了BOMB的例子,我們無處可講,所以只能用老版本,實戰應用的話建議大家應用新版本,因為每一次的更新總會帶來驚喜。

      首先從簡單的QEvent事件結構開始,分析,在新版本中改名字了,更簡潔叫QEvt,對比一下文檔中的樣子和實際版本中的樣子,如下:

       書中的版本:

      QP5.3.1中的版本:

      雖然擴展的變量不一樣了,但并沒有復雜多少,可以先忽略。

      函數指針類型定義,書中版本和QP5.3.1區別不大,如下:

      接下來使我們的QFSM了,這里的差別就大了,其實在是實戰中QFSM的應用意義并不大,所以升級版把他融合到了 HSM中,作為了層次式狀態機的子集,理解這段話你就理解了新版本更新后差別出在哪里。

      文檔中的版本,還保存著其本真的東西,如下:

      接下來我們看看真實的QP5.3.1中他是什么樣子,如下

      神奇的事情發生了,FSM和HSM居然都是一個MSM的別名,也就是兩者居然是一樣的,其實就是我們前面講的,以前可能分兩個狀態機結構,現在通過一個MSM實現了兩者的融合,那么在程序看來,一個MSM既可以當做FSM也可以當做HSM,這樣做會有個缺點,就是MSM有點復雜和有點大。如下:

      挺復雜,那么我們只關注成員state,繼續跟蹤他的結構,如下:

      

      看不懂的部分,直接忽略掉,他的意義當我們用到的時候會再講,看一下其成員fun的類型,就是我們的函數指針了。

      接下來還有FSM必要的三個函數,來支持其功能,ctor構造,init初始化,dispatch事件分發,這里我們不再對比文檔中的代碼,那個相對簡單,而且太老版本支持,我們直接上QP5.3.1,如下:

      定義在這個文件中,路徑如下:

這個定義很神奇,我們原本需要關注的ctor中me->temp.fun = initial;這一句,但是在構造函數中,除了構造我們的初始狀態以外,還幫我們綁定了init初始化和事件分發函數,很驚喜也很以外。

      接下來我們看看這個init函數,定義如下:

這個函數一看巨復雜,QS開頭的是軟件追蹤部分代碼,忽略,重要的部分,

/*執行具體的初始化函數,例如我們的bomb4代碼中的init,要求我們初始化函數必須返回Q_RET_TRAN*/

(*me->temp.fun)(me,e) == (QState)Q_RET_TRAN

完成初始化,觸發一個Q_ENTRY_SIG事件,接收該事件的時間處理函數為me-temp.fun

也就是執行temp.fun的進入動作,如下:

(void)QEP_TRIG_(me-temp.fun,Q_ENTRY_SIG);這是一個宏,展開后

執行完畢,后temp.fun更新到state.fun中。

最后還有一個函數沒有講,dispatch,我先找找他在哪,如下:

這個函數有點復雜,但我還是能看得懂,真到了HSM說實話,我真沒看懂,我也不斷講HSM中dispatch的實現,說實話太復雜了,能學會說明你算法基礎好,到哪里我們只講規則,如何應用,不講實現,有興趣筒子們自己研究源碼,這里我們把FSM的dispatch貼出來,如下:

      代碼很長,其實很簡單,首先進入的時候,有兩個狀態處理函數,代碼兩個狀態,state和temp,這倆咋進入的時候是相等的 ,會有一個斷言判斷,如果不相等,那么說明狀態機有異常,如下:

      68:Q_REQUIRE_ID(100, me->state.fun == me->temp.fun);

      接下來執行事件處理函數,返回狀態很重要,r很重要,如下:

         r = (*me->state.fun)(me, e); /* call the event handler */

      如果if (r != (QState)Q_RET_TRAN),dispatch就結束了,如果發生了轉換,

那么先執行源的退出,在執行目標的進入,最后再把目標賦值給源,完成了狀態轉換,如下,

      QEP_EXIT_(me->state.fun); /* exit the source */

      QEP_ENTER_(me->temp.fun); /* enter the target */

      me->state.fun = me->temp.fun; /* record the new active state */

到這里一個完整的QFSM(基于QEP)講完了,上面講的這些都不需要我們去編碼,這是框架的部分,QP幫我們寫好了,直接應用就好了,假如你真的按我的步驟把QPC5.3.1的這部分代碼通讀了一遍,那么,關于bomb如何基于他實現,就不需要任何言語了,直接上代碼.

      bomb第一部分,如下:

      第二部分,如下:

main.c如下:

      基于通用的QEP實現的bomb,到此完結,再見~!

聲明:本內容為作者獨立觀點,不代表電子星球立場。未經允許不得轉載。授權事宜與稿件投訴,請聯系:editor@netbroad.com
覺得內容不錯的朋友,別忘了一鍵三連哦!
贊 6
收藏 7
關注 151
成為作者 賺取收益
全部留言
0/200
主站蜘蛛池模板: 安塞县| 彭州市| 肇东市| 台中县| 利津县| 雷山县| 崇仁县| 山西省| 黄冈市| 隆尧县| 临潭县| 包头市| 沅陵县| 辛集市| 贵阳市| 正蓝旗| 汉中市| 保山市| 宁南县| 武宣县| 晋宁县| 双辽市| 邵阳县| 双江| 安丘市| 广汉市| 淮安市| 青河县| 临桂县| 太康县| 涪陵区| 秭归县| 远安县| 洪湖市| 萍乡市| 丰顺县| 长乐市| 吴堡县| 烟台市| 阿拉善右旗| 镇赉县|