ROS2实战:从零搭建IMU数据采集与可视化节点
1. 硬件准备与串口连接第一次接触IMU传感器时我选择了性价比极高的GY-95T模块。这个小巧的六轴传感器集成了加速度计和陀螺仪通过USB转串口芯片CH340与电脑通信。拆开包装后你会看到模块上有明显的VCC、GND、TX、RX标识用USB转TTL工具连接时要注意红线接VCC5V黑线接GND绿线接TX白线接RX——这里最容易出错的是TX/RX交叉连接记得传感器的TX要接转换器的RX。在Ubuntu 22.04上插入USB后打开终端输入lsusb如果看到QinHeng Electronics CH340 serial converter字样说明硬件识别成功。接着用ls /dev/ttyUSB*查看设备节点通常会是/dev/ttyUSB0。我遇到过设备节点不显示的情况这时候需要检查驱动是否加载lsmod | grep ch34如果输出空白需要安装CH340驱动sudo apt install build-essential git clone https://github.com/juliagoda/CH341SER.git cd CH341SER make sudo make load2. Python串口通信实战安装pyserial库时建议使用系统包管理器避免权限问题sudo apt install python3-serial创建serial_imu.py文件初始化串口时要注意几个关键参数import serial imu_port serial.Serial( port/dev/ttyUSB0, baudrate115200, # 必须与传感器设置一致 bytesizeserial.EIGHTBITS, parityserial.PARITY_NONE, stopbitsserial.STOPBITS_ONE, timeout0.1 # 超时设置影响数据读取流畅度 )我踩过的一个坑是波特率不匹配导致乱码。GY-95T默认115200但有些兼容模块可能是9600。如果看到类似䅀䅓䅂的乱码先用stty -F /dev/ttyUSB0 9600测试不同波特率。3. IMU数据协议解析技巧GY-95T采用Modbus-RTU协议数据帧格式如下A4 03 08 23 D2 └─┬┘ └┬┘ └┬┘ └─校验和 │ │ └──寄存器数量(0x2335个) │ └─────起始寄存器地址(0x08) └─────────功能码(0x03读寄存器)写解析代码时我推荐用状态机方式处理def parse_imu_data(raw_data): state HEADER for byte in raw_data: if state HEADER and byte 0xA4: state FUNC_CODE elif state FUNC_CODE and byte 0x03: state REG_ADDR # ...其他状态转移逻辑特别注意校验和计算我最初没验证校验和结果发现10%的数据包是错误的。正确的校验方法是累加所有字节后取低8位checksum sum(raw_data[:-1]) 0xFF if checksum ! raw_data[-1]: raise ValueError(Checksum error)4. ROS2消息封装核心要点创建ROS2包时别忘了添加依赖ros2 pkg create imu_pkg --build-type ament_python \ --dependencies rclpy sensor_msgs在package.xml中要明确声明exec_dependpython3-pyserial/exec_depend exec_dependimu_tools/exec_depend消息发布的关键在于正确填充Imu消息各字段。注意单位转换imu_msg Imu() imu_msg.header.stamp self.get_clock().now().to_msg() imu_msg.header.frame_id imu_link # 必须与TF树对应 # 加速度单位转为m/s² imu_msg.linear_acceleration.x accel_x * 9.8 # 角速度转为rad/s imu_msg.angular_velocity.x gyro_x * 3.1415926 / 180.0 # 四元数需归一化 norm sqrt(q0**2 q1**2 q2**2 q3**2) imu_msg.orientation.x q0 / norm # ...其他四元数分量5. Rviz2可视化实战技巧安装可视化工具包sudo apt install ros-humble-rviz2 ros-humble-imu-tools配置RViz2时重点注意添加Imu显示插件设置Fixed Frame为imu_link调整箭头尺寸0.1m比较合适开启Axes显示观察坐标系方向我建议创建配置保存文件imu.rviz下次直接加载rviz2 -d ~/imu.rviz常见问题排查看不到数据检查topic名称是否匹配箭头方向异常检查坐标系定义数据跳动严重尝试增加rviz的QoS深度6. 进阶优化与调试技巧提升数据质量的关键点时间同步为消息添加精确时间戳from builtin_interfaces.msg import Time stamp self.get_clock().now().to_msg() imu_msg.header.stamp.sec stamp.sec imu_msg.header.stamp.nanosec stamp.nanosec温度补偿GY-95T的陀螺仪受温度影响明显def compensate_gyro(raw_gyro, temp): return raw_gyro * (1 0.001*(temp - 25)) # 示例补偿公式数据滤波简单的移动平均滤波实现from collections import deque class MovingAverage: def __init__(self, window_size5): self.window deque(maxlenwindow_size) def filter(self, value): self.window.append(value) return sum(self.window)/len(self.window)7. 完整项目集成建议实际部署时建议采用launch文件统一管理launch node pkgimu_pkg execimu_node nameimu param nameport value/dev/ttyUSB0/ param namebaudrate value115200/ /node node pkgrviz2 execrviz2 args-d $(find-pkg-share imu_pkg)/imu.rviz/ /launch性能优化技巧使用异步串口读取避免阻塞开启ROS2的组件模式提升效率合理设置QoS策略qos_profile QoSProfile( depth10, reliabilityQoSReliabilityPolicy.BEST_EFFORT, durabilityQoSDurabilityPolicy.VOLATILE ) self.publisher_ self.create_publisher(Imu, imu_data, qos_profile)记得定期校准传感器我的经验是每周做一次水平静止校准放在平整表面运行def auto_calibrate(self, samples100): accel_z_sum 0 for _ in range(samples): accel_z_sum self.ACC_Z time.sleep(0.01) self.accel_offset accel_z_sum / samples - 9.8