ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

从零搭智能小车(4):传感器集成与 SLAM 初探

从零搭智能小车(4):传感器集成与 SLAM 初探 这个月过的有点充实先是在闲鱼买了二手的RPLIDAR A3和JY901S IMU然后等货期间把古月居的ROS入门21讲看了一下以前也没接触过这个关注的公众号Datewhale正好推了个AI夏令营本来想报智能体项目因为限定是在校学生我报名的时候已经满了只能报了个SKILL项目边学边练两头忙活就把写文章记录这事给忘了明天返校了今天补一下时间长了怕想不起来了。折腾了两周底盘终于不再乱飘了。之前把rpm_per_mps从 184 修正到 176 之后1 米直线测试的误差缩到了 2cm 以内虽然还是开环积分但至少 RViz 里的轨迹和实际车头能对上号。这一阶段的目标是把手头这两样东西——RPLIDAR A3 和 JY901S IMU——真正接到系统里让车从盲跑变成有感知再试着跑通 gmapping输出第一张地图。一、先搞定 TF 树不然后面全是乱的之前底盘节点chassis_driver.py只发布了odom → base_link的 TF雷达和 IMU 装上去之后ROS 的坐标系链是断的。没做这一步就去开 SLAM点云会直接飘在原地或者根本对不上车体。我的安装方式雷达用铝型材支架架在车头正上方离地约 15cmIMU 用海绵垫固定在底盘几何中心X 轴朝前、Y 轴朝左、Z 轴朝上。海绵减震是必须的直接拧在碳纤维板上电机的振动会把加速度计的数据彻底污染。先用static_transform_publisher把两个静态 TF 挂上# base_link 到 laserrosrun tf static_transform_publisher0.1800.15000base_link laser100# base_link 到 imurosrun tf static_transform_publisher000.08000base_link imu100这里有个细节RPLIDAR A3 的官方 ROS 包rplidar_ros默认发布的 frame_id 是laserJY901S 的wit_ros_imu包默认是imu_link我为了统一把 IMU 的改了一下不然 TF 树会分叉。建议大家在 launch 文件里用remap或者改驱动参数不要像我一样先手动发 static_tf 试错半小时。二、RPLIDAR A3知道了为什么叫点云雷达驱动直接git clone官方包编译没什么坑。启动节点roslaunch rplidar_ros rplidar_a3.launch第一次看 RViz 里刷出 360° 点云的时候确实有点激动。A3 的扫描频率最高能到 10Hz我先用 115200 波特率跑后续如果做高速避障再切 256000。室内环境下 5m 以内的障碍物轮廓很清晰但黑色吸光物体和玻璃还是会有漏扫这个属于硬件物理限制后面写测试用例的时候得专门记一笔。这里有个小经验A3 的 USB 转接板带独立 5V 供电口我直接拿了一根 USB 转 DC 5.5×2.1mm 的线接到 多路电源 的 5V 输出上这样不需要占用 PC 的 USB 口供电转接板工作稳定很多。短线 独立供电是跑雷达的基本礼仪。三、JY901S IMU零偏比想象中难搞维特智能的 JY901S 接的是 STM32 的 UART2PA2/PA3但我没走 STM32 转发而是直接拉了一根 TTL 转 USB 线接 PC用wit_ros_imu包解析。原因是 STM32 上已经没有多余的串口中断资源做数据透传而且 IMU 的帧率 50~100Hz走底盘节点转发容易丢包。接线注意 TX/RX 交叉VCC 接 5V 或者 3.3V 都行JY901S 是宽压的。驱动跑起来之后先看/imu话题的linear_acceleration和angular_velocity。静态放置时Z 轴加速度应该在 9.8 左右XY 接近 0。但我第一次看数据X 轴有 0.3m/s² 的零偏Y 轴也有 0.15 左右。查了半天发现是海绵垫太薄舵机齿轮的振动传上来了。换了一块 5mm 厚的减震棉之后零偏降到 0.05 以内能接受。磁力计部分更头疼。室内环境铁磁干扰多航向角yaw会缓慢漂移。我现在的做法是IMU 只用来提供高频的角速度和加速度航向还是主要依赖雷达的 scan-to-scan 匹配来修正。后续如果做室外测试可能得上扩展卡尔曼滤波EKF做融合但现阶段robot_pose_ekf包先不急着开先把单传感器跑稳。四、gmapping第一张地图TF 齐了、传感器数据流通了就可以上 SLAM。我选的是 gmapping因为 ROS Noetic 支持成熟参数调好理解对 1:10 小车这种低速平台够用了。launch 文件核心配置nodepkggmappingtypeslam_gmappingnameslam_gmappingparamnamedeltavalue0.05/paramnamexminvalue-5.0/paramnamexmaxvalue5.0/paramnameyminvalue-5.0/paramnameymaxvalue5.0/paramnamemaxUrangevalue4.0/paramnamelinearUpdatevalue0.2/paramnameangularUpdatevalue0.1//nodedelta是地图分辨率0.05m 对一个轴距 255mm 的小车来说够细了。maxUrange设成 4 米是因为室内走廊最宽也就 3 米A3 的有效测距 5~6 米留点余量。我用teleop_twist_keyboard控制着车来回走速度压得很低大概 0.3m/s。阿克曼车不能原地转所以转弯必须带前进速度这一点在建图时反而成了优势——雷达始终有平移分量scan matching 比差速车原地打转要稳定。地图保存rosrun map_server map_saver-flab_map生成的lab_map.pgm能看到墙体轮廓但拐角处有些模糊这是因为我的里程计还是开环的虽然rpm_per_mps标过但轮胎打滑和地面不平还是会造成累积误差。下一步必须把 STM32 的编码器反馈接进chassis_driver.py把开环改成闭环地图质量才能上去。五、rosbag 与测试用例既然定位是测试验证方向光跑通不够得留下可复现的数据。这个阶段我养成了两个习惯1. 每次测试先录 bagrosbag record-Otest_$(date%Y%m%d_%H%M%S).bag /cmd_vel /odom /scan /imu /tf /tf_static命名带时间戳方便回溯。录完之后用rosbag info看消息数量和时间跨度确认没有丢话题。回放的时候注意--clock参数不然 TF 的时间戳对不上。2. 输出第一批测试用例我按等价类划分和边界值分析写了 10 条基础用例覆盖底盘、雷达、IMU 三个模块。举几个例子用例编号测试项输入/操作预期结果优先级TC-001底盘直线精度指令 0.5m/s持续 2s实际位移 1.0m ± 5cmP0TC-002舵机中位保护发送角度 0°底盘节点限幅到 60°不异常P0TC-003雷达帧率静止状态统计/scan频率稳定在 10Hz ± 0.5P1TC-004IMU 零偏静置 30s采集加速度XYZ 合模 9.8 ± 0.2P1TC-005急停响应运行中发送0x15急停帧电机 PWM 归零200ms 内停车P0TC-006地图闭合沿走廊走回起点gmapping 终点与起点重合误差 10cmP2写用例的时候发现一个问题阿克曼车的最小转弯半径左右不对称左 1.3m / 右 1.3m这在设计路径覆盖测试时必须考虑。我专门加了一条 TC-007验证左向和右向的转弯半径差异是否在机械标定范围内。六、阶段总结与下一步到这一步小车的软件架构已经变成teleop_twist_keyboard ──/cmd_vel──► chassis_driver.py ──0xAA──► STM32 │ ┌─────────────────────┼─────────────────────┐ ▼ ▼ ▼ /odom /scan /imu │ │ │ └─────────────────────┼─────────────────────┘ ▼ gmapping │ ▼ map_serverTF 树完整了传感器数据流打通了gmapping 能出图也建立了基础的测试文档规范。但问题还很明显里程计是开环的轮胎打滑和地面材质变化会让 SLAM 地图扭曲必须上编码器闭环。IMU 的航向漂移还没解决后续需要用 EKF 把 IMU 和雷达做融合。测试用例目前只有 10 条偏功能验证缺少异常测试比如串口突然断开、雷达数据丢包、电池低压保护。下一阶段P2 收尾 P3 起步的重点是编码器反馈接入、EKF 多传感器融合、以及把测试用例扩充到 30 条以上覆盖边界和异常场景。另外CAN 总线的学习也该排上日程了毕竟企业里没人用 TTL 串口做整车通信。当然这些都要等十月一放假的时候看看有没有时间还准备搞个二手的深度相机。附录本阶段参考与工具ROS Noetic Ubuntu 20.04rplidar_ros驱动包wit_ros_imu驱动包维特智能 GitHubgmappingmap_serverteleop_twist_keyboard阿克曼适配版自研chassis_driver.pyPython pyserial rospy标定工具卷尺 手机秒表 RViz低成本高精度
返回列表