成功案例

您所在位置:首頁 > 成功案例 > 正文

RT-Thread如何使用串口或者無線和ROS連接

文章作者:www.411998.tw發布時間:2020-07-12瀏覽次數:1197

介紹

本文主要介紹RT-Thread如何使用串口或無線與ROS連接。它將包括以下內容:

第一部分:活性氧環境建設

第二部分:實時線程串行軟件包

第二部分:實時線程增加了USART2和脈寬調制

第三部分:實時線程是使用8266 AT固件聯網的。

活性氧首先是什么?你為什么想和羅斯聯系?

機器人操作系統(ROS)最初是斯坦福大學的軟件框架,現在工業機器人和娛樂機器人都在運行ROS。

圖片來源網絡,如果有侵權,請聯系刪除

機器人通常有許多部件和傳感器。為了保證機器人不會因為某個傳感器故障而導致整個系統癱瘓,分布式節點通過不同節點之間的通信來收集傳感器數據和控制指令。本文后面使用的通信協議是?rosserial .與ROS連接的優點是,一方面,ROS在管理每個機器人節點時更穩定;另一方面,ROS已經有許多成熟的軟件包。使用ROS可以輕松地為您的機器人添加高級功能,如相機圖像識別、激光雷達地圖導航等。然而,本文件僅涉及建立實時線程和實時操作系統之間的基本連接,以實現汽車的運動控制。稍后,可能會有后續文檔描述如何連接激光雷達來構建地圖和執行全局路徑規劃。

本文假設每個人都已經使用RT-Thread的環境工具下載軟件包,生成項目上傳固件到stm32,并熟悉Ubuntu的基本用法。

活性氧介紹

這里的開發環境需要構建兩個副本,一個是ARM開發板(草莓派、納米芯片等)。)上,另一臺是我們自己的計算機,因為我們想把計算機用作ROS從節點,并把它連接到汽車上的ROS主節點,但計算機的開發板和ROS安裝是一樣的。

因為必須與活性氧連接,所以首先必須有一個正常的活性氧。安裝ROS實際上非常簡單。這里推薦Ubuntu 18(Armbian推薦給開發委員會推薦系統),因為Ubuntu的官方支持優先級最高,安裝指南也可以參考?官方網站:只需輸入以下4行命令就可以在Ubuntu上安裝ROS。

1sudo?噓。-c?“回聲,”黛比。(lsb _釋放?-sc?主要的?/etc/apt/sources . list . d/ROS-latest . list ' 2 sudo?apt-key?adv?-鑰匙服務器?“?- recv-key?c1cf 6 e 31e 6 bade 8868 b 172 B4 f 42 ed 6 fbab 17c 654 3 sudo?apt?更新4sudo?apt?安裝?我使用清華大學的鏡像資源,所以從中國下載Ros會快得多。此外,我只安裝了ROS的基本軟件包,沒有安裝圖形軟件包gviz、gazebo或其他什么,因為后來沒有使用。

1.2活性氧環境初始化

安裝ROS后,需要初始化,但只有幾行命令可用:

1sudo?rosdep?init 2rosdep?更新3 4echo?來源?/opt/ros/melodic/setup.bash?~/。bashrc 5source?~/。巴什爾克。1.3要啟動ROS,我們需要確保它在后臺運行,這樣我們就可以使用tmux:1 oscore

在操作系統主節點在tmux中啟動后,我們可以在操作系統主節點仍在后臺運行時退出。

1.4參考

Armbian:

rosmeladic installation//wiki . ROS . org/meladic/installation/Ubuntu

2RT-線程串行端口連接

本節將介紹如何使用串口連接運行實時線程的STM32開發板和運行實時操作系統的ARM開發板,如下所示。

這里解釋了不同開發委員會之間的分工。STM32運行實時線程,負責控制電機和接收傳感器信息。ARM正在運行ROS,它負責全局控制,比如給汽車前進指令。

2.1實時線程配置

首先,我們需要打開usart2,因為usart1是由msh使用的,所以在調試時保持它是非常方便的。

?在CubeMX中,我打開了USART2,同時也打開了4個脈寬調制通道,因為我在身后使用了2個電機,每個電機需要2個脈寬調制通道來分別控制向前和向后。接下來,您需要在menuconfig中打開相應的選項。考慮到某些開發板的默認bsp可能沒有這些選項,您可以修改board/Kconfig來添加以下內容。串行端口配置:

1菜單配置?使用通用異步收發器?啟用?UART默認?y 4select?使用串行5if?使用通用異步收發器6配置?BSP_USING_UART1 7bool?啟用?UART1默認?y 910配置?通用異步收發器1 _接收_使用_直接存儲器11總線?啟用?UART1?RX?DMA分支?打開。使用通用異步收發器1?13默認?n 14配置?BSP_USING_UART2 16bool?啟用?UART2默認值?y 18配置?使用DMA總線?啟用?UART2?RX?DMA分支?打開。使用通用異步收發器2?22默認?n 23endif?脈寬調制配置:1菜單配置?使用脈寬調制?啟用?pwm' 3default?n 4select?使用脈寬調制5中頻?使用脈寬調制6門配置?BSP_USING_PWM3 7bool?啟用?定時器3?輸出?pwm默認值?n 9if?BSP _ USING _ PWM3配置?BSP_USING_PWM3_CH1 11bool?啟用?PWM3?通道1 ' 12默認?n配置?BSP_USING_PWM3_CH2 14bool?啟用?PWM3?通道2 ' 15默認?n16配置?BSP_USING_PWM3_CH3 17bool?啟用?PWM3?通道3 ' 18默認?n配置?BSP_USING_PWM3_CH4 20bool?啟用?PWM3?通道4 ' 21默認?n 22endif 23endif?

所以我們可以在env下看到相應的配置。

此外,我們需要選擇rosserial軟件包:

您可以看到上面的默認串行端口是USART2,所以我們可以生成相應的項目:

1公斤?-更新2個副本?-目標=mdk5?-s如果我們打開Keil項目,我們需要先將main.c改為main.cpp,因為很多rosserial數據格式的定義都是用c編寫的,所以如果我們想使用rosserial庫,我們需要先將后綴改為cpp,這樣Keil就可以用c編譯器編譯。

事實上,馬達被初始化,然后兩個主題(主題)被發布。一種是/vel_x告訴活性氧當前的汽車速度,另一種是/turn_bias告訴活性氧當前的汽車轉速。與此同時,主題/cmd_vel被訂閱以接收來自ROS的控制命令。代碼不是特別長,我還添加了一些注釋,所以這里我們不會逐行分析。

1 #包括?2 #包括?3 #包括?4 5 #包括?6 #包括?7 #包括?8 #包括?馬達。h ' 9 10 ROS : NodeHandleNH;11馬達控制?地鐵(1?2,3?4);//電機12 13bool?微軟俱樂部?=?假的;14float?velX?=?0,turnBias?=?0;15char?stat _ log[200];16 17/?接收到命令時的回調函數18虛空?velCB(?康斯。幾何圖形_ msgs:Twist扭曲?麻花味精)?19{ 20velX?=?麻花味精。線性的。x;21轉?=?麻花味精。棱角分明。z;22毫秒已收到?=?真的23 } 24 25//訂戶26ros:Subscriber訂閱者訂閱者?sub('cmd_vel ',velCB?);27 28//發布者29std _ msgs:Float64?velX_tmp .30std_msgs:Float64?turnBias_tmp .31發布者?xv('vel_x ',velX _ tmp);32ros:Publisher?XT(‘轉向偏置’,轉向偏置tmp);33 34靜態?無效?rosserial_thread_entry(無效?*參數)35 { 36//初始化?馬達?指定?那個。各自的?馬達?引腳37地鐵。init MotorS();38 39//初始化?節點每小時40英里。InitNode();41 42/?訂閱了一個話題?/cmd_vel?接收控制指令43nh。sub(sub);44 45/?發布了一個話題?/vel_x?告訴?羅斯?小車速度46nh。廣告(十五);47 48/?發布了一個話題?/turn_bias?告訴?羅斯?小車的旋轉角速度49nh。廣告(XT);50 51地鐵。stop MotorS();52 53while?(1) 54{ 55/?如果接收到了控制指令56if?(微軟俱樂部)?57{ 58velX?*=?mtr.maxSpd59mtr.moveBot(velX,轉向偏差);60平方米?=?假的;61} 62 63velX_tmp.data?=?velX64turnBias_tmp.data?=?轉彎偏置/mtr。轉向系數;65 66/?更新話題內容67xv.publish(?velX_tmp?);68xt.publish(?turnBias_tmp?);每小時69 70英里。spin once();71} 72} 73 74int?main(void) 75{ 76/?啟動一個線程用來和?羅斯?通信77rt_thread_t?線程?=?rt_thread_create('rosserial ',rosserial_thread_entry,空值什么?2048年?8?10);78if(線程?=?79{ 80rt_thread_startup(線程);81rt_kprintf('[rosserial]?新的?線程?Ross erial ');82 } 83其他84{ 85rt_kprintf('[rosserial]?失敗了?去哪里?創建?線程?Ross erial ');86 } 87返回?EOK;88}

另外還有對應的電機控制的代碼,不過這個大家的小車不同,驅動應當也不一樣,我這里由于小車電機上沒有編碼器,所以全部是開環控制的。

motors.h

1 #包括?2 3玻璃?汽車控制?{ 4 public : 5//Var 6rt _ uint 32 _ TMax SpD;7float?移動因子;8float?轉向因素;9 10馬達控制(int?fl_for,int?fl_back,11?int?fr_for,int?fr _ back);12伏?init MotorS();13虛空?rotateBot(int?迪爾。漂浮?社會民主黨);14void?移動機器人(浮動?spd?漂浮?偏見);15void?stop MotorS();16private: 17struct?rt_device_pwm?* pwm _ dev18//那個?引腳19int?fl _ for20磅?fl _ back21分鐘?fr _ for22英寸?fr _ back23英寸?bl _ for24int?bl _ back25int?br _ for26int?br_back .27 };電機#包括?2 #包括?3 #包括?電機。4 5 #定義?脈寬調制_開發_名稱?pwm3 ' 6馬達控制:馬達控制(int?fl_for,int?fl_back,8?int?fr_for,int?fr_back)?9{ 10this-maxSpd?=?11這個-移動因子?=?1.0;12這是轉向因素嗎?=?3.0;13 14this-fl_for?=?15分鐘后回來?=?fl _ back16 17this-fr_for?=?fr _ for18這-回來?=?fr _ back19} 20 21void?電機控制:初始化電機()?{ 22 23this-pwm_dev?=?(結構?rt_device_pwm?*)rt_device_find(脈寬調制_開發_名稱);24if?(pwm_dev?==?RT_NULL) 25{ 26rt_kprintf('pwm?樣本?快跑。失敗!不能嗎?找到?%s?"設備!”什么?脈寬調制_開發_名稱);27} 28rt_kprintf('pwm?找到了嗎?%s?"設備!”什么?脈寬調制_開發_名稱);29rt_pwm_set(pwm_dev,fl_for,maxSpd?0);30rt_pwm_enable(pwm_dev,fl _ for);31 32rt_pwm_set(pwm_dev,fl_back?maxSpd?0);33rt_pwm_enable(pwm_dev,fl _ back);34 35rt_pwm_set(pwm_dev,fr_for,maxSpd?0);36rt_pwm_enable(pwm_dev,fr _ for);37 38rt_pwm_set(pwm_dev,fr_back?maxSpd?0);39rt_pwm_enable(pwm_dev,fr _ back);40} 41 42/?小車運動43虛空?電機控制:移動機器人(浮動?spd?漂浮?偏見)?{ 44float?sL?=?spd?*?maxSpd .45float?sR?=?spd?*?maxSpd .46int?迪爾=?(spd?0)?1?0;47 48if(偏差?=?0) 49{ 50rotateBot((偏差?0)?1?0,偏見);51回復;52} 53 54if(?移動因子?*?maxSpd) 59{ 60sL?=?移動因子?*?maxSpd .61} 62 63if(?移動因子?*?maxSpd) 68{ 69sR?=?移動因子?*?maxSpd .70} 71 72if?(sL?0)?73{ 74sL?*=?-1;75} 76 77if?(sR?0)?78{ 79sR?*=?-1;80 } 81 82rt _ kprintf('速度?左轉:" %ld ",(rt _ int 32 _ t)Sl);83rt _ kprintf('速度?對嗎:" %ld ",(rt _ int 32 _ t)sR);84 85 if(dir)86 { 87rt _ PWM _ set(脈寬調制_ dev,fl_for,maxSpd?(rt _ int 32 _ t)Sl);88rt_pwm_set(pwm_dev,fl_back?maxSpd?0);89rt_pwm_set(pwm_dev,fr_for,maxSpd?(rt _ int 32 _ t)sR);90rt_pwm_set(pwm_dev,fr_back?maxSpd?0);91 } 92else 93 { 94rt _脈寬調制_ set(脈寬調制_ dev,fl_for,maxSpd?0);95rt_pwm_set(pwm_dev,fl_back?maxSpd?(rt _ int 32 _ t)Sl);96rt_pwm_set(pwm_dev,fr_for,maxSpd?0);97rt_pwm_set(pwm_dev,fr_back?maxSpd?(rt _ int 32 _ t)sR);98 } 99 100 rt _ thread _ mde層(1);101} 102 103 104/?小車旋轉105虛空?電機控制:旋轉電機(int?迪爾。漂浮?spd)?{ 106float?s?=?spd?*?maxSpd .107if?(dir?0)?108{ 109s?*=?-1;110} 111if(dir) 112{ 113/?順時針114rt_pwm_set(pwm_dev,fl_for,maxSpd?(rt _ int 32 _ t)s);115rt_pwm_set(pwm_dev,fl_back?maxSpd?0);116rt_pwm_set(pwm_dev,fr_for,maxSpd?0);117rt_pwm_set(pwm_dev,fr_back?maxSpd?(rt _ int 32 _ t)s);118 } 119其他120{ 121/?柜臺?順時針122rt_pwm_set(pwm_dev,fl_for,maxSpd?0);123rt_pwm_set(pwm_dev,fl_back?maxSpd?(rt _ int 32 _ t)s);124rt_pwm_set(pwm_dev,fr_for,maxSpd?(rt _ int 32 _ t)s);125rt_pwm_set(pwm_dev,fr_back?maxSpd?0);126 } 127 rt _ thread _ mde層(1);128 } 129 130//轉彎?關閉?都是嗎?馬達131void?電機控制: top電機()?132{ 133rt_pwm_set(pwm_dev,fl_for,maxSpd?0);134rt_pwm_set(pwm_dev,fl_back?maxSpd?0);135rt_pwm_set(pwm_dev,fr_for,maxSpd?0);136rt_pwm_set(pwm_dev,fr_back?maxSpd?0);137}一共只需要這么一點代碼就可以實現和活性氧的連接了,所以其實活性氧也不是那么神秘,它就是因為簡單好用所以才這么受歡迎的。既然線程已經配置好了,下一步就是活性氧的配置了。

2.2活性氧配置

我們把上面線程的固件傳到板子上以后,可以用一個通用串行總線TTL一邊和STM32控制板的USART2連接,另一邊插到手臂控制板的通用串行總線口,接下來就可以建立連接了,在手臂板上輸入命令:

1美元?rosrun?rosserial_python?serial_node.py?/dev/ttyUSB0如果看到下面的輸出,那就成功建立連接了:1tpl

东方6 1开奖结果