亚搏体育官方平台-亚搏体育客户端官方下载

成功案例

您所在位置:亚搏体育官方平台 > 成功案例 > 正文

RT-Thread如何使用串口或者无线和ROS连接

文章编辑:www.vjkim.com发布时间:2020-07-12浏览次数:1197

先容

本文主要先容RT-Thread如何使用串口或无线与ROS连接。它将包括以下内容:

第一部分:活性氧环境建设

第二部分:实时线程串行App包

第二部分:实时线程增加了USART2和脉宽调制

第三部分:实时线程是使用8266 AT固件联网的。

活性氧首先是什么?你为什么想和罗斯联系?

机器人操作系统(ROS)最初是斯坦福大学的App框架,现在工业机器人和娱乐机器人都在运行ROS。

图片来源网络,如果有侵权,请联系删除

机器人通常有许多部件和传感器。为了保证机器人不会因为某个传感器故障而导致整个系统瘫痪,分布式节点通过不同节点之间的通信来收集传感器数据和控制指令。本文后面使用的通信协议是?rosserial .与ROS连接的优点是,一方面,ROS在管理每个机器人节点时更稳定;另一方面,ROS已经有许多成熟的App包。使用ROS可以轻松地为您的机器人添加高级功能,如相机图像识别、激光雷达地图导航等。然而,本文件仅涉及建立实时线程和实时操作系统之间的基本连接,以实现汽车的运动控制。稍后,可能会有后续文档描述如何连接激光雷达来构建地图和实行全局路径规划。

本文假设每个人都已经使用RT-Thread的环境工具下载App包,生成项目上传固件到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的基本App包,没有安装图形App包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下看到相应的配置。

此外,大家需要选择rosserialApp包:

您可以看到上面的默认串行端口是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?MicroSoft俱乐部?=?假的;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?(MicroSoft俱乐部)?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

XML 地图 | Sitemap 地图