
做机器人或者搞SLAM的朋友应该都有过这种经历想验证一个建图算法但找不到合适的传感器或者好不容易弄到一台激光雷达光是把驱动跑起来就折腾了好几天。我第一次接触思岚RPLIDAR C1的时候最大的感受就是“这玩意儿是真的便宜”但同时也在想——这么便宜的雷达到底能不能稳?地跑起来后来我用树莓派4B配合Ubuntu22.04把RPLIDAR C1从SDK编译、串口调试、数据可视化到简单环境扫描完整走了一遍整体体验比预期要省心不少。这篇文章就是我个人完整实操的记录适合手里有树莓派4B、想低成本入门激光雷达和ROS2导航的玩家。文章会讲清楚硬件怎么接线、驱动怎么编译、数据怎么看、扫描结果怎么存还会把我在实际过程中踩过的坑整理成排查手册。无论你是刚接触激光雷达的小白还是准备给机器人配雷达的进阶玩家这篇文章应该都能帮你少走不少弯路。1. 项目定位与整体方案设计1.1 为什么选择RPLIDAR C1做环境扫描RPLIDAR C1在思岚的产品线里定位很明确入门、低成本、低功耗专门给教育机器人、扫地机器人原型和个人DIY项目设计的。它最吸引我的一点是性价比高市面上几百块的雷达里C1的测距精度和抗环境光干扰能力做得比较均衡而且官方开源了全套SDK对开发者的支持很到位。另外C1的核心是激光三角测距方案工作频率大概在10Hz左右测距半径对于家用环境扫描完全够用。我实测在3到6米的范围内输出数据稳定性不错墙角和家具边缘能扫出清晰的轮廓。对于“简单环境扫描”这种需求来说C1的性能不会成为瓶颈真正的瓶颈反而在树莓派4B的性能和系统环境配置上。从功耗上看C1比A系列雷达省电得多直接用树莓派4B的USB口供电就能跑起来不需要额外接降压模块或独立电源。这对我来说非常重要因为我之前用某些雷达时需要外接5V电源不仅接线麻烦还会引入共地噪声导致数据抖动。C1用一根USB线搞定供电和通信硬件设计很干净。1.2 方案选型对比为什么必须配树莓派4BUbuntu22.04很多人会问不就有个雷达吗直接用电脑连不行吗当然行但如果你后续打算把环境扫描扩展成自主建图、路径规划那树莓派4B几乎是绕不开的硬件平台。我选择树莓派4B的原因有三点第一它性能足够跑Ubuntu22.04桌面版和ROS2 Humble虽然不能像PC那样全速跑重型算法但对于雷达数据采集、点云可视化和cartographer建图这种中轻量任务压力不大第二树莓派自带USB接口C1直接插上就能识别免去了串口转接的麻烦第三树莓派的GPIO和I2C接口方便以后扩展IMU、电机驱动为后续做完整机器人留下空间。至于Ubuntu22.04它和ROS2 Humble是官方推荐的搭配版本Humble LTS支持周期到2027年稳定性和资料丰富度都很好。如果装Ubuntu20.04虽然也能用但ROS2对应的是Foxy已经进入维护后期如果想用新版的Nav2或者cartographer的Humble分支还是建议直接上22.04。方案整体链路是这样的树莓派4B跑Ubuntu22.04USB连接RPLIDAR C1通过官方SDK读取激光原始数据再把数据发布为ROS2话题最终用rviz2或者Python脚本完成可视化与数据保存。这一套下来你既理解了激光雷达底层数据流也为后续做SLAM建图打好了基础。1.3 硬件清单与版本核对正式开始前先把所有需要的东西列清楚。注意树莓派4B建议选择4GB及以上内存版本2GB版本在跑rviz2的时候会明显吃力画面拖影严重。硬件/软件推荐型号/版本备注激光雷达思岚RPLIDAR C1自带USB转串口线即插即用主控板Raspberry Pi 4B 4GB/8GB跑Ubuntu22.04桌面版系统Ubuntu 22.04.3 LTS 64位树莓派ARM64版本ROS2版本Humble Hawksbill与22.04原生匹配雷达SDKrplidar_sdk v2.x官方开源可视化工具rviz2 / matplotlib两者选其一即可存储卡32GB以上TF卡Class1016GB太小系统会频繁报警电源5V3A USB-C电源必须足安否则雷达系统会掉电一个容易忽略的细节是TF卡的速度。Ubuntu22.04桌面版启动后系统读写压力不小如果TF卡写入速度太慢雷达数据保存和系统响应都会变卡。我第一张卡是杂牌Class4跑ROS2的时候CPU动不动就满载换了三星EVO Plus之后明显流畅。所以建议别在存储卡上省钱。2. 树莓派4B系统安装与基础环境准备2.1 Ubuntu22.04系统烧录与首次启动配置树莓派安装Ubuntu22.04最省事的方法是用Raspberry Pi Imager官方工具。这里要注意不要直接选“Ubuntu 22.04”通用映像而是下载树莓派的专用arm64版本官方叫“Ubuntu Server 22.04.x”或者“Ubuntu Desktop 22.04.x”。如果图方便推荐先装Server版本再手动安装桌面省掉很多不必要的预装软件。烧录流程很简单TF卡插电脑打开Raspberry Pi Imager选择镜像点击烧录。重点在于烧录完成后系统第一次启动会很慢因为要自动扩展分区。这时候不要急等两三分钟都是正常的。启动后默认用户名是ubuntu密码是ubuntu首次登录会强制要求改密码。系统起来后我习惯先做几件事启用SSH服务、更新软件源、设置静态IP。静态IP对远程调试雷达特别有用否则每次树莓派IP变了你都要重新接显示器看。sudo apt update sudo apt upgrade -y sudo apt install net-tools git vim -y如果你在安装Ubuntu后出现没有无线WiFi驱动的情况这一般是系统默认没有包含某些Broadcom固件。树莓派4B的WiFi模块在Ubuntu22.04下偶尔会遇到驱动未加载的问题可以尝试更新固件后再看。sudo apt install linux-firmware -y sudo reboot2.2 安装ROS2 Humble完整步骤ROS2的安装是整个环境准备里最容易出错的一步。官方文档其实写得已经很清楚但很多人会在“添加ROS2软件源”时卡住因为那个公钥链接在部分地区访问不稳定。我实操下来推荐用镜像源方式安装能省下不少时间。先添加ROS2 apt仓库的keysudo apt install software-properties-common curl -y sudo add-apt-repository universe sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg然后把软件源写进sources.list这里我把官方源替换成清华镜像源echo deb [signed-by/usr/share/keyrings/ros-archive-keyring.gpg] https://mirrors.tuna.tsinghua.edu.cn/ros2/ubuntu jammy main | sudo tee /etc/apt/sources.list.d/ros2.list /dev/null更新后安装桌面版ROS2 Humblesudo apt update sudo apt install ros-humble-desktop -y注意如果你只是想在命令行下跑雷达驱动装ros-humble-base就够了能省将近1GB的磁盘空间。但如果你后面想用rviz2看点云那就必须装桌面版。安装完成后把环境变量写进bashrc这样每次开终端都能直接使用ROS2命令echo source /opt/ros/humble/setup.bash ~/.bashrc source ~/.bashrc验证ROS2是否安装成功跑一下小海龟测试是最直观的ros2 run turtlesim turtlesim_node如果小海龟窗口弹出来了说明ROS2环境没问题。如果提示找不到包大概率是环境变量没生效重新打开终端或者重新source一下。2.3 基础编译工具与Python依赖准备RPLIDAR C1驱动编译需要cmake、g等基础工具同时Python环境建议装好pyserial、matplotlib、numpy方便后面直接读取雷达串口数据做可视化。sudo apt install cmake g python3-pip python3-serial python3-numpy python3-matplotlib -y pip3 install pyserial --upgrade这些库看起来简单但很关键。特别是pyserial如果版本过低可能无法正确解析C1的高波特率数据包导致读了半天全是乱码。建议安装后检查一下版本python3 -c import serial; print(serial.__version__)3. RPLIDAR C1驱动安装与数据读取实战3.1 双方案从官方SDK编译到ROS2节点运行思岚官方提供了两种使用方式一是直接用C SDK来读取数据适合想理解底层协议的朋友二是通过ROS2驱动包直接发布/scan话题适合专注上层应用的开发者。我个人的建议是两种都试一遍。先用SDK验证雷达硬件本身有没有问题再用ROS2驱动接入ROS生态这样一旦后面数据异常你能快速判断是硬件问题还是驱动配置问题排查效率会高很多。官方SDK的GitHub仓库是slamtec/rplidar_sdk下载后用cmake编译git clone https://github.com/Slamtec/rplidar_sdk.git cd rplidar_sdk mkdir build cd build cmake .. make编译完成后在output目录下会生成一个ultra_simple的可执行文件这个工具会直接输出雷达扫描到的距离和角度数据。运行它会自动检测USB端口如果检测不到就手动指定端口./ultra_simple /dev/ttyUSB0如果你能看到类似下面这样的持续输出恭喜你雷达硬件工作正常Theta: 0.00, Dist: 0.450, Quality: 79 Theta: 1.00, Dist: 0.452, Quality: 70 Theta: 2.00, Dist: 0.449, Quality: 783.2 USB串口权限与udev规则配置权限问题是新手最容易踩的坑。树莓派默认情况下普通用户是没有权限直接访问/dev/ttyUSB0端口的如果不配置udev规则运行SDK时会提示Permission denied。最简单的临时解决办法是sudo chmod 666 /dev/ttyUSB0但这个方法重启后会失效。正规做法是创建udev规则sudo vim /etc/udev/rules.d/99-rplidar.rules写入以下内容KERNELttyUSB*, ATTRS{idVendor}10c4, ATTRS{idProduct}ea60, MODE:0666, GROUP:dialout, SYMLINKrplidar这里面的idVendor和idProduct是通过lsusb查到的C1的USB转串口芯片一般显示为CP2102对应的就是10c4:ea60。设置好后执行sudo udevadm control --reload-rules sudo udevadm trigger配置完成后重启系统你会发现每次插上雷达系统都会自动创建/dev/rplidar软链接再也不用去猜到底是ttyUSB0还是ttyUSB1了。提示如果以后你同时插了多个USB串口设备建议也加上SYMLINK避免设备编号变化导致程序找不到雷达。3.3 用Python脚本直接读取原始数据如果你不想一开始就上ROS2只是想快速验证数据流写个Python脚本是最高效的方式。C1的串口默认波特率是256000数据包格式在SDK文档里有详细说明但直接解析协议有点繁琐。更简单的方式是直接利用SDK编译出的动态库但这对Python环境不太友好。这里我分享一个绕过协议解析的思路用pyserial读取串口原始字节流然后找帧头来切分数据包再解析出角度和距离。import serial import struct ser serial.Serial(/dev/ttyUSB0, 256000, timeout1) # 向雷达发送请求指令 (0xA5, 0x20 表示开始扫描) ser.write(b\xA5\x20) while True: data ser.read(5) if len(data) 5: continue # 解析数据包这里简化处理仅当帧头匹配时输出 if data[0] 0xA5 and data[1] 0x1F 0x01: angle_raw struct.unpack(H, data[2:4])[0] dist_raw struct.unpack(H, data[4:6])[0] angle angle_raw / 64.0 dist dist_raw / 4.0 print(fAngle: {angle:.2f} deg, Distance: {dist:.2f} mm)这个脚本虽然简陋但能跑通数据流理解整个过程之后再去看SDK源码你会有一种豁然开朗的感觉。实际项目中还是建议直接用官方SDK的接口因为官方库已经处理好了数据校验、丢帧重传等问题。3.4 ROS2驱动编译与话题发布进入ROS2环节思岚官方在GitHub上提供了rplidar_ros驱动包支持ROS2 Humble。不过这个包不是预编译的需要你自己建一个工作空间来编译。mkdir -p ~/rplidar_ws/src cd ~/rplidar_ws/src git clone https://github.com/Slamtec/rplidar_ros.git cd ~/rplidar_ws colcon build source install/setup.bash编译过程中如果提示缺少colcon或ament_cmake先安装sudo apt install python3-colcon-common-extensions ros-humble-ament-cmake -y启动雷达驱动这个launch文件会自动创建/scan话题ros2 launch rplidar_ros view_rplidar.launch.py如果一切正常终端会滚动输出日志rviz2窗口也会自动弹出显示雷达扫描到的环境轮廓。如果rviz2窗口没弹出来或者看不到点云别急这个问题我放在后面“常见问题排查”里详细说。4. 简单环境扫描实现从数据流到可视化地图4.1 激光雷达测距原理与数据理解既然标题是“环境扫描”那你至少要明白雷达返回的数据到底代表什么。RPLIDAR C1采用的是三角测距法原理很简单雷达内部的激光发射器发出一束红外激光打到障碍物表面后发生漫反射接收器上的线性CCD/CMOS阵列捕捉反射光斑的位置根据光斑偏移量和几何关系就能算出障碍物距离。这个原理决定了三角测距雷达的两个特点一是近距离精度高非常适合室内环境二是对物体表面颜色和材质比较敏感纯黑色物体反射率低容易丢点镜面或者透明玻璃基本测不到。所以实测时最好不要正对黑丝绒窗帘或大玻璃窗做扫描否则你会看到一圈数据里出现明显的空洞。数据格式方面每一帧扫描点包含三个关键信息角度、距离、信号质量。角度单位是0.015625度步进距离单位是0.25毫米步进信号质量则是0-255的整数数值越高说明该点的反射越稳定。数据字段含义单位分辨率Angle当前扫描角度0.015625 度Distance障碍物距离0.25 mmQuality信号强度/置信度0-255理解这个数据格式你就能解释为什么有人扫同一个房间出来的点云图差别很大——关键就看有没有做数据过滤。我习惯把质量值低于20的点直接丢掉因为这些点通常是镜面反射、边缘拖尾或者环境光干扰产生的噪声点。4.2 静态扫描单帧环境轮廓可视化雷达启动后它默认会持续旋转扫描每一圈生成一帧完整的环境轮廓。所谓静态扫描就是保持雷达不动取一帧或者几帧数据叠加画出当前环境在2D平面上的轮廓。用ROS2的话可以订阅/scan话题然后用Python写一个小节点来读取LaserScan消息简单处理之后存为CSV文件或者直接画图。LaserScan消息里的range数组就是每个角度的距离值非常直观。import rclpy from rclpy.node import Node from sensor_msgs.msg import LaserScan class ScanListener(Node): def __init__(self): super().__init__(scan_listener) self.sub self.create_subscription(LaserScan, /scan, self.callback, 10) def callback(self, msg): # angle_min ~ angle_max, 角度步长 angle_increment print(fTotal points: {len(msg.ranges)}) print(fAngle range: {msg.angle_min:.2f} ~ {msg.angle_max:.2f} rad) # 打印前方1米处的距离值 mid len(msg.ranges) // 2 print(fForward distance: {msg.ranges[mid]:.2f} m) rclpy.init() rclpy.spin(ScanListener())如果你更习惯用SDK原始数据也可以把之前的Python脚本扩展一下积累一定数量的点之后用matplotlib画出俯视图import matplotlib.pyplot as plt import math points_x [] points_y [] # 假设你已经从雷达读取到 angle_deg 和 dist_mm for angle_deg, dist_mm in raw_points: angle_rad math.radians(angle_deg) dist_m dist_mm / 1000.0 points_x.append(dist_m * math.cos(angle_rad)) points_y.append(dist_m * math.sin(angle_rad)) plt.figure(figsize(6, 6)) plt.scatter(points_x, points_y, cblue, s1) plt.axis(equal) plt.title(RPLIDAR C1 Static Scan) plt.show()运行之后你会看到雷达周围的环境轮廓被画成一个圆形的点云图墙面的直线轮廓清晰可见。我第一次跑出来的时候还挺有成就感的那种“传感器真的在感知环境”的直观反馈比看任何文档都有说服力。4.3 动态扫描多帧拼接与数据保存静态扫描只能反映雷达位姿固定时看到的环境而“环境扫描”更常见的使用场景是雷达放在小车上或者拿在手里缓慢移动通过多帧数据拼接扫描出整个房间的轮廓。这一步的难点不在于数据采集而在于数据对齐。如果只是简单地把所有帧的数据堆叠在一起你会发现图像是糊的因为雷达每帧的位姿并不完全相同。专业SLAM会通过里程计或者IMU计算位姿变化但我们做简单环境扫描可以用一个取巧的办法保持雷达缓慢匀速移动利用相邻帧之间的匹配来粗对齐。为了不让本篇文章过于复杂这里我给出一个最基础的方案固定雷达位置旋转雷达本体或者将雷达放在转盘上将每一圈扫描的起始角度对齐到同一个原点然后逐帧叠加。这个方法虽然不能用于真实移动场景但用来理解多帧拼接的概念足够了。数据保存方面建议直接存为numpy数组或者CSV后续用任何工具都能读。保存示例import numpy as np all_scans [] # 每一帧是 (N, 2) 的数组存储 x, y for frame in frame_list: all_scans.append(frame) np.save(room_scan.npy, np.array(all_scans))如果你确实想让雷达在移动中扫描那我的建议是至少加一个IMU模块或者参考后面讲的cartographer方案它会自动处理点云匹配和位姿估计比自己手动拼接靠谱得多。4.4 从点云到占位栅格地图的简单实现环境扫描做到最后很多人的目标就是一张可以被机器人导航直接使用的二维栅格地图。这需要把点云数据投影到2D平面然后对每个栅格判断“有障碍物”还是“无障碍物”。如果你不想安装复杂的SLAM库自己写一个极简的栅格图生成器其实也不难。思路如下建立一个尺寸已知的二维数组比如10米×10米的环境栅格分辨率为0.05米那就是200×200个栅格。遍历每个点计算出它落在哪个栅格里然后把这个栅格标记为占用。最后用matplotlib的imshow画出来就是最原始的占据栅格图。import matplotlib.pyplot as plt import numpy as np GRID_SIZE 200 grid_map np.zeros((GRID_SIZE, GRID_SIZE), dtypenp.uint8) # points: 所有扫描点的 (x, y)单位米 for x, y in points: if -5 x 5 and -5 y 5: grid_x int((x 5) / 0.05) grid_y int((y 5) / 0.05) grid_map[grid_y, grid_x] 1 plt.imshow(grid_map, cmapgray_r, originlower) plt.title(Occupancy Grid from RPLIDAR C1) plt.show()这个简易栅格图的问题很明显没有处理噪声也没有做膨胀处理所以边界不够平滑。但它足够帮你理解SLAM建图的基本逻辑后面再用cartographer这类完整方案时你会更清楚它在干什么。5. 常见问题排查与避坑实录5.1 雷达不转或灯不亮先查供电再查驱动RPLIDAR C1插上树莓派USB口之后如果雷达不转动首先摸一下雷达底部有没有温度。如果完全没温度基本可以判断是供电问题树莓派USB口可能进入了限流保护状态。解决办法是拔掉雷达用命令查看系统日志dmesg | grep usb如果看到了over-current或者device descriptor read/64, error -71之类的日志那就说明供电确实不足。这时候换一个单独带供电的USB HUB或者给树莓派使用5V3A足安电源问题基本就能解决。如果雷达嗡嗡响但数据出不来那大概率是驱动或者端口权限问题。这时可以先用lsusb确认设备是否被识别再用ls /dev/ttyUSB*确认端口存在。5.2 数据乱跳、距离突然变0多半是环境干扰运行雷达的时候距离数据偶尔变成0或者某个角度突然跳出一大堆杂乱点这通常是三种原因一是环境里有强反射面比如玻璃、镜子、金属抛光表面二是雷达距离物体太近小于最小测距范围三是激光雷达受强光干扰。处理办法是加数据过滤我在实际扫描时会把距离为0的点直接剔除同时把质量值低于某个阈值的点也过滤掉filtered [(a, d) for a, d in raw if d 0.15 and quality 20]0.15米是C1的最小有效测距小于这个距离的数值本身就是无效的。质量阈值的调节要看你室内的光照条件光线暗的时候可以把阈值调低到10光线强的时候可能需要调到40以上。5.3 rviz2里面看不到点云这是ROS2入门者问得最多的问题。雷达驱动明明启动了终端也有输出但rviz2界面里就是黑漆漆一片什么都没有。我排除了半天最后发现90%的情况是Fixed Frame的问题。rviz2默认的Fixed Frame是map但雷达驱动发布的点云的坐标系是laser坐标系名称对不上点云自然就不显示。解决办法是在rviz2左侧的Displays面板里点击Global Options把Fixed Frame改成laser。如果你的雷达驱动没有发布/tf变换那就必须手动指定Fixed Frame为laser。如果launch文件里启动了robot_state_publisher那最好把所有frame统一命名为laser或base_scan避免混淆。5.4 树莓派跑ROS2卡顿性能调优三件套树莓派4B跑Ubuntu22.04桌面版加ROS2内存占用确实不低。我刚开始跑rviz2的时候CPU经常飙到100%拖动窗口都卡。后来做了三个优化效果立竿见影。第一禁用系统自带的Gnome动画效果。在“设置-外观”里把动画关闭或者使用轻量级桌面如LXDE。第二给树莓派的GPU内存分多一点在/boot/firmware/config.txt里设置gpu_mem256。第三启动rviz2时降低点云显示频率把rviz2的刷新率改成5Hz肉眼基本察觉不到但CPU占用能下降一半。如果你只是做数据采集而不需要实时可视化更推荐直接在终端运行驱动把/scan话题录成rosbag之后放到电脑上回放分析这样树莓派压力会小很多。5.5 常见问题速查表症状可能原因解决方法雷达不转USB供电不足换带供电HUB检查电源适配器端口无权限udev规则未配置chmod 666 /dev/ttyUSB0或配置udev规则数据全是0雷达未开始扫描发送A5 20指令启动扫描数据点稀疏环境反射率低提高信号质量阈值下限改善环境照明rviz2无显示Fixed Frame不匹配修改为laserCPU满载可视化耗资源降低刷新率用rosbag离线处理6. 从环境扫描到SLAM建图的扩展之路一旦你理解了如何用RPLIDAR C1进行环境扫描下一步就很自然地想试试完整的SLAM建图。这里我强烈推荐ROS2 cartographer它和激光雷达的配合非常成熟尤其适合室内环境。Cartographer的核心思想是“前端扫描匹配后端图优化”它会自动处理点云匹配、位姿估计和回环检测最终输出一张干净的栅格地图。相比自己手动拼接多帧扫描cartographer的效果可以说是碾压级别的墙线笔直房间轮廓清晰。在树莓派4B上运行cartographer的步骤也不复杂。先安装依赖包sudo apt install ros-humble-cartographer ros-humble-cartographer-ros -y然后下载官方的cartographer_turtlebot示例配置修改雷达话题名称和坐标系让它默认订阅/scan话题。启动后缓慢移动雷达扫描整个房间按下保存地图的按键系统就会生成.pgm和.yaml两个文件。但要注意树莓派4B的性能跑cartographer时不能和PC比CPU通常会比较紧张。我建议扫描时不要开rviz2实时显示或者把显示窗口放到电脑上用远程桌面/SSH转发来看这样建图过程会流畅很多。从环境扫描升级到SLAM建图本质上就是从二维数据到姿态估计的跃迁。环境扫描只需要雷达一个传感器建图往往还需要里程计或IMU来提供运动估计。如果暂时没有IMUcartographer也可以纯靠雷达做scan-to-scan匹配只是转弯时容易丢失位置信息。我个人在实际操作中的体会是很多看起来高深的建图系统底层依赖的数据源其实就是RPLIDAR C1输出的那一个个微小角度和距离值。把环境扫描这一步吃透理解激光雷达到底在测什么、数据格式是什么、噪声从哪来后面玩SLAM、导航会顺手很多。最后再分享一个小技巧如果你把雷达放在桌面边缘让它悬空扫描对比桌面上方和下方两圈点云的差异你能直观看到雷达的盲区范围和垂直视场角对数据的影响。这种小实验不用写代码但对理解雷达物理特性特别有帮助。后续有空的话我打算写一篇RPLIDAR C1配合cartographer在树莓派4B上完整建图的配置记录这次先到这。