让不同机器上的时间,保持一致,就是时间同步。多台机器下的任务需要在一个时间基准下工作,就需要时间同步。本文讨论的时间同步协议是PTP。
时间同步在自动驾驶领域是至关重要的核心技术,其重要性不亚于传感器硬件和算法本身。它如同整个系统的"神经系统时钟",确保各个部分协调一致地工作。
多传感器数据融合的基础
自动驾驶汽车依赖激光雷达、摄像头、毫米波雷达、惯性导航单元等多种传感器。这些传感器以不同的频率(如10Hz、50Hz、100Hz)采集数据。
-
问题:如果没有精确到毫秒甚至微秒级的时间同步,一个"看到"障碍物的摄像头帧和一个"检测到"物体的激光雷达点云就无法准确对应到同一时刻的同一物体。
-
后果 :会导致融合算法产生"鬼影"或位置错乱,严重降低感知精度。高精度时间同步(如基于PTP或GPS PPS) 为所有数据打上统一的时间戳,是生成准确、一致的"世界模型"的前提。
决策与控制的时效性和一致性
从感知到规划再到控制执行,是一个严密的因果链条。
-
问题:规划模块基于"过去某个时刻"的感知结果做决策,而车辆状态(速度、位置)却在实时变化。如果各模块间的处理时间戳不一致,规划出的轨迹可能基于过时或超前的信息。
-
后果:导致控制指令(转向、刹车)不准确、不平稳,甚至产生危险。同步的时间戳确保了整个信号链的时序逻辑正确。
1PTP
1.1示意

时间同步通过主时钟和从时钟之间的报文交互来完成。
主时钟:
时钟源,发布时间,其它从时钟都要和主时钟的时间进行同步
从时钟:
与主时钟的时间保持同步
t1:
Sync报文离开主时钟时的时间戳
t2:
从时钟接收到Sync报文时的时间戳
t3:
从时钟发送Delay_Req报文时的时间戳
t4:
主时钟接收到Delay_Req报文时的时间戳
从时钟要基于t1、t2、t3、t4进行计算,计算的核心目标是此时此时主时钟的真实实践。t1和t4都是主时钟的真实时间,但是当从时钟收到Delay_Resp报文时,t4已经发生了一段时间,主要是进过了Delay_Resp在网络上传输的时间。
t2 = t1 + delay + offset
t4 = t3 + delay - offset
通过上边两个公式计算得出:
delay = ((t2 - t1) + (t4 - t3))/2
offset = ((t2 - t1) - (t4 - t3))/2
delay和offset分别表示什么意思,为什么要计算这两个值呢?
delay表示报文在链路上的传输延时,PTP协议假设主时钟->从时钟,以及从时钟->主时钟的链路是对称的,也就是说双向的链路延时是相同的。
offset表示从时钟相对于主时钟的偏移。在某一时刻,比如在t1时刻,主时钟的时间是t1,那么此时从时钟的时间不一定是t1,如果每一时刻,两者的时间都是相同,那么便不需要时间同步,从时钟的时间和主时钟的时间肯定在每时每刻都有一个差值,这个差值就是offset。
1.2ptp在协议栈第几层之上:以太网、udp
使用ptp4l命令可以-2指定使用以太网,-4使用udp。

1.2.1udp:320和319
1、Announce、Follow-Up、Delay_Resp报文,使用端口320;Sync、Delay_Resq使用端口319
2、使用目标ip地址,224.0.1.129





1.2.2以太网
以太网的ptp协议号是0x88f7。

1.3时钟类型

Master:主时钟,时钟源
Slave:从时钟,同步主时钟的时间
Boundary:边界时钟,边界时钟包含一个Slave和Master,Slave从上游的Master同步时间;Master向下游的Slave同步时间,那么下游的Slave就只认识Boundary中的Master,不认识上游的Master了。
Transparent:同名时钟,只做转发。
为了简单,本文只讨论Master和Slave之间存在透明时钟的情况。
1.4延时测量机制:E2E和P2P
在PTP中,测量延时是非常重要的工作,延时测量的精确与否,是影响是将同步是否精确的重要因素。延时测量机制有两种E2E和P2P。
E2E假设双向链路对称,如果实际不对称,也计算结果不精确;P2P消除了双向链路对称的假设依赖。
E2E适用场景:
网络拓扑简单、稳定的线性或星型网络。
不需要极高精度(亚微秒级)的应用,例如企业网、某些音视频流媒体系统。
网络设备较旧或仅支持普通二层/三层交换,无法部署P2P透明时钟。
主从时钟之间跳数较少。
P2P适用场景:
对同步精度要求较高的应用。
大规模,多跳的复杂网络。
网络拓扑肯呢个变化或存在冗余路径。
1.4.1E2E

端到端,slave发送Delay_Req报文到Master,Master发送Delay_Resp报文到slave。
Delay_Req离开slave的时刻是t3,Delay_Req到达Master的时刻是t4。
1.4.2P2P
peer to peer,不是测量slave和master之间的delay,所有peer之间的延时。

每个节点都会测量和上游peer的链路延时,然后加到correctioField中。
1.4.3correctionField
在E2E场景下:
Transparent1和Transparent2会将报文在本节点中的驻留时间加到correctionField中。对于Sync报文、Follow_up报文,和Delay_Resp报文,均会做这样的额操作。

当接收到Follow_up报文时,也就得到了t1和t2两个值,t1会用correction进行纠正,后边计算delay或者offset均使用纠正后的t1,即t1c。
这里有个疑问,为什么t1要使用sync和follow up报文中的correction进行修正,两个correction,不会重复吗?在如下代码中,透明时钟转发sync和follow up报文的时候,都加上了correction。
static void tc_complete(struct port *q, struct port *p,
struct ptp_message *msg, tmv_t residence)
{
switch (msg_type(msg)) {
case SYNC:
case FOLLOW_UP:
tc_complete_syfup(q, p, msg, residence);
break;
case DELAY_REQ:
tc_complete_request(q, p, msg, residence);
break;
case DELAY_RESP:
tc_complete_response(q, p, msg, residence);
break;
}
}
收到Delay_Resp报文时,t4会用Delay_Resp的correction field进行修正。

在P2P模式下:
correctionField已经包含了所有链路的延时和每个透明时钟的驻留时间,但是缺少slave和它的peer的链路延时,这个延时有slave和它的peer通过Pdelay_Req、Pdelay_Resp、Pdelay_Resp_Fup来完成。
在如下的计算offset的代码中,兼容E2E和P2P两种模式。
int tsproc_update_offset(struct tsproc *tsp, tmv_t *offset, double *weight)
{
...
/* offset = t2 - t1 - delay */
*offset = tmv_sub(tmv_sub(tsp->t2, tsp->t1), delay);
}
在E2E模式下,t2是Slave接收到Sync报文的时间,t1是修正后的Master发送Sync的时间,两者相见,再减去delay,就是offset。在E2E模式下,delay是path delay。
在P2P模式下,t2是与E2E模式下意思相同;t1也是修正后的时间,但是修正t1的时间是包含了所有的驻留时间和链路延时,缺少Slave也它额peer的链路延时。这里的delay是Slave和它的peer的链路延时。
1.4.4目的mac
如果工作在以太网协议上。
1.5一步模式和两步模式
一步模式下,t1包含在Sync报文中,没脱Follow_up报文;两步模式,t1在Follow_up中。
1.2ptp4l测试结果
如下是slave侧的打印信息:
master offset:slave相对于master的偏移,相位同步
freq:slave相对于master的频率偏移,频率同步
ptp4l[541.135]: port 1 (ens33): INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[541.135]: port 0 (/var/run/ptp/ptp4l): INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[541.136]: port 0 (/var/run/ptp/ptp4lro): INITIALIZING to LISTENING on INIT_COMPLETE
ptp4l[547.144]: selected local clock 000c29.fffe.092928 as best master
ptp4l[562.962]: port 1 (ens33): new foreign master 000c29.fffe.a13faa-1
ptp4l[566.963]: selected best master clock 000c29.fffe.a13faa
ptp4l[566.963]: foreign master not using PTP timescale
ptp4l[566.963]: port 1 (ens33): LISTENING to UNCALIBRATED on RS_SLAVE
ptp4l[567.963]: master offset 18513043 s0 freq +81 path delay 236121
ptp4l[568.964]: master offset 18510264 s0 freq +81 path delay 227600
ptp4l[569.965]: master offset 18731866 s0 freq +81 path delay 221137
ptp4l[570.965]: master offset 19175564 s0 freq +81 path delay 197590
ptp4l[571.967]: master offset 18936113 s0 freq +81 path delay 197590
ptp4l[572.967]: master offset 18910735 s0 freq +81 path delay 199041
ptp4l[573.967]: master offset 19049961 s0 freq +81 path delay 199041
ptp4l[574.967]: master offset 19078099 s0 freq +81 path delay 208858
ptp4l[575.968]: master offset 19214035 s0 freq +81 path delay 192378
ptp4l[576.968]: master offset 19471511 s0 freq +81 path delay 181110
ptp4l[577.968]: master offset 19382949 s0 freq +81 path delay 192378
ptp4l[578.970]: master offset 19503267 s0 freq +81 path delay 192378
ptp4l[579.970]: master offset 19451555 s0 freq +81 path delay 192378
ptp4l[580.971]: master offset 19594674 s0 freq +81 path delay 192378
ptp4l[581.971]: master offset 19627512 s0 freq +81 path delay 178572
ptp4l[582.972]: master offset 19730776 s0 freq +81 path delay 171225
ptp4l[583.974]: master offset 19781335 s1 freq +79299 path delay 167683
ptp4l[584.976]: clockcheck: clock frequency changed unexpectedly!
ptp4l[584.976]: master offset 1668894 s2 freq +247858 path delay 167683
ptp4l[584.976]: port 1 (ens33): UNCALIBRATED to SLAVE on MASTER_CLOCK_SELECTED
ptp4l[585.979]: master offset 3541232 s2 freq +438633 path delay 171225
ptp4l[586.980]: master offset 4889923 s2 freq +578392 path delay 189939
ptp4l[587.984]: master offset 5915394 s2 freq +686854 path delay 189939
ptp4l[588.984]: master offset 6695837 s2 freq +771594 path delay 189939
ptp4l[589.986]: master offset 7138014 s2 freq +822950 path delay 194640
ptp4l[590.986]: master offset 7464812 s2 freq +863095 path delay 194640
ptp4l[591.987]: master offset 7529117 s2 freq +877054 path delay 194640
ptp4l[592.987]: master offset 7564216 s2 freq +888129 path delay 194640
ptp4l[593.988]: master offset 7680397 s2 freq +907427 path delay 212139
ptp4l[594.988]: master offset 7409660 s2 freq +887763 path delay 212929
ptp4l[595.988]: master offset 6931089 s2 freq +846837 path delay 195431
ptp4l[596.988]: master offset 6864990 s2 freq +847092 path delay 195431
ptp4l[597.988]: master offset 6283599 s2 freq +795237 path delay 179609
ptp4l[598.988]: master offset 5964667 s2 freq +769308 path delay 179609
ptp4l[599.988]: master offset 5558496 s2 freq +734249 path delay 175563
ptp4l[600.989]: master offset 5146096 s2 freq +698155 path delay 191385
s0、s1、s2:
代表从时钟的伺服状态,其实还有s4,但是测试环境达不到同步精度,所以没有打印出来。
/**
* Defines the caller visible states of a clock servo.
*/
enum servo_state {
/**
* The servo is not yet ready to track the master clock.
*/
SERVO_UNLOCKED,
/**
* The servo is ready to track and requests a clock jump to
* immediately correct the estimated offset.
*/
SERVO_JUMP,
/**
* The servo is tracking the master clock.
*/
SERVO_LOCKED,
/**
* The Servo has stabilized. The last 'servo_num_offset_values' values
* of the estimated threshold are less than servo_offset_threshold.
*/
SERVO_LOCKED_STABLE,
};
- SERVO_UNLOCKED(未锁定)
-
初始状态或失步状态
-
伺服器尚未准备好跟踪主时钟
-
通常发生在:
-
刚启动时
-
失去主时钟连接时
-
同步质量太差无法跟踪时
-
- SERVO_JUMP(跳变状态)
-
过渡状态,准备开始跟踪
-
检测到时间偏移过大,需要立即校正
-
伺服器请求时钟跳变(clock jump)来快速纠正时间差
-
跳变后进入锁定状态
- SERVO_LOCKED(已锁定)
-
正常跟踪状态
-
伺服器正在调整本地时钟频率来跟踪主时钟
-
使用PI(比例-积分)控制算法进行微调
-
时间同步已建立但可能还不够稳定
- SERVO_LOCKED_STABLE(稳定锁定)
-
最佳工作状态
-
满足两个条件:
-
最近
servo_num_offset_values个偏移测量值 -
都小于
servo_offset_threshold阈值
-
-
表明时钟同步已经稳定可靠
2gPTP
gPTP是在ptp协议上做了更具体的要求,删除一些灵活的配置,是TSN网络工作的基础。在TSN网络中,gPTP协议,硬具有最高的优先级。
(1)只使用以太网进行传输,不使用udp进行传输,减少协议栈引入的抖动
(2)delay测量方式,只使用P2P,P2P协议有自己专用的目的MAC地址
.TP
.B ptp_dst_mac
The MAC address to which PTP messages should be sent.
Relevant only with L2 transport. The default is 01:1B:19:00:00:00.
.TP
.B p2p_dst_mac
The MAC address to which peer delay messages should be sent.
Relevant only with L2 transport. The default is 01:80:C2:00:00:0E.
(3)只能工作在局域网内