ROS2-Foxy 串口通讯

ROS2-Foxy 串口通讯

环境:Ubuntu20.04 + ROS2-Foxy
时间:2023年11月

截至目前,在全网搜了搜关于ROS2-Foxy串口通信的内容,没有找到官方正式的办法,好像也并没有官方的串口包。通过综合参考几个文档,安装一个大佬修改适配的第三方包,成功实现了串口通讯。

一、环境准备

(一)安装ros2-for-serial-driver

sudo apt install ros-foxy-serial-driver

(二)安装第三方包串口包

GitHub: ZhaoXiangBox/serial: ROS2 foxy serial

1. 下载源码
git clone https://github.com/ZhaoXiangBox/serial.git
2. 编译源码
cd serial
mkdir build
cd build
cmake ..
make
3. 安装
sudo make install

(三)加载共享库缓存

sudo ldconfig

如果没有安装过第三方开源库,需要将第三方库常用安装路径写入共享库配置文件中:

sudo sh -c "echo '/usr/local/lib' >> /etc/ld.so.conf"
sudo ldconfig

(四)安装串口调试工具

sudo apt-get install cutecom

二、示例代码

串口操作包的 API 请参考:serial: Serial Library

#include "rclcpp/rclcpp.hpp"
#include "serial/serial.h"

serial::Serial ser;//数据串口

#define sBUFFERSIZE 1000// send buffer size 串口发送缓存长度
#define rBUFFERSIZE 1000// receive buffer size 串口接收缓存长度
unsigned char s_buffer[sBUFFERSIZE]; //发送缓存
unsigned char r_buffer[rBUFFERSIZE]; //接收缓存

class ExampleNode : public rclcpp::Node
{
public:
    // 构造函数,有一个参数为节点名称
    ExampleNode(std::string name) : Node(name)
    {
        RCLCPP_INFO(this->get_logger(), "大家好,我是%s.", name.c_str());

        // 创建发布者
        ser_pub = this->create_publisher<XXX>("ser_data", 10);
        // 创建定时器,500ms为周期,定时发布
        timer = this->create_wall_timer(std::chrono::milliseconds(500), std::bind(&ExampleNode::timer_callback, this));

    }

private:
    void timer_callback()
    {
        if (ser.available()) {

            size_t bytes_read_r_buffer = ser.read(r_buffer, ser.available());//bytes_read_r_buffer 自己定义的r_buffer读到多少bytes

            printf("bytes_read_r_buffer: %zd\n", bytes_read_r_buffer);

            // 数据转换打包
            
            ...

            // 发布消息
            imu_data_pub->publish(imu_data);
            // 日志打印
            RCLCPP_INFO(this->get_logger(), "接收到串口数据,发送成功!");
        }
        else
        {
            //test
            RCLCPP_INFO(this->get_logger(), "500ms内未接收到串口数据");
        }
    }
    // 声名定时器指针
    rclcpp::TimerBase::SharedPtr timer;
    // 声明话题发布者指针
    rclcpp::Publisher<XXX>::SharedPtr ser_pub;
};

int main(int argc, char **argv)
{
    /* 初始化rclcpp */
    rclcpp::init(argc, argv);

    //串口初始化
    try
    {
        ser.setPort("/dev/ttyUSB0");
        ser.setBaudrate(115200);
        //串口设置
        serial::Timeout to = serial::Timeout::simpleTimeout(1000);
        ser.setTimeout(to);

        ser.setStopbits(serial::stopbits_t::stopbits_one);
        ser.setBytesize(serial::bytesize_t::eightbits);
        ser.setParity(serial::parity_t::parity_none);       //设置校验位

        //打开
        ser.open();
    }
    catch(serial::IOException &e)
    {
        std::cout<<"unable to open ser"<<std::endl;
        return -1;
    }
    catch(std::invalid_argument &e)
    {
        std::cout<<"std::invalid_argument"<<std::endl;
        return -1;
    }
    catch(serial::SerialException &e)
    {
        std::cout<<"serial::SerialException"<<std::endl;
        return -1;
    }
    //检查串口
    if(ser.isOpen())
    {
        std::cout<<"ser open"<<std::endl;
    }
    else
    {
        return -1;
    }
    

    /* 产生一个的节点 */
    auto node = std::make_shared<ExampleNode>("example_node");
    // 打印一句自我介绍
    RCLCPP_INFO(node->get_logger(), "example_node节点已经启动.");
    /* 运行节点,并检测退出信号 Ctrl+C */
    rclcpp::spin(node);
    /* 停止运行 */
    rclcpp::shutdown();

    //关闭串口
    ser.close();

    return 0;
}

三、参考

四、【避雷】尝试失败的方法

鱼香ROS自己写的一个包FishProtocol:安装后,运行样例代码没有跑通。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值