ROS串口编程学习笔记

2023-05-16

串口是一种设备间常用的通讯接口,本文将记录如何在ROS上使用其提供的serial包进行串口通信。

首先,这里要引入一个名称为serial的包,这个包的安装命令为:

$ sudo apt-get install ros-<版本号>-serial

serial包的介绍:http://wiki.ros.org/serial

接下来,创建一个自己的包,借助serial这个包来编写串口通信的代码。

1、创建一个包,依赖roscpp和serial两个包

$ catkin_create_pkg serial_port roscpp serial

2、在这个包的目录下面创建src目录,并在src目录中编写串口通信的代码

//serial_port.cpp
#include <ros/ros.h>
#include <serial/serial.h>
#include <iostream>

int main(int argc, char** argv)
{
    ros::init(argc, argv, "serial_port");
    //创建句柄(虽然后面没用到这个句柄,但如果不创建,运行时进程会出错)
    ros::NodeHandle n;
    
    //创建一个serial类
    serial::Serial sp;
    //创建timeout
    serial::Timeout to = serial::Timeout::simpleTimeout(100);
    //设置要打开的串口名称
    sp.setPort("/dev/ttyUSB0");
    //设置串口通信的波特率
    sp.setBaudrate(115200);
    //串口设置timeout
    sp.setTimeout(to);

    try
    {
        //打开串口
        sp.open();
    }
    catch(serial::IOException& e)
    {
        ROS_ERROR_STREAM("Unable to open port.");
        return -1;
    }
    
    //判断串口是否打开成功
    if(sp.isOpen())
    {
        ROS_INFO_STREAM("/dev/ttyUSB0 is opened.");
    }
    else
    {
        return -1;
    }
    
    ros::Rate loop_rate(500);
    while(ros::ok())
    {
        //获取缓冲区内的字节数
        size_t n = sp.available();
        if(n!=0)
        {
            uint8_t buffer[1024];
            //读出数据
            n = sp.read(buffer, n);
            
            for(int i=0; i<n; i++)
            {
                //16进制的方式打印到屏幕
                std::cout << std::hex << (buffer[i] & 0xff) << " ";
            }
            std::cout << std::endl;
            //把数据发送回去
            sp.write(buffer, n);
        }
        loop_rate.sleep();
    }
    
    //关闭串口
    sp.close();

    return 0;
}

serial包的文档有对每个类和函数的解释,可以参考:http://docs.ros.org/kinetic/api/serial/html/annotated.html

其中解释一下timeout的作用,在serial::Timeout结构体中有这么5个成员:


serial::Timeout::Timeout	(	
    uint32_t 	inter_byte_timeout_ = 0,
    uint32_t 	read_timeout_constant_ = 0,
    uint32_t 	read_timeout_multiplier_ = 0,
    uint32_t 	write_timeout_constant_ = 0,
    uint32_t 	write_timeout_multiplier_ = 0 
)	

参考另一个大神的解释:(出处:https://www.cnblogs.com/visionfeng/p/5614066.html)

“间隔超时=ReadIntervalTimeout
总超时   =   ReadTotalTimeoutMultiplier   * 字节数   +   ReadTotalTimeoutConstant 

串口读取事件分为两个阶段(我以Win32 API函数ReadFile读取串口过程来说明一下)
第一个阶段是:串口执行到ReadFile()函数时,串口还没有开始传输数据,所以串口缓冲区的第一个字节是没有装数据的,这时候总超时起作用,如果在总超时时间内没有进行串口数据的传输,ReadFile()函数就返回,当然 没有读取到任何数据。而且,间隔超时并没有起作用。
第二阶段:假设总超时为20秒,程序运行到ReadFile(),总超时开始从0 计时,如果在计时到达10秒时,串口开始了数据的传输,那么从接收的第一个字节开始,间隔超时就开始计时,假如间隔超时为1ms,那么在读取完第一个字节后,串口开始等待1ms,如果1ms之内接收到了第二个字节,就读取第二个字节,间隔超时重置为0并计时,等待第三个字节的到来,如果第三个字节到来的时间超过了1ms,那么ReadFile()函数立即返回,这时候总超时计时是没到20秒的。如果在20秒总计时时间结束之前,所有的数据都遵守数据间隔为1ms的约定并陆陆续续的到达串口缓冲区,那么就成功进行了一次串口传输和读取;如果20秒总计时时间到,串口还陆陆续续的有数据到达,即使遵守字节间隔为1ms的约定,ReadFile()函数也会立即返回,这时候总超时就起作用了。
总结起来,总超时在两种情况下起作用
第一:串口没进行数据传输,等待总超时时间那么长ReadFile()才返回。非正常数据传输
第二:数据太长,总超时设置太短,数据还没读取完就返回了。读取的数据是不全的
间隔超时触发是有条件的
第一:在总超时时间内。
第二:串口进行了数据的传输。
成功的进行一次串口数据的传输和读取,只有总超时和间隔超时相互参与配合才能完成”

3、修改CMakeList文件,添加选项

add_executable(serial_port src/serial_port.cpp)

add_dependencies(serial_port ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})

target_link_libraries(serial_port
  ${catkin_LIBRARIES}
)

4、编译,运行即可看到结果(记得运行roscore和在工程目录下source devel/setup.bash)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

ROS串口编程学习笔记 的相关文章

随机推荐

  • TCP的建立

    大家好呀 xff0c 我是请假君 xff0c 今天又来和大家一起学习数通了 xff0c 今天要分享的知识是TCP的建立 TCP是一个面向连接的可靠的传输控制协议 xff0c 在每次数据传输之前首先需要建立连接 xff0c 连接建立成功后才开
  • Java根据数字金额生成大写金额

    要求 根据用户输入金额数字转换成相对应大写金额例如 xff1a 430 65 xff0c 转换成肆佰叁拾元陆角伍分代码如下 xff1a public class MoneyFormatUtils private static final S
  • POI 设置Excel单元格背景色(参考颜色代码)

    创建一个 workbook 对象 Workbook workbook 61 new XSSFWorkbook 创建一个 sheet Sheet sheet 61 workbook createSheet 创建一行 Row row 61 sh
  • RedisTemplate之opsForValue使用说明

    转载链接出自 xff1a https blog csdn net qq 25135655 article details 80357137 Redis中opsForValue 方法的使用介绍 xff1a 1 set K key V valu
  • Python爬虫(二)——爬取电影天堂,保存下载地址

    首先我们开始要分析一下 xff0c 下载种子我们需要哪几步 xff1a 获取所有电影页的访问地址获取电影页源码提取出下载地址将下载地址保存 首先第一步 xff0c 我们来分析一下电影天堂网站的结构 xff0c 发现他跟我们的古诗文网还是非常
  • pixhawk飞控中添加uORB主题

    本说明针对 Firmware v1 2 0 参考 xff1a https pixhawk org start id 61 zh dev shared object communication 1 添加流程说明 在Firmware msg下新
  • px4 多旋翼SITL仿真

    好久不写csdn了 xff0c 自己的笔记都记在了onenote里面了 xff0c 没有时间写东西分享 xff0c 今天找了个记得比价规整的分享一下 备注 xff1a SITL需要程序源码和QGC xff0c 以及配置环境时安装的一些东西
  • keil空间不足,.\Objects\template.axf: Error: L6406E: No space in execution regions with .ANY selector mat

    关于keil空间报错 xff0c 我总结了一下集中解决方案 xff1a 1 有可能是所选主控芯片RAM xff0c ROM真的被用完了 xff0c 这是需要更换主控芯片 2 keil里面的优化还可以继续优化省出一点空间 下面红色标的选择跟你
  • 无人机之姿态控制篇

    姿态控制篇 拿四旋翼无人机为例 xff0c 四个桨叶旋转是的无人机产生了升力 xff0c 但是这个升力要怎么匹配才能使得无人机能够平稳的飞行呢 xff0c 这个就是无人机姿态控制的关键 如图四个电机1 2 3 4 xff0c 水平位置X x
  • 无人机小四轴定高篇

    无人机定高篇 定高 xff0c 也是无人机的标配功能 xff0c 可以说必须要有的 一般来说定高怎么做 xff0c 常规的思维就是计算出无人机的高度和Z轴速度 xff0c 然后对高度和速度进行PID运算 实际上大思想就是这么的简单 xff0
  • 无人机光流定点讲解

    无人机光流定点 光流是测速算法 xff0c 并不是直接定位的 简单理解 xff0c 光流就是通过检测图像中光点和暗点的移动 xff0c 来判断图像中像素点相对于飞行器的移动速度 如果地面是静止的 xff0c 自然就可以得到飞行器相对于地面的
  • TinyXml快速入门(一)

    作者 xff1a 朱金灿 来源 xff1a http blog csdn net clever101 对于xml文件 xff0c 目前我的工作只是集中在配置文件和作为简单的信息文件来用 xff0c 因此我不太喜欢使用msxml这种重量级的x
  • 华大单片机HC32L130/HC32L136从机IIC通信

    从机IIC理论知识 主机IIC的做法比较多 xff0c 从机IIC的就相对比较难一点 先补充一下从机IIC的思路 xff1a 先看IIC时序图 xff0c 然后根据时序图理清IIC从机需要做哪些判断 xff1a 从机发送 xff1a 判断I
  • cannot access memory

    cannot access memory 先说一个经历 xff1a 在一次我测试单片机FLASH时候 xff0c 程序就是一直运行的擦除FALSH xff0c 写入FLASH 然后再想通过SWD重新烧录程序就无法烧录进去了 具体现象如下 x
  • 无刷电机反方向高速旋转

    无刷电机反方向高速旋转 最近遇到一个问题 xff0c 就是无刷电机在给正转的力的时候如果用手往反方向快速的掰 xff0c 突然的电机会往反方向高速运动 xff0c 除非电机有阻力让转速慢下来 xff0c 要不就会一直反方向运动 经过一个晚上
  • 串口仿真数据正常,不接仿真数据异常

    今天遇到一个奇怪的问题 xff0c 折腾了大半天 具体问题如下 xff1a 串口我用的DMA空闲中断接收 xff0c 接仿真器仿真时接收数据完全正确 xff0c 没有异常 但是仿真器不接的时候 xff0c 正常外部供电串口接收数据就异常了
  • 普通定时器输出互补PWM带死区

    普通定时器输出互补PWM带死区 一般来说三相半桥电路需要互补PWM驱动 xff0c 而且互补PWM需要带死区 xff0c 死区的大小跟管子的性能参数有关 公司为了省成本 xff0c 在云台上把电机驱动芯片替换成三相半桥 用6个MOS驱动无刷
  • STM32F4配置内部时钟(HSI)

    STM32F4配置内部时钟 半年多没更新了 xff0c 今天配置F4的时候内部时钟问题整了2个小时 xff0c 记录下这个坑 有些板子由于没有贴外部晶振 xff0c 所以代码运行起来的时候时钟就会出问题 xff0c 本来配置的中断是1ms实
  • 无人机加速计、气压计、GPS数据融合

    加速计 气压计 GPS数据融合 在无人机控制当中 xff0c 传感器的参与那是必不可少的 xff0c 特别是陀螺仪 xff0c 最经典的为MPU6050 xff0c 目前大部分的无人机都是用的这个器件 熟悉MPU6050的都知道 xff0c
  • ROS串口编程学习笔记

    串口是一种设备间常用的通讯接口 xff0c 本文将记录如何在ROS上使用其提供的serial包进行串口通信 首先 xff0c 这里要引入一个名称为serial的包 xff0c 这个包的安装命令为 xff1a sudo apt get ins