![2983419a2abb355b7863e80e4d965de8.png](https://i-blog.csdnimg.cn/blog_migrate/8ca74bdaa6eada7521c2941a8f66293d.png)
玩过ROS的人都会知道,玩ROS绝对不是我等屌丝的游戏,毕竟投入成本太高,稍微搞点高端的SLAM、做个机器学习、图像识别和跟随,那激光雷达、深度摄像头这些大件就必须得上,而这些硬件往往价格都非常高。
当然我等屌丝自有办法,毕竟ROS的灵活性摆在那里,低端硬件在手依然不妨碍你要玩ROS的心,作为入门和简单的算法验证,这些低成本硬件可完全满足你的需求,这篇就讲讲ROS与低成本硬件的通讯。
基于ROS应用层算法的实现少不了跟硬件跟传感器和执行器打交道,通讯方式当然有很多种,如CAN通讯、LIN通讯和无线通讯等,其中最常用的当属串口通讯。
ROS与嵌入式系统实现串口通讯的方式有很几种,如已开发好的Roserial,Roserial已支持Arduino、STM32等开源或低成本硬件的通讯。
![9e7db91268d9865d72e41cb02795bcd0.png](https://i-blog.csdnimg.cn/blog_migrate/b43c1247f530ff036ee35daa28fa48ed.jpeg)
Rosserial的作用是让嵌入式系统作为一个ros节点实现与其他节点的直接交互,在架构上更符合ros,但由于需要移植ros的一些库,嵌入式开发人员可能需要在原先熟悉的开发方式下去熟悉另外一套语法,其次譬如STM32如果要支持rosserial,其开发环境的配置就过于复杂和繁琐(反正我不喜欢在Linux敲那一堆命令去配置一个开发环境,我更倾向于在熟悉的IDE下去开发嵌入式应用),因此这次讲一种相对灵活的方式,你唯一费时要做的就是在ros应用层写一个与串口通讯的ros节点,该节点负责从串口读取嵌入式系统传输给ros应用层的数据同时也负责将控制指令通过串口发送给嵌入系统系统最终驱动实际的执行器去动作,其示意图如下:
![56428a37e3719ab20189299643929958.png](https://i-blog.csdnimg.cn/blog_migrate/1ae058631ea1f593c093823df4620832.jpeg)
这种方式虽然不太符合ros架构,但更灵活,因为你依然可采用熟悉的方式进行嵌入式系统的开发,同时也不影响ROS与硬件的交互,当然这种方式需要提前约定好通讯协议规则。
下面干货来了:首先需安装一些必要的依赖库,如ros的serial功能包和c++ boost库,其中c++ boost如何在Ubuntu中配置请参照官网指导。
![239c433895379199a248588c62793829.png](https://i-blog.csdnimg.cn/blog_migrate/eaf8f3f5131d9ecb90b66c7ffc56d0cd.jpeg)
而ros的serial功能包安装只需要在命令行输入如下命令:
![c879006f814cba2bb469076b4c0911df.png](https://i-blog.csdnimg.cn/blog_migrate/05620116f936c02e3feb004cec1aa378.jpeg)
然后在自己功能包src下新建一个源文件(即ROS节点),例如我在catkin_ws/src/beginner_tutorials下新建了一个serial_example_node_Lijing.cpp的源文件。
![ce2334d93e9bbebabb485a004c2ff2a4.png](https://i-blog.csdnimg.cn/blog_migrate/f3eddc14965c3cf5772c05d4ecef2ecd.jpeg)
在serial_example_node_Lijing.cpp中撸上其作为一个ROS节点的尊严,该ROS节点的作用就是从串口上读取数据并往串口里写数据,部分代码如下(想要源码的请发邮件至Ljhuster@gmail.com)。
![14702848bfd13f3ab7f3aa3a0fdd5f22.png](https://i-blog.csdnimg.cn/blog_migrate/aac854358828ad4c4305766807c4306d.jpeg)
然后就是一些节点配置工作,首先在beginner_tutorials文件下的package.xml添加必要的依赖,如下我标出来的部分,其中serial的依赖一定要加。
![80d8d24f421d389c77ef0f380701f12e.png](https://i-blog.csdnimg.cn/blog_migrate/cc59e54cb3762466442579c301943d5a.jpeg)
最后在beginner_tutorials文件下的CMakeLists.txt文件中对节点进行配置,需在两处添加如下标黄的部分。
![bc97715f02b410c078ff4cadb58e4152.png](https://i-blog.csdnimg.cn/blog_migrate/b517ef835ca4067f9d1e96e27ac58918.jpeg)
配置完成后即可编译,下面就是见证奇迹的时刻,首先你需要在嵌入式设备写个Demo程序,例如我写了个通过串口持续输出“Hello ROS Edit by Lijing”的例程,此时我需要将刚编译好的Ros节点运行起来,依次输入如下命令。
首先将主节点运行起来,即运行roscore:
![018ce168ffe869234d3f464a792c30d9.png](https://i-blog.csdnimg.cn/blog_migrate/8c347cee159a2ca3d6cede9c127204bf.jpeg)
再放开串口的读写权限,即sudo chmod 666 /dev/ttyUSB0(具体哪个串口视各自具体情况定):
![2df24c6da978d7e9d56f9e94ea6e532f.png](https://i-blog.csdnimg.cn/blog_migrate/9c34bbe0a227d3ae14e234f521f55dba.jpeg)
因为我嵌入式系统会通过串口持续发送Hello ROS Edit by Lijing,此时运行编译好的serial_example_node_Lijing节点,即输入如下命令:
![3f75f1cdb7bb180df021f56f98546b2a.png](https://i-blog.csdnimg.cn/blog_migrate/a93a6f11cf27e94812a184548b0d384c.jpeg)
即可看到ROS串口节点从串口读取到的信息,如下
![89dd3b44654c0dcf37733abf695e7b39.png](https://i-blog.csdnimg.cn/blog_migrate/a8c7888885b4f6702d786e34cb425acd.jpeg)
而实际背后运行的机理就是只有serial_example_node_Lijing节点在运行,该节点负责从串口读取从嵌入式发送来的数据并打印到控制台。同理通过该节点你可以发送特定的信息经过串口送给嵌入式设备,从而实现最终的控制。
![3cae912f122cf925cc2ec280eb4cb53f.png](https://i-blog.csdnimg.cn/blog_migrate/11856d2a7113a62d7898f5647b7c659e.jpeg)