Ubuntu 22.04 ROS2 Humble 串口通信全流程避坑实战
第一次在Ubuntu 22.04上配置ROS2 Humble与CH340串口通信时,我遇到了驱动签名失败、权限不足、动态库缺失等一系列问题。经过多次尝试和排查,终于整理出这份覆盖完整流程的解决方案。本文将重点解决实际开发中最容易卡住的几个关键环节,帮助开发者快速搭建稳定的串口通信环境。
1. 环境准备与驱动安装
1.1 系统基础配置
在开始之前,建议先更新系统软件包:
sudo apt update && sudo apt upgrade -yUbuntu 22.04默认启用了安全启动(Secure Boot),这会导致第三方驱动无法直接加载。对于CH340这类常见USB转串口芯片,我们需要特别注意驱动签名问题。
1.2 CH340驱动安装与签名
CH340驱动安装过程中最常见的错误是"Key was rejected by service"。这是因为新版本Ubuntu对内核模块有更严格的安全要求。以下是具体解决方案:
首先安装编译依赖:
sudo apt install build-essential linux-headers-$(uname -r) -y下载官方驱动源码:
git clone https://github.com/juliagoda/CH341SER.git cd CH341SER make处理签名问题:
sudo mkdir -p /usr/local/lib/modules/$(uname -r)/kernel/drivers/usb/serial sudo cp ch34x.ko /usr/local/lib/modules/$(uname -r)/kernel/drivers/usb/serial sudo depmod -a
如果仍然遇到签名错误,可以尝试临时禁用Secure Boot或在BIOS中将其关闭。
1.3 验证驱动加载
安装完成后,插入CH340设备,检查驱动是否加载成功:
dmesg | grep ch34x ls /dev/ttyUSB*正常情况应该能看到类似输出:
[ 1234.567890] usbserial: USB Serial support registered for ch34x [ 1234.567891] ch34x 1-1.2:1.0: ch34x converter detected /dev/ttyUSB02. ROS2串口通信环境配置
2.1 安装ROS2 Humble基础环境
确保已正确安装ROS2 Humble桌面版:
sudo apt install ros-humble-desktop source /opt/ros/humble/setup.bash2.2 安装串口通信相关包
ROS2的串口通信主要依赖serial-driver包:
sudo apt install ros-humble-serial-driver同时安装调试工具:
sudo apt install cutecom2.3 解决动态库缺失问题
运行程序时可能会遇到"error while loading shared libraries: libserial.so"错误。这是因为系统找不到serial库文件。解决方法如下:
临时方案(当前终端有效):
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH永久方案:
echo '/usr/local/lib' | sudo tee -a /etc/ld.so.conf sudo ldconfig验证是否生效:
ldconfig -p | grep libserial3. 串口权限与常见冲突解决
3.1 串口设备权限管理
默认情况下,普通用户无法直接访问串口设备。不建议使用chmod 777这种不安全的方式,而是应该将用户加入dialout组:
sudo usermod -aG dialout $USER然后重新登录使更改生效。验证权限:
ls -l /dev/ttyUSB0正确输出应包含dialout组:
crw-rw---- 1 root dialout 188, 0 Jun 1 10:00 /dev/ttyUSB03.2 解决brltty服务冲突
Ubuntu 22.04默认安装的brltty服务会占用串口设备,导致无法访问。解决方法:
检查服务状态:
systemctl status brltty-udev.service禁用服务:
sudo systemctl mask brltty-udev.service sudo systemctl stop brltty-udev.service移除自动安装:
sudo apt remove brltty
4. ROS2串口通信实战
4.1 创建工作空间与包
mkdir -p ~/ros2_ws/src cd ~/ros2_ws/src ros2 pkg create --build-type ament_cmake serial_demo4.2 编写串口发布节点
创建serial_publisher.cpp文件:
#include "rclcpp/rclcpp.hpp" #include "std_msgs/msg/string.hpp" #include "serial/serial.h" class SerialPublisher : public rclcpp::Node { public: SerialPublisher() : Node("serial_publisher") { publisher_ = this->create_publisher<std_msgs::msg::String>("serial_data", 10); timer_ = this->create_wall_timer( std::chrono::milliseconds(500), std::bind(&SerialPublisher::timer_callback, this)); serial_.setPort("/dev/ttyUSB0"); serial_.setBaudrate(9600); serial::Timeout timeout = serial::Timeout::simpleTimeout(1000); serial_.setTimeout(timeout); try { serial_.open(); } catch (serial::IOException& e) { RCLCPP_ERROR(this->get_logger(), "无法打开串口"); } } private: void timer_callback() { auto message = std_msgs::msg::String(); if(serial_.isOpen()) { size_t bytes = serial_.available(); if(bytes > 0) { std::string result = serial_.read(bytes); message.data = result; publisher_->publish(message); RCLCPP_INFO(this->get_logger(), "收到数据: '%s'", message.data.c_str()); } } } rclcpp::TimerBase::SharedPtr timer_; rclcpp::Publisher<std_msgs::msg::String>::SharedPtr publisher_; serial::Serial serial_; }; int main(int argc, char * argv[]) { rclcpp::init(argc, argv); rclcpp::spin(std::make_shared<SerialPublisher>()); rclcpp::shutdown(); return 0; }4.3 修改CMakeLists.txt
在CMakeLists.txt中添加:
find_package(serial REQUIRED) find_package(rclcpp REQUIRED) find_package(std_msgs REQUIRED) add_executable(serial_publisher src/serial_publisher.cpp) target_link_libraries(serial_publisher ${rclcpp_LIBRARIES} ${std_msgs_LIBRARIES} serial::serial ) install(TARGETS serial_publisher DESTINATION lib/${PROJECT_NAME} )4.4 编译与运行
cd ~/ros2_ws colcon build --packages-select serial_demo source install/setup.bash ros2 run serial_demo serial_publisher5. 高级调试技巧
5.1 串口调试工具使用
推荐使用cutecom进行基础调试:
sudo cutecom在界面中选择正确的串口设备(/dev/ttyUSB0),设置波特率等参数后,可以手动发送和接收数据。
5.2 查看系统日志
当遇到问题时,系统日志往往能提供有用信息:
journalctl -f5.3 检查USB设备详情
lsusb -v | grep -A 3 CH340输出示例:
Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics CH340 serial converter Device Descriptor: bLength 18 bDescriptorType 1 bcdUSB 1.105.4 自定义udev规则(可选)
为避免每次插拔USB设备后节点名称变化(/dev/ttyUSB*编号变化),可以创建udev规则:
创建规则文件:
sudo nano /etc/udev/rules.d/99-ch340.rules添加内容:
SUBSYSTEM=="tty", ATTRS{idVendor}=="1a86", ATTRS{idProduct}=="7523", SYMLINK+="ttyROS_CH340"重新加载规则:
sudo udevadm control --reload-rules sudo udevadm trigger
之后设备将固定出现在/dev/ttyROS_CH340,在代码中可以直接使用这个固定名称。