用PythonPi實現門禁系統-模式識別

模式識別聽起來很高大上,其實就是特徵識別。人類對事物的識別過程其實就是提取特徵、根據特徵對事物進行分類的過程,然後人類就可以將這類事物的特點與規律套用到這個事物上。

我們在門禁課程中曾提出過一個雙人開門的練習:在某些安全性要求較高的門禁控制點,要求兩人以上才能開門。但如果用通常的狀態機來實現這個功能,我在思考題中也說,會有非常多的問題難以解決。這些問題包括:

  • 有權限的人連刷兩次怎麼辦(如何將兩個不同的人識別爲事件)

  • 幾十個有權限的人中只要有兩個就可以雙人開門(幾十個人中隨便挑兩個的數字是一個組合問題,如果有20個人就有190種可能,好不容易做好了,再增加一個人怎麼辦?)

要完美解決雙人開門的問題,就需要使用模式識別。當然我們用到的是最簡單的模式:序列。所謂的序列,就是一個連續的事物組合。最常用的序列就是密碼了:一組連續的特定數字或字母。

PythonPi平臺中的序列也被稱爲一個窗口,就是一個觀察連續輸入的數據流的窗口,如果輸入數據流中的某一段數據符合窗口規定的特定條件即被被該窗口所識別爲合法的輸入數據序列。如0101窗口即可從下面的輸入流中識別出相應的序列:011010001101010011。

一個識別特定序列的窗口由一組窗格組成,而每個窗格包括了三個對輸入數據進行篩選的要素:

  • 輸入數據來源:如連接到1號樹莓派1號GPIO口的開關量輸入源:/pi1/1、連接到2號樹莓派下連的單片機上的i2c總線72號地址2號寄存器處的模數轉換器:/pi2/nodeMCU_n1/i2c_72_2

  • 判別條件:等於、不等於、大於、大於等於、小於、小於等於,甚至是大於5小於9(?>5)And(?<9)這樣的篩選條件

  • 預設的判別比較值:即上述識別表達式中(?>5)And(?<9)的5、9

窗口同時保存了一個輸入數據的隊列,每次有數據輸入,則將輸入數據推入到該隊列(隊列長度即爲窗口大小),然後讓每個窗格一一對應的對隊列中的各個數據進行檢測,如果能夠通過所有窗格的檢測,即實現了對序列的識別。

序列是對控制邏輯單元中的特定輸入進行識別,即我們可以定義待識別的序列爲:

1、/pi1/1的輸入爲0(即按鈕按下)
2、/pi2/nodeMCU_n1/i2c_72_2的值大於128(即搖桿向右打)

用口語的說法就是:啓動並向右搬動搖桿,則如何如何。下面的代碼就是如何設置上面的識別序列:

#導入依賴包
from cn.ijingxi.corpuscle.python import input
from cn.ijingxi.corpuscle.python import sequence
from cn.ijingxi.corpuscle.python import condition
from cn.ijingxi.corpuscle.python import logic
#定義啓動開關
inputSwitch=input.getGPIO("/pi1/1",input.PULL_UP,input.Flitter)
#定義每0.5秒讀取模數轉換器的一個字節來感知搖桿的x軸位置
inputDirection=input.getI2C("/pi2/nodeMCU_n1/i2c_72_2",1,500)
#定義開關輸入值的檢測條件
c0=condition.getCompare(condition.Equal,input.LOW)
#定義搖桿位置輸入值的檢測條件
c1=condition.getCompare(condition.Greate,128)
#定義一個序列,該序列從輸入流中匹配成功,則觸發start事件
s=sequence("start")
#序列的第一個窗格是檢測啓動開關是否啓動
s.addDetection(inputSwitch,c0)
#序列的第二個窗格是檢測搖桿x軸位置
s.addDetection(inputDirection,c1)
#定義控制邏輯
l=logic("smtest")
#將序列添加到控制邏輯中
l.addSequence(s)

這段代碼在啓動並向右搬動搖桿將觸發start事件

由於個體識別設備的引入,就有了基於個體身份的權限管理的問題。而雙人開門功能中,就有一個很明確的要求:必須是兩個不同的有權限的人在一定時間內先後刷卡纔可以開門。這裏不要求識別具體的人,而是要求識別不同的人、相同的權限組。所以就有了一種特殊的序列:緩存序列。

緩存序列和普通序列的不同在於:普通序列的條件檢測值是預置的、固定的,如上面代碼中的128,而緩存序列的條件檢測值則是前一個輸入值,即比較前後兩次的輸入是否相同。

目前,PythonPi平臺提供的緩存序列在場景中提供了四種預設的檢測事件:

  • SamePeople:前後是同一個人

  • DifferPeople:前後不是同一個人

  • SameRole:前後是同一個組有權限的人

  • DifferRole:前後不是同一個組有權限的人

這些事件是識別爲有權限通過者纔會進行檢測

利用這些預設事件,則雙人開門功能的實現,可以通過如下的狀態機定義來實現:

d.addTrans("closed","open","waitOther","第一個有權限的人刷卡",startTimer1)#open事件是有權限纔會發出的
d.addTrans("waitOther","DifferPeople","otherDetect","有另外的人刷卡")
d.addTrans("otherDetect","SameRole","open","第二個刷卡的人也有權限,開門",openDoor,stopTimer1)
d.addTrans("otherDetect","DifferRole","closed","第二個刷卡的人沒有權限",stopTimer1)#用超時可以省掉這條代碼
d.addTrans("waitOther","timeover","closed","超時")
d.addTrans("otherDetect","timeover","closed","超時")

====================================================================================================

關注我的公衆號及時獲取推送的最新文章

公衆號

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章