1. Fast-LIVO2对时间同步的底层要求
1.1 Fast-LIVO2的时间戳链路:到底哪里会出问题
Fast-LIVO2是港大MaRS实验室FAST-LIVO系列的第二代开源框架,核心是把激光雷达、IMU、视觉相机做紧耦合的里程计与建图系统。相比第一代,它支持多激光雷达、多相机同时输入,前端用直接法做体素特征提取,后端用迭代误差状态卡尔曼滤波(IESKF)做状态估计。传感器越多,对时间一致性的要求就越苛刻,因为多路数据要进同一个优化框架,时间戳如果各自为政,残差计算就是错的。
这套系统里,时间戳的角色非常具体:
- 雷达点云帧有帧起始时间,帧内每个点还有一个相对于帧起始的
offset_time,单位一般是纳秒。 - 相机图像帧在驱动回调里被标记一个时间戳,代表曝光时刻(实际上取决于驱动实现,可能是曝光开始、结束或读出时刻)。
- IMU数据由硬件采样后打上时间戳,频率通常在200Hz以上。
这三个传感器的时间戳必须落在同一个时间坐标系里,否则状态估计器在“用雷达帧传播状态、用图像帧更新观测”时会直接算错。你可能会想:几毫秒的偏差真的有那么严重吗?有。做一次快速甩镜头运动,图像上同一个特征点在3毫秒内能移动好几个像素,激光点云里的边缘也会跟着飘。时间不同步的后果不是“精度下降一点”,而是初始化失败、地图重影、轨迹漂移,甚至整个系统直接发散。
1.2 软同步和硬同步的差别:为什么差几毫秒就不行
所谓软同步,就是靠软件在数据到达时打时间戳,或者事后用时间戳做插值和匹配。这种方式实现简单,几乎所有驱动都是这么干的,但问题在于时间戳的精度受CPU调度、网卡缓冲、USB控制器排队、操作系统负载影响。你无法知道相机曝光的那一刻到底发生在哪个系统时间点,因为驱动回调拿到图像时,曝光已经结束很久了。
硬同步的思路完全不同:用一根硬件信号线,把相机曝光时刻直接和雷达扫描时刻“钉”在同一个时钟源上。信号沿一到,相机立刻曝光,雷达的时间基准也由同样的脉冲校准。这样得到的传感器时间戳是物理事件发生时刻,而不是软件处理的时刻,偏差可以控制在微秒甚至亚微秒级别。
Fast-LIVO2这种视觉-惯性-激光融合系统,如果想在室内、隧道、快速运动等场景下稳定工作,硬同步几乎是躲不开的。软同步在低速、小视角变化场景下勉强够用,但一旦车辆或手持设备运动加快,软同步带来的时间偏差就会直接映射为几何残差,严重影响精度。这也是为什么很多团队在Fast-LIVO2、FAST-LIO、LVI-SAM这类框架上,都会额外做硬同步改造。
2. 同步方案选型:谁当主时钟、谁当从设备
2.1 三种可落地的同步架构,先别急着买设备
在做海康工业相机与Livox雷达的时间戳硬同步之前,先想清楚整体架构。我从工程落地的角度,把常见方案归纳为三种,各有各的适用场景。
架构A:外部脉冲源同时触发相机和雷达。用一个信号发生器或单片机产生固定频率的脉冲(比如10Hz或20Hz),分两路输出,一路接到海康相机的外触发输入,另一路接到Livox雷达的同步输入。这种方案最直接,相机和雷达的采样时刻都由同一个信号沿决定,时间偏差本身就很小。前提是你的Livox型号支持外部同步输入,并且能接受这个频率的触发信号。
架构B:雷达作为主时钟,输出同步脉冲触发相机。让Livox工作在主模式下,利用它的同步输出接口产生脉冲,去触发海康相机。这种方案的好处是雷达扫描周期和相机曝光完全绑定,每一帧雷达数据对应一次相机触发,数据流高度一致。但注意,不是所有Livox型号都开放了同步输出功能,能用的一般是带同步接口的型号。选型时务必确认固件和硬件版本支持。
架构C:用GPS/PPS做绝对时间基准,雷达做PPS同步,相机用同源脉冲触发。这种方案在室外移动平台很常见:GPS模块输出1Hz的PPS秒脉冲和GPRMC UTC时间,Livox接收PPS和GPRMC完成绝对时钟校准;同时把PPS通过分频电路变成10Hz或20Hz脉冲去触发海康相机。Livox的时间戳因此是GPS绝对时间,相机曝光时刻由同一授时源的衍生脉冲触发,两者的时间漂移在统计上被约束在一个极小范围内。
我在实际项目中默认优先推荐架构C。原因很简单:Livox对PPS同步的支持是最成熟的,海康相机的外触发输入是标准功能,不需要定制硬件,最多加一个分频小板。架构A对雷达外部触发频率的要求较高,很多雷达不支持任意频率外部触发。架构B则受限于雷达型号的同步输出能力。架构C的容错性最好,即便某个脉冲丢失,下一次PPS也会把时间拉回,不会产生累计漂移。
2.2 为什么优先选“PPS校准雷达+同源触发相机”这条路
很多新手第一次听到硬同步,以为要买昂贵的同步机箱或授时板卡。其实对于Fast-LIVO2这种系统,一条PPS信号线和一根触发线就能解决大部分问题。
Livox雷达的时间同步机制比较统一:支持PPS(秒脉冲)同步,部分型号还支持PTP(IEEE 1588)和GPRMC时间信息输入。PPS的作用是校准雷达内部时钟的秒边界,GPRMC提供UTC绝对时间,两者配合后,雷达输出点云的时间戳就是可靠的绝对时间。雷达被校准后,帧内每个点的offset_time也都有了明确的物理含义。
海康工业相机则通过外部触发输入线接收脉冲信号,在信号沿到来时开始曝光。曝光开始的时刻,就是硬同步要捕捉的那个时间点。MVS SDK在回调帧信息里会给一个设备时间戳,这个设备时间戳和Livox的绝对时间没有直接换算关系,但因为触发信号来自同一个授时源,所以相机每次曝光在物理时间轴上和Livox的时间戳天然对齐。软件上只需要做一个“触发沿对应到Livox时间戳”的映射,就能把两个传感器拉进同一个坐标系。
这样设计还有一个好处:相机帧率和雷达帧率解耦。你不需要让相机帧率等于雷达扫描频率,只要保证相机触发脉冲和雷达时间基准来自同一个授时源即可。Fast-LIVO2在状态更新时会用时间戳搜索最近的图像帧和雷达帧,物理上对齐后,软匹配的误差也降到了最低。
3. 海康工业相机外触发配置实操
3.1 用MVS把相机从自由运行切到外部触发
海康工业相机的配置我建议先在MVS客户端里调通,再落实到代码。MVS是海康的官方机器视觉软件,支持图形界面操作和SDK二次开发,配置参数是所见即所得。
打开MVS,连上相机后,进入相机参数树。首先要找到“触发模式”,默认是Off,也就是自由运行模式。把它改成On,相机就不再自己按帧率出图,而是等待外部触发信号。
然后设置触发源。海康相机的触发源一般有Line0、Line1等,不同型号的线路数量不一样,根据说明书选择你实际接线的那一路。选定之后,再选择触发激活方式:上升沿还是下降沿。这个必须和你的信号发生器/分频电路的输出极性保持一致,电气上正逻辑就选上升沿,负逻辑就选下降沿。
关键参数整理如下:
| 参数 | 推荐设置 | 说明 |
|---|---|---|
| TriggerMode | On | 开启外部触发,关闭自由运行 |
| TriggerSource | Line0(按实际接线) | 选择触发信号输入线 |
| TriggerActivation | RisingEdge / FallingEdge | 按信号极性选择,常用上升沿 |
| ExposureTime | 200~1000 us,按场景调 | 固定曝光,不要用自动曝光 |
| AcquisitionFrameRateEnable | Off 或按需 | 外部触发模式优先设Off |
| LineSelector | Line0 | 把对应线路配置为输入 |
| LineMode | Input | 确认该线路是输入方向 |
这里有一个容易忽略的坑:改触发模式、触发源、触发沿的顺序。一定要先确认线路方向是输入,再开触发模式。如果先开了触发模式,再把线路方向从输出改成输入,有些固件版本会直接报错或者配置不生效,卡你半天。
3.2 接线与电气参数,最容易踩坑的环节
海康工业相机的外触发输入一般是光耦隔离输入,电气上分正负极。信号源的一端接入触发输入正端,另一端接GND。这里有个很容易出问题的地方:信号发生器或者单片机输出的电平范围,以及共地。
光耦输入通常需要一个驱动电流才会导通,不同型号的要求不太一样,常见的是5V~24V的直流信号。如果你的信号源是3.3V的MCU引脚,可能驱动电流不够,相机收不到有效的触发信号。这时候不能直接插上去就完事,需要加一个三极管或MOSFET驱动电路,或者用带推挽输出的信号发生器。我见过不少人在这里翻车,示波器量信号有波形,但相机就是不触发,原因就是电平不够。
共地问题更是经典。信号发生器和相机必须参考同一个地,如果两边电源隔离,触发信号就会漂浮,导致随机丢触发。最简单的检查方法是:把信号发生器的GND和相机的GND(也就是相机电源的地)用导线连起来,再用示波器看触发引脚上的电平,确保在低电平和高电平之间干净切换。
3.3 从帧信息里拿到曝光时间戳,并换算曝光中心
海康MVS SDK在图像回调里会返回一个帧信息结构体,里面包含设备时间戳。这个时间戳是相机内部时钟的计数,不代表绝对时间,但在同一个相机上具有单调递增的性质。硬同步系统里,我们借助它来判断“哪一帧对应哪一次触发”,再和Livox点云时间戳做关联。
伪代码如下:
// 回调函数中获取帧信息 MV_FRAME_OUT_INFO_EX stFrameInfo = {0}; // ... 取流后填充 stFrameInfo ... // 获取设备时间戳 uint64_t nDevTimestamp = stFrameInfo.nDevTimeStamp; // 获取曝光时间(单位微秒) float exposureTimeUs = GetNodeValue<float>("ExposureTime"); // 曝光中心时刻 = 触发时刻 + 曝光时间 / 2 // 注意:实际时间基准需要映射到系统时间,这里只演示补偿思路 uint64_t exposureCenterTimestamp = nDevTimestamp + static_cast<uint64_t>(exposureTimeUs * 1000 / 2);曝光时间越长,曝光中心修正越重要。如果曝光时间是2000微秒,不修正就有1毫秒的误差,这一毫秒在快速运动场景下已经足够让投影点偏移好几个像素。我建议在软件链路里始终输出曝光中心对应的时间戳,而不是原始帧时间戳。
另一个注意点是MVS的设备时间戳单位是纳秒还是微秒,不同SDK版本有差异。拿到手先打印几帧,看一下数值的量级,确认单位后再做换算。
4. Livox雷达的同步配置与时间戳校验
4.1 在Livox设备端开启PPS同步
Livox雷达的同步配置通常在Livox Viewer或者Livox SDK的参数里完成。以Livox Viewer为例,连接设备后,在设备信息页能看到同步状态。需要设置的同步模式是PPS同步。
开启PPS同步后,雷达会等待外部PPS信号和GPRMC时间信息。如果只接PPS不接GPRMC,雷达也能锁定秒脉冲,但绝对时间会有偏移,因为缺少UTC时间基准。所以在室外场景,最好把GPS模块的PPS和GPRMC都接到设备上;如果是室内测试,至少要让雷达锁定PPS,保证内部时钟的连续性。
SDK方式配置时,设置的主要参数是同步模式:0代表自由运行,1代表PPS同步,2代表PTP同步。选择PPS模式后,雷达驱动会输出点云的同时,在点云头信息里携带经过校准的时间戳。
有个细节值得提:Livox的点云帧头时间戳默认是多少?在使用livox_ros_driver2时,点云消息的header.stamp是驱动发布时间,不一定等于雷达内部校准时间。所以判断硬同步是否生效,不能只看ROS消息头,要看雷达设备内的时间同步状态,以及点云数据里的offset_time是否连续正常。
4.2 如何验证雷达时间戳是真的被校准了
验证PPS同步是否生效,最直接的手段是在Livox Viewer里看同步状态标识。状态正常后,可以做一个简单实验:给雷达一个固定频率的脉冲,打印雷达点云帧的时间间隔,正常情况下应该是触发频率的整数倍,且各个间隔的抖动在微秒量级。
另一个方法是在ROS里订阅点云话题,用rostopic echo查看帧头时间戳和点的offset_time,观察连续帧时间戳间隔是否稳定。如果间隔忽大忽小,或者和预期值偏差超过几毫秒,说明PPS信号质量有问题或同步没有真正锁定。
我自己在测试时发现一个现象:在室内没有GPS信号的环境下,单靠PPS信号,Livox能保持相对时间连续,但绝对时间基准是未知的。如果你需要把雷达时间和相机时间严格对齐到GPS/UTC时间轴,GPRMC必不可少。如果只是设备之间的相对对齐,不接GPRMC关系也不大,关键是确保雷达内部时钟不乱跳。
4.3 Livox同步接口连接时的硬件注意事项
Livox同步接口的电气特性与海康相机不同。PPS信号一般要求是TTL或RS422电平,具体看型号说明书。接线前务必确认引脚定义,不要把PPS信号和电源线接反。接反的后果轻则同步失效,重则损坏雷达同步接口。
在搭建测试环境时,建议先用示波器检查PPS信号的电压、脉宽和上升沿质量。PPS信号虽然只有1Hz,但对沿的陡峭度是有要求的,信号上升沿太缓会导致雷达内部时间捕获不准。如果信号源输出的边沿不够陡,可以在中间加一个施密特触发器整形。
还有一个共地问题,和相机侧一样重要。GPS模块、雷达、相机、工控机,所有设备的地必须连在一起,否则信号上的地弹噪声会随机扰乱边沿判断。我在一次现场排查中,发现相机偶尔丢帧、雷达时间偶尔跳变,最后定位到是两个电源适配器没有共地,换成一个多路输出的工业电源后问题立刻消失。这类小问题,往往比算法更让人头疼。
5. 时间戳对齐与Fast-LIVO2运行验证
5.1 把相机时间戳和雷达时间戳统一到同一基准
硬同步完成之后,软件层面还要做一步关键工作:把相机的触发时刻对应到雷达的时间坐标系里。因为海康的设备时间戳是相机内部时钟,Livox的时间戳是雷达校准后的时钟,两者数值上没有直接换算关系,但物理上它们都被同一个授时源约束。
实现上有两种思路。第一种是把相机的触发时刻记录到系统时间:在PPS脉冲或触发脉冲输出的同时,在工控机上记录对应的系统单调时钟。这样每一次相机触发都可以打上一个系统时间戳,Livox的GPRMC同步后也能换算到系统时间,两个传感器就统一了。第二种思路是直接用ROS的时间同步机制,以雷达时间戳为主轴,寻找时间上最近的图像帧。硬同步做好后,最近邻搜索的误差很小,不需要复杂的插值滤波。
Fast-LIVO2对图像和雷达时间戳的处理本质上就是第二种思路。它不要求图像帧和雷达帧精确到微秒,但要求时间偏差足够小,使得状态估计在传播过程中不会引入额外漂移。硬同步保证了这个“足够小”的物理基础。
5.2 在Fast-LIVO2里启动并观察同步效果
启动Fast-LIVO2前,需要把相机标定内参、畸变系数、雷达到IMU的外参、相机到IMU的外参,以及话题名都配置好。这里默认你已经完成标定,只讨论时间同步相关的验证。
启动后,在RViz里观察两个东西:一是地图点云的颜色贴合度,二是运动过程中的重影情况。如果时间同步差,地图边缘会明显发虚,或者颜色错位到物体轮廓之外。硬同步正常的情况下,颜色贴合是严丝合缝的,尤其在快速平移或转动时,这种差异会放大得特别明显。
我还用一个方法验证同步精度:拍一张打印的棋盘格,放在雷达和相机都能看到的位置,人手持设备快速摆动,观察棋盘格边缘在点云地图里的锐利度。如果边缘锐利,说明同步好;如果边缘出现拖影,说明要么时间没对齐,要么曝光时间太长引入运动模糊。
另一个指标是Fast-LIVO2的初始化是否顺利。时间戳偏差大的系统经常在初始化时失败,因为状态估计器无法把视觉观测和雷达观测关联起来。如果你发现系统经常在启动几秒后发散、轨迹飞掉,优先怀疑时间同步,而不是外参标定错误。时间戳问题比外参问题更容易排查,只要把几个话题的时间戳打印出来对比一下即可。
5.3 用rosbag记录数据时要注意时间戳的保存
在调试Fast-LIVO2的过程中,rosbag是必不可少的工具。但要特别注意:rosbag保存的是消息里的时间戳,如果驱动在发布消息时打的时间戳不是硬件触发时刻,而是接收时刻,那么bag回放的时间同步就会受影响。
我在实际项目中习惯在驱动层就把时间戳修正为曝光中心时刻,然后再发布到ROS。这样做的好处是bag里保存的时间戳直接反映物理事件,回放时不需要额外修正。如果想用系统时间做二次验证,可以同时保存一份监控数据,包括PPS脉冲对应的系统时间、相机触发对应的系统时间,用于事后对齐检查。
6. 常见问题与排查技巧实录
6.1 相机触发异常速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| 相机完全不触发 | 触发模式未打开 | 确认TriggerMode为On,触发源选择正确 |
| 相机随机丢帧 | 光耦驱动电流不足 | 用示波器量触发信号,确认电平范围 |
| 相机频繁误触发 | 触发信号上有毛刺 | 加施密特触发器整形,检查共地 |
| 触发沿不对导致相位偏 | 触发极性设置反了 | 切换RisingEdge/FallingEdge |
| 图像过曝/欠曝 | 曝光时间不匹配现场光照 | 固定曝光,调ExposureTime |
相机侧的问题大多是电气问题,不是软件问题。遇到“软件配置没问题但就是不触发”的情况,不要反复改参数,先拿起示波器去量触发引脚,这是最有效的排查路径。
6.2 雷达时间戳异常排查
如果Livox点云帧的时间间隔不稳定,优先检查PPS信号。常见问题包括:PPS信号没有真正接入、GPS模块尚未定位导致无PPS输出、共地不良导致信号抖动。Livox Viewer里的同步状态能帮你快速定位问题。
还有一种情况是雷达固件版本不一致,导致同步行为有差异。多台雷达混用时,尽量统一固件版本,否则可能出现一台时间正常、另一台时间漂移的情况。Fast-LIVO2支持多雷达输入,这种场景下时间一致性检查更要严格。
6.3 针对Fast-LIVO2的专项排查建议
如果时间戳和硬件配置都正常,Fast-LIVO2仍然表现不佳,建议按这个顺序排查:
- 打印图像话题和雷达话题的时间戳,确认两者时间差在合理范围,而不是仅靠感觉判断。
- 检查IMU话题的时间戳是否连续,IMU时间戳跳变会直接影响状态传播。
- 确认相机内参和畸变模型与实际相符,尤其是鱼眼和广角镜头,畸变参数错误时表现很像时间没对齐。
- 运行场景光照是否剧烈变化。曝光时间自适应关闭之后,如果光照不足导致图像太暗,视觉特征点提取会失败,症状也类似同步失败。
我调试时习惯先固定曝光、固定白平衡,排除图像自动调节带来的变量,再逐步放开。视觉里程计这种系统,变量越多越难定位问题。
硬同步做完之后,还有一个小技巧值得分享:在镜头前放一个高频闪烁的LED灯,比如100Hz闪烁,用相机短曝光抓拍,然后用雷达点云去量这个LED的位置。如果能稳定对齐在同一个点,说明整个时间链路是通的。这个方法比反复看RViz里的颜色贴合要定量得多,也更适合写进项目验收报告里。