时间同步 - PPS+GPRMC

一、原理

GNSS输出两条信息,一条是时间周期为1s的同步脉冲信号PPS,脉冲宽度5ms~100ms;一条是通过标准串口输出GPRMC标准的时间同步报文。GPRMC报文中的时间是通过NTP获得的。

同步脉冲前沿时刻与GPRMC报文的发送在同一时刻,误差为ns级别,误差可以忽略。GPRMC是一条包含UTC时间(精确到秒),经纬度定位数据的标准格式报文。

PPS秒脉冲为物理电平输出,接收及处理PPS信号的时间在ns级别,依旧可以忽略。但GPRMC数据一般通过波特率9600的串口发送,发送、接收、处理时间tx在ms级别,是时间同步的关键。

1)设备收到PPS秒脉冲信号后,将内部以晶振为时钟源的系统时间里的毫秒及以下时间清零,并由此开始计算毫秒时间。

(2)当收到GPRMC数据后,提取报文里的时、分、秒、年、月、日UTC时间。

(3)将收到秒脉冲到解析出GPRMC中UTC时间所用的时间tx,与UTC整秒时间相加,同步给系统时间,至此已完成一次时间同步。下一秒再进行相同的过程,每秒准确校准一次。

但是PPS+GPRMC存在如下问题。

(1)PPS是一个低功率的脉冲电平信号,驱动电流少的只有0.5mA,多的也就20mA,带几个同步节点(激光雷达和其他需要时间同步的节点),十几个就很困难了。

(2)PPS是无屏蔽的单线脉冲信号,十几根PPS线穿梭在车内,极易受到车内恶劣电磁环境的干扰,届时根本无法区分出是干扰脉冲还是同步脉冲。

(3)GPRMC通过RS232串口发送同步报文,RS232是一种1对1的全双工通信形式,也可以通过主从形式实现1对几数据传输。但对十几,实属罕见,只能通过试验验证到底可不可行。但至少线束工程师是打死不愿答应的。

(4)当时钟源丢失的时候,所有需要时间同步的设备都一下子没有了主心骨,每个小弟都可以自立门户,没有二当家的及时站出来,主持大局。这对功能安全要求极高的自动驾驶系统来说,根本无法接受。

二、PPS+GPRMC接入工控机

需满足条件:

1.工控机支持;(不支持的设备可以考虑GPIO)

2.GNSS给出PPS和GPRMC,接入到设备;

我们的工控机往往采用的都是linux内核的ubuntu系统,例如目前主流使用的Ubuntu18.04以及20.04。

工控机支持,首先工控机要能够接收到PPS信号以及GPRMC串口信息等,有内部晶振控制授时(这个一般目前的工控机都具备)

打开你的设备手册

找COM口的说明(一般通过9针COM接入)

查阅发现4个COM口都是支持RS232 mode的也就是GNSS接入的Mode,这里需要指明的是这四个COM口对应设备的(ttyS0~ttyS3)。可以发现Pin1是可以接收DCD的,也就是这个pin接入PPS,RX为接收口、TX为发出口、5Pin为GND。

接下来查阅GNSS手册,根据要求接线:

 参考接线方式(需要根据pin定制),将最右边的看作GNSS

确认GPRMC是否正常接入:

下载诸如cutecom等串口管理工具来查看

sudo apt install cutecom

如果你插入到COM1口:

  点击open device能看到GPRMC的滚动输出说明GPRMC正常接入了

确认PPS是否正常接入:

PPS如何传到系统层呢?查询ubuntu的系统kernel版本后,在linux doc中:

PPS - Pulse Per Second — The Linux Kernel documentation

可以找到关于PPS的内容,发现LinuxPPS目前已经是内置了。

检查pps状态:

grep '^CONFIG_PPS' /boot/config-$(uname -r)

输出应为:

CONFIG_PPS=m  (为y也没问题)
CONFIG_PPS_CLIENT_LDISC=m

配置PPS_ldisc.service

将下述etc/systemd/system/pps_ldisc.service 放到/etc/systemd/system下

[Unit]
Description=Modprobe pps_ldisc
After=setserial.service
 
[Service]
Type=oneshot
ExecStart=/sbin/modprobe pps_core
ExecStart=/sbin/modprobe pps_ldisc
 
[Install]
WantedBy=gpsd.service

执行:

systemctl enable pps_ldisc.service  
systemctl start pps_ldisc.service
 
#第一行使得开机能自启,第二行启动这个service

 (非必要)安装Setserial ,此举是为了低延迟和提升准确率

sudo apt-get install setserial

安装后,在var/lib/setserial/autoserial.conf 中修改:

#
###AUTOSAVE-ONCE###
###AUTOSAVE-ONCE###
###AUTOSAVE###
#
# If you want to configure this file by hand, use 
# dpkg-reconfigure setserial
# and change the configuration mode of the file to MANUAL. If you do not do this, this file may be overwritten automatically the next time you upgrade the
# package.
#
 
# dpkg-reconfigure setserial   ...  set configuration mode to MANUAL
# Added next line for ttyS1 for Garmin 18 LVC GPS
# From: http://www.rjsystems.nl/en/2100-ntpd-garmin-gps-18-lvc-gpsd.php
# Only needed to add 'low_latency' to default port configuration
# Print out current port configuration:
#   setserial -G /dev/ttyS1
/dev/ttyS1 uart 16550A port 0x02f8 irq 3 baud_base 115200 spd_normal skip_test low_latency
 
#该文件仅需修改上面的端口映射ttyS1代表COM2口,此地需要根据你真实接入的串口修改, 
#UART越大,内部buffer就越大(16550A有16位的buffer),但是对于本任务来说,不用UART更好,
#因为缓冲区会增加延迟从而降低精度;为了最大限度地降低 CPU 利用率,默认情况下,
串口流量通常会延迟 5 到 10 毫秒。但是,在这种情况下,使用了 low_latency 设置,
#设置高一点的CPU负载是值得的。
#115200是波特率,可以尝试改为9600,如果改动后找不到数据了,就改回来

然后运行:

dpkg-reconfigure setserial

点击OK,选择为MANUAL;(可能会有错误提示)

重启该service:

for op in stop start; do systemctl $op setserial.service; done

pps测试:

sudo ppswatch /dev/pps1
#pps1后面的数字根据实际情况来 可使用ppsfind --help

 说明PPS正常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值