【自己動手做一臺SLAM導(dǎo)航機器人】第四章:差分底盤設(shè)計

本專欄目錄
第四章:差分底盤設(shè)計
第五章:樹莓派3開發(fā)環(huán)境搭建
第六章:SLAM建圖與自主避障導(dǎo)航
第七章:語音交互與自然語言處理
附錄A:用于ROS機器人交互的Android手機APP開發(fā)
附錄B:用于ROS機器人管理調(diào)度的后臺服務(wù)器搭建
附錄C:如何選擇ROS機器人平臺進行SLAM導(dǎo)航入門
視頻教程
https://www.bilibili.com/video/BV1jS4y1a7Lz
運動底盤是移動機器人的重要組成部分,不像激光雷達、IMU、麥克風(fēng)、音響、攝像頭這些通用部件可以直接買到,很難買到通用的底盤。一方面是因為底盤的尺寸結(jié)構(gòu)和參數(shù)是要與具體機器人匹配的;另一方面是因為底盤包含軟硬件整套解決方案,是很多機器人公司的核心技術(shù),一般不會隨便公開。出于強烈的求知欲與學(xué)習(xí)熱情,我想自己DIY一整套兩輪差分底盤,并且將完整的設(shè)計過程公開出去供大家學(xué)習(xí)。說干就干,本章節(jié)主要內(nèi)容:
1.stm32主控硬件設(shè)計
2.stm32主控軟件設(shè)計
3.底盤通信協(xié)議
4.底盤ROS驅(qū)動開發(fā)
5.底盤PID控制參數(shù)整定
6.底盤里程計標定

下面這本書是本篇文章的參考文獻,大家有需要可以入手一本:


1.stm32主控硬件設(shè)計
完整的stm32主控硬件包括:帶霍爾編碼器的直流減速電機、電機驅(qū)動、stm32單片機開發(fā)板等配件。
1.1.帶霍爾編碼器的直流減速電機

要制作一臺機器人底盤,需要一套完整的電機部件,就如圖1中看到的一樣,需要有輪胎、聯(lián)軸器、減速箱、電機和編碼器,具體選型可以參考這幾個方面的因素:
輪胎:直徑越大,小車的越障能力越好,但會降低小車爬坡的馬力;
聯(lián)軸器:選擇跟輪胎與電機輸出軸尺寸相匹配的型號;
減速箱:減速比決定電機輸出軸的扭矩,減速比越大,輸出軸扭矩越大,但輸出軸轉(zhuǎn)速越慢;
電機:一般是12V的電機,直流有刷簡單易控制;
編碼器:一般為增量式正交編碼器,編碼線數(shù)根據(jù)實際需要精度進行選擇。

如圖2,可以清楚的看到電機的接線端口,其實電路板上也是有絲印標注的。接線分為兩類,一類是電機控制(電機線+、電機線-),另一類是編碼器(編碼器5V、編碼器A相、編碼器B相、編碼器GND)。
1.2.電機驅(qū)動電路

了解了電機的構(gòu)造知識后,就來介紹一下如何將電機驅(qū)動起來。如圖3所示,TB6612FNG是很流行的一款電機驅(qū)動芯片,相比于傳統(tǒng)的L298N效率上提升很多,而且體積大幅減小。TB6612FNG是雙驅(qū)動,也就是可以驅(qū)動兩個電機;TB6612FNG每通道輸出最高1.2 A的連續(xù)驅(qū)動電流,啟動峰值電流達2A/3.2 A(連續(xù)脈沖/單脈沖);4種電機控制模式:正轉(zhuǎn)/反轉(zhuǎn)/制動/停止;PWM支持頻率高達100 kHz。

TB6612FNG的引腳定義,如圖4所示,引腳分為電源腳、控制輸入腳、控制輸出腳。
VM:為電機驅(qū)動電壓,根據(jù)實際電機額定電壓選擇,推薦使用12V供電;
VCC:邏輯電源供電,推薦使用5V供電;
STBY:待機/工作狀態(tài)切換,低電平待機,高電平工作;
?
PWMA:A端口電機PWM調(diào)速信號輸入;
AIN1和AIN2:A電機轉(zhuǎn)向控制信號輸入;
PWMB:B端口電機PWM調(diào)速信號輸入;
BIN1和BIN2:B電機轉(zhuǎn)向控制信號輸入;
?
AO1和AO2:A端口電機驅(qū)動信號輸出;
BO1和BO2:B端口電機驅(qū)動信號輸出。

最后,我們來看一下控制信號的邏輯真值表,如圖5,輸入由單片機IO口給定,再結(jié)合PWM信號,便可以實現(xiàn)對電機的正/反轉(zhuǎn)和調(diào)速控制了。由于兩路電機控制是一模一樣的,所以另一路控制信號的邏輯真值表就不重復(fù)贅述了。
1.3.霍爾正交編碼器原理

如果兩個信號相位相差90度,則這兩個信號稱為正交。由于兩個信號相位相差90度,因此可以根據(jù)兩個信號哪個先哪個后來判斷方向。利用單片機的IO口對編碼器的A、B相進行捕獲,很容易得到電機的轉(zhuǎn)速和轉(zhuǎn)向?;魻栒痪幋a器原理,如圖6。
1.4.stm32單片機最小系統(tǒng)
stm32單片機常用的型號是stm32f103,根據(jù)具體需求的Flash容量、RAM容量、IO口數(shù)量進行選擇,下面是常用的一些型號參數(shù)對比,如圖7。

考慮到stm32主控只是用于兩個電機的控制,資源開銷不算大,需要用到的IO口也不是很多,定時器資源也不多,出于性價比考慮推薦stm32f103c8t6這個型號。

如圖8所示,stm32f103c8t6最小系統(tǒng)板比較簡潔,控制兩個電動機,只需要用兩個IO口輸出2路PWM分別給兩個電機調(diào)速,用4個IO口分別控制兩個電機的方向,另外4個IO口分別接兩個電機的正交編碼器輸入,UART1與UART2跟上位機連接分別用于程序debug與上層指令控制。
1.5.stm32主控硬件整體框圖
第一個版本的硬件電路是用飛線連接的各個模塊,電路穩(wěn)定性很差,而且外觀極其丑陋。痛定思痛,決心老老實實設(shè)計電路板,把各模塊集成到一個板子上,經(jīng)過兩次改板打樣,終于成功了。如圖9,板子簡潔美觀,而且接插端子布局合理,符合我一向嚴苛的標準。

好了,有了這個電路板就好辦多了。針對這個電路板,講講我的設(shè)計思路吧。首先需要設(shè)計一個電源系統(tǒng),用于單片機供電、電機供電、外部設(shè)備供電,同時還要考慮電源反接、過壓、短路等保護;然后需要設(shè)計一個stm32單片機最小系統(tǒng)電路;最后圍繞stm32最小系統(tǒng),需要設(shè)計電機驅(qū)動、UART轉(zhuǎn)USB、編碼器信號捕獲這些外圍電路,同時還要考慮電機堵轉(zhuǎn)保護、電機對系統(tǒng)電源干擾等問題。逐一采坑之后,差不多就完成設(shè)計了。stm32主控硬件整體框圖,如圖10。

2.stm32主控軟件設(shè)計
上一節(jié)搭建好了底盤的stm32主控硬件,現(xiàn)在就來說說怎么開發(fā)配套的stm32軟件。關(guān)于建立stm32工程、使用stm32開發(fā)庫、stm32軟件調(diào)試方法等基礎(chǔ)知識就不多說了,有需要的可以查閱相關(guān)資料學(xué)習(xí),我覺得http://www.openedv.com《正點原子》的開發(fā)資料寫的還可以。我就直接從底盤控制的項目入手,直接進行項目中各個功能需求開始分析講解,如圖11,是我的底盤控制stm32工程項目。

2.1.電機控制
電機控制分為兩個部分(電機轉(zhuǎn)向控制、電機轉(zhuǎn)速控制),這些都集成在了電機驅(qū)動芯片TB6612FNG里面,所以只需要用單片機的IO口產(chǎn)生控制轉(zhuǎn)向的高低電平和控制轉(zhuǎn)速的PWM波就能實現(xiàn)。
首先,初始化IO口作為輸出腳,用于產(chǎn)生高低電平輸出來控制轉(zhuǎn)向,實例代碼如圖12。

然后,用通用定時器TIM4的通道CH1和CH2分別產(chǎn)生兩路PWM輸出用于兩個電機的轉(zhuǎn)速控制,定時器默認引腳分配如圖13。

初始化通用定時器TIM4的通道CH1和CH2為PWM輸出,實例代碼如14。

最后,將電機轉(zhuǎn)向和速度控制的操作封裝在一個函數(shù)中,便于其它地方調(diào)用,實例代碼如圖15。

2.2.編碼器數(shù)據(jù)讀取
編碼器對底盤來說至關(guān)重要,一方面底盤通過編碼器的反饋進行PID閉環(huán)速度控制,另一方面底盤通過編碼器進行航跡推演得到里程計用于后續(xù)的定位與導(dǎo)航等高級算法中。這里用到的編碼器是正交編碼器,所以直接使用通用定時器的輸入捕獲中的編碼器模式來讀取編碼器。采用通用定時器TIM2的通道CH1和CH2捕獲encoder1的A相和B相脈沖,采用通用定時器TIM3的通道CH1和CH2捕獲encoder2的A相和B相脈沖。
先初始化TIM2作為編碼器encoder1的捕獲,實例代碼如圖16。

然后,將讀取編碼器計數(shù)值的操作封裝在一個函數(shù)中,便于其它地方調(diào)用,實例代碼如圖17。

最后,編寫TIM2計數(shù)溢出時的中斷處理函數(shù),實例代碼如圖18。

同理可得TIM3捕獲encoder2的代碼實現(xiàn),這里就不在贅述了。
2.3.串口數(shù)據(jù)收發(fā)
串口2是數(shù)據(jù)接口,負責(zé)接收上位機發(fā)送過來的控制指令,同時將編碼器值返回給上位機;串口1是debug接口,負責(zé)接收上位機發(fā)送過來的版本信息請求、PIDm默認值恢復(fù)、PID值設(shè)定等調(diào)試指令,同時將程序中的debug打印信息返回給上位機。但是在底盤正常工作時,只需要連接串口2;串口1是預(yù)留出來給有需要自己動手修改PID參數(shù)使用的。
首先,配置串口1,先對串口1的輸出進行printf函數(shù)打印支持,實例代碼如圖19。

然后,初始化串口1,實例代碼如圖20。

最后,編寫串口1接收中斷處理函數(shù),此函數(shù)主要進行對上位機發(fā)過來的數(shù)據(jù)進行協(xié)議解析,實例代碼如圖21。

接下來,介紹串口2,初始化串口2,實例代碼如圖22。

然后,將串口2發(fā)送數(shù)據(jù)的操作封裝到函數(shù)中,便于其它地方調(diào)用,實例代碼如圖23。

最后,編寫串口2接收中斷處理函數(shù),此函數(shù)主要進行對上位機發(fā)過來的數(shù)據(jù)進行協(xié)議解析,實例代碼如圖24。

到這里,串口有1和串口2的數(shù)據(jù)發(fā)送與接收都編寫好了,依據(jù)我們定義的usart2數(shù)據(jù)通信協(xié)議和usart1調(diào)試通信協(xié)議,上位機就可以編寫對應(yīng)的程序來跟底盤的串口2和串口1進行通信了。關(guān)于通信協(xié)議的具體內(nèi)容,將在后續(xù)做展開。
2.4.電機速度PID控制
我在底盤中采用的是增量型PID算法,編程涉及到的數(shù)學(xué)表達式有3個,分別是:
e(k) = target_value - current_value
delta_u(k) = Kp*[e(k)-e(k-1)] + Ki*e(k) + Kd*[e(k)-2*e(k-1)+e(k-2)]
u(k) = u(k-1) + delta_u(k)
將這3個數(shù)學(xué)表達式封裝到函數(shù)中,便于其它地方調(diào)用,實例代碼如圖25。

電機1與電機2采用同樣的PID算法,所以電機2的PID算法代碼實現(xiàn)就不贅述了。關(guān)于PID參數(shù)的整定方法,將在后續(xù)做展開。
2.5.周期性控制
通過上面的講解,各個模塊的驅(qū)動代碼都準備就緒了,現(xiàn)在需要產(chǎn)生一個周期性的過程,在里面實現(xiàn)編碼器計數(shù)值采樣、PID控制等具體實現(xiàn)。這里采用定時器TIM1產(chǎn)生一個周期性的中斷,在中斷處理函數(shù)中實現(xiàn)各模塊的具體操作。
首先,配置定時器TIM1,實例代碼如圖26。

然后,編寫中斷處理函數(shù),實例代碼如圖27。

2.6.stm32主控軟件整體框圖
通過上面的講解,對底盤控制的stm32程序?qū)崿F(xiàn)有了一定的了解,接下來就來做一個總結(jié)。
先來看看main()函數(shù)實現(xiàn),如圖28。

結(jié)合上面TIM1中斷處理函數(shù),不難發(fā)現(xiàn),整個stm32程序的執(zhí)行過程:
a.在main()函數(shù)中初始化各個模塊;
b.TIM1中斷處理函數(shù)周期性的讀取編碼器值、反饋獲取的編碼值、PID控制;
c.剩下的就是串口1和串口2的通信交互。
具體stm32主控軟件整體框圖如圖29。

需要說明的是,在周期性循環(huán)體中,要首先讀取編碼器的值,來保證嚴格的等間隔采樣。
3.底盤通信協(xié)議
對于做純SLAM算法、機器人導(dǎo)航避障、或者別的需要用到移動底盤的應(yīng)用,其實不需要搞明白底盤的底層硬件原理和軟件實現(xiàn)等繁瑣的細節(jié),只需要根據(jù)底盤通信協(xié)議,在上層應(yīng)用程序中利用串口以收發(fā)數(shù)據(jù)的方式來完成對底盤的操作。也就是說底盤的底層操作細節(jié)被封裝到基于串口通信的API中了。
先來說說ROS社區(qū)提供的rosserial庫,rosserial庫是為了解決單片機與機器人之間的通信問題,使用rosserial庫可以實現(xiàn)單片機與機器人之間透明的ROS主題發(fā)布與訂閱通信。原理其實很簡單,如圖30。

單片機中通過包含rosserial.h頭文件來引用rosserial庫中的數(shù)據(jù)封裝與數(shù)據(jù)解析方法,這樣在單片機上可以直接按照ROS中發(fā)布和訂閱數(shù)據(jù)的語法來編寫程序,rosserial庫會自動完成封裝和解析;被rosserial庫封裝成串口字節(jié)流后可以在串口數(shù)據(jù)線上傳輸;在機器人上同樣通過包含rosserial.h頭文件來引用rosserial庫中的數(shù)據(jù)封裝與數(shù)據(jù)解析方法,這樣在機器人上直接按照ROS中發(fā)布和訂閱數(shù)據(jù)的語法來編寫程序,rosserial庫會自動完成封裝和解析。rosserial協(xié)議建立了單片機與機器人之間的透明ROS通信,這個ROS機器人開發(fā)這帶來了很大的方便。
但是,rosserial協(xié)議雖然好,目前rosserial對很多單片機的支持還不是很好,只對少數(shù)型號的單片機(比如Arduino系列單片機)有支持,像應(yīng)用廣泛的stm32單片機就沒有官方rosserial庫的支持;另一個缺點,rosserial協(xié)議比較臃腫,這樣對通信的資源消耗大并且影響數(shù)據(jù)實時性。
其實解決rosserial協(xié)議這幾個缺點很簡單,我們借鑒rosserial協(xié)議的思想,對rosserial協(xié)議中的冗余進行裁剪,我們miiboo機器人底盤自己的通信協(xié)議也就應(yīng)運而生了。miiboo機器人底盤自己的通信協(xié)議,如圖31。

其實很好理解,miiboo機器人底盤自己的通信協(xié)議包含兩個部分:DEBUG-uart1和DATA-uart2。DEBUG-uart1用于stam32與機器人之間傳輸調(diào)試打印信息、調(diào)試命令;DATA-uart2用于stam32與機器人之間傳輸速度反饋、速度控制。并且DEBUG-uart1和DATA-uart2兩個串口都采用波特率115200進行數(shù)據(jù)傳輸。下面就針對DEBUG-uart1和DATA-uart2這兩部分的協(xié)議進行詳細的講解。
3.1.DEBUG-uart1協(xié)議內(nèi)容
DEBUG-uart1協(xié)議內(nèi)容分為:調(diào)試打印信息(stm32單片機==>機器人)、調(diào)試命令(stm32單片機<==機器人)。調(diào)試打印信息是stm32單片機向機器人發(fā)送數(shù)據(jù),調(diào)試命令是機器人向stm32單片機發(fā)送數(shù)據(jù)。

在機器人端,對從串口獲取的字符串數(shù)據(jù)流,直接用printf()函數(shù)就可以解析。

在機器人端,將要下發(fā)的調(diào)試命令(其實就是請求stm32單片機的版本信息與PID信息命令、請求將stm32中PID恢復(fù)為默認值命令、請求將stm32中PID設(shè)置為指定值命令)封裝成對應(yīng)的數(shù)據(jù)幀,然后讓串口下發(fā)由這15個字節(jié)組成的數(shù)據(jù)幀就行了。 ??
3.2.DATA-uart2協(xié)議內(nèi)容
DATA-uart2協(xié)議內(nèi)容分為:速度反饋(stm32單片機==>機器人)、速度控制(stm32單片機<==機器人)。速度反饋是stm32單片機向機器人發(fā)送數(shù)據(jù),速度控制是機器人向stm32單片機發(fā)送數(shù)據(jù)。

在機器人端,對從串口獲取的字符串數(shù)據(jù)流,按照這個數(shù)據(jù)幀格式進行解析,就可以從這11字節(jié)組成的數(shù)據(jù)幀中解析出左輪速度、右輪速度。

在機器人端,將要下發(fā)的目標速度控制值(左輪速度、右輪速度),按照這個數(shù)據(jù)幀格式進行封裝,然后讓串口下發(fā)由這11個字節(jié)組成的數(shù)據(jù)幀就行了。其實不難發(fā)現(xiàn),速度反饋和速度控制遵循同樣的數(shù)據(jù)幀格式,這也是很好理解的。
4.底盤ROS驅(qū)動開發(fā)
對于做純SLAM算法、機器人導(dǎo)航避障、或者別的需要用到移動底盤的應(yīng)用,根據(jù)底盤的通信協(xié)議,直接使用底盤ROS驅(qū)動實現(xiàn)跟底盤的交互。miiboo機器人底盤的ROS驅(qū)動代碼組織如圖36。

整個代碼組織是一個完整的ROS功能包,功能包名為miiboo_bringup,功能包中包含兩個ROS節(jié)點源碼(base_controller.cpp和pid_set.cpp),不難看出這兩個節(jié)點正是對底盤通信協(xié)議中的DATA-uart2與DEBUG-uart1的具體實現(xiàn)。base_controller.cpp負責(zé)對底盤控制驅(qū)動的具體實現(xiàn),pid_set.cpp負責(zé)對底盤調(diào)試驅(qū)動的具體實現(xiàn)。本節(jié)重點對這兩個節(jié)點進行講解,至于功能包名下的其他內(nèi)容將放在后面的miiboo機器人SLAM導(dǎo)航實戰(zhàn)中具體展開。
4.1.底盤控制節(jié)點
接口:
底盤控制節(jié)點對下與底盤DATA-uart2串口通信,對上開放ROS接口為應(yīng)用層提功能數(shù)據(jù)發(fā)布與訂閱,便于SLAM導(dǎo)航等功能的開發(fā)。

節(jié)點實現(xiàn)源碼解析:
底盤控制節(jié)點由base_controller.cpp實現(xiàn)。程序主要分為兩個過程:訂閱topic數(shù)據(jù)并下發(fā)給底盤、從底盤接收數(shù)據(jù)并發(fā)布到topic。
首先,程序訂閱/cmd_vel作為用戶的控制輸入,將控制輸入的速度信息轉(zhuǎn)換為通信協(xié)議中DATA-uart2規(guī)定的格式,然后通過串口下發(fā)給底盤,實現(xiàn)對底盤的運動控制。訂閱/cmd_vel的回調(diào)函數(shù)和串口下發(fā)函數(shù)分別如圖38和圖39所示。


然后,程序從串口獲取底盤的速度反饋,并將速度反饋數(shù)據(jù)放入航跡推演算法中進行解算,得到里程計,將反饋回來的左輪速度、右輪速度值分別發(fā)布到/wheel_left_speed和/wheel_right_speed主題,將解算出來的里程計分別發(fā)布到/odom和/tf主題。由于不同的算法對里程計的格式要求不一樣,所以將里程計同時發(fā)布到/odom和/tf主題,便于不同的算法使用。從串口獲取速度反饋并求解里程計和發(fā)布反饋速度與里程計到topic分別如圖40和圖41所示。


基于航跡推演算法的里程計解算:
首先,我們需要了解一下ROS下的機器人坐標系為右手坐標系,如圖42,機器人底盤的正前方為x軸正方向、機器人底盤的正上方為z軸正方向、機器人底盤的正左方向為y軸正方向、機器人航向角theta坐標軸以x軸為0度角并逆時針方向增大。一般以機器人底盤上電時刻,機器人底盤的位置建立里程計坐標系,也就是說機器人底盤的起始位姿為原點O,機器人底盤在運動過程中,通過前一時刻的位置和左、右輪位移可以推算出機器人底盤的下一時刻位姿,這就是航跡推演算法。

我們這里值討論兩輪差分底盤的情況,分析如圖41,通過前一時刻的位置和左、右輪位移可以推算出機器人底盤的下一時刻位姿。航跡推演的數(shù)學(xué)模型如圖43。

在很短的時間間隔里,前后兩個機器人位姿滿足一定的關(guān)系,具體看圖44的推導(dǎo)。

這樣,經(jīng)過進一步的化簡,可以得到我們解算里程計的核心公式,如圖45。

不難發(fā)現(xiàn),上面程序中解算里程計部分的代碼就是這個核心公式的具體編程實現(xiàn)。關(guān)于航跡推演算法更詳細的推導(dǎo),請參考:
http://faculty.salina.k-state.edu/tim/robotics_sg/Control/kinematics/odometry.html
4.2.底盤調(diào)試節(jié)點
接口:
底盤調(diào)試節(jié)點對下與底盤DEBUG-uart1串口通信,對上通過命令行終端指令交互方式。

節(jié)點實現(xiàn)源碼解析:
底盤調(diào)試節(jié)點由pid_set.cpp實現(xiàn)。程序主要分為兩個過程:從終端獲取調(diào)試命令并下發(fā)給底盤、從底盤接收應(yīng)答數(shù)據(jù)并顯示在終端。
首先,程序從終端獲取調(diào)試命令,用戶可輸入數(shù)字1,2,3,如果用戶輸入3會再要求輸入kp,ki,kd這三個數(shù),將調(diào)試命令轉(zhuǎn)換為通信協(xié)議中DEBUG-uart1規(guī)定的格式,然后通過串口下發(fā)給底盤,實現(xiàn)對底盤的調(diào)試。調(diào)試命令獲取與下發(fā)如圖47。

然后,程序從串口獲取底盤的應(yīng)答信息,這里就比較簡單了,直接將獲取的應(yīng)答數(shù)據(jù)原樣打印到終端就行了,如圖48。

5.底盤PID控制參數(shù)整定
我們的miiboo機器人底盤的stm32控制板中已經(jīng)內(nèi)置了整定好的PID參數(shù),如果選用我們提供的控制板和電機,一般情況下是不需要整定PID的。
對于想體驗一下PID參數(shù)整定過程或?qū)⑽覀兊膍iiboo機器人底盤的stm32控制板應(yīng)用到其他地方的朋友,這里給出了整定PID的整個操作過程和思路,方便大家學(xué)習(xí)和更深層次的研究。首先,對PID三個參數(shù)定性的分析,先有個感性的認識,如圖49。

其次,由于我們的miiboo機器人底盤的stm32控制板中采用的是增量式PID,所以這里對增量式PID參數(shù)的特殊性進行一些說明,如圖50。

位置型PID的參數(shù)整定過程一般是,先整定KP,然后整定KI,最后整定KD;對比位置型PID與增量型PID的數(shù)學(xué)表達式,可以發(fā)現(xiàn)位置型KP和增量型KI一樣,位置型KI和增量型KD一樣,位置型KD和增量型KP一樣,如圖51。這樣,增量型PID應(yīng)該先整定KI,然后整定KD,最后整定KP。這一點需要特別注意,弄錯順序的話會發(fā)現(xiàn)整定規(guī)律完全不適用的。

在機器人上進行具體PID整定操作之前,先對整定原理做一些講解。下面的表述是針對增量型PID的,即KI為比例參數(shù)、KD為積分參數(shù)、KP為微分參數(shù)。這里使用試湊法對miiboo機器人底盤的增量PID參數(shù)進行整定:
第1步:
首先只整定比例部分。比例系數(shù)KI由小變大,觀察相應(yīng)的系統(tǒng)響應(yīng),直到得到反應(yīng)快,超調(diào)小的響應(yīng)曲線。系統(tǒng)若無靜差或靜差已小到允許范圍內(nèi),并且響應(yīng)效果良好,那么只須用比例調(diào)節(jié)器即可。
第2步:
若穩(wěn)態(tài)誤差不能滿足設(shè)計要求,則需加入積分控制。整定時先置KD為較小值,并將經(jīng)第1步整定得到的KI減小些( 如縮小為原值的0.8倍 ),然后增大KD,并使系統(tǒng)在保持良好動態(tài)響應(yīng)的情況下,消除穩(wěn)態(tài)誤差。這種調(diào)整可根據(jù)響應(yīng)曲線的狀態(tài),反復(fù)改變KI及KD,以期得到滿意的控制過程。
第3步:
若使用比例-積分調(diào)節(jié)器消除了穩(wěn)態(tài)誤差,但動態(tài)過程仍不能滿意,則可加入微分環(huán)節(jié)。在第2步整定的基礎(chǔ)上,逐步增大KP,同時相應(yīng)地改變KI和KD,逐步試湊以獲得滿意的調(diào)節(jié)效果。
原理了解后,就要到實際的miiboo機器人上進行整定了,首先需要將底盤的DATA-uart2與DEBUG-uart1串口連接到機器人的主板樹莓派3中,并確保被樹莓派識別的串口設(shè)備號為底盤驅(qū)動設(shè)置的值,如果串口號不匹配需要先進行匹配,關(guān)于這部分內(nèi)容將在miiboo機器人SLAM導(dǎo)航中做更詳細的展開。然后,需要啟動底盤控制節(jié)點、底盤調(diào)試節(jié)點、鍵盤控制節(jié)點。
鍵盤控制節(jié)點teleop_twist_keyboard需要通過apt-get命令來安裝,rqt_plot是ROS提供的繪圖工具,關(guān)于這些的具體使用方法將在miiboo機器人SLAM導(dǎo)航中做更詳細的展開。
最后,就是通過觀察速度曲線,按照試湊法的步驟,在底盤調(diào)試節(jié)點的終端中輸入相應(yīng)的kp、ki、kd參數(shù),不斷重復(fù)這個過程直到速度曲線達到一個比較滿意的形狀。rqt_plot速度曲線的樣子如圖52所示。

6.底盤里程計標定
機器人底盤運行的精度是衡量底盤的重要指標。底盤精度受里程計的走直線誤差和轉(zhuǎn)角誤差影響。因此,需要對里程計的走直線和轉(zhuǎn)角進行標定,盡量減小誤差。miiboo機器人底盤的ROS驅(qū)動中已經(jīng)寫好了相應(yīng)的標定程序,跟里程計標定有關(guān)的文件主要有:
.../miiboo_bringup/launch/check_linear.launch為里程計走直線標定啟動文件
.../miiboo_bringup/launch/check_angular.launch為里程計轉(zhuǎn)角標定啟動文件
.../miiboo_bringup/launch/minimal.launch為設(shè)置標定參數(shù)及底盤控制啟動文件
下面是標定步驟過程。
第一步:
打開終端,給標定腳本賦予可執(zhí)行權(quán)限
第二步:
連接好底盤DATA-uart2串口,啟動底盤
第三步:
設(shè)定前進1米的目標,對走直線進行標定
測量底盤停止時實際走的直線距離M,按下面的規(guī)則調(diào)整里程計直線參數(shù)speed_ratio
如果M > 1米,增大speed_ratio
如果M < 1米,減小speed_ratio
里程計的參數(shù)存放在miiboo_bringup/launch/minimal.launch文件中,如圖53所示。

修改好參數(shù)后,需要保存,然后重新啟動一下底盤節(jié)點,這樣參數(shù)才能生效。
重復(fù)第三步的操作,直到走直線的誤差達到我們能接受的范圍(比如1%的誤差),則進入下一步。
第四步:
設(shè)定旋轉(zhuǎn)360度的目標,對轉(zhuǎn)角進行標定
測量底盤停止旋轉(zhuǎn)時實際轉(zhuǎn)過的角度A,按下面的規(guī)則調(diào)整里程計轉(zhuǎn)角參數(shù)wheel_distance
如果A > 360度,減小wheel_distance
如果A < 360度,增大wheel_distance
上面已經(jīng)講過,里程計的參數(shù)存放在miiboo_bringup/launch/minimal.launch文件中,如圖53所示。
修改好參數(shù)后,需要保存,然后重新啟動一下底盤節(jié)點,這樣參數(shù)才能生效。
重復(fù)第四步的操作,直到走轉(zhuǎn)角的誤差達到我們能接受的范圍(比如1%的誤差),則標定完成。
當然,有興趣的朋友可以閱讀miiboo_bringup/scripts/中的標定腳本源碼,結(jié)合航跡推演算法,理解里程計標定的整個原理。其實wheel_distance這個參數(shù)是編碼脈沖值與電機輪胎位移值的一個比例系數(shù),簡單點說就是電機轉(zhuǎn)過一個編碼脈沖,這個時候電機輪胎走過多少距離;wheel_distance這個參數(shù)是左右兩個輪子的間距。有了這個認識后,我們可以在這兩個參數(shù)的理論值附近對參數(shù)進行微調(diào),標定起來會更快。
后記
為了防止后續(xù)大家找不到本篇文章,我同步制作了一份文章的pdf和本專欄涉及的例程代碼放在github和gitee方便大家下載,如果下面給出的github下載鏈接打不開,可以嘗試gitee下載鏈接:
github下載鏈接:https://github.com/xiihoo/DIY_A_SLAM_Navigation_Robot
gitee下載鏈接:https://gitee.com/xiihoo-robot/DIY_A_SLAM_Navigation_Robot
技術(shù)交流
QQ技術(shù)交流群:117698356
參考文獻
[1] 張虎,機器人SLAM導(dǎo)航核心技術(shù)與實戰(zhàn)[M]. 機械工業(yè)出版社,2022.
