運動底盤是移動機器人的重要組成部分,不像激光雷達、IMU、麥克風、音響、攝像頭這些通用部件能夠直接買到,很難買到通用的底盤。一方面是由於底盤的尺寸結構和參數是要與具體機器人匹配的;另外一方面是由於底盤包含軟硬件整套解決方案,是不少機器人公司的核心技術,通常不會隨便公開。出於強烈的求知慾與學習熱情,我想本身DIY一整套兩輪差分底盤,而且將完整的設計過程公開出去供你們學習。說幹就幹,本章節主要內容:html
1.stm32主控硬件設計python
2.stm32主控軟件設計nginx
3.底盤通訊協議算法
4.底盤ROS驅動開發django
6.底盤裏程計標ubuntu
上一節搭建好了底盤的stm32主控硬件,如今就來講說怎麼開發配套的stm32軟件。關於創建stm32工程、使用stm32開發庫、stm32軟件調試方法等基礎知識就很少說了,有須要的能夠查閱相關資料學習,我以爲http://www.openedv.com《正點原子》的開發資料寫的還能夠。我就直接從底盤控制的項目入手,直接進行項目中各個功能需求開始分析講解,如圖11,是個人底盤控制stm32工程項目。centos
(圖11)底盤控制stm32工程項目網絡
電機控制分爲兩個部分(電機轉向控制、電機轉速控制),這些都集成在了電機驅動芯片TB6612FNG裏面,因此只須要用單片機的IO口產生控制轉向的高低電平和控制轉速的PWM波就能實現。架構
首先,初始化IO口做爲輸出腳,用於產生高低電平輸出來控制轉向,實例代碼如圖12。
(圖12)電機轉向控制IO口初始化
而後,用通用定時器TIM4的通道CH1和CH2分別產生兩路PWM輸出用於兩個電機的轉速控制,定時器默認引腳分配如圖13。
(圖13)stm32定時器通道默認引腳分配
初始化通用定時器TIM4的通道CH1和CH2爲PWM輸出,實例代碼如14。
(圖14)電機轉速控制IO口初始化
最後,將電機轉向和速度控制的操做封裝在一個函數中,便於其它地方調用,實例代碼如圖15。
(圖15)電機轉向和速度控制封裝
編碼器對底盤來講相當重要,一方面底盤經過編碼器的反饋進行PID閉環速度控制,另外一方面底盤經過編碼器進行航跡推演獲得里程計用於後續的定位與導航等高級算法中。這裏用到的編碼器是正交編碼器,因此直接使用通用定時器的輸入捕獲中的編碼器模式來讀取編碼器。採用通用定時器TIM2的通道CH1和CH2捕獲encoder1的A相和B相脈衝,採用通用定時器TIM3的通道CH1和CH2捕獲encoder2的A相和B相脈衝。
先初始化TIM2做爲編碼器encoder1的捕獲,實例代碼如圖16。
(圖16)初始化TIM2做爲編碼器encoder1的捕獲
而後,將讀取編碼器計數值的操做封裝在一個函數中,便於其它地方調用,實例代碼如圖17。
(圖17)讀取編碼器encoder1計數值封裝
最後,編寫TIM2計數溢出時的中斷處理函數,實例代碼如圖18。
(圖18)TIM2計數溢出中斷處理函數
同理可得TIM3捕獲encoder2的代碼實現,這裏就不在贅述了。
串口2是數據接口,負責接收上位機發送過來的控制指令,同時將編碼器值返回給上位機;串口1是debug接口,負責接收上位機發送過來的版本信息請求、PIDm默認值恢復、PID值設定等調試指令,同時將程序中的debug打印信息返回給上位機。可是在底盤正常工做時,只須要鏈接串口2;串口1是預留出來給有須要本身動手修改PID參數使用的。
首先,配置串口1,先對串口1的輸出進行printf函數打印支持,實例代碼如圖19。
(圖19)串口1的輸出進行printf函數打印支持
而後,初始化串口1,實例代碼如圖20。
(圖20)初始化串口1
最後,編寫串口1接收中斷處理函數,此函數主要進行對上位機發過來的數據進行協議解析,實例代碼如圖21。
(圖21)串口1接收中斷處理函數
接下來,介紹串口2,初始化串口2,實例代碼如圖22。
(圖22)初始化串口2
而後,將串口2發送數據的操做封裝到函數中,便於其它地方調用,實例代碼如圖23。
(圖23)串口2發送數據封裝
最後,編寫串口2接收中斷處理函數,此函數主要進行對上位機發過來的數據進行協議解析,實例代碼如圖24。
(圖24)串口2接收中斷處理函數
到這裏,串口有1和串口2的數據發送與接收都編寫好了,依據咱們定義的usart2數據通訊協議和usart1調試通訊協議,上位機就能夠編寫對應的程序來跟底盤的串口2和串口1進行通訊了。關於通訊協議的具體內容,將在後續作展開。
我在底盤中採用的是增量型PID算法,編程涉及到的數學表達式有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個數學表達式封裝到函數中,便於其它地方調用,實例代碼如圖25。
(圖25)串口2接收中斷處理函數
電機1與電機2採用一樣的PID算法,因此電機2的PID算法代碼實現就不贅述了。關於PID參數的整定方法,將在後續作展開。
經過上面的講解,各個模塊的驅動代碼都準備就緒了,如今須要產生一個週期性的過程,在裏面實現編碼器計數值採樣、PID控制等具體實現。這裏採用定時器TIM1產生一個週期性的中斷,在中斷處理函數中實現各模塊的具體操做。
首先,配置定時器TIM1,實例代碼如圖26。
(圖26)配置定時器TIM1
而後,編寫中斷處理函數,實例代碼如圖27。
(圖27)TIM1中斷處理函數
2.6.stm32主控軟件總體框圖
經過上面的講解,對底盤控制的stm32程序實現有了必定的瞭解,接下來就來作一個總結。
先來看看main()函數實現,如圖28。
(圖28)main()函數實現
結合上面TIM1中斷處理函數,不難發現,整個stm32程序的執行過程:
a.在main()函數中初始化各個模塊;
b.TIM1中斷處理函數週期性的讀取編碼器值、反饋獲取的編碼值、PID控制;
c.剩下的就是串口1和串口2的通訊交互。
具體stm32主控軟件總體框圖如圖29。
(圖29)stm32主控軟件總體框圖
須要說明的是,在週期性循環體中,要首先讀取編碼器的值,來保證嚴格的等間隔採樣。
------SLAM+語音機器人DIY系列【目錄】快速導覽------
第1章:Linux基礎
第2章:ROS入門
第3章:感知與大腦
第4章:差分底盤設計
第5章:樹莓派3開發環境搭建
第6章:SLAM建圖與自主避障導航
2.google-cartographer機器人SLAM建圖
第7章:語音交互與天然語言處理
第8章:高階拓展
2.centos7下部署Django(nginx+uwsgi+django+python3)
----------------文章將持續更新,敬請關注-----------------
若是你們對博文的相關類容感興趣,或有什麼技術疑問,歡迎加入下面的《SLAM+語音機器人DIY》QQ技術交流羣,一塊兒討論學習^_^
關於咱們:
視頻教程: