ROS应用笔记之——串口

当我们使用ROS的时候,如果条件运行的话,肯定不仅仅只希望在碰不到摸不着的仿真环境中控制机器人,我们往往更希望能够真实地控制机器人,但是ROS和机器人上的嵌入式系统中总是隔着几道屏障,包括软件上的和硬件上的,软件上的屏障可以通过使用ros_control来跨越,当然你也可以自己编写自己的robot_control来实现与ros_control相同的功能,这篇博文暂时不讲软件这部分的屏障,我们来聊聊跨越硬件上的屏障的一种方式——串口,看完本篇博文,你将了解到如何使用串口让ROS的信息跨过山和大海,来到你的嵌入式系统上。

0. ROS官方包:ros_serial

ros_serial
官方wiki

0.0 install

sudo apt install ros-kinetic-serial

0.1 初始化

    try
    {
        //设置串口属性,并打开串口
        ros_serial.setPort("/dev/ttyUSB0");
        ros_serial.setBaudrate(115200);
        serial::Timeout to = serial::Timeout::simpleTimeout(1000);
        ros_serial.setTimeout(to);
        ros_serial.open();
    }
    catch (serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port ");
    }
    if(ros_serial.isOpen())
    {
        ROS_INFO("Serial Port initialized");
    }
    else
    {
        ROS_ERROR_STREAM("Serial Port fails");
    }

0.2 发送数据

pSendBuf是发送缓存区的地址,len是发送字符串的长度

    if(ros_serial.isOpen())
    {
        ros_serial.write(pSendBuf,len);  /* 用串口发送出去 */
    }

1. Linux ttyUSB权限问题

上面的内容都是一些很简单的操作,相关的资料也很多,我就不多讲了。
至于这部分,在Linux下操作USB时经常会遇到的权限问题:

首先,Linux与Windows不同,Linux将硬件设备视为一个文件,在/dev路径下,你可以看到很多像这样的文件:
ROS应用笔记之——串口_第1张图片
这些文件实际上的访问这些硬件设备的端口,我们在Linux下将通过访问这些文件来访问对应的硬件设备,综上所述,/dev路径下的东西很重要,既然这么重要,Linux这么可能让你随随便便的使用呢?
在没有任何处理的前提下,你在代码中操作这些文件,一般只会被没有权限的错误甩一脸。
那么,我们该怎么办呢?

1.0 方法0:

sudo chmod a+rw /dev/ttyUSB0

这种方法最简单粗暴,但是同时缺点也很明显,就是每次运行代码前都得先执行一次这条命令。如果你不嫌麻烦,那么后面两种方法可以忽略掉

1.1 方法1:

使用udev规则:

sudo gedit /etc/udev/rules.d/70-ttyusb.rules

先创建一个udev规则文件
再将下面这句添加到文件中

KERNEL=="ttyUSB[0-9]*", MODE="0666"

这就可以将ttyUSB(0~9)十个设备全开了权限

缺点:没有建立一个特定设备对应的特定映射,会出现偶尔找不到设备的现象,比如你在代码打开ttyUSB0,然而在/dev只有一个ttyUSB1

1.2 方法2:

udev的另一种写法:
首先用lsusb查看USB转串口芯片的idVendor和idProduct

lsusb

我现在插入了一个CH340,执行命令后可以在终端中看到下面这条信息
在这里插入图片描述
这表示了CH340的idVendor和idProduct分别为:la86和7523

每一个不同厂家的设备会有一个不同的idVendor和idProduct,我们可以利用这一点来实现设备的识别,不过要是同时出现两个同类设备,这个方法就gg了。比如同时插入两个CH340

KERNEL=="ttyUSB*", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", MODE:="0777", SYMLINK+="mcu_uart"

这时,将方法1中那个文件的内容改为上面这行,保存,注销。

然后将我们的代码改为:

	try
    {
        //设置串口属性,并打开串口
        ros_serial.setPort("/dev/mcu_uart");
        ros_serial.setBaudrate(115200);
        serial::Timeout to = serial::Timeout::simpleTimeout(1000);
        ros_serial.setTimeout(to);
        ros_serial.open();
    }
    catch (serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port ");
    }
    if(ros_serial.isOpen())
    {
        ROS_INFO("Serial Port initialized");
    }
    else
    {
        ROS_ERROR_STREAM("Serial Port fails");
    }

嗯~一劳永逸

你可能感兴趣的:(ROS应用笔记,Linux,ROS,串口,ros_serial,udev)