前言
时间同步是组合导航里不得不解决的问题,为什么要做时间同步,用我自己的理解来说就是:不做时间同步,那就是用从前的A传感器信息来校正当前的B传感器信息,两者都不是描述的同一个时间点的物体,融合出来的结果能对才是见了鬼了。
(ps:以工程经验来说,其实不少人做法是:以gps10hz,imu100hz,低速车载环境为例,在程序端取一个gps数据再取10个imu数据,这样其实也可以粗糙的使用)
具体原理可以查看新手入门系列4——MEMS IMU原始数据采集和时间同步的那些坑,本文中只做具体的工程应用,就是为了让读者能够快速手搓板子实现时间同步,然后把精力放在组合导航算法研究上。
硬件平台
STM32F407ZGT6+um982(gps设备)+mti300(imu设备)+stlink(下载器)
GPS设备需要能够输出PPS脉冲触发,1s一次;IMU需要设置成触发模式
软件平台
win10+STM32cubeIDE+micro-lab(串口调试助手,这玩意挺好用的)
最终效果
原理
时间同步准确的说是同步采样。在GPS和imu中就是用GPS时间来uimu数据打上时间戳,但由于数据从串口来是需要耗时,且解算也需要耗时,以我使用的这款gps设备为例子:配置好后串口输出为:
$KSXT,20190909084745.00,116.23662400,40.07897925,68.3830,299.22,67.03,190.28,0.022,,1,3,46,28,,,,-0.004,-0.021,-0.020,,*27
其中"20190909084745.00"为utc时间(yyyymmddhhmmss.ss),但GPS频率为10hz,imu为高频(以100hz为例),只用utc时间的话是没法给imu打上时间戳的,且utc小数位后时间还要考虑各种延迟,并不准确。最好的方法就是利用utc的整数秒,和stm32定时器来维持一个小数秒。拼接成一个完整得时间戳来给imu打上。
这里要有个概念,对于PPS的,其得益于卫星的授时功能,精度很高,至于为啥这么高,俺不懂,就是误差在纳秒级,以它为基准就很准就成了。那我们写代码的思路就来了:
1.PPS第一次来,因为其快于串口传输来的UTC时间,那PPS第一次来后,记录下稍晚来的utc时间整数秒作为IMU时间戳的整数秒(这可以从下面博客中上电瞬间串口5来的数据来看,明显先PPS来了启动了定时器,然后后续含有UTC时间的GPS数据才来,整数秒有数据是因为缓存区存有以前的整数秒数据,会在第一次来UTC时间后被更新成最新的)
2.第一次PPS来的时候开启晶振定时器,让晶振计数器开始计数,并翻转触发口的电平,形成一个20ms一次的上升沿脉冲。
这里的定时时间设置为0.01s.怎么设置涉及到STM32定时器,后续会介绍到,参照这个链接里的公式
为了后续扩展u盘存储功能,我这里主频设置为48Mhz,即我想设置定时器为0.01s。则在stm32cubeide中我的定时器两个参数分别为47999和9
3、除了第一次PPS脉冲来,那后面每次PPS来都表示距离第一次运行了一整秒了,则
T
整数
+
1
秒
T_{\text{整数}}+1\text{秒}
T整数+1秒
注意:这里有个需要注意的逻辑是:PPS信号可能会丢失,那下一次PPS来则就不能单纯+1s,需要检测最后一次整数秒+1与当前获取到的串口utc时间差距是否在1s内,如果在1s内,说明PPS中途没有丢失,不是,则 T 整数 = u t c 时间当前整数秒 T_{\text{整数}}=utc_{\text{时间当前整数秒}} T整数=utc时间当前整数秒
4.从第二次开始,PPS来一次需要重置一次定时器,小数秒ss001重置为0,防止长时间运行晶振定时器误差累积,用PPS来校正
5.
t
i
m
u
时间戳
=
T
整数秒
+
s
s
001
∗
0.01
t_{imu\text{时间戳}}=T_{\text{整数秒}}+ss001*0.01
timu时间戳=T整数秒+ss001∗0.01
6.最后都是通过串口5发射出去,为了防止同时来GPS数据和IMU数据时候串口被一个占用,另一个无法发射出去,使用了串口DMA的环形缓存区设计。注意TX RX都设置成normal模式,这里我翻了跟头,设置成circle,导致数据循环发送,一个数据发几遍
7.最后IMU触发口波形
8.还有很多改进空间,比如增加U盘存储功能,比如弄成多线程,比如我这里还出现一个问题,比如是10hz的GPS,50hz的IMU,那时间戳在运行过程中,虽然可以准确保证一个GPS和5个imu数据一段一段的来,但时间戳上我不知道为啥会出现诸如这样子的情况,会突变,
这也是我把这套系统开源的原因,难度不是很大,我很久没碰过单片机,然后stm32cubeide也是现学的,不少东西没考虑周全,但用来同步采样数据是没啥大的问题,也希望佬们能分享改进后的源码,不甚感激,能因为我这篇博客解决你组合导航上一点点小问题,甚是荣幸。
一步步手把手的复现我的板子和采集系统
下载好stm32cubeide 1.30.0(没测试过其他版本,这里提供一个1.30.0版本的百度云链接)
确保没有中文路径安装也没有中文的项目名字
1.新建项目
2.选择自己芯片,我用的是一块140多元的stm32f407zgt6,淘宝链接
3.next后给定英文项目名
4.
5.按序号来
6.按照序号来,打开后这样
6.要一份自己所用单片机的电路原理图,这个小系统用到的各个口子和序号如下:
当然还有为了检测用的GPIO口和蜂鸣器,这部分比较简单,具体可以看我放出的代码
具体引脚、时钟树、代码生成配置
这部分主要说明怎么用刚建立好的新项目里配置新文件。要是用我得同款板子直接使用我的项目就成,这里写一下是为了让读者能够适配自己的板子,能够尽快的部署自己的时间同步系统。
1.基础配置——先不管要干啥,按照我的图配置,后面再解释配置了啥子,毕竟我们的目标是尽快实现时间同步然后精力放在其他地方
a)仿真器选择(这里我使用的stlink)
b)
c)gpio口设置
这里分两种,一种是led0-2和BEED直接gpio_output和Imutriger,另一种是用来接收PPS的中断,具体来说就是
上述几个都是GPIO_Output类型,具体名字是使用了右击修改的。
然后PPS信号由于是要由GPS引入,这里的gpio使用中断,注意开中断
d)串口设置
这里使用了3个串口——串口1和2用来接收gps和imu数据,串口5用来发送处理后数据
串口2和5同样配置,注意一个点是这里DMA模式都选择normal
e)配置时钟树和定时器——注意这里的48Mhz就成,其他的按照我的图来,使用外部晶振
为了配置成0.01s一次计数,
至于为啥这么配置,可以看这个教程
注意配置
到这里基本配置完成。生成代码即可
保存即可生成代码
2.功能说明(简述代码大概逻辑)
2.1 上电检测
这部分逻辑很简单,就是调用了蜂鸣器和3个led灯,原理图如下:
上电后依次闪烁LED0-2,然后蜂鸣器响一声代表检测板子完成
Check_LED();//板子依次亮起,闪烁,最后保持全亮
Check_BEED();//蜂鸣器响一声,代表计时器启动
2.2串口数据获取
正常获取数据即可
2.3数据拼接
这里使用了DMA环形缓冲区,把gps来的数据和imu数据都放到缓冲区内,防止gps和imu同时来数据只能发送其中一个
完整工程代码我到了博客主页资源里,自行下载就成,我都是设置的免费开源。可以任意下载。文章来源:https://www.toymoban.com/news/detail-823213.html
杂谈
1.当然,该板子在实测过程中出现了跳秒现象,可惜我确实没有时间弄了,很多杂事缠身,我给提供给了导师做本科毕设题目之一,有时候真的挺无力的。想快点工作了,攒点小钱钱。
2.不少博客下面我都留下了自己联系方式,继续留一下,qq3233456044,有关博客的任何东西细节都欢迎一起交流。
3.还挺想继续弄小车和组合导航的,如果看到我博客的老哥公司有hc,也可以加我我发你简历😁,做的东西其实看我博客都大概可知知道,一直在玩各种小车车和农机。
大概成果是2ei论文+3专利+2软著的样子(在投在写的加起来),要是时间来的急还想继续写篇sci投投,涨涨英文写作经验。文章来源地址https://www.toymoban.com/news/detail-823213.html
到了这里,关于论如何零基础stm32手搓出来一个多传感时间同步板(基于STM32F407ZGT6+um982+mti300)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!