☰
ROS智能车激光雷达建图与自主导航全链路调试指南
2026/10/31 8:16:30 网站建设 项目流程

简介:智能车 ABOT-M1-ATK 的配置与实操手册面向准备参加中国机器人及人工智能大赛、全球校园精英人工智能算法大赛巡航赛项的选手及指导教师,围绕 ROS 平台下的激光雷达建图、机器人导航、视觉识别与无人驾驶调试展开,帮助零基础使用者按序完成整车功能验证与赛前联调。资源包共 1 个 PDF 文件,体积约 2.3MB;单文件即覆盖安全注意事项(取放车体、激光雷达与相机模块保护、电源充电维护)、启动开机、远程桌面接入,以及建图、导航、射击、视觉、语音各模块的测试流程,并按 abot_vision、abot_voice、lidar_ws、robot_ws 等工作空间梳理功能包结构,给出 Gmapping、Hector、Cartographer 三种建图方式的启动指令与地图保存方法。目前已有 585 人学习,适合需要快速上手整车、逐步排查硬件与算法链路的参赛者对照实操。

1. 一台 ROS 智能车的开箱账:激光雷达、导航与视觉三条主线怎么串

把一台双轮差速智能车从航空箱里抬出来,接通 10 寸显示器,按下主控开关等五秒——这个动作我在某实验室的竞赛准备间里每月至少重复一次。ABOT-M1-ATK 是一台跑 ROS 的移动机器人平台,硬件上集成了激光雷达、USB 相机、麦克风与蓝牙音频链路,外加一个可装水弹的射击模块,底盘走两轮差速,主控运行 Ubuntu 与 ROS。它面向的任务很集中:激光雷达建图、自主导航巡航、视觉识别与语音交互,适合准备机器人及人工智能类竞赛的学生队伍,也适合刚把 ROS 从仿真迁移到实车、想找一台能跑通全链路的开发者。下面按实际调试顺序,从开箱上电、远程桌面、雷达建图一路写到导航巡航和外设联调,脚本、参数、踩坑点逐条拆开。

2. 上电与远程桌面:首次进场先过网络、显示、主控三道关

2.1 开箱之后先做电气与机械检查

很多新手拿到车第一件事是找电源键,我一般会先绕车看一圈。取机器时双手放在前后轮胎之间的底盘位置抬起,不要拎激光雷达那一段,雷达内部有旋转部件,单手托拽最容易让扫描出现莫名的扇形缺口。雷达上方不要压任何东西,包括调试时随手放的笔记本和工具包,遮挡物在 scan 数据里会变成一圈固定距离的假障碍,建图时表现为地图边缘糊成一团。

供电这块有两个硬约束:电量显示剩一格就必须充电,充电器用 DC12.6V/2.0A,背部红灯表示正在充、绿灯表示充满;如果半个月以上不用,也要补一次电,锂电池长期亏电后再唤醒,电压跌到保护板阈值以下就直接罢工。开机顺序是固定的:先接 HDMI 线和 10 寸显示器供电,再按车身电源开关等 5 秒,最后按主控制器开关等系统启动完成。关机反过来,先关主控再断总电源,不要在主控还在读写磁盘时直接切电,文件系统损坏过一次就得重刷镜像,这是实打实的血泪经验。

还有几条是写在手册里但容易被忽略的:不要往机身倒任何液体;操作时手指和螺丝刀远离相机模组;不系统学习之前不要私自拆机。射击模块的水弹要提前用矿泉水泡 8 小时以上,泡不到位的水弹偏小,进弹仓后容易卡在拨轮里。

2.2 向日葵远程桌面:网络通了再谈调试

车载屏幕只有 10 寸,趴在车前敲键盘的姿势撑不过半小时,所以第二步是把远程桌面配通。流程不复杂,但顺序不能乱:先在车端连上 WiFi,手机热点也行,注意热点频段选 2.4G,部分 5G 热点在车端网卡上扫描不到;然后在调试电脑上安装向日葵远程助手;接着在车端桌面左下角图标里打开向日葵,记下识别码和验证码;最后在电脑端输入这两串数字发起连接。

每台设备的识别码都不一样,以车端界面显示的为准,不要抄别人机器上的。连接成功后先别急着跑脚本,把车端分辨率调低一档、关闭桌面动画,远程操作时的鼠标延迟会明显下降。如果连上了但画面卡成幻灯片,优先查热点上行带宽和车端 CPU 占用,而不是反复重装软件。

提示:远程桌面依赖车端网络,调试前把手机热点设成常开,避免息屏后热点断开导致连接中断。

2.3 四个工作空间与启动脚本的关系

车端文件系统里和机器人相关的目录有四个,搞清楚它们的分工,后面找 launch 文件就不用满硬盘翻。abot_vision放视觉相关功能,abot_voice放语音,lidar_ws放激光与导航,robot_ws放底盘驱动、各模块驱动和综合 demo,自主巡航的入口也在这里。每个工作空间的src下按功能拆成若干功能包,launch 文件就在包内。

# 逐个列出四个工作空间 src 下的功能包,确认驱动和算法包都在位 for ws in ~/abot_vision ~/abot_voice ~/lidar_ws ~/robot_ws; do echo "===== $ws =====" ls "$ws/src" done

这段循环里ws是临时变量,依次取四个工作空间路径;ls "$ws/src"输出每个空间下的包名。正常情况应该能看到abot_bringup、abot_slam、robot_slam、usb_cam、robot_voice这类目录,缺哪个,后面启动对应功能时就会报package not found。

环境变量也要提前 source 好,否则roslaunch找不到包:

# 把四个工作空间的环境变量按依赖顺序载入 source ~/robot_ws/devel/setup.bash source ~/lidar_ws/devel/setup.bash source ~/abot_vision/devel/setup.bash source ~/abot_voice/devel/setup.bash

setup.bash的作用是把该工作空间的devel/lib、share路径追加到ROS_PACKAGE_PATH,并设置LD_LIBRARY_PATH。顺序上先载底盘所在的robot_ws,再叠加上层功能包,避免同名包被低优先级路径覆盖。可以在~/.bashrc末尾追加同样几行,省得每次开终端手动敲。

3. 激光雷达建图:gmapping、hector、cartographer 该在什么场景切换

3.1 gmapping 的启动链路与里程计依赖

gmapping 是这套车上手最快的建图方案,它依赖轮式里程计提供初始位姿,再用激光扫描匹配修正。一键脚本在车端桌面:

# 启动 gmapping 建图脚本,内部会拉起底盘驱动、雷达、gmapping 与可视化 ./1-gmapping.sh

脚本本质上是把roscore、robot_with_imu.launch、gmapping.launch、view_mapping.launch和键盘遥控节点串在一个终端窗口组里。想确认它到底启动了什么,直接看脚本内容:

# 查看一键脚本启动的节点清单 cat ~/1-gmapping.sh

脚本会开多个终端标签,切到第五个终端用键盘控制。按键映射要记清:U、I、O分别对应左前、正前、右前,J、L对应左转、右转,M、<、>对应左后、正后、右后;打开大写锁定后,U与O变成左前平移和右前平移,<与>变成左后、右后平移。建图时不要原地高速旋转,角速度过大扫描匹配会跟不上,地图墙体出现重影。速度控制在 0.2 m/s 左右、角速度 0.5 rad/s 以内,走一圈让雷达扫到足够的回环。

地图保存不关终端,另开一个终端执行:

# 保存当前建图结果,输出 pgm 与 yaml 两个文件 roslaunch abot_slam save_map.launch

save_map.launch内部调用map_saver,默认把地图写到指定目录,文件名可在 launch 里改。保存路径会在终端打印,记下来,导航阶段要加载同一份地图。

3.2 hector 与 cartographer 的适用边界

hector 不需要轮式里程计,纯靠激光扫描匹配估计位姿,优点是接线少、对轮子打滑不敏感,缺点是缺少回环检测,走大场地时累计误差回不来,地图首尾接不上。启动方式:

# 启动 hector 建图与可视化 roslaunch abot_slam hector_mapping.launch roslaunch abot_slam view_mapping.launch

它的参数里map_resolution默认 0.05 米,map_size决定地图覆盖范围,场地超过默认尺寸时要把map_size调大,否则车走出边界后地图直接截断。hector 更适合小面积、结构特征明显的房间,走廊太长或者四周全是白墙时,扫描匹配会退化。

cartographer 走的是另一条路:它融合激光与 IMU,带子图与回环检测,适合大场地和长走廊,代价是启动依赖多、参数敏感。启动顺序是先起底盘与 IMU,再起建图:

# 先启动底盘、IMU 与雷达驱动 roslaunch abot_bringup robot_with_imu.launch # 再启动 cartographer 建图 roslaunch abot_slam cartographer.launch

robot_with_imu.launch负责发布/odom、/imu/data、/scan和 TF;cartographer.launch订阅这些话题做子图构建。IMU 没起来时 cartographer 会一直等imu话题,终端刷imu data not ready,这时候不要怀疑雷达,先rostopic hz /imu/data看有没有数据。三种方案都跑完后,同样用save_map.launch保存,不要再重启建图节点。

3.3 地图保存后的质量验证

地图存出来是两个文件:.pgm是栅格图像,.yaml是元信息。打开 yaml 核对几个字段:

# 查看地图元信息,确认分辨率与原点坐标 cat ~/map.yaml

重点看三项:resolution一般是 0.05,表示每个像素代表 5 厘米;origin是地图左下角在全局坐标系里的位姿[x, y, yaw],导航时的初始位姿要跟它对上;occupied_thresh和free_thresh决定灰度值怎么判成障碍与空闲,默认 0.65 和 0.196,墙体偏灰时不要乱改,先查雷达安装角度有没有偏。

验证地图能不能被正常加载:

# 用 map_server 单独加载地图,检查是否有报错 rosrun map_server map_server ~/map.yaml

终端打印Loading map from ...且没有Failed to load就说明文件完整。再开rviz,添加 Map 显示,把 Fixed Frame 设成map,看地图是否闭合、墙体是否连续。如果地图上出现一圈圈同心圆状的噪点,多半是建图时有人站在雷达旁边跟着走,人腿被扫成了移动障碍。

4. 导航与巡航:从 2D Nav Goal 到代价地图的六个参数

4.1 导航栈的启动顺序与 TF 链路

导航必须在地图建好之后跑,而且车的初始位置要跟建图时的起点一致,否则amcl定位从第一步就偏。启动分三条命令,顺序不能颠倒:

# 1. 底盘、IMU、雷达驱动 roslaunch abot_bringup robot_with_imu.launch # 2. 导航栈:map_server、amcl、move_base roslaunch robot_slam navigation.launch # 3. 可视化界面 roslaunch robot_slam view_nav.launch

navigation.launch里通常已经包含地图加载,如果它引用的是默认地图路径,而你的地图存在别处,要在 launch 里改map_file参数,或者启动时用map:=/home/xxx/map.yaml覆盖。TF 链路是map → odom → base_footprint → base_link → laser,任何一环断了,move_base都不会规划。

检查 TF 的常用手段:

# 查看 map 到 base_footprint 的实时变换 rosrun tf tf_echo map base_footprint # 生成 TF 树状图,排查断链 rosrun tf view_frames

tf_echo持续输出平移和旋转量,车静止时数值应该基本不跳;如果map到odom这一段的变换一直在飘,说明amcl没收敛,把车放回建图起点重新给初始位姿。view_frames生成frames.pdf,看哪个坐标系没有父节点,一眼就能定位。

4.2 代价地图参数怎么调

move_base的避障表现主要由两张代价地图决定:全局代价地图负责整张地图上的路径搜索,局部代价地图负责眼前几米的实时避障。参数在costmap_common_params.yaml、global_costmap_params.yaml、local_costmap_params.yaml三个文件里,常改的就六个:

参数典型值作用调大后的效果
robot_radius0.18机器人外接圆半径路径更保守,窄门过不去
inflation_radius0.35障碍膨胀半径离墙更远,通道利用率下降
cost_scaling_factor3.0膨胀代价衰减速度值越小,远离障碍的意愿越强
transform_tolerance0.5TF 容忍延迟太大会导致定位滞后
planner_frequency1.0全局规划频率太高徒增 CPU 占用
controller_frequency10.0局部控制频率太低转弯会画龙
# local_costmap_params.yaml 片段:局部代价地图的更新与膨胀设置 local_costmap: update_frequency: 5.0 publish_frequency: 2.0 global_frame: odom robot_base_frame: base_footprint rolling_window: true width: 3.0 height: 3.0 resolution: 0.05 plugins: - {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"} - {name: inflation_layer, type: "costmap_2d::InflationLayer"}

rolling_window: true表示局部地图跟着车滚动,width和height是滚动窗口的物理尺寸,设 3 米够用了;resolution保持 0.05 跟全局地图一致,避免两层地图分辨率不同带来的插值误差。obstacle_layer订阅/scan把激光点写进代价地图,inflation_layer按inflation_radius向外扩散代价。场地窄的时候先把inflation_radius降到 0.25 试,一次改一个参数,改完重启导航栈,别热改。

4.3 2D Nav Goal 实操与失败诊断

在rviz里点工具栏的2D Nav Goal,再在地图空白处按住鼠标拖出方向箭头,松开后move_base开始规划。成功时能看到一条绿色全局路径和一条红色局部路径,车沿着路径走。常见的三种失败:

第一种,点了没反应。看终端有没有Failed to get robot pose,有就是amcl没收到初始位姿,用rviz里的2D Pose Estimate在地图上把车的位置和朝向标出来。

第二种,路径规划出来了但车不动。查cmd_vel有没有输出:rostopic echo /cmd_vel,没数据说明move_base卡在规划阶段;有数据但轮子不转,查底盘驱动是否订阅了同一话题名,话题名不一致是 remap 没配。

第三种,车走到一半停住或者原地转圈。多半是局部代价地图里出现了动态障碍,或者inflation_radius把通道堵死。把rviz的局部代价地图显示打开,看车周围红色膨胀区是不是盖住了通道中心,是就调小膨胀半径。

5. 视觉、语音与射击联调:外设链路的五个排查点

5.1 USB 相机与图像话题

视觉测试前先确认设备节点:ls /dev/video*,正常应该看到video0之类的条目。启动相机:

# 启动 USB 相机测试 launch roslaunch usb_cam usb_cam_test.launch # 另开终端用 rqt 查看图像 rosrun rqt_image_view rqt_image_view

usb_cam_test.launch会发布/usb_cam/image_raw,在rqt_image_view左上角下拉框里选这个话题就能看到画面。画面全绿或者花屏,先换 USB 口,再查pixel_format参数,常见值是yuyv和mjpeg,带宽不够时用mjpeg降负载。相机模组不要用手摸镜头,指纹在逆光下就是一层雾。

5.2 语音 TTS 与蓝牙音频路由

语音链路分两段:ROS 节点把文本转成音频,系统把音频送到蓝牙耳机。先连蓝牙:

# 启动核心与语音订阅节点 roscore rosrun robot_voice tts_subscribe # 发布一条文本,触发语音播报 rostopic pub /voiceWords std_msgs/String "data: '1234'"

tts_subscribe订阅/voiceWords,收到字符串后调用 TTS 引擎合成并播放。终端能看到回调日志,但耳机没声音,八成是系统默认输出还挂在 HDMI 或者板载声卡上。用pavucontrol把输出设备切到蓝牙耳机,或者在车端右上角设置里选音频输出。蓝牙耳机先配对再启动节点,顺序反了节点会绑到旧设备上。

5.3 射击模块的供电与水弹

射击模块有独立电源开关,测试前先打开。水弹必须用矿泉水泡足 8 小时,泡好的弹径接近 7.3 毫米,偏小会卡弹,偏大会在枪管里碎。启动驱动与发射:

# 启动射击模块驱动 roslaunch abot_bringup shoot.launch # 发布空字符串触发一次发射 rostopic pub /shoot std_msgs/String "data: ''"

/shoot话题每收到一条消息触发一次拨轮动作。测试时枪口朝空地,不要对着人和显示器。连续发射之间留间隔,拨轮电机过热会停转,等几十秒再试。

5.4 外设链路的五个排查点

现象一:rqt_image_view里没有任何话题。原因:相机节点没起来,或者 launch 里设备名写的是/dev/video1而实际枚举成video0。解决:ls /dev/video*核对编号,改 launch 里的video_device参数,重新启动。

现象二:语音节点日志正常,耳机静音。原因:系统音频输出没切到蓝牙,或者蓝牙耳机进入省电休眠。解决:pavucontrol里把输出设备锁定到蓝牙,播放前先放一段本地音乐唤醒耳机。

现象三:建图时地图墙体出现重影。原因:建图速度过快,或者雷达被人或杂物遮挡。解决:降速到 0.2 m/s 以下,清空雷达上方物品,重新从起点走一圈。

现象四:导航启动后move_base报TF timeout。原因:底盘驱动没起来,odom到base_footprint的变换缺失;或者系统时间跳变导致 TF 缓存失效。解决:确认robot_with_imu.launch已启动,rosrun tf tf_echo odom base_footprint有输出;车端没有外网时用date检查时间是否一致。

现象五:射击模块上电后无动作。原因:水弹泡发时间不足卡在弹仓,或者射击模块电源开关没开。解决:换一批泡足 8 小时的水弹,检查模块开关和供电线,单发测试时用rostopic pub只发一条消息。

6. 用 rosbag 把建图过程变成可回放的验证副本

建图这件事最怕“当时看着挺好,回头复现不了”。我现在的习惯是每次建图前先开录包,把雷达、TF、里程计一起录下来,场地调完参数再回放对比,比在现场反复推车省事得多。

# 录制建图关键话题,-O 指定输出文件名 rosbag record /scan /tf /tf_static /odom -O mapping_test.bag

/scan是雷达数据,/tf与/tf_static是坐标变换,/odom是轮式里程计。四个话题缺一个,回放时建图节点就会报错。录完后用rosbag info mapping_test.bag看时长和消息数,确认没有中途断录。

回放时加--clock让节点使用 bag 内时间:

# 回放录制的数据,配合 use_sim_time 参数做离线建图 rosbag play mapping_test.bag --clock

如果要做离线建图对比,先在 launch 里把use_sim_time设为true,再启动 gmapping,最后回放。这样同一段数据可以反复喂给不同参数组合,调inflation_radius或者扫描匹配参数时不用重新推车。我一般会录三段:小房间、长走廊、有动态障碍的开放场地,分别验证定位收敛、回环闭合和避障反应。

还有一个小技巧:建图前在场地四角贴几段胶带做地面标记,回放时对照地图上的墙角位置,能快速判断地图是整体缩放还是局部漂移。地图原点对不上时,导航阶段的初始位姿怎么标都别扭,这一步偷懒,后面要花几倍时间找补。

从那以后我每次上车调试前都强制走一遍“录包—建图—回放对比”的流程,参数改动有据可查,换场地也能快速定位是环境问题还是配置问题。希望帮到你。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询