前言
時(shí)間同步是組合導(dǎo)航里不得不解決的問(wèn)題,為什么要做時(shí)間同步,用我自己的理解來(lái)說(shuō)就是:不做時(shí)間同步,那就是用從前的A傳感器信息來(lái)校正當(dāng)前的B傳感器信息,兩者都不是描述的同一個(gè)時(shí)間點(diǎn)的物體,融合出來(lái)的結(jié)果能對(duì)才是見(jiàn)了鬼了。
(ps:以工程經(jīng)驗(yàn)來(lái)說(shuō),其實(shí)不少人做法是:以gps10hz,imu100hz,低速車(chē)載環(huán)境為例,在程序端取一個(gè)gps數(shù)據(jù)再取10個(gè)imu數(shù)據(jù),這樣其實(shí)也可以粗糙的使用)
具體原理可以查看新手入門(mén)系列4——MEMS IMU原始數(shù)據(jù)采集和時(shí)間同步的那些坑,本文中只做具體的工程應(yīng)用,就是為了讓讀者能夠快速手搓板子實(shí)現(xiàn)時(shí)間同步,然后把精力放在組合導(dǎo)航算法研究上。
硬件平臺(tái)
STM32F407ZGT6+um982(gps設(shè)備)+mti300(imu設(shè)備)+stlink(下載器)
GPS設(shè)備需要能夠輸出PPS脈沖觸發(fā),1s一次;IMU需要設(shè)置成觸發(fā)模式
軟件平臺(tái)
win10+STM32cubeIDE+micro-lab(串口調(diào)試助手,這玩意挺好用的)
最終效果
原理
時(shí)間同步準(zhǔn)確的說(shuō)是同步采樣。在GPS和imu中就是用GPS時(shí)間來(lái)uimu數(shù)據(jù)打上時(shí)間戳,但由于數(shù)據(jù)從串口來(lái)是需要耗時(shí),且解算也需要耗時(shí),以我使用的這款gps設(shè)備為例子:配置好后串口輸出為:
$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時(shí)間(yyyymmddhhmmss.ss),但GPS頻率為10hz,imu為高頻(以100hz為例),只用utc時(shí)間的話(huà)是沒(méi)法給imu打上時(shí)間戳的,且utc小數(shù)位后時(shí)間還要考慮各種延遲,并不準(zhǔn)確。最好的方法就是利用utc的整數(shù)秒,和stm32定時(shí)器來(lái)維持一個(gè)小數(shù)秒。拼接成一個(gè)完整得時(shí)間戳來(lái)給imu打上。
這里要有個(gè)概念,對(duì)于PPS的,其得益于衛(wèi)星的授時(shí)功能,精度很高,至于為啥這么高,俺不懂,就是誤差在納秒級(jí),以它為基準(zhǔn)就很準(zhǔn)就成了。那我們寫(xiě)代碼的思路就來(lái)了:
1.PPS第一次來(lái),因?yàn)槠淇煊诖趥鬏攣?lái)的UTC時(shí)間,那PPS第一次來(lái)后,記錄下稍晚來(lái)的utc時(shí)間整數(shù)秒作為IMU時(shí)間戳的整數(shù)秒(這可以從下面博客中上電瞬間串口5來(lái)的數(shù)據(jù)來(lái)看,明顯先PPS來(lái)了啟動(dòng)了定時(shí)器,然后后續(xù)含有UTC時(shí)間的GPS數(shù)據(jù)才來(lái),整數(shù)秒有數(shù)據(jù)是因?yàn)榫彺鎱^(qū)存有以前的整數(shù)秒數(shù)據(jù),會(huì)在第一次來(lái)UTC時(shí)間后被更新成最新的)
2.第一次PPS來(lái)的時(shí)候開(kāi)啟晶振定時(shí)器,讓晶振計(jì)數(shù)器開(kāi)始計(jì)數(shù),并翻轉(zhuǎn)觸發(fā)口的電平,形成一個(gè)20ms一次的上升沿脈沖。
這里的定時(shí)時(shí)間設(shè)置為0.01s.怎么設(shè)置涉及到STM32定時(shí)器,后續(xù)會(huì)介紹到,參照這個(gè)鏈接里的公式
為了后續(xù)擴(kuò)展u盤(pán)存儲(chǔ)功能,我這里主頻設(shè)置為48Mhz,即我想設(shè)置定時(shí)器為0.01s。則在stm32cubeide中我的定時(shí)器兩個(gè)參數(shù)分別為47999和9
3、除了第一次PPS脈沖來(lái),那后面每次PPS來(lái)都表示距離第一次運(yùn)行了一整秒了,則
T
整數(shù)
+
1
秒
T_{\text{整數(shù)}}+1\text{秒}
T整數(shù)?+1秒
注意:這里有個(gè)需要注意的邏輯是:PPS信號(hào)可能會(huì)丟失,那下一次PPS來(lái)則就不能單純+1s,需要檢測(cè)最后一次整數(shù)秒+1與當(dāng)前獲取到的串口utc時(shí)間差距是否在1s內(nèi),如果在1s內(nèi),說(shuō)明PPS中途沒(méi)有丟失,不是,則 T 整數(shù) = u t c 時(shí)間當(dāng)前整數(shù)秒 T_{\text{整數(shù)}}=utc_{\text{時(shí)間當(dāng)前整數(shù)秒}} T整數(shù)?=utc時(shí)間當(dāng)前整數(shù)秒?
4.從第二次開(kāi)始,PPS來(lái)一次需要重置一次定時(shí)器,小數(shù)秒ss001重置為0,防止長(zhǎng)時(shí)間運(yùn)行晶振定時(shí)器誤差累積,用PPS來(lái)校正
5.
t
i
m
u
時(shí)間戳
=
T
整數(shù)秒
+
s
s
001
?
0.01
t_{imu\text{時(shí)間戳}}=T_{\text{整數(shù)秒}}+ss001*0.01
timu時(shí)間戳?=T整數(shù)秒?+ss001?0.01
6.最后都是通過(guò)串口5發(fā)射出去,為了防止同時(shí)來(lái)GPS數(shù)據(jù)和IMU數(shù)據(jù)時(shí)候串口被一個(gè)占用,另一個(gè)無(wú)法發(fā)射出去,使用了串口DMA的環(huán)形緩存區(qū)設(shè)計(jì)。注意TX RX都設(shè)置成normal模式,這里我翻了跟頭,設(shè)置成circle,導(dǎo)致數(shù)據(jù)循環(huán)發(fā)送,一個(gè)數(shù)據(jù)發(fā)幾遍
7.最后IMU觸發(fā)口波形
8.還有很多改進(jìn)空間,比如增加U盤(pán)存儲(chǔ)功能,比如弄成多線(xiàn)程,比如我這里還出現(xiàn)一個(gè)問(wèn)題,比如是10hz的GPS,50hz的IMU,那時(shí)間戳在運(yùn)行過(guò)程中,雖然可以準(zhǔn)確保證一個(gè)GPS和5個(gè)imu數(shù)據(jù)一段一段的來(lái),但時(shí)間戳上我不知道為啥會(huì)出現(xiàn)諸如這樣子的情況,會(huì)突變,
這也是我把這套系統(tǒng)開(kāi)源的原因,難度不是很大,我很久沒(méi)碰過(guò)單片機(jī),然后stm32cubeide也是現(xiàn)學(xué)的,不少東西沒(méi)考慮周全,但用來(lái)同步采樣數(shù)據(jù)是沒(méi)啥大的問(wèn)題,也希望佬們能分享改進(jìn)后的源碼,不甚感激,能因?yàn)槲疫@篇博客解決你組合導(dǎo)航上一點(diǎn)點(diǎn)小問(wèn)題,甚是榮幸。
一步步手把手的復(fù)現(xiàn)我的板子和采集系統(tǒng)
下載好stm32cubeide 1.30.0(沒(méi)測(cè)試過(guò)其他版本,這里提供一個(gè)1.30.0版本的百度云鏈接)
確保沒(méi)有中文路徑安裝也沒(méi)有中文的項(xiàng)目名字
1.新建項(xiàng)目
2.選擇自己芯片,我用的是一塊140多元的stm32f407zgt6,淘寶鏈接
3.next后給定英文項(xiàng)目名
4.
5.按序號(hào)來(lái)
6.按照序號(hào)來(lái),打開(kāi)后這樣
6.要一份自己所用單片機(jī)的電路原理圖,這個(gè)小系統(tǒng)用到的各個(gè)口子和序號(hào)如下:
當(dāng)然還有為了檢測(cè)用的GPIO口和蜂鳴器,這部分比較簡(jiǎn)單,具體可以看我放出的代碼
具體引腳、時(shí)鐘樹(shù)、代碼生成配置
這部分主要說(shuō)明怎么用剛建立好的新項(xiàng)目里配置新文件。要是用我得同款板子直接使用我的項(xiàng)目就成,這里寫(xiě)一下是為了讓讀者能夠適配自己的板子,能夠盡快的部署自己的時(shí)間同步系統(tǒng)。
1.基礎(chǔ)配置——先不管要干啥,按照我的圖配置,后面再解釋配置了啥子,畢竟我們的目標(biāo)是盡快實(shí)現(xiàn)時(shí)間同步然后精力放在其他地方
a)仿真器選擇(這里我使用的stlink)
b)
c)gpio口設(shè)置
這里分兩種,一種是led0-2和BEED直接gpio_output和Imutriger,另一種是用來(lái)接收PPS的中斷,具體來(lái)說(shuō)就是
上述幾個(gè)都是GPIO_Output類(lèi)型,具體名字是使用了右擊修改的。
然后PPS信號(hào)由于是要由GPS引入,這里的gpio使用中斷,注意開(kāi)中斷
d)串口設(shè)置
這里使用了3個(gè)串口——串口1和2用來(lái)接收gps和imu數(shù)據(jù),串口5用來(lái)發(fā)送處理后數(shù)據(jù)
串口2和5同樣配置,注意一個(gè)點(diǎn)是這里DMA模式都選擇normal
e)配置時(shí)鐘樹(shù)和定時(shí)器——注意這里的48Mhz就成,其他的按照我的圖來(lái),使用外部晶振
為了配置成0.01s一次計(jì)數(shù),
至于為啥這么配置,可以看這個(gè)教程
注意配置
到這里基本配置完成。生成代碼即可
保存即可生成代碼
2.功能說(shuō)明(簡(jiǎn)述代碼大概邏輯)
2.1 上電檢測(cè)
這部分邏輯很簡(jiǎn)單,就是調(diào)用了蜂鳴器和3個(gè)led燈,原理圖如下:
上電后依次閃爍LED0-2,然后蜂鳴器響一聲代表檢測(cè)板子完成
Check_LED();//板子依次亮起,閃爍,最后保持全亮
Check_BEED();//蜂鳴器響一聲,代表計(jì)時(shí)器啟動(dòng)
2.2串口數(shù)據(jù)獲取
正常獲取數(shù)據(jù)即可
2.3數(shù)據(jù)拼接
這里使用了DMA環(huán)形緩沖區(qū),把gps來(lái)的數(shù)據(jù)和imu數(shù)據(jù)都放到緩沖區(qū)內(nèi),防止gps和imu同時(shí)來(lái)數(shù)據(jù)只能發(fā)送其中一個(gè)
完整工程代碼我到了博客主頁(yè)資源里,自行下載就成,我都是設(shè)置的免費(fèi)開(kāi)源??梢匀我庀螺d。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-823213.html
雜談
1.當(dāng)然,該板子在實(shí)測(cè)過(guò)程中出現(xiàn)了跳秒現(xiàn)象,可惜我確實(shí)沒(méi)有時(shí)間弄了,很多雜事纏身,我給提供給了導(dǎo)師做本科畢設(shè)題目之一,有時(shí)候真的挺無(wú)力的。想快點(diǎn)工作了,攢點(diǎn)小錢(qián)錢(qián)。
2.不少博客下面我都留下了自己聯(lián)系方式,繼續(xù)留一下,qq3233456044,有關(guān)博客的任何東西細(xì)節(jié)都?xì)g迎一起交流。
3.還挺想繼續(xù)弄小車(chē)和組合導(dǎo)航的,如果看到我博客的老哥公司有hc,也可以加我我發(fā)你簡(jiǎn)歷??,做的東西其實(shí)看我博客都大概可知知道,一直在玩各種小車(chē)車(chē)和農(nóng)機(jī)。
大概成果是2ei論文+3專(zhuān)利+2軟著的樣子(在投在寫(xiě)的加起來(lái)),要是時(shí)間來(lái)的急還想繼續(xù)寫(xiě)篇sci投投,漲漲英文寫(xiě)作經(jīng)驗(yàn)。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-823213.html
到了這里,關(guān)于論如何零基礎(chǔ)stm32手搓出來(lái)一個(gè)多傳感時(shí)間同步板(基于STM32F407ZGT6+um982+mti300)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!