自动驾驶 时间表(自动驾驶中的时间同步方案)
本文重点讨论自动驾驶中使用比较多的gps+pps+gpsd+chrony+ptpd+gptpd的时间同步方案 ,本文仅为自己在调试过程中的记录 ,如有不对地方欢迎讨论:853906167@qq.com
详细方案如下:Tbox端(IMX8系列)的ubxclient接收来自gps(如ublox系列)的GPS时间和PPS信号,Tbox端将接收到gps的NEMA/UBX消息通过udp转发给gpsd,然后chrony在结合gpsd的时间信息还有linux下的pps信息做时间同步和修正 ,后续Tbox作为server端通过ptpd给自动驾驶算力芯片(如nvida orin/xavier)做时间同步 ,然后自动驾驶算力芯片在通过gptpd给mcu/lidar等做时间同步 ,详细的框图如下:
1.PPS信号处理
配置ublox芯片PPS信号输出频率1HZ,实测tbox端pps_in输入信号:
从测试结果来看17次的脉冲信号周期为7.441s+9.564=17.005s,周期精度小于0.001s,精度比较高
linux 打开pps配置:
CONFIG_PPS=y
CONFIG_PPS_DEBUG=n
CONFIG_PPS_CLIENT_KTIMER=n
CONFIG_PPS_CLIENT_LDISC=n
CONFIG_PPS_CLIENT_GPIO=ynote:如果ktimer/ldisc打开注意设备节点可能不一样 ,kernel log中可以看到具体对应的设备节点 ,我们这边ktimer/ldisc都没打开 ,pps_gpio节点是/dev/pps2,后续消除误差需要配置这个节点
dts配置:
pps_ubx{
compatible = "pps-gpio";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pps>;
gpios = <&gpio4 2 GPIO_ACTIVE_HIGH>;
status = "okay";
};kernel中pps处理相关代码:drivers/pps/clients/pps-gpio.c
linux默认已经在kernel代码中加入了pps的相关处理 ,重点为触发PPS的中断 ,本人的项目采用的是上升沿触发中断(因为ublox默认上升沿跟整秒对齐)
中断处理函数:
static irqreturn_t pps_gpio_irq_handler(int irq, void *data)
{
const struct pps_gpio_device_data *info;
struct pps_event_time ts;
int rising_edge;/* Get the time stamp first */
pps_get_ts(&ts); ----获取中断触发的时间信息 ,后续传给应用层info = data;
rising_edge = gpio_get_value(info->gpio_pin);
if ((rising_edge && !info->assert_falling_edge) ||
(!rising_edge && info->assert_falling_edge))
pps_event(info->pps, &ts, PPS_CAPTUREASSERT, NULL);else if (info->capture_clear &&
((rising_edge && info->assert_falling_edge) ||
(!rising_edge && !info->assert_falling_edge)))
pps_event(info->pps, &ts, PPS_CAPTURECLEAR, NULL);return IRQ_HANDLED;
}pps_event:register a PPS event into the system,后续应用层可以获取pps触发的时间和序号等信息
详细pps相关请参考:PPS - Pulse Per Second — The Linux Kernel documentation
pps-tools:http://linuxpps.org , GitHub - redlab-i/pps-tools: User-space tools for LinuxPPS
ppstest/ppswatch使用(同步后的结果):
2.GPSD部分
GPSD的启动配置:
/usr/sbin/gpsd -n -P /run/gpsd.pid -F /var/run/gpsd.sock udp://127.0.0.1:50000
-n dont wait for client connects to poll GPS 与chrony配合时候必选
-F sockfile specify control socket location
udp://127.0.0.1:50000 接收ubxclientsocket发送的nema 、ubx数据,也直接直接通过配置ublox的uart设备节点
相关工具使用:
cgps:
note:通过图中的time/latitude/longitude等信息可以判定是否已经搜到星 、获取到时间和定位信息 ,gpsd只有在获取到时间和定位信息后才能跟chrony配合同步时间消除pps误差
3.Chrony部分
Chrony是NTP(Network Time Protocol ,网络时间协议,服务器时间同步的一种协议)的另一种实现 ,与ntpd不同 ,它可以更快且更准确地同步系统时钟,最大程度的减少时间和频率误差,chrony是两个用来维持计算机系统时钟准确性的程序 ,这两个程序命名为chronyd和chronyc
chronyd为后台运行守护进程 ,用于同步系统时间
chronyc提供了一个用户界面 ,用于监测性能和配置
chrony+gpsd校准的原理:
gpsd从串口或者网络读取gnss数据并进行解析 ,将解析结果以UNIX socket或者共享内存等方式输出 ,chrony从UNIX socket或者共享内存取得解析后的gnss ,和pps信息结合 ,校正系统时间
note:chrony校正的原则是通过控制时间的增减率来达到校正时间 ,较少采用跳变的方式 ,跳变的方式可能对其他应用有影响,这样可能会导致校正的比较慢点 ,但是如果偏差过大或者第一次校正也可以配置成有条件的跳变方式
note:chrony和ntp是冲突的不能同时存在 ,systemd启动配置的时候需要注意
chronyd配置文件/etc/chrony.conf
driftfile chronyd程序的主要行为之一,就是根据实际时间计算出计算机增减时间的比率 ,将它记录到一个文件中是最合理的 ,它会在重启后为系统时钟作出补偿,甚至可能的话 ,会从时钟服务器获得较好的估值
allow/deny 这里你可以指定一台主机、子网 ,或者网络以允许或拒绝NTP连接到扮演时钟服务器的机器
makestep 通常 ,chronyd将根据需求通过减慢或加速时钟 ,使得系统逐步纠正所有时间偏差 。在某些特定情况下 ,系统时钟可能会漂移过快 ,导致该调整过程消耗很长的时间来纠正系统时钟 。该指令强制chronyd在调整期大于某个阀值时步进调整系统时钟 ,但只有在因为chronyd启动时间超过指定限制(可使用负值来禁用限制) ,没有更多时钟更新时才生效
rtcsync 启用内核模式 ,系统时间每11分钟会拷贝到实时时钟(RTC)
refclock 设置时钟源
note:详细完整的说明请查看chrony官方文档:chrony – chrony.conf(5)
chronyc sources -v 命令查看同步结果:
可以看到偏差大概在 125ns左右
相关说明:
M: 这表示信号源的模式 。表示服务器,=表示对等方 ,#表示本地连接的参考时钟
S:此列指示源的状态
* 表示chronyd当前同步到的源
- 表示被合并算法排除的可接受源
+ 表示可接受的信号源 ,与选定的信号源组合在一起
? 指示已失去连接性或其数据包未通过所有测试的源 。它也显示在启动时,直到从中至少收集了3个样本为止
x 表示chronyd认为是虚假行情的时钟(即 ,其时间与大多数其他来源不一致)
〜 表示时间似乎具有太多可变性的来源
Name/IP address:这显示了源的名称或IP地址 ,或参考时钟的参考ID
Stratum:这显示了来源的层,如其最近收到的样本中所报告的那样 。层1表示一台具有本地连接的参考时钟的计算机 。与第1层计算机同步的计算机位于第2层 。与第2层计算机同步的计算机位于第3层 ,依此类推
Poll:这显示轮询源的速率 ,以秒为单位的时间间隔的以2为底的对数 。因此 ,值为6表示每64秒进行一次测量 。chronyd会根据当前情况自动更改轮询速率
Reach:这显示了源的可达性寄存器以八进制数字打印。寄存器有8位 ,并在每个从源接收或丢失的数据包上更新 。值377表示从最后八次传输中收到了对所有用户的有效答复
LastRx:此列显示多长时间前从来源接收到了最后一个好的样本(在下一列中显示) 。未通过某些测试的测量将被忽略。通常以秒为单位 。字母m ,h ,d或y表示分钟 ,小时 ,天或年
Last sample:此列显示上次测量时本地时钟与源之间的偏移 。方括号中的数字表示实际测得的偏移量。可以用ns(表示纳秒) ,us (表示微秒),ms(表示毫秒)或s(表示秒)作为后缀 。方括号左侧的数字表示原始测量值 ,已调整为允许此后施加于本地时钟的任何摆度 。+/-指示器后面的数字表示测量中的误差范围 。正偏移表示本地时钟位于源时钟之前
参考文档:
GPSD Time Service HOWTO
chrony – chrony.conf(5)
创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!