Ubuntu 下 ROS 使用 serial 包进行无线串口通信

1、查看本机当前USB、串口设备

  • 查看当前已连接的 USB 设备:lsusb;
  • 查看电脑连接的USB 转串口的信息:dmesg | grep ttyUSB*;
  • 查看电脑连接的串口的信息:dmesg | grep ttyS*;
  • 查看串口名称使用:一般USB转串口设备/dev/ttyUSB*,如果是普通的串口设备会是/dev/ttyS*
    ls -l /dev/tty*;
    ls -l /dev/ttyS*;
    ls -l /dev/ttyUSB*;

2、安装 Linux 下的串口调试助手

2.1 CuteCom

// 安装
sudo apt-get install cutecom
// 运行
sudo cutecom

Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第1张图片
CuteCom 使用可参考:Linux下uart通讯——cutetom的使用

2.2 CommMaster

CommMaster 是一款跨平台调试工具,支持 deepin, windows xp, macos。Gitee 仓库地址:https://gitee.com/itas109/CommMaster/
Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第2张图片

3、使用 ROS 提供的 serial包实现串口通信

serial作为ROS与下位机通讯的功能包,可以很方便的供我们与我们的下位机通信。

3.1 安装 ros-melodic-serial 包

// 安装
sudo apt install ros-melodic-serial

进入下载的软件包的位置 roscd serial,若是安装成功会看到:
在这里插入图片描述

3.2 创建工作空间和功能包

// 创建工作空间
$ mkdir -p ~/serial_port_ws/src
$ cd ~/serial_port_ws/src/
$ catkin_init_workspace

// 编译工作空间
$ cd ~/serial_port_ws/
$ catkin_make

// 设置环境变量
$ source devel/setup.bash

// 检查环境变量
$ echo $ROS_PACKAGE_PATH

// 创建功能包
$ cd ~/serial_port_ws/src/
$ catkin_create_pkg serial_communicate std_msgs rospy roscpp serial

// 编译功能包
$ cd ~/serial_port_ws/
$ catkin_make
$ source ~/serial_port_ws/devel/setup.bash

笔者在创建功能包时直接包含了serial,所以CMakelists.txt和package.xml文件无需再次添加编译规则:$ catkin_create_pkg serial_communicate std_msgs rospy roscpp serial

3.3 编写串口发送和接收节点

创建名为 key_input_send.cpp 节点文件:

#include
#include
#include

#include
#include
#include

using namespace std;


/**************************************************************************
函数功能:将数据经由串口发送出去
入口参数:[serial::Serial &ser]:              串口类名称;
        [std::string &serial_msg]:      发送的数据数组;
返  回  值:无
说        明:无
**************************************************************************/
int serial_write(serial::Serial &ser, std::string &serial_msg)
{
    ser.write(serial_msg);
    return 0;
}

/**************************************************************************
函数功能:将数据经由串口读取进来
入口参数:[serial::Serial &ser]:              串口类名称;
        [std::string &serial_msg]:      接收的数据数组;
返  回  值:无
说        明:无
**************************************************************************/
int serial_read(serial::Serial &ser, std::string &result)
{
    result = ser.read( ser.available() );
    return 0;
}


int main(int argc, char** argv)
{
    ros::init(argc, argv,"my_serial_port");
    ros::NodeHandle n;

    //创建一个serial类
   serial::Serial ser;

    //初始化串口相关设置
   ser.setPort("/dev/ttyUSB0");         //设置打开的串口名称
   ser.setBaudrate(9600);                //设置串口的波特率
   serial::Timeout to = serial::Timeout::simpleTimeout(1000);           //创建timeout
   ser.setTimeout(to);                           //设置串口的timeout

    //打开串口
    try
    {
        ser.open();         //打开串口
    }
    catch(const std::exception& e)
    {
        ROS_ERROR_STREAM("Unable to open port ");           //打开串口失败,打印信息
        return -1;
    }

    //判断串口是否成功打开
    if( ser.isOpen() )
    { 
        ROS_INFO_STREAM("Serial Port initialized. \n");         //成功打开串口,打印信息
    }
    else
    {
        return -1;
    }


    ros::Rate loop_rate(50);
	
	//data 为发送数据
    //result 为接收数据
  	std::string data, result;
    int func(0);
    
    cout << "Please input function number:" << endl;

    while( ros::ok() )
    {
      	//从键盘中读取键入数据
      	cout << "Your function number is: ";
        cin >> func;
        
  /*****************************************************************************
 * 以下逻辑可以按照你自己的写,主要工作是根据键盘键入的数据,为 data 赋值
 *****************************************************************************/
     	 switch (func)
        {
            case 0:     data = "A 800 456\r\n";         break;
            case 1:     data = "B 1200 456\r\n";        break;
            case 2:     data = "C 1600 456\r\n";        break;
            case 3:     data = "D 1800 456\r\n";        break;
            default:    ROS_ERROR_STREAM("No this function number!!!");     break;
        }

        //串口写数据
        serial_write(ser, data);
        cout << " the data write to serial is :  " << data.c_str();
        //串口读数据
        serial_read(ser, result);
        cout << " the data read from serial is : " << result.c_str();
        cout << endl;
    }

	ser.close();
    return 0;
}

配置 CMakeLists.txt 文件:

# 生成可执行文件
add_executable(key_input_send src/key_input_send.cpp)
# 链接库
target_link_libraries(key_input_send  ${catkin_LIBRARIES})

以上代码参考自CSDN博客:ROS使用serial包进行串口通信

3.4 测试节点

使用刘老师自研的两个 USB 转串口无线收发模块,进行无线串口收发通信测试。其中 ttyUSB0 采用上述节点控制,ttyUSB1 采用 CommMaster 串口调试助手测试。
Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第3张图片

// 开启一个终端
$ roscore
// 再开启一个终端
$ rosrun serial_communicate key_input_send

Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第4张图片

打开 CommMaster,连接串口 /dev/ttyUSB1
Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第5张图片
在终端中依次输入 0 1 2 3,观察到 CommMaster 中接收区显示:
Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第6张图片
可见,ttyUSB0ttyUSB1 发送数据正常。

CommMaster 发送区发送一次 HuangXiaoBaiDeJinJieZhiLu,然后在终端随意输入0 1 2 3 中的任意一个数字,显示如下:
Ubuntu 下 ROS 使用 serial 包进行无线串口通信_第7张图片
可见,ttyUSB1ttyUSB0 发送数据正常,且 ttyUSB0读取数据正常。测试完毕。

你可能感兴趣的:(ubuntu,linux,串口通信)