资讯动态

保姆级教程:在ROS2 Humble上搞定串口通信,从源码编译到避坑全记录

发布时间:2026/10/3 16:08:34 来源:尧图企业网站定制
ROS2 Humble串口通信实战从环境配置到故障排除的完整指南在机器人开发中串口通信就像机器人的神经系统——它连接着大脑主控计算机与四肢执行器和传感器。对于使用ROS2 Humble的开发者来说搭建稳定可靠的串口通信环境是项目成功的第一步。本文将带你从零开始逐步构建ROS2与Arduino、STM32等设备的串口通信桥梁避开那些让新手头疼的坑。1. 环境准备与依赖安装1.1 系统基础配置在开始之前确保你的Ubuntu 22.04系统已经完成以下准备sudo apt update sudo apt upgrade -y sudo apt install build-essential cmake gitROS2 Humble的官方安装指南建议使用Ubuntu 22.04这是最稳定的组合。如果你还在使用20.04现在是时候升级了——Humble对22.04有更好的支持。提示建议在物理机上安装Ubuntu而非虚拟机USB直通在虚拟环境中常会出现权限问题1.2 ROS2 Humble核心安装按照官方推荐的方式安装ROS2 Humble桌面版sudo apt install software-properties-common sudo add-apt-repository universe sudo apt update sudo apt install curl -y sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo deb [arch$(dpkg --print-architecture) signed-by/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release echo $UBUNTU_CODENAME) main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null sudo apt update sudo apt install ros-humble-desktop安装完成后别忘了设置环境变量source /opt/ros/humble/setup.bash echo source /opt/ros/humble/setup.bash ~/.bashrc2. 串口驱动编译与安装2.1 获取串口库源码ROS2官方并未集成串口驱动我们需要手动编译安装。国内开发者维护的这个仓库已经过Humble版本测试git clone https://github.com/ZhaoXiangBox/serial cd serial这个fork版本针对ROS2做了优化解决了原版的一些兼容性问题。仓库结构如下serial/ ├── CMakeLists.txt ├── include ├── src └── test2.2 编译安装步骤遵循标准的CMake编译流程mkdir build cd build cmake .. make sudo make install编译过程中可能会遇到的依赖问题及解决方案错误提示缺失依赖安装命令Could NOT find ackermann_msgsros-humble-ackermann-msgssudo apt install ros-humble-ackermann-msgsMissing Eigen3libeigen3-devsudo apt install libeigen3-devPython.h not foundpython3-devsudo apt install python3-dev注意绝对不要在git clone时使用sudo这会导致后续编译权限问题。如果已经错误使用建议删除整个目录重新clone3. 权限配置与设备连接3.1 USB设备权限管理Linux系统默认限制普通用户直接访问硬件设备。连接你的Arduino或STM32后执行ls /dev/ttyUSB*你应该能看到类似/dev/ttyUSB0的设备。永久解决权限问题的最佳实践是创建udev规则文件sudo nano /etc/udev/rules.d/99-arduino.rules添加以下内容替换your_username为你的实际用户名SUBSYSTEMtty, ATTRS{idVendor}2341, ATTRS{idProduct}0043, MODE0666, GROUPdialout, OWNERyour_username重新加载udev规则sudo udevadm control --reload-rules sudo udevadm trigger常见设备厂商ID参考表设备类型idVendoridProductArduino Uno23410043STM32 VCP04835740CH3401a8675233.2 测试串口通信安装一个简单的串口测试工具sudo apt install cutecom运行后选择正确的设备如/dev/ttyUSB0设置波特率常用115200尝试发送数据。如果能看到设备返回的数据说明物理连接正常。4. ROS2串口节点开发实战4.1 创建工作空间与包mkdir -p ~/ros2_serial_ws/src cd ~/ros2_ws/src ros2 pkg create serial_example --build-type ament_cmake --dependencies rclcpp serial编辑package.xml确保包含以下依赖dependserial/depend dependrclcpp/depend dependstd_msgs/depend4.2 编写简单的串口发布者在src目录下创建serial_publisher.cpp#include rclcpp/rclcpp.hpp #include serial/serial.h #include std_msgs/msg/string.hpp class SerialPublisher : public rclcpp::Node { public: SerialPublisher() : Node(serial_publisher) { try { serial_.setPort(/dev/ttyUSB0); serial_.setBaudrate(115200); serial::Timeout timeout serial::Timeout::simpleTimeout(1000); serial_.setTimeout(timeout); serial_.open(); } catch (const std::exception e) { RCLCPP_ERROR(this-get_logger(), Failed to open port: %s, e.what()); rclcpp::shutdown(); } publisher_ this-create_publisherstd_msgs::msg::String(serial_data, 10); timer_ this-create_wall_timer( std::chrono::milliseconds(100), std::bind(SerialPublisher::timer_callback, this)); } private: void timer_callback() { if (serial_.isOpen()) { std::string data serial_.read(serial_.available()); if (!data.empty()) { auto message std_msgs::msg::String(); message.data data; publisher_-publish(message); RCLCPP_INFO(this-get_logger(), Publishing: %s, message.data.c_str()); } } } serial::Serial serial_; rclcpp::Publisherstd_msgs::msg::String::SharedPtr publisher_; rclcpp::TimerBase::SharedPtr timer_; }; int main(int argc, char** argv) { rclcpp::init(argc, argv); rclcpp::spin(std::make_sharedSerialPublisher()); rclcpp::shutdown(); return 0; }4.3 编译与运行修改CMakeLists.txt添加可执行文件add_executable(serial_publisher src/serial_publisher.cpp) ament_target_dependencies(serial_publisher rclcpp serial std_msgs) install(TARGETS serial_publisher DESTINATION lib/${PROJECT_NAME})编译并运行cd ~/ros2_serial_ws colcon build --packages-select serial_example source install/setup.bash ros2 run serial_example serial_publisher在另一个终端中查看发布的数据ros2 topic echo /serial_data5. 常见问题深度解决方案5.1 动态链接库错误编译成功后运行时出现error while loading shared libraries: libserial.so: cannot open shared object file这是Linux动态链接库路径问题。永久解决方案确认库文件位置通常在/usr/local/libsudo find / -name libserial.so创建conf文件sudo nano /etc/ld.so.conf.d/serial.conf添加库路径/usr/local/lib更新缓存sudo ldconfig5.2 端口占用与冲突当出现SerialException: [Error 16] device or resource busy时可能是其他程序正在使用该端口之前的实例没有正确关闭udev规则冲突排查步骤lsof /dev/ttyUSB0 ps aux | grep ros2 sudo kill -9 process_id5.3 波特率不匹配虽然代码中设置了波特率但实际通信乱码可能是设备端与主机端波特率不一致流控设置不匹配数据位/停止位配置错误建议的串口初始化参数检查清单波特率9600, 19200, 38400, 57600, 115200数据位通常8位停止位通常1位校验位无、奇校验、偶校验流控通常无在代码中添加完整参数设置serial_.setBytesize(serial::eightbits); serial_.setParity(serial::parity_none); serial_.setStopbits(serial::stopbits_one); serial_.setFlowcontrol(serial::flowcontrol_none);6. 高级应用自定义消息与双向通信6.1 创建自定义消息在包目录下创建msg文件夹并添加SerialMessage.msgbool led_status float32 temperature uint32 encoder_count修改CMakeLists.txt和package.xml支持消息生成然后编写订阅者节点监听单片机数据并发送控制命令。6.2 双向通信实现扩展之前的发布者节点添加订阅功能subscription_ this-create_subscriptionstd_msgs::msg::String( serial_command, 10, [this](const std_msgs::msg::String::SharedPtr msg) { if (serial_.isOpen()) { serial_.write(msg-data); RCLCPP_INFO(this-get_logger(), Sent command: %s, msg-data.c_str()); } });在Arduino端实现简单的echo功能void setup() { Serial.begin(115200); } void loop() { if (Serial.available()) { String received Serial.readStringUntil(\n); Serial.print(Echo: ); Serial.println(received); } }7. 性能优化与调试技巧7.1 提高通信效率使用二进制协议而非文本协议实现数据校验如CRC合理设置读取超时使用异步读写优化后的读取代码示例void async_read() { std::vectoruint8_t buffer(256); serial_.async_read(buffer, [this](const std::vectoruint8_t data, size_t len) { if (len 0) { process_data(data, len); } async_read(); // 继续下一次异步读取 }); }7.2 调试工具推荐ros2 topic hz /serial_data- 检查数据频率ros2 topic bw /serial_data- 监控带宽使用rqt_plot- 可视化数据变化putty或screen- 直接与串口交互对于复杂问题可以启用串口库的调试输出serial::Serial::setDebug(true);

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑