前阵子公司要做一套室内环境快速扫描的验证方案,我顺手把手头闲置的树莓派4B翻了出来,配合思岚的RPLIDAR C1激光雷达,在Ubuntu 22.04上从零开始搭了一套简单环境扫描系统。整个过程比我想象中顺利,但中间也踩了几个典型的坑,比如串口权限、USB供电不足、ROS 2驱动编译依赖这些。今天就把这套“树莓派4B + Ubuntu 22.04 + RPLIDAR C1”的实践过程完整记录下来,从硬件接线到系统配置,再到驱动安装、数据可视化和简单建图,全部手把手拆开讲,保证新手照着做也能跑起来。
这个项目适合谁?如果你是做机器人入门、AGV底盘调试、室内空间测量,或者单纯想在树莓派上玩一把激光雷达,这篇都非常合适。哪怕是第一次接触激光雷达,只要会基本的Linux命令,跟着步骤走,一晚上就能把点云数据在屏幕上刷出来。
1. 项目整体设计与硬件准备
1.1 RPLIDAR C1的核心参数与选型理由
先说为什么选RPLIDAR C1而不是A系列或其他品牌。C1是思岚科技在2023年推出来的入门级雷达,主打低成本、低功耗、易集成。它的测距半径是12米,采样频率标称8000次/秒,扫描频率在5Hz到15Hz之间可调,测距精度在1.5米内能做到正负1厘米左右。最关键的是它采用USB接口直连,不需要额外的串口转接板,这对树莓派用户来说简直太友好了。
对比一下A1M8,C1的体积更小、功耗更低,整体重量只有约68克,适合装在轻量化的小车上。虽然精度和采样率比不上A2/A3这种更高系列的雷达,但做环境扫描、简单建图完全够用。在这个项目里,我们需要的是快速拿到激光测距数据并可视化,而不是做高精度的工业测量,所以在入门阶段选C1是目前性价比很高的方案。
1.2 树莓派4B的环境准备与系统烧录
树莓派4B我手里是8GB内存版本,但其实这个项目内存占用不高,2GB版本也跑得动。系统我选了Ubuntu 22.04 LTS Server版,注意是Server版,不是Desktop版。为什么不用桌面版?因为这台树莓派大部分时间是无头运行,也就是通过SSH远程操作,桌面环境纯属浪费资源,还会拖慢编译速度。如果你买的是Desktop镜像,也可以,后面所有命令在桌面版里同样适用。
系统烧录用的是树莓派官方的Raspberry Pi Imager工具,选择Ubuntu 22.04 LTS时它会自动下载镜像并写入SD卡。这里有个细节:烧录完成后,如果你打算用SSH连接,需要在烧录时提前配置无线网络和SSH。在Imager中选择完系统后,点击右下角的齿轮图标,可以设置主机名、开启SSH、设置Wifi的SSID和密码。这一步非常关键,因为Ubuntu Server默认不安装桌面环境,没有公网连接只能通过网线直连树莓派,体验会很差。
1.3 硬件接线与C1雷达的安装要点
RPLIDAR C1的硬件安装很简单,包装盒里附带了一个USB转Type-C的线缆,雷达本体底部有四个螺丝孔,可以直接安装在亚克力板或者小车底盘上。接头是8针的PHR-8连接器,直接插到雷达底座的对应接口就行。接线其实没有太多可讲的,但有一个点必须提醒:C1的额定工作电流在300毫安左右,瞬时启动电流可能更高。
如果直接插在树莓派的USB口上,早期我遇到过一种情况:雷达启动瞬间拉低电压,导致树莓派USB口上其他设备掉线。解决方法是使用带有外部供电的USB HUB,把雷达单独插在HUB上,尽量避免和无线网卡、键盘接收器共用同一个USB口。另外还建议尽量用雷达自带的线缆,别用劣质USB线,供电差的线材会直接导致扫描数据抖动。
2. 环境扫描的原理与整体方案拆解
2.1 激光雷达测距的基本原理
这个项目核心是激光雷达测距,但你真的理解它怎么测得距离吗?RPLIDAR C1用的是三角测距原理,这也是大多数低成本2D雷达采用的技术方案。雷达内部的激光发射器会发射一束红外激光,照射到前方物体后产生漫反射,反射光经过接收透镜投射到摄像头感光芯片上。当物体距离变化时,反射光落在感光芯片上的位置也会发生变化,通过检测光斑的位置偏移,再利用几何三角关系就能算出物体到雷达的距离。
简单理解就是:它就像一个极坐标测量仪,每隔一定角度测一次距离,然后以雷达为圆心,把距离和角度组合成一个点。电机带动整个测距模块旋转一圈,就得到了360度范围内所有障碍物的分布点,这就是一次完整的扫描。C1在每个角度上还会输出信号质量值,这个值代表反射光强度,可以用来判断测量结果是否可靠。参考实现里面通常会把信号质量差的数据过滤掉,避免噪声点进入后续算法。
2.2 数据格式与坐标约定
理解C1输出的数据格式是后续开发的基础。每次扫描过程中,每个采样点主要包含三个关键数据:角度(单位为度)、距离(单位为毫米)、信号质量(百分比)。角度范围是0到360度,0度通常是雷达正前方的标记位置。在环境扫描应用里,这些点会以物体表面轮廓的形式呈现。
实际操作时会发现,C1输出的健康数据里距离有可能会出现零值,这个代表测距失败或者雷达在这个角度上没有检测到有效反射。处理时一般有两种策略:直接丢弃,或者做一次插值。对于环境扫描来说直接丢弃就够了,Cartographer这类建图算法本身对噪声点有一定的容忍度。
2.3 软件方案的选型:SDK直读还是ROS 2驱动
这是动手之前要想清楚的问题。如果只是为了把雷达接上,然后在电脑屏幕上看到一圈点,直接用思岚官方的rplidar_sdk就能搞定,SDK里自带的ultra_simple示例程序不需要安装ROS 2,一条命令编译完就能看到原始数据。这套方案上手最快,适合扫盲和单次测试。
但如果你后续还想做建图、导航或者和机器人其他传感器做融合,那就得走ROS 2路线。在Ubuntu 22.04上默认搭配的是ROS 2 Humble版本,思岚官方维护的sllidar_ros2驱动包可以直接拉下来编译使用。这个驱动里面已经包含了雷达启动节点,发布/scan话题,可视化直接用Rviz2就行。
两个方案并不冲突,我建议先跑通SDK,确认雷达硬件没问题,再去折腾ROS 2。一步一步来,排查问题的时候才不会混淆是硬件问题还是软件问题。
3. 完整实操:从零到可视化扫描
3.1 创建设备访问权限:串口权限与udev规则
无论你是跑SDK还是跑ROS 2驱动,第一步都是确保系统能访问雷达。C1通过USB虚拟出一个串口设备,默认设备名通常是/dev/ttyUSB0。但在Linux下,普通用户默认没有权限打开串口设备,如果你直接在非root账号下运行程序,会报出“Permission denied”之类的错误。
解决办法有两种,第一种最简单,把当前用户加入dialout组:
sudo usermod -a -G dialout $USER然后注销重新登录,或者重启树莓派,让组权限生效。第二种是创建udev规则,把串口设备的owner改成当前用户。这个方案更适合后续要反复插拔雷达、或者有多个用户需要访问的场景。在/etc/udev/rules.d/目录下新建一个规则文件,内容可以参考:
KERNEL=="ttyUSB*", MODE="0666"保存后重新加载规则:
sudo udevadm control --reload-rules sudo udevadm trigger再插上雷达,用下面的命令确认系统能识别设备:
lsusb ls -l /dev/ttyUSB0如果lsusb输出里能看到Silicon Labs或者CP210x相关的设备,说明USB转串口芯片被系统识别了,接下来就可以正常访问了。
3.2 编译并测试思岚官方SDK
确认串口权限没问题之后,先把官方SDK跑起来。思岚的rplidar_sdk在GitHub上开源,直接把仓库拉下来:
git clone https://github.com/Slamtec/rplidar_sdk.git cd rplidar_sdkSDK的编译方式是纯CMake,没有太多依赖,只需要系统里装好build-essential和cmake。在Ubuntu 22.04上如果没有装,先用apt装一下:
sudo apt update sudo apt install build-essential cmake然后编译:
cd rplidar_sdk cmake . make -j4编译完成后,编译产物在output/linux/Release/目录下,里面有一个ultra_simple的可执行文件。运行方式是指定串口设备路径:
./output/linux/Release/ultra_simple --channel --serial /dev/ttyUSB0如果一切正常,终端里会不断刷新输出的角度和距离数据。看到数据流不断滚动,说明雷达硬件和SDK工作正常。这一步我建议跑个一两分钟,顺便转转雷达或者朝不同方向放一下遮挡物,确认数据有实时变化。
如果这个环节就报错,大概率还是权限问题,先检查/dev/ttyUSB0是否可读,再检查雷达指示灯是否常亮。C1的绿色指示灯亮就代表供电正常。
3.3 安装ROS 2驱动:sllidar_ros2实战
SDK跑通之后,就可以上ROS 2了。在Ubuntu 22.04上我使用的是ROS 2 Humble。如果树莓派之前没有安装过ROS 2,按官方文档安装即可,这里列一个精简步骤:
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-ros-base然后在~/.bashrc里加上ROS 2的环境变量:
echo "source /opt/ros/humble/setup.bash" >> ~/.bashrc source ~/.bashrc接着创建我们的工作空间,拉取思岚ROS 2驱动源码:
mkdir -p ~/slamtec_ws/src cd ~/slamtec_ws/src git clone https://github.com/Slamtec/sllidar_ros2.git cd ~/slamtec_ws colcon build --symlink-install编译完成后装载环境:
source install/setup.bash启动雷达节点,注意默认设备名是/dev/ttyUSB0,如果你所在的设备名不同,需要先修改sllidar_ros2包里的launch文件,或者直接命令行指定参数:
ros2 launch sllidar_ros2 sllidar_launch.py serial_port:=/dev/ttyUSB0看到节点启动并且给出一些参数信息后,用以下命令验证话题是否正常输出:
ros2 topic list ros2 topic hz /scan如果/scan话题被持续发布,说明驱动正常工作。
3.4 Rviz2实时可视化:把数据变成看得见的点云
现在数据已经在ROS 2里流动了,但光看数字太抽象,直接上Rviz2可视化。由于树莓派桌面环境不一定装了Rviz2,最简单的做法是在同一台机器上安装:
sudo apt install ros-humble-rviz2启动命令:
ros2 run rviz2 rviz2打开Rviz2之后,左侧面板需要手动配置一下。把Fixed Frame从默认的map改成laser_frame,然后在左下角点击Add,选择By topic,找到/scan话题,添加LaserScan。显示出来的效果会是以雷达为中心的一圈点云,周围的墙壁、柱子、办公桌轮廓会清晰呈现出来。
初次连接时可能会遇到一个常见问题:Rviz2里看不到任何点,但/scan话题的hz明明是正常的。这种大多数情况是Fixed Frame和LaserScan的frame_id不匹配导致的。检查雷达驱动launch文件里的frame_id,我一般在launch里显式设为laser_frame,同时Rviz2里也改成laser_frame,问题就解决了。
可视化之后可以试着缓慢转动雷达或者推动雷达一端,观察点云跟随变化,这一步能直观感受到环境扫描的效果。
4. 进阶:用Cartographer把扫描数据变成地图
4.1 Cartographer在树莓派上的编译与安装
环境扫描的基础是看到点云,更进一步就是把这些点云拼成一张2D占用栅格地图。Cartographer是目前社区里效果好、适配度高的2D建图算法。虽然号称是百年一遇难编译之一,但在Ubuntu 22.04 + ROS 2 Humble上安装反而没那么折腾,因为官方把依赖分好了包。
先安装Cartographer的ROS 2相关依赖:
sudo apt install ros-humble-cartographer ros-humble-cartographer-ros如果你的Ubuntu 22.04源里没有包,就需要源码编译。源码编译需要额外安装一系列依赖:
sudo apt install libgoogle-glog-dev libceres-dev libcairo2-dev liblua5.3-dev libabsl-dev然后在工作空间里拉代码:
cd ~/slamtec_ws/src git clone https://github.com/ros2/cartographer.git -b ros2 git clone https://github.com/ros2/cartographer_ros.git -b ros2 cd ~/slamtec_ws rosdep install --from-paths src --ignore-src --rosdistro humble -y colcon build --symlink-install注意树莓派的CPU性能有限,编译时我加了-j2限制并发数,避免内存不足导致编译过程被杀掉。实测下来源码编译Cartographer在树莓派4B上大概需要30到40分钟,放那儿慢慢编就行。
4.2 配置launch文件并启动建图
Cartographer在ROS 2下的启动需要配置一个launch文件和一个Lua配置文件。Lua配置文件里面定义了激光雷达输入的话题名、坐标系、体素大小、扫描匹配参数这些。
我用的Lua配置核心参数如下:
include "map_builder.lua" include "trajectory_builder.lua" options = { map_builder = MAP_BUILDER, trajectory_builder = TRAJECTORY_BUILDER, map_frame = "map", tracking_frame = "base_link", published_frame = "odom", odom_frame = "odom", provide_odom_frame = true, use_odometry = false, num_laser_scans = 1, num_multi_echo_laser_scans = 0, num_subdivisions_per_laser_scan = 1, num_point_clouds = 0, lookup_transform_timeout_sec = 0.2, submap_publish_period_sec = 0.3, pose_publish_period_sec = 0.2, } return options在命令行里启动建图时,把雷达驱动、Cartographer节点和Rviz2一起拉起来。我这里通常是先启动雷达:
ros2 launch sllidar_ros2 sllidar_launch.py再启动Cartographer:
ros2 launch cartographer_ros cartographer.launch.py由于雷达没有IMU,也没有轮式里程计,Cartographer的纯激光建图在小范围环境里是可以工作的,但扫描匹配的鲁棒性会差一些。需要我手动推动雷达缓缓移动,不能急转或者快速平移,否则会丢定位导致地图分叉。
4.3 地图保存与转换
建图结束后,Cartographer会发布/submap_list和/map这两个话题。我推荐用Nav2的map_saver组件来保存地图。命令如下:
ros2 run nav2_map_server map_saver_cli -f ~/map/my_map这句命令会生成my_map.pgm和my_map.yaml两个文件。pgm是灰度图,白色代表空闲区域,黑色代表障碍物,灰色代表未知区域。yaml文件记录了地图的分辨率、原点、占用阈值这些元信息。
保存地图后,还需要为后续导航做一点优化。Cartographer默认输出的地图灰度阈值比较严格,直接用于Nav2导航时可能地图会有点膨胀感。可以在yaml文件里调整occupied_thresh和free_thresh的数值,或者用图像处理工具对pgm图做一次形态学腐蚀膨胀,效果会更干净一些。
4.4 扫描结果的质量评估与调优方向
建图完成后,怎么判断这次环境扫描的质量呢?最直观的方法是用occupancy grid的形式在Rviz2里打开/map话题,观察走廊和墙面的形状是否笔直、边缘是否有重影。我实测的经验是,如果环境中存在大量玻璃门、白墙、镜面等低反射率的物体,Cartographer的建图结果容易出现局部漂移。
这时候可以先看看雷达数据本身,如果在C1的数据流里这些区域的信号质量明显偏低,就不是建图算法的问题,而是激光雷达本身受反射率影响。也可以把雷达的扫描频率调低一些,降到5Hz,增加每帧的采样密度,对图的质量会有帮助。
调优方面还可以调整trajectory_builder_2d.lua里的一些关键参数,比如submaps的size、ceres_scan_matcher的旋转和平移权重。但说实话,在树莓派4B的性能约束下,把雷达固定牢固、匀速移动、避免在空洞房间里建图,带来的效果提升比调参数更明显。
5. 常见问题与排查实录
5.1 串口设备无法识别或/dev/ttyUSB0不出现
这个我遇到得最多。先确认雷达USB线插好了,然后执行dmesg,查看内核输出有没有相关错误。最常见的错误是供电不足导致USB设备反复断开,也就是内核日志里出现“device descriptor read/64, error -71”之类的记录。此时优先更换USB口、换一根短而粗的电源线,或者把雷达接到有源HUB上,基本能解决。
如果dmesg里完全没有任何提示,可能是雷达USB线内部断线,或者是Type-C插口接触不良。我用过一根第三方的USB线,就出现过这种问题,换回原装线立刻正常。
5.2 扫描数据出现断层或距离跳变异常
雷达在正常情况下扫描出的轮廓是连续、平滑的。如果出现某一区域距离值乱跳、甚至变为零值,我第一个怀疑的是目标表面反射率。黑色吸光物体,尤其是黑色绒毛材质,基本测不到有效回波;哑光深色墙面的效果也会差很多。
排除反射率后,再检查雷达前面的保护罩是否有灰尘或者指纹污渍。C1虽然自带保护罩,但时间长了上面还是容易沾灰,用无尘布擦干净以后数据质量会有明显改善。
供电也是导致跳变的元凶之一。当USB口电压不足时,雷达的电机转速会不稳定,导致扫描一周的时间不均匀,表现出来就是数据显示的角度和距离错位。这种情况配合ros2 topic hz来看,会发现/scan话题发布的频率也在波动的,很不稳定。
5.3 Rviz2接收不到数据或看不到点
先确认C1驱动节点起来没有,用ros2 node list查看节点是否存在,再用ros2 topic info /scan确认这个数据到底有没有在发。如果话题有数据但Rviz2里没有显示,排查顺序是:Fixed Frame是否和雷达frame_id一致、LaserScan话题是否添加成功、Color Scheme是不是选成Monochrome了。
还有一个容易被忽略的细节:ROS 2的DDS默认域ID是0,如果之前运行过其他ROS 2程序没有清理干净,或者同一网段下有多台机器在发布相同话题,可能会造成数据串扰。我习惯在启动节点时显式设置ROS_DOMAIN_ID,比如:
export ROS_DOMAIN_ID=42这样既能避免干扰,又方便排查。
5.4 Cartographer建图时地图漂移或出现分叉
纯激光雷达建图本来就没有绝对闭环能力,如果环境是个大空旷空间、中间又没什么特征,漂移几乎是必然的。实测在十几米长的走廊建图,走到尽头再转回起点时,地图出现明显的错位,这是正常现象。
缓解办法有几个:一是用尽量小的环境区域分多次建图,最后拼接;二是控制移动速度,让雷达相邻两帧的重叠率足够高;三是给雷达加装一个小高度的安装位,使扫描平面尽量平行于地面。只要扫描平面歪了,哪怕歪了不到两度,转一圈之后地图就会出现整体倾斜,这个在树莓派摄像头支架上装雷达时特别明显。
如果确实需要大范围高精度建图,建议增加一个IMU传感器,通过Cartographer的IMU数据输入来辅助位姿估计,效果会好很多。
结尾再聊几句
整套流程走下来,我自己最大的感受是:这个组合虽然不算强劲,但作为激光雷达入门学习平台非常合适。RPLIDAR C1的数据质量对得起它的价格,树莓派4B跑ROS 2虽然编译的时候有点熬人,但运行起来完全不卡。你不需要一开始就把SDK、ROS 2、Cartographer全上齐,完全可以先从ultra_simple那里看到不断刷新的原始数据,感受一下“激光扫描”到底是怎么回事,然后再逐步加功能。
最后分享一个小技巧:给雷达做环境扫描时,别让它固定在一个位置扫描,试试拿在手里缓慢平移,观察Rviz2里的点云如何平滑变化,这种感觉会直接帮你建立对雷达工作原理的直觉。下一步想折腾的话,可以考虑把SD卡换成SSD启动,再把Cartographer换成slam_toolbox对比一下建图效果,同样是很有意思的扩展方向。