林粵偉,牟 森,姜海君,2
1(青島科技大學 信息科學技術學院,青島 266061)
2(北京郵電大學 電子工程學院,北京 100876)
隨著經濟與科技的快速發展,機器人技術正在逐步普及,在各行各業得到了較多應用.在社會上的部分崗位中,機器人已經可以完全替代人類.當前對于四輪簡易機器人,即智能小車的開發仍是大學生創新創業訓練、各類大賽的熱點題目,相關技術資料較為豐富,文獻[1]對無線遙控智能小車進行了介紹.對于小車的輪子電機控制硬件設計,在文獻[2]中給出了描述.對于小車的PID控制軟件設計,在文獻[3]中給出了介紹.本文借鑒智能小車相關文獻和大賽,如恩智浦杯[4]、博創杯等比賽成果用到的開發技術,進行具有計算機視覺人臉識別功能的無線遙控智能小車的技術實踐.本文采用基于ARM[5]和嵌入式Linux系統的方案實現屬于簡易機器人的四輪智能小車,較傳統單片機的解決方案,其智能性和擴展性較高.較同類基于ARM和嵌入式Linux的解決方案,其主要特點在于基于OpenCV實現了一定的人臉識別功能.
本文中手機可以通過傳統“按鍵動作”發送命令,也可以通過較為新穎的“重力感應動作”發送命令,提高了無線遙控的用戶體驗和樂趣.在手機和小車之間組建無線網絡,通過Android智能手機的APP發送無線遙控命令,手機可以通過按鍵動作發送命令也可以通過重力感應動作發送命令.重力感應指的是手機上的重力傳感器能夠根據手機的不同擺放狀態獲得不同的數據,ARM芯片通過WiFi模塊接收命令并進行相應的操作控制,如小車的前進、后退、轉彎、旋轉、停車等.
如圖1,無線遙控小車架構由車輪、小車底板、電機、電池、OK6410 ARM開發板[6](帶S3C6410處理器)、WiFi模塊(SDIO接口)、USB攝像頭、速度傳感器、Android手機客戶端組成.

圖1 智能小車系統架構
使用的關鍵技術包括:基于重力傳感器的智能手機無線遙控、WiFi/Socket套接字[7]通信、計算機視覺人臉檢測算法、PID控制算法[8]等.
如圖2,基于Android智能手機中的重力傳感器實現重力感應[9],需要首先得到x、y、z三軸的加速度的值.該值包含了地心引力的影響,如當將手機放在水平桌面上時,x軸默認值為0,y軸默認值為0,z軸默認值為9.81.將手機向左傾斜時,x軸的值為正.將手機向右傾斜時,x軸的值為負.將手機向前傾斜時,y軸的值為負.將手機向后傾斜時,y軸的值為正.

圖2 傳感器的坐標軸
利用傳感器技術獲得手機狀態后,還要將與狀態對應的命令通過專門的通信技術發送給小車(如手機左傾代表遙控小車左轉).ARM開發板與智能手機之間采取C/S架構的WiFi/Socket(套接字)技術進行互聯通信.其中ARM板上運行著Socket服務器,負責驅動WiFi模塊并獲取Android智能手機客戶端發送來的數據命令包,然后把命令解析出來,通過GPIO端口把控制信息傳送給小車底板,小車底板中的驅動電路接收到控制信號,做出相應的操作驅動電機改變車輪運動狀態,從而達到無線遙控小車運動的目的.ARM小車上運行Socket服務端程序,設置WiFi模塊為熱點模式,手機上安裝Socket通信客戶端APP,使手機連接到ARM小車WiFi熱點,打開手機APP,設置相應的服務端IP和端口號,設置發送的命令.控制端手機APP(Socket通信客戶端)發送命令數據包,手機APP發送指令數據包分為兩種方式:屏幕按鍵、重力感應.屏幕按鍵操作是用戶按住APP的前、后、左、右鍵發送相應的數據包命令;重力感應操作是用戶在手機APP上選擇重力感應模式,通過把手機前傾、后傾、左傾、右傾完成數據包命令的發送.ARM小車服務端接收到數據包后,對數據包進行解析,然后執行相應的操作,如前進、后退、左轉、右轉、左旋、右旋、停車等.
人臉識別用到的人臉檢測算法是采用Adaboost學習算法[10],它把一些比較弱的分類方法級聯整合在一起,組合出新的很強的分類措施.采用比例積分微分(Proportion Integral Differential,PID)控制算法控制小車的車輪轉速,確保其直線行走和準確轉彎.關于人臉檢測算法和PID控制算法將在軟件設計與實現小節詳細描述.
小車采用四個驅動車輪,四個輪子都安裝了直流電機,大大增加了地面的阻力.四個輪子和電機都是同種型號的,各個輪子幾乎沒有差別,在相同供電的情況下,小車運動時,小車的重力中心在小車底盤中心,由于四個輪子都可以單獨控制,小車運動時很難跑偏.當然四個驅動輪使得小車有更快的速度,當小車停止時,由于四個輪子都不轉,直接增大了摩擦力,小車很快就能停下,這個小車底盤性能較好,滿足本小車的需求[11].四驅小車速度達到了預期要求,在小車執行直行、轉彎、旋轉等動作時更便于控制.
S3C6410芯片是三星公司的ARM11架構處理器,本文選用的中國飛凌公司的OK6410開發板采用了S3C6410為主控芯片,功能強大,便于用戶二次開發[3].WiFi模塊較藍牙模塊的通信距離更遠,更適合無線遙控,因此選用飛凌公司基于RTL8189ES型號的WiFi模塊[6],該模塊通過SDIO接口與板子連接.選用普通USB接口的攝像頭,通過USB口與板子連接.

圖3 雙L298N原理圖
選擇了4個130直流電機,130電機慣量適中.小車的輪子由四個電機構成,且每個電機都可以單獨控制,即四輪驅動.小車的轉向是通過輪子的差速實現的,即左右兩個輪子存在速度差時,小車就能實現轉彎.假如左邊兩個輪子的速度比右邊兩個輪子的快,那么小車會偏向右;同理,左邊兩個輪子比右邊兩個輪子速度慢,那么小車就會偏左.由于四個輪子的130電機需要差速轉彎,轉向時輪子與地面有很大的阻力,使用的電流比較大,實際測量,小車在走直線時需要600–850 mA的電流,轉向時需要提供的電流約為1.2–1.5 A.130直流電機工作電壓在3–9 V之間,實際選取6 V左右,此時小車狀態較好.
四個直流電機選用雙L298N電機驅動模塊[8]驅動,兩個電機分別驅動左右兩對輪子.L298N芯片是ST公司制作的,并且工藝穩定性高,其原理圖如圖3,能夠直接驅動4路3–16 V直流電機.電機驅動電路輸入接口的GND與OK6410開發板的GND連在一起,電機供電電池的GND和驅動電路輸出接口的GND連在一起,保證邏輯電平的統一.制作了專門的排線以連接ARM開發板與電機驅動電路.
電機驅動電路的輸入端有8個管腳(IN1~IN8),分別連接OK6410板子的8個引出的預留給用戶的GPIO管腳,這8個GPIO管腳分別連接驅動電路的IN1~IN8輸入管腳,對應驅動電路的8路輸出端口OUT1~OUT8,以控制車輪旋轉方向(使輪子正轉、反轉、不轉).基于S3C6410處理器的定時器內部中斷,由軟件模擬產生GPIO管腳上的PWM波,可為左右兩對車輪的電機提供PWM信號,以控制車輪轉速(在左右兩對輪子之間形成速度差,使小車利用差速轉彎).除了上述8個作為輸出端口的GPIO管腳,板子還有另外2個GPIO管腳作為輸入端口,分別連接速度傳感器的輸出管腳,以達到測速目的.
如表1,驅動電路輸出端的8路輸出端口分別連接4個車輪的電機(每個電機需要2根接線,4個電機共需8根線,分別接8個輸出端口).以左上電機為例:當OUT1、OUT2同為高電平或低電平時,左上電機不轉;當OUT1為低電平,OUT2為高電平時,左上電機正轉;當OUT1為高電平,OUT2為低電平時,左上電機反轉.其他3個電機的控制以此類推.

表1 驅動模塊輸出端口與電機接線
在PC機安裝虛擬機軟件,虛擬機內安裝的是Ubuntu 12.04,安裝ARM交叉編譯器、QT Creator IDE(用于開發QT程序,QT是嵌入式Linux系統的一種圖形化用戶界面,類似于PC Windows系統中的桌面[6]).OK6410板子中燒錄Linux 3.0.1版本的內核.
三星S3C6410芯片包含187個多功能輸入/輸出端口管腳,而小車的控制采用OK6410開發板預留的用戶端口中的10路GPIO,分別為GPC0~GPC7(輸出由軟件模擬的PWM波)、GPP8~GPP9(輸入端口,分別檢測由速度傳感器產生的關聯左右兩對輪子轉速的外部中斷).以GPC寄存器的配置為例,GPCCON、GPCDAT、GPCPUD、GPCCONSLP、GPCPUDSLP,這五個控制寄存器都屬于端口GPC控制寄存器.寄存器GPC的端口都有多種的配置方式,包括輸入、輸出、外部中斷等,在小車控制中需要把GPIO端口配置為輸出模式,具體配置見表2.此時GPC7~0的管腳狀態與GPCDAT的低八位[7:0]相應的位狀態相同,GPP9、GPP8的管腳狀態與GPPDAT的中間兩位[9:8]相應的位狀態相同[12].

表2 GPCCON寄存器配置
在GPIO的驅動中,首先要編寫驅動的入口函數和卸載函數[13],驅動的入口函數為mygpio_init(),卸載函數為mygpio_exit(),打開設備的函數為mygpio_open(),控制設備的函數為mygpio_ioctl().在mygpio_open()函數中,首先要進行地址映射,內核中訪問IO內存之前,只知道它們的物理地址,不能使用軟件直接訪問,調用ioremap()將設備物理地址映射為虛擬地址,然后根據虛擬地址范圍去訪問IO資源.mygpio_ioctl()函數可以控制每一個車輪的轉動狀態.
小車的實際速度有時不穩定,不能直接線性調速,且小車的四個輪子的直流電機也存在微小的差異,使得小車輪子之間的轉速有差異.為此,本設計采用PID(Proportion Integral Differential,比例積分微分)控制算法控制小車的車輪轉速,確保其直線行走和準確轉彎.采用定時器來模擬四路PWM(Pulse Width Modulation,脈沖寬度調制)來控制四個直流電機的轉速.PID一般包括兩種:位置式PID和增量式PID,在小車控制中一般采用增量式,本文采用的就是這種方式.
計算機控制是經過采樣后的數字化控制,這種控制必須按照采樣時間點的偏差計算控制量,無法輸出連續的模擬控制量,因此積分項和微分項是不能被直接使用的,而是要先進行處理,使之離散化.其離散化處理的方法為:以T為采樣周期,k為采樣序號,則離散采樣時間kT對應著連續時間t,用求和代替積分,用后向差分代替微分,則離散化的PID表達式近似如下:

式(1)中,ek為輸入的控制誤差,uk為輸出,Kp為比例系數,Ti與積分時間相關,Td為微分時間常數.所謂增量式PID是指數字控制器的輸出只是控制量的增量,增量式PID控制算法可以得到控制器的第k–1個采樣時刻的輸出值為:

將(1)與(2)相減并整理,就可以得到增量式PID控制算法公式為:

其中

由式(3)可以看出,如果計算機控制系統采用恒定的采用周期T,只要確定了A、B、C的值,并使用時間上前后三次測量的目標速度與實際速度的偏差值ek、ek-1、ek-2,就可以求出控制量的增量△uk.小車的車輪轉速采樣周期為100 ms,由PID算法得出A、B、C三個參數,按照△uk來增大或減小輸出PWM波的占空比,從而調整車輪轉速.
攝像頭與ARM開發板通過USB口連接.在ARM開發板上,采用V4L2(Video for Linux 2)API[14]進行打開攝像頭等操作,并基于Open CV 2.0開源計算機視覺代碼包[15]處理視頻數據.使用QT界面程序顯示采集到的視頻并進行人臉檢測.
開發時發現Open CV的打開攝像頭的接口函數在ARM開發板上不能正常運行,故采用Linux中的V4L2接口來配合編寫攝像頭程序,其中包括:打開攝像頭、初始化攝像頭、采集視頻幀、停止采集視頻幀、卸載攝像頭設備、獲取視頻幀、關閉攝像頭等.獲取到攝像頭視頻后,把視頻進行壓縮,從而提高人臉檢測的速度,在視頻流中進行人臉檢測,然后恢復原圖像的大小,使用Open CV函數進行圖像格式轉換并把視頻顯示在QT界面程序中.在人臉檢測中,如果檢測到人臉,則在圖像中以人臉為中心,圍繞著人臉畫出一個方框來標注人臉,如圖4.
利用Open CV中支持的人臉檢測方法實現人臉識別:首先利用樣本的Haar特征進行分類訓練,獲得級聯boosted分類器,進而獲得級聯分類器類CascadeClassifier,使用該類對視頻流中的目標進行檢測.檢測時需要加載XML分類器文件("haarcascade_frontalface_alt.xml").在程序中構造了一個detectAndDisplay()函數,對在視頻流中讀取的每一幀圖像進行檢測.該函數主要是將每一幀圖像轉換為灰度圖像,然后進行直方圖均衡化,然后找出人臉區域;最后顯示人臉目標:定出人臉區域后,以人臉為中心畫出一個方框,如圖4.

圖4 人臉識別運行界面
軟件主流程如圖5,整體為C/S架構,小車做服務端,手機做客戶端,兩者之間采取WiFi/Socket技術進行通信.其中小車部分為多線程結構,主線程負責視頻采集與人臉識別,次線程負責小車控制.
首先,使用OpenCV的函數調用攝像頭在虛擬機中的Linux中可以正常運行,沒有問題存在,但是當把程序移植到ARM開發板的嵌入式Linux系統中時,會出現段錯誤,主要是OpenCV的相關函數出現問題.比如其中一個出現問題的函數是cvCreateCameraCapture(),調試時發現運行到這里就出現錯誤了.采取的措施是避開使用OpenCV的函數打開攝像頭,采用V4L2來打開攝像頭,使用OpenCV的函數來處理圖像,問題成功解決.
另外,在QT調用OpenCV的功能調試時調試時間較長,發現導致問題的因素大都是某些細節沒有處理好,但初次實踐者較易忽略.筆者經過實踐解決了問題,總結經驗如下:在QT程序中,需要把OpenCV的動態鏈接庫路徑加入到工程中,并在ARM開發板中把所有的鏈接庫(*.so)文件添加,此時需要保證路徑和PC機上的一致.如果出現在ARM上運行的程序提示找不到鏈接庫,可能是由于鏈接庫路徑太長.

圖5 C/S架構智能小車主程序流程圖
本文研制的小車實物如圖6.經過實測,小車各項功能達到了預期設計目標,運行穩定,小車可被手機無線遙控,并支持視頻采集與人臉檢測,有效遙控距離為60米左右,在防爆、救援、養老等領域具有較好的應用價值.比如,小車可在人類視野內被遙控進入危險的人類不便進入的區域,以進行識別、救援、排爆等任務.將來考慮實現其他計算機視覺算法,并增加語音識別等功能.

圖6 智能小車實物照片