蘇娟 郝欣偉 李志超
摘要:基于多線程和模塊化的設(shè)計(jì)思想,以abview為開發(fā)平臺(tái),實(shí)現(xiàn)了人機(jī)交互式控制系統(tǒng)軟件的設(shè)計(jì)開發(fā)。本方案的設(shè)計(jì)難點(diǎn)是基于Labview開發(fā)平臺(tái)的人機(jī)交互式控制軟件的架構(gòu)設(shè)計(jì)以及高實(shí)時(shí)性和可靠性的多線程協(xié)同工作模式的實(shí)現(xiàn)。本方案具有人機(jī)交互界面友好、開發(fā)周期短、穩(wěn)定可靠、控制準(zhǔn)確度高等特點(diǎn),極大地提高了控制系統(tǒng)的開發(fā)效率和自動(dòng)化程度。
關(guān)鍵詞:多線程;人機(jī)交互式控制;Labview;
中圖分類號(hào):A06-029文獻(xiàn)標(biāo)識(shí)碼:A文章編號(hào):1674-3520(2014)-06-00259-021、前言
人機(jī)交互式控制模式是指操作人員通過終端設(shè)備輸入信息和操作命令,系統(tǒng)接到后立即處理,并通過終端設(shè)備顯示處理結(jié)果,操作人員根據(jù)處理結(jié)果進(jìn)一步輸入信息和操作命令。系統(tǒng)與操作人員以人機(jī)對(duì)話的方式一問一答,直至最終獲得理想的結(jié)果,這種方式與傳統(tǒng)的非交互式處理相比,具有靈活、直觀、便于控制的優(yōu)點(diǎn),在工業(yè)控制領(lǐng)域越來(lái)越廣泛地采用。
而傳統(tǒng)的基于Keil平臺(tái)狀態(tài)機(jī)的開發(fā)模式和基于Vxworks平臺(tái)多任務(wù)的開發(fā)模式都不能很好地滿足人交互式控制系統(tǒng)軟件的開發(fā)要求。Labview是一種基于圖形化數(shù)據(jù)流的編程語(yǔ)言,為人機(jī)交互式控制軟件的設(shè)計(jì)開發(fā)提供了嶄新的平臺(tái)。它使用圖形語(yǔ)言(如各種圖標(biāo)、圖形符號(hào)、連線等)以框圖的形式編寫程序,在提供強(qiáng)大功能的同時(shí)保證了系統(tǒng)的靈活性。
2、軟件結(jié)構(gòu)設(shè)計(jì)
2.1Labview多線程運(yùn)行機(jī)制介紹
Labview的運(yùn)行機(jī)制是一種協(xié)作式的多線程并行運(yùn)行機(jī)制,當(dāng)同等優(yōu)先級(jí)線程被執(zhí)行時(shí),時(shí)間片循環(huán)排序?yàn)槊總€(gè)線程分配了同等的處理器時(shí)間。在一個(gè)線程用完了可用的時(shí)間片,操作系統(tǒng)自動(dòng)地停止處理該線程,開始執(zhí)行隊(duì)列中下一個(gè)線程。這種混合了搶占式和時(shí)間片輪轉(zhuǎn)式的任務(wù)排序能夠保證多任務(wù)的并行實(shí)時(shí)處理。
基于Labview多線程并行執(zhí)行,分割時(shí)間片占用CPU資源的運(yùn)行機(jī)制,根據(jù)軟件需求,將該軟件分為主程序MAIN.VI和它所調(diào)用的各子程序組成。主程序采用面向數(shù)據(jù)流的結(jié)構(gòu)化設(shè)計(jì)思路,分為若干個(gè)線程并行執(zhí)行,每個(gè)線程由一個(gè)while循環(huán)構(gòu)成。不同線程的優(yōu)先級(jí)不同,通過在循環(huán)空閑時(shí)段調(diào)用“等待到下一個(gè)整數(shù)倍毫秒”函數(shù)和隊(duì)列的使用來(lái)調(diào)節(jié)CPU資源占有線程時(shí)間和數(shù)據(jù)的讀寫速度,從而達(dá)到不同優(yōu)先級(jí)線程并行執(zhí)行的效果。
2.2線程間通訊方式
其他線程之間的數(shù)據(jù)交互通過隊(duì)列、局部變量及VI服務(wù)器引用進(jìn)行。通過局部變量進(jìn)行數(shù)據(jù)交互多用于數(shù)據(jù)更新頻率低,數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單的控件的值屬性改變,主要包括CAN總線初始化標(biāo)志位、流程參數(shù)(標(biāo)量)等;為了避免內(nèi)存的消耗和數(shù)據(jù)競(jìng)爭(zhēng),保證數(shù)據(jù)不丟失,指令響應(yīng)的及時(shí)準(zhǔn)確,采用隊(duì)列來(lái)進(jìn)行不同線程之間的數(shù)據(jù)傳遞;而人機(jī)交互界面上控件的動(dòng)畫實(shí)時(shí)顯示則采用VI服務(wù)器引用來(lái)與運(yùn)動(dòng)控制子VI進(jìn)行信息交互。
3、CAN協(xié)議層的實(shí)現(xiàn)
CAN總線協(xié)議層基于已在各型號(hào)中廣泛使用的雙通道切換通信原理,基于Labview語(yǔ)言,總線接收采用查詢方式實(shí)現(xiàn),開啟獨(dú)立2個(gè)線程,由當(dāng)前工作通道來(lái)決定哪個(gè)線程處于工作狀態(tài),而備用通道工作線程處于空閑狀態(tài)。當(dāng)數(shù)據(jù)接收高峰時(shí)段,相鄰兩次接收時(shí)間間隔小于1ms,當(dāng)數(shù)據(jù)接收空閑時(shí)段,相鄰兩次查詢延時(shí)設(shè)置為10ms,讓出CPU資源,保證了其他線程執(zhí)行的實(shí)時(shí)性。
CAN總線發(fā)送采用FIFO隊(duì)列模式,當(dāng)不同的線程在相臨時(shí)間間隔內(nèi)均需發(fā)送數(shù)據(jù)時(shí),僅需將所要發(fā)送的數(shù)據(jù)放入發(fā)送隊(duì)列。而在數(shù)據(jù)發(fā)送線程中,以查詢方式讀取隊(duì)列緩沖區(qū)內(nèi)的數(shù)據(jù),當(dāng)發(fā)送函數(shù)返回值為1時(shí),代表本次發(fā)送成功,此時(shí)才從隊(duì)列中取出下一個(gè)待發(fā)送數(shù)據(jù);若發(fā)送失敗,則通過備用通道向總線各節(jié)點(diǎn)發(fā)送切換幀,告之各節(jié)點(diǎn)切換CAN工作通道,并將未發(fā)送成功數(shù)據(jù)重新發(fā)送。當(dāng)總線切換3次均為發(fā)送成功,則在人機(jī)交互界面彈出報(bào)警對(duì)話框,告之操作者總線通訊失敗。
如應(yīng)用局部變量實(shí)現(xiàn)線程間數(shù)據(jù)交互,如果查詢速度大于局部變量的速度,則會(huì)多次重復(fù)讀取同一數(shù)據(jù);如果查詢速度小于局部變量的改變速度,則會(huì)導(dǎo)致數(shù)據(jù)遺漏。
4、過程控制的實(shí)現(xiàn)
控制功能的實(shí)現(xiàn)是本設(shè)計(jì)的重點(diǎn)和難點(diǎn)。怎樣實(shí)現(xiàn)控制流程執(zhí)行時(shí)在各個(gè)狀態(tài)中靈活切換并能及時(shí)有效響應(yīng)“停止”按鍵,不出現(xiàn)死循環(huán)或響應(yīng)不及時(shí)現(xiàn)象?通過大量實(shí)驗(yàn),最終確定使用“生產(chǎn)者——消費(fèi)者”+“狀態(tài)機(jī)”的設(shè)計(jì)模式來(lái)實(shí)現(xiàn)人機(jī)指令觸發(fā)響應(yīng)和控制狀態(tài)的靈活切換。
4.1生產(chǎn)者——消費(fèi)者設(shè)計(jì)
“生產(chǎn)者——消費(fèi)者”設(shè)計(jì)模式是事件處理器和隊(duì)列消息處理器相結(jié)合構(gòu)成的復(fù)合設(shè)計(jì)模式。生產(chǎn)者是指令的提供方,產(chǎn)生指令,并將指令放入隊(duì)列,由事件結(jié)構(gòu)+while循環(huán)組成;消費(fèi)者是指令的消費(fèi)方,依次從隊(duì)列中取出指令,由while循環(huán)+條件結(jié)構(gòu)處理。生產(chǎn)者和消費(fèi)者之間存在一個(gè)指令緩沖區(qū),通過隊(duì)列來(lái)實(shí)現(xiàn)。例如當(dāng)“推進(jìn)”指令按下,“推進(jìn)”指令入隊(duì)列,在消費(fèi)者循環(huán)中指令出隊(duì)列并執(zhí)行相應(yīng)流程,當(dāng)推進(jìn)過程中“停止”按下,則清空隊(duì)列,并執(zhí)行“停止”入隊(duì)列最前端,這樣在消費(fèi)者循環(huán)中就能及時(shí)切換并執(zhí)行停止流程。
具體程序結(jié)構(gòu)框圖如圖1所示。
5.1狀態(tài)機(jī)設(shè)計(jì)
在消費(fèi)者循環(huán)中,采用“狀態(tài)機(jī)”的設(shè)計(jì)模式來(lái)實(shí)現(xiàn)某個(gè)事件中各個(gè)狀態(tài)的切換,主要采用“while循環(huán)+條件分支”結(jié)構(gòu),并利用移位寄存器來(lái)傳遞狀態(tài)。在程序執(zhí)行完任一狀態(tài)時(shí),對(duì)狀態(tài)變量賦值并存儲(chǔ)于移位寄存器中,實(shí)現(xiàn)將下一個(gè)狀態(tài)傳遞到下一次循環(huán)判斷中。下一次執(zhí)行while循環(huán)進(jìn)行狀態(tài)判斷時(shí),通過條件結(jié)構(gòu)對(duì)移位寄存器中存儲(chǔ)的狀態(tài)進(jìn)行判斷,來(lái)執(zhí)行相應(yīng)的狀態(tài)。這樣,就實(shí)現(xiàn)了動(dòng)態(tài)實(shí)時(shí)地改變程序執(zhí)行順序,以適應(yīng)多種控制情況的目的。具體結(jié)構(gòu)圖如圖2所示。
當(dāng)控制過程復(fù)雜時(shí),在消費(fèi)者循環(huán)中需要運(yùn)行多層狀態(tài)機(jī),即每一個(gè)狀態(tài)中又包含若干個(gè)子狀態(tài)。這樣,在程序?qū)崿F(xiàn)時(shí)就需要調(diào)用多層條件結(jié)構(gòu),每一層條件結(jié)構(gòu)都需要有對(duì)應(yīng)的移位寄存器用來(lái)判斷本次循環(huán)條件執(zhí)行的分支。如圖3所示。這樣,就造成了程序?qū)哟芜^多,可讀性維護(hù)性差的弊端。因此,我們可分析將每一層狀態(tài)機(jī)都封裝為一個(gè)函數(shù)功能模塊,而此VI的輸入輸出參數(shù)設(shè)為本次執(zhí)行的狀態(tài)和下一次要執(zhí)行的狀態(tài)。
以對(duì)中控制為例,對(duì)中的控制過程復(fù)雜,存在多個(gè)控制狀態(tài),狀態(tài)切換圖如圖4所示。如對(duì)中控制過程分為“左右粗對(duì)中”、“上下粗對(duì)中”、“左右平行”、“左右對(duì)中”、“上下平行”、“上下對(duì)中”6個(gè)順序執(zhí)行階段,每個(gè)控制階段中多次對(duì)油缸進(jìn)行控制,油缸有上下左右四個(gè)運(yùn)動(dòng)方向。油缸控制存在11種狀態(tài)切換,所以將油缸控制編寫為controlMotor.vi模塊,此VI的輸入輸出參數(shù)為本次油缸執(zhí)行狀態(tài)、和下次油缸執(zhí)行狀態(tài)。每次調(diào)用controlMotor.vi時(shí)只執(zhí)行一種狀態(tài),通過外層循環(huán)的移位寄存器改變狀態(tài)值來(lái)實(shí)現(xiàn)狀態(tài)切換,這樣簡(jiǎn)化了程序結(jié)構(gòu),也避免了與主VI無(wú)法實(shí)時(shí)進(jìn)行數(shù)據(jù)交互的問題。程序框圖如圖5所示。
10、仿真及桌面聯(lián)調(diào)
各項(xiàng)控制功能調(diào)試:水平裝填車電控系統(tǒng)在實(shí)際大型試驗(yàn)應(yīng)用中,能夠正確執(zhí)行自動(dòng)對(duì)中、抓彈、放彈、裝填、退彈等控制功能,能夠?qū)崟r(shí)響應(yīng)停止操作,并能夠正確恢復(fù)繼續(xù)執(zhí)行,各故障狀態(tài)能夠及時(shí)準(zhǔn)確報(bào)警。
CAN總線通信功能及性能:總線上各節(jié)點(diǎn)給控制單元發(fā)送數(shù)據(jù),當(dāng)總線負(fù)載率為100%時(shí),CAN數(shù)據(jù)接收線程仍能夠正常接收數(shù)據(jù),未出現(xiàn)丟數(shù)現(xiàn)象;水平裝填車電控系統(tǒng)信息傳輸?shù)恼_性、協(xié)調(diào)性,即水平裝填車電控系統(tǒng)內(nèi)部各設(shè)備間軟件接口正確,所有指令、數(shù)據(jù)收發(fā)正確。在運(yùn)行期間CPU為43%內(nèi)存使用為256M,遠(yuǎn)遠(yuǎn)低于系統(tǒng)總內(nèi)存。在執(zhí)行控制流程或用戶對(duì)人機(jī)交互界面進(jìn)行操作時(shí),數(shù)據(jù)處理能夠正常收發(fā),未出現(xiàn)丟數(shù)死機(jī)等異?,F(xiàn)象。
11、程序設(shè)計(jì)時(shí)應(yīng)注意的問題
11.1多線程的同步執(zhí)行
多線程的同步執(zhí)行,應(yīng)合理分配CPU資源,優(yōu)先級(jí)高的線程。如總線數(shù)據(jù)接收線程,應(yīng)避免使用延時(shí)函數(shù),以保證數(shù)據(jù)接收的及時(shí)性??偩€數(shù)據(jù)存儲(chǔ)線程應(yīng)根據(jù)數(shù)據(jù)接收的最小周期來(lái)設(shè)定循環(huán)的周期,做到不占用過多的CPU資源,保證其他線程的執(zhí)行,又不會(huì)出現(xiàn)數(shù)據(jù)存儲(chǔ)遺漏。
11.2內(nèi)存泄漏的避免
程序中打開了某些資源(文件、引用等),在程序退出之前,不論是否有異常出現(xiàn),都一定要把資源關(guān)閉。若打開的資源不關(guān)閉,則一直駐留在內(nèi)存中。但程序關(guān)閉后再無(wú)法訪問這些資源,這就造成了內(nèi)存泄漏。不論在過程中是否有錯(cuò),打開的文件都應(yīng)當(dāng)在程序結(jié)束前被關(guān)閉。
11.3狀態(tài)機(jī)的使用
狀態(tài)機(jī)的應(yīng)用重點(diǎn)是移位寄存器的靈活使用,移位寄存器會(huì)動(dòng)態(tài)地將狀態(tài)變量存在一個(gè)內(nèi)置的緩沖區(qū)中,不能通過局部變量或全局變量在其他線程中賦值來(lái)更改狀態(tài)執(zhí)行步驟。
11.4文件存儲(chǔ)過大問題
用TDMS文件將總線數(shù)據(jù)存儲(chǔ)在硬盤中,存儲(chǔ)數(shù)據(jù)線程的執(zhí)行周期如果過小,會(huì)造成存儲(chǔ)數(shù)據(jù)文件過大,存儲(chǔ)數(shù)據(jù)索引文件過大的問題,會(huì)大大影響硬盤存儲(chǔ)數(shù)據(jù)效率。所以,存儲(chǔ)數(shù)據(jù)線程的周期要根據(jù)數(shù)據(jù)產(chǎn)生周期而定,當(dāng)數(shù)據(jù)以1幀/ms的速率進(jìn)行入隊(duì)列操作時(shí),數(shù)據(jù)存儲(chǔ)的周期要大于等于1s。
12結(jié)束語(yǔ)
本文的創(chuàng)新點(diǎn)在于多線程協(xié)同工作的設(shè)計(jì)思想,以及處理人機(jī)交互式控制的編程框架。以Labview2011為集成開發(fā)環(huán)境,以水平裝填車控制系統(tǒng)軟件為例,對(duì)多功能控制系統(tǒng)進(jìn)行了設(shè)計(jì)。實(shí)驗(yàn)表明,各功能模塊運(yùn)行良好,對(duì)外界觸發(fā)響應(yīng)及時(shí),線程間數(shù)據(jù)交互準(zhǔn)確無(wú)誤。程序中使用動(dòng)態(tài)設(shè)計(jì),程序方便修改,具有較大的靈活性。很好地保證了系統(tǒng)的可視化操作和應(yīng)用實(shí)施的通用性。
參考文獻(xiàn):
[1]Labview寶典/陳樹學(xué),劉萱編著.—北京:電子工業(yè)出版社,2011.3
[2]我和Labview:一個(gè)NI工程師的十年編程經(jīng)驗(yàn)/阮奇楨編著.—北京:北京航空航天大學(xué)出版社,2009.9