天天看點

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

摘自:https://zhuanlan.zhihu.com/p/165162578

全網最實用的STM32和ROS機器人的序列槽通信方案

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

小白學移動機器人

同名公衆号:小白學移動機器人

創作聲明:内容包含虛構創作

内容中的情節存在虛構加工,僅供參考

全網最實用的STM32和ROS機器人的序列槽通信方案(大量網友調用成功)

具體協定大緻如下,易讀、易調用、易拓展、易更改。

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

源碼檔案:進入下面公衆号:小白學移動機器人,發送:序列槽通信更新。即可獲得。

http://weixin.qq.com/r/KERAWIvE1daqrc879xE6 (二維碼自動識别)

本方案解決的問題:解決以STM32做ROS機器人底層驅動的序列槽通信問題。

為什麼要寫篇文章?:

最近發現越來越多的小夥伴走入ROS機器人的領域,而ROS機器人與底層驅動的序列槽通信問題,是大家學習路上的一個難題。很多小夥伴對STM32單片機并不熟悉,對序列槽通信的了解并不透徹,自己去解決這個問題,費時費力,最後也可能沒有好的結果,并且這又不是大多數學習ROS機器人的重點。最後發現網上也沒有很好的教程(也可能是我沒找到),是以,這裡根據本人的開發經曆,給大家提供一種高效、穩定、易用的ROS機器人與STM32序列槽通信的常用方案。

如果不想了解細節的朋友,可以隻看下面方案介紹和方案快速使用部分,關于方案的原理就不用花時間思考了,但是還是希望大家對細節有敬畏之心。

本方案提供的API:(最基礎的ROS機器人需要的協定)

STM32向ROS發送左輪實時輪速、右輪實時輪速、實時角度、預留控制位。

ROS向STM32發送左輪設定速度、右輪設定速度、預留控制位

本方案優勢:

經測試,長期穩定運作

保證資料準确率極高

頻率50HZ左右,可更高,根據自己發送頻率設定

易用,引入相關頭檔案即可,低耦合

------------------------------------------------華麗麗的分界線--------------------------------------------

方案介紹:

本方案将資料開頭加入資料頭,資料尾部加入資料循環備援校驗和資料尾,将資料打包發送,確定資料的正确性,避免出現一些無法察覺的問題。同樣根據STM32和Linux系統配備相應的資料解析協定。

本方案STM32下位機依托USART1編寫的收發協定,ROS上位機依托boost::asio編寫的收發協定。序列槽并不一定是序列槽1,可以更改,但是需要程式變更一些内容(很容易,程式中有标記共三處)。

本方案巧妙的使用共用體的特性,進行資料解析,(也就是無需使用資料分離技術解析資料)。關于共用體,你隻需要知道以下幾點:

  1. C語言的一種機制,結構體内不同成員共享記憶體的機制,(即記憶體位址一緻)
  2. 同一時刻,隻能通路其中的一個成員
  3. 不同成員,按照成員類型的性質進行記憶體通路

不了解的小夥伴,可以看下圖,有直覺的了解即可。有圖有真相

溫馨提示:從左向右讀圖。

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

-----------------------------------------------華麗麗的分界線--------------------------------------------

方案快速使用:

硬體環境準備:(必須)

STM32序列槽+TTL轉USB子產品(CH340)+Linux硬體裝置

線路連接配接:(有圖有真相)

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

STM32下位機軟體使用介紹:

首先是STM32序列槽參數的配置:(這裡配置代碼和相關例程都一緻)

  • 波特率=115200
  • 資料長度=8位
  • 停止位=1個
  • 奇偶校驗位=無
  • 硬體資料流控制=無

其次是函數使用說明,封裝函數如下圖:

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

這裡做簡單說明:

函數usartReceiveOneData(int *p_leftSpeedSet,int *p_rightSpeedSet,unsigned char *p_crtlFlag),填入位址參數作資料擷取,使用時放在相應序列槽的中斷服務函數中即可。如這裡使用的序列槽1,如下圖所示:

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

函數usartSendData(short leftVel, short rightVel,short angle,unsigned char ctrlFlag),填入需要發送的資料變量作發送,使用時放入指定頻率的循環裡使用,每次發送一次資料,最好延時10-15ms,下位機發送和上位機接收都需要時間(時間和序列槽波特率有關)。我使用的如下圖所示:

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

其餘的兩個函數是被上面兩個函數調用的,這裡就不多說了。

注意:

在外部引用函數時,注意引用頭檔案#include "mbotLinuxUsart.h"

小夥伴在編譯時,可能出現#include "mbotLinuxUsart.h"檔案下 sys.h不存在,原因是使用的不是正點原子的例程,此時将#include <sys.h> 替換為各自版本的配置頭檔案,如果不清楚,就在其他.h檔案中複制粘貼已有的頭檔案,關于stm32的

ROS上位機軟體使用介紹:(PC)

看圖說話,下面共有四個函數,看函數名和參數就可以了解用途。

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

首先是調用頭檔案#include "mbot_linux_serial.h",然後進行初始化序列槽

在程式初始化的時候調用serialInit()函數,内置序列槽參數和下位機序列槽參數一緻。

然後就是在調用writeSpeed(double RobotV, double YawRate,unsigned char ctrlFlag)函數,參數是機器人線速度和角速度,也就是/cmd_vel的資料。将機器人的需要設定的速度下發到下位機。

最後就是調用readSpeed(double &vx,double &vth,double &th,unsigned char &ctrlFlag)函數,這裡使用的引用,輸入存放機器人線速度、角速度、角度的變量即可。為了釋出機器人裡程計用的。

注意:

這裡需要兩個參數根據自己的機器人進行更改,ROBOT_LENGTH 機器人真實輪間距(從左側輪子中心到右側輪子中心的距離),ROBOT_RADIUS 機器人輪間距的一半。

文中boost::asio::serial_port sp(iosev, "/dev/mbot");的裝置名字是我的序列槽的裝置名字,小夥伴可以根據自己的進行更改,例如,/dev/ttyUSB0。

到這裡大家肯定都可以愉悅的使用了。如果想知道細節,請往下看。

-------------------------------------------華麗麗的分界線-----------------------------------------------

方案的原了解釋:

此方案用的是共用體的思路,上面小夥伴們也都對共用有個大緻的了解。這是一種按照共用體内成員的資料類型進行記憶體通路的特性,不同資料類型按照自己的類型通路記憶體。上位機和下位機的原理是一緻的。都定義了資料頭、資料尾的常量,和收發共用體。

下位機發送的資料協定: 上位機發送的資料協定:

全網最實用的STM32和ROS機器人的序列槽通信方案全網最實用的STM32和ROS機器人的序列槽通信方案

STM32的序列槽接收原理:每接收到一個位元組就會觸發一次中斷,我這裡采用在序列槽的中斷服務函數中進行資料接收的解析,具體函數展現在receiveTo103()

根據上位機發送的協定進行判斷解析,詳見代碼,注釋清晰。

Linux上位機采用ASIO,ASIO不僅支援網絡通信,還能支援序列槽通信。

這裡采用boost::asio::write(sp, boost::asio::buffer(buf));發送資料

使用boost::asio::read_until(sp, response, "\r\n",err);

copy(istream_iterator<unsigned char>(istream(&response)>>noskipws),

istream_iterator<unsigned char>(),buf);

擷取資料,再具體的細節需要見源碼解釋了。腦子裡的思想就是把相應的資料放到相應的位置,沒有資料解析概念,對應的字元資料存好後,就可以通過另外一個成員通路了。

釋出于 07-30

STM32

單片機

序列槽通信