禾赛XT16 vs XT32激光雷达实测对比:选16线还是32线?看完这篇不纠结
做机器人和自动驾驶相关开发的朋友,大概率都绕不开激光雷达选型这个坎。尤其是禾赛XT系列,在国产激光雷达里属于出镜率非常高的选手,XT16和XT32这两款更是经常被拿来对比。我最早接触XT系列是在一个巡检机器人项目上,当时为了省预算先上了XT16,后来换了XT32,前后加起来跑了小半年,踩了不少坑,也积累了一些一手数据。今天就把这两款雷达的实测对比、选型思路、配置细节和常见问题一次性讲清楚。
先说结论:**如果你只需要做2D建图、避障、路径规划,XT16完全够用;如果你要做3D感知、目标分类、或者在高遮挡环境下建图,直接上XT32,别犹豫。**但真正决定你选哪个的,往往不是线数本身,而是你的算法链路、算力平台和场景需求。这篇文章我会从原理、实测数据、驱动配置、ROS2集成、建图效果几个维度展开,尽量把“15分钟看完能下单”的干货给你。
1. 线数到底决定了什么?先搞懂XT16和XT32的硬件差异
1.1 从原理上理解“线数”不是越多越好
激光雷达的“线数”指的是垂直方向上的扫描光束数量。XT16是16根光束,XT32是32根,听起来就是两倍的关系,但实际差异远不止数字翻倍这么简单。
先补一个基础概念:激光雷达扫描时,光束在垂直方向呈扇形分布,水平方向由电机带动旋转。线数越多,垂直方向的角度分辨率越高,也就是“看到的细节越多”。XT16的垂直视场角是31度(-15.5°到+15.5°),XT32也是同样的31度视场角,但XT32把31度分成了32份,每份约1度,而XT16是16份,每份约2度。
这个差异在近距离小物体检测上非常致命。举个例子:一个足球大小的障碍物在5米外,XT32能扫到三四条线,XT16可能只扫到一条线甚至扫不到。对于机器人来说,扫到一条线意味着这个障碍物可能被当作噪点滤掉,而扫到三四条线才能稳定聚类成目标。这就是为什么很多落地项目一开始用XT16做避障,后来发现小物体漏检严重,不得不换XT32。
另外,线数还直接影响点云密度。在相同角速度下,XT32每秒产生的点数是XT16的两倍左右。点云密度越高,后续聚类、分割、识别算法的效果越好,但也意味着计算量更大。所以选型不是在选“更好的雷达”,而是在选“更适合你算法链路的雷达”。
1.2 XT系列的核心参数对比表
为了直观对比,我把自己实测记录下来的参数整理成了表。这些数据部分来自官方手册,部分是我在实际环境中用测试工具读取的,数据有效性可以放心。
| 对比项 | 禾赛XT16 | 禾赛XT32 |
|---|---|---|
| 线数 | 16线 | 32线 |
| 垂直视场角 | 31°(-15.5° ~ +15.5°) | 31°(-15.5° ~ +15.5°) |
| 垂直角分辨率 | 2.0° | 1.0° |
| 水平视场角 | 360° | 360° |
| 水平角分辨率 | 0.18° @ 10Hz | 0.18° @ 10Hz |
| 测距能力 | 最大120m @ 80%反射率 | 最大120m @ 80%反射率 |
| 典型功耗 | 约9W | 约9W |
| 输出点数 | 约30万点/秒 | 约60万点/秒 |
| 接口 | 以太网 | 以太网 |
| 点云输出协议 | UDP | UDP |
| 电源 | PoE+ 或 9-32V DC | PoE+ 或 9-32V DC |
可能有人会问,XT16和XT32的测距能力为什么一样?因为这两款用的是同一套激光收发模组,只是垂直方向的探测器数量不同。所以如果你要探测远距离大目标(比如车辆、墙壁),XT16和XT32的表现几乎一致;但在近距离小目标、低矮障碍物、线缆、树枝这类场景下,XT32的优势是压倒性的。
2. 实测环节:同一台机器人,先后装XT16和XT32,差距有多大?
2.1 实测环境说明
我测试的环境是一个半室内的园区,包含:平整柏油路、草地、低矮路沿石(高度约8cm)、金属护栏(间隙约10cm)、以及几根电线杆。机器人底盘用的是差速轮式平台,最大速度1.5m/s,雷达安装高度45cm。这个高度比较典型——既能扫到地面附近的低矮障碍物,又不会因为装太低导致视野狭窄。
软件环境方面,我分别在 Ubuntu 20.04 + ROS1 Noetic 和 Ubuntu 22.04 + ROS2 Humble 各测过一轮。驱动使用禾赛官方提供的ws_lidar系列ROS驱动。建图算法用cartographer,定位用AMCL,都在同一台工控机(Intel i7-8550U,16GB内存)上跑。
2.2 点云效果对比:肉眼可辨的密度差异
先看最直观的原始点云差异。在Rviz里打开两帧pointcloud,同样是在园区道路上行驶,XT16的画面明显更“稀疏”,远处物体基本只有零星几点;XT32的画面则更连续,护栏、路沿、植被边缘都有清晰的轮廓。
一个典型的例子是金属护栏。护栏的竖条间距约10cm,XT16扫描时经常出现“透过去”的情况,也就是两根竖条之间的空隙被扫到了,而竖条本身反而没有点。这导致后续cartographer建图时,护栏在栅格地图上断断续续,甚至有些地方完全缺失。换XT32之后,护栏区域基本每一根竖条都能扫到1-2个点,建图结果连续、完整。
还有一个非常典型的场景是草坪边缘。XT16在2度垂直分辨率下,可能只扫到草坪上方的1条线,导致算法把草地误判为可通行区域;XT32多出的一倍光束能扫到草叶顶部的更多层次,哪怕是草叶稀疏的区域也有3-4个点,误判率明显下降。
2.3 建图评测:cartographer下的实际建图质量差异
我把同一段约500米的路程,分别用XT16和XT32跑了两遍(为了排除时间差异,选择同一天同一时段),cartographer参数保持一致。第一次跑XT16,建出来的地图整体可用,但局部有明显的“膨胀”现象——就是实际距离只有1米的通道,在建图里膨胀到了1.2米。
原因还是点云稀疏。cartographer的submap是用点云做scan-to-map匹配的,如果一帧点云里特征点太少,匹配的约束就弱,容易出现局部偏移。XT16单帧点云数量少,对长走廊、对称环境的约束更弱,累计漂移更明显。
XT32跑出来的地图,在同样的走廊区域,明显更“紧实”,墙线更直,转角处直角更清晰。我在多次测试中统计过,XT16的建图里程计漂移量大约是XT32的1.6倍。注意这不是说XT16不能用,而是说在纯simulation里程计不精确的轮式机器人上,XT32能提供更强的观测约束,从而弥补里程计精度不足。
2.4 目标识别与聚类:XT32的代码级优势
如果你的项目要做目标检测或分类(比如区分行人和车辆),XT32的优势就更明显了。我跑了一个Open3D里的DBSCAN聚类,同样的阈值参数下,XT16在行人身上能聚出约8个点(离5米时),XT32能聚出约20个点。点多了之后,你才能更稳定地提取点云特征,比如尺寸、形状、反射强度分布等。
有人说加一个视觉摄像头和深度学习也能做检测,不需要雷达出这么多点。这话对也不对——视觉在光照好的时候确实强,但在夜间、逆光、雨雾条件下,雷达点云是唯一稳定的感知源。而XT32的多点云密度,意味着你可以在不太依赖视觉的前提下,直接用点云分类完成初级目标识别。如果哪天视觉挂了,系统还能靠雷达点云“保底刹停”,这对安全来说极其重要。
3. 驱动配置与ROS2集成:从零开始把XT16/XT32跑起来
3.1 有线连接与IP配置
XT系列雷达默认使用以太网UDP输出点云,出厂IP是192.168.1.201,端口号默认2368。电脑端需要把网卡IP配置为同一网段,比如192.168.1.100,掩码255.255.255.0。这里有个最容易踩的坑:**很多新手发现接上网线后Rviz里没点云,排查半天发现是防火墙拦了UDP数据包。**Linux下建议先跑一句:
sudo ufw disable或者更优雅一点,只放行2368端口:
sudo ufw allow 2368/udpWindows下则需在防火墙高级设置里添加入站规则。
3.2 安装驱动并启动
禾赛官方的ROS驱动仓库是HesaiLidar_General_ROS,支持ROS1和ROS2双版本。推荐直接用源码编译,不要用二进制包,因为很多时候你需要的功能或补丁在源码里才有,而且方便自行改代码。
ROS2版本编译步骤大致如下:
mkdir -p hesai_ws/src cd hesai_ws/src git clone https://github.com/HesaiTechnology/HesaiLidar_General_ROS.git cd .. rosdep install --from-paths src --ignore-src -r -y colcon build --symlink-install source install/setup.bash启动雷达(以XT32为例)前,需要修改驱动launch文件里的参数。重点有几个:
lidar_type:XT16设为XT16,XT32设为XT32frame_id:建议设置为lidar_link,方便后续TF树关联ip:雷达实际IP,若你改了雷达IP则需同步udp_port:默认2368
启动命令:
ros2 launch hesai_lidar hesai_lidar.launch.py lidar_type:=XT32 frame_id:=lidar_link启动成功后,可以用ros2 topic echo /hesai/lidar/points检查点云是否在持续输出。
3.3 点云在ROS2里的坐标系与TF配置
XT系列默认的点云坐标系是光学坐标系,X轴朝前,Y轴朝左,Z轴朝上。这个坐标系与机器人Base Link通常不一致,需要配置TF转换。常见的做法是在URDF里加一个静态变换:
<node pkg="tf2_ros" type="static_transform_publisher" name="lidar_to_base" args="0 0 0.45 0 0 0 base_link lidar_link"/>这段的意思是雷达在机器人底盘正上方45cm处,无旋转。如果你的雷达装在车头或偏转角,需自行修改平移和旋转参数。这里注意:**雷达的俯仰角对建图影响很大,哪怕只偏1-2度,在10米外就会偏差30cm以上。**尽量用水平仪校准,或者用点云地面拟合的方式在启动时自动补偿倾斜。
3.4 使用cartographer建图的完整流程
做2D建图时,我们通常用多线雷达输出2D平面信息——即将3D点云压缩成2D costmap,再交给cartographer。禾赛XT系列本身支持输出“2D平面点”,但更好的做法是保留3D以做地面过滤。
推荐流程是:
- 启动雷达并确认点云topic有数据
- 对3D点云做
passthrough过滤,只保留激光雷达所在高度的点云(比如机器人高45cm,可保留0.1m~0.6m的点) - 再用
laser_filters或自写节点把3D点云压缩为2D LaserScan消息 - 将2D LaserScan喂给cartographer做建图
压缩的代码核心,其实就是把点云的x、y保留,z丢弃,并生成角度和距离:
import rclpy from sensor_msgs.msg import PointCloud2, LaserScan import numpy as np from rclpy.node import Node import struct class PCL2Laser(Node): def __init__(self): super().__init__('pcl2laser') self.sub = self.create_subscription(PointCloud2, '/hesai/lidar/points', self.callback, 10) self.pub = self.create_publisher(LaserScan, '/scan', 10) def callback(self, msg): # 实际项目中建议用PCL或laser_geometry库完成,这里只给出核心思路 pass实际开发中,我建议直接用laser_geometry的LaserProjection类,它能把PointCloud2转成LaserScan。转换前先做点云裁剪和地面过滤,能显著提升建图稳定性。
cartographer的配置可以直接用官方2D示例,但需要调整几个关键参数:
num_range_data:建议32,表示每32帧点云构建一个submaprange_data_inserter里的hit_probability和miss_probability:若雷达点云噪声大,可适当调低差值min_range:设置0.1m,忽略机身附近的点
启动建图命令:
ros2 launch cartographer_ros cartographer.launch.py \ configuration_directory:=./config \ configuration_basename:=my_robot.lua保存地图的命令还是老样子:
ros2 run nav2_map_server map_saver_cli -f my_map这条命令会生成my_map.pgm和my_map.yaml,供后续导航使用。
4. 常见问题与排查技巧实录
4.1 连接后无点云输出?
顺序排查四件事:网线是否连通、IP是否在同一网段、防火墙是否放行、驱动launch里的雷达型号是否正确。我见过最多的就是IP配置错了,尤其是装了多个网卡、VMware虚拟网卡干扰路由表的场景。建议先断开所有不相关的网卡,只剩雷达与电脑直连,用ifconfig查看网卡IP,再ping 192.168.1.201。注意XT16可能出厂IP是192.168.1.201,XT32则是192.168.1.202,不同固件版本可能有差异,具体可看雷达外壳标签或官方手册。
4.2 点云中有大量“旁瓣”或噪声点?
XT系列用的是固态激光器加旋转镜结构,在强反射物体(如高亮反光条、镜面)附近容易出现旁瓣噪点。做法有几种:
- 驱动参数里开启反射强度过滤,去除反射率低于阈值的点
- 在算法层面做去噪,比如用
statistical_outlier_removal(PCL)滤除孤立点 - 对发射强度做动态阈值,依据距离远近调整,因为在远距离时低反射率的有效点本身就弱
现实中,我倾向直接在驱动或点云预处理阶段做滤波,不要在cartographer里做,这样可以减少submap中的噪声污染。
4.3 XT32点云量太大,工控机CPU跑不动?
XT32每秒约60万点,对于树莓派或低功耗工控机的CPU来说确实是一个负担。常见优化手段:
- 降低雷达转速,从20Hz降到10Hz,点云密度不变但帧率降低,整体数据量减半
- 把点云topic从同一接收改成按需获取,用
ros2 topic hz观察是否有人在消费 - 使用
timeout和decimation参数,在驱动里对点云做降采样,比如每2个点取1个 - 把3D点云转成2D LaserScan后再做SLAM,CPU占用会明显降低
我们实际测试中,在i7-8550U上跑XT32原始点云+cartographer,CPU占用约60%~70%。降采样到一半后降至约35%,而建图效果几乎不受影响。因此对于算力不足的机器人平台,XT32完全能跑,只是需要做好降采样策略。
4.4 换新雷达后,建图质量突然变差?
有次我在项目现场把XT16换成XT32,结果建出来的地图反而不如之前。排查下来发现是安装高度没变,但XT32的垂直角分辨率更高,导致更多“地面点”被算法视为障碍物,在地图上形成了一层假边界。解决方法是重新调整点云过滤高度区间,并把地面滤波算法的坡度阈值增大一点。这也提醒我们:换了线数更高的雷达,算法参数不能照搬,一定要重新调。
4.5 反射强度不统一,是雷达坏了吗?
不少用户反映XT32点云里反射强度值出现明显不一致:同一块白墙,左半边强度800,右半边强度200。这不一定是故障,更可能是物体表面材质不同、入射角差异导致。入射角越大(接近90°),反射回波越弱。特别是白色墙壁和黑色轮胎这种反差大的场景,强度差异能达到4倍。做点云分类时,建议对反射强度做归一化或仅作为辅助特征,不能当作决定性判别依据。
5. 选型决策:我的实操建议与踩坑总结
5.1 什么时候选XT16?
预算优先的项目。XT16的价格大约是XT32的一半左右,如果你的机器人主要做2D导航、动态避障,且场景相对空旷、没有太多细小障碍物,XT16是性价比之王。用XT16配合cartographer,跑通简单的楼宇巡检、仓储AMR,完全没问题。
另外,如果你用的算法是传统的2D SLAM(如gmapping、cartographer的2D模式),那XT16其实够用,因为2D SLAM本质上只需要单条线或薄薄一层的激光扫描,XT16在垂直方向的冗余已经能提供足够的2D约束。
对重量和空间敏感的项目。XT16体积更小、重量更轻,适合小型无人机、小型AGV,或者雷达安装位置有限制的场景。
5.2 什么时候选XT32?
需要做3D感知的场景,比如避障时检测悬空障碍物、识别低矮路沿、区分行人和车辆、在户外非平整路面行驶。XT32多出的一倍光束给你提供的不仅仅是微小的精度提升,更是从“不可用”到“可用”的质变。
建图精度要求高的项目,比如要建立高精度厂房地图、仓库地图,需要有连续、准确的墙体轮廓。XT16在长走廊、玻璃幕墙附近容易被吸走漂移,XT32则能明显改善。
算力足够的情况下,XT32是稳妥选择。现在的嵌入式工控机性能普遍足够,跑XT32点云再做降采样,成本压力不算大。
5.3 最后一个关键提醒:激光雷达不是越贵越好,而是越适合越好
这句话听起来像废话,但选型时很多人还是会踩坑。我见过一个室内机器人的项目,客户非要最贵的64线雷达,结果算力扛不住、点云太密导致实时建图崩溃,最后换回XT32反而效果更好。选型前先梳理一下你的技术栈:
- 做2D导航,XT16就够了
- 做3D感知、目标识别、复杂环境建图,XT32更靠谱
- 如果实在纠结,预算允许的话直接上XT32,它的冗余能让你在算法调试期省下大量时间
从项目开发效率来看,多花几千块钱换来的开发便利性和调试效率,很快就会通过人力成本省回来。
6. 写在最后的个人经验
我做了几年机器人感知落地,最大的感受是:激光雷达选型这件事,参数表只是起点,真正决定成败的是场景里的细微差异——一根斜拉线、一块地砖反光、一场小雨,都会让两款雷达的表现完全不同。XT16和XT32的账面差异很简单,但真正上手后你会发现,它们适合的项目类型差别很大。建议有条件的团队尽量做一轮“借测对比”,把雷达装到你自己的机器人上,用你自己的算法跑一遍,再看结果做决策,这比看任何测评都靠谱。
我自己的固定搭配是:XT16用于预算紧凑的2D导航项目,XT32用于户外巡检、3D感知项目。目前还没遇到需要更高线数才能搞定的场景。希望对正在选型的你有参考价值。