過去3年、RTKシステムと衛星実時刻とのリアルタイム同期で、マイコンプログラムで苦労してきたのですが、
STA25では、現場モニターでは、リアルタイムで同期する必要がないので、後処理で同期する方法にしました。
そのおかげで、マイコン側のプログラム負荷がへりましたが、タイミング管理用のファイルが1個増えました。
●タイムパルスとの同期アルゴリズム
RTKが120msecとタイムパルスが1000msec、BNO,ADSが10msecと各デバイスの周期が異なりますので、itow時刻で統一します。
itowは,厳密な時間単位ではありませんが、メッセージの先頭にある対うスタンプなので、UBXを使う分には基準時間として
使うと便利です。ですので、タイムパルスのitowとIMUのitowを決めておけば、RTKとの同期ができます。
下図は、アルゴリズムの説明です。3秒に一回同期をあわせて、それの時刻データをTPファイルとして保存しておきます。
●F9P出力のばらつきの吸収方法
衛星からのタイムスタンプがついが電波を受信しているのですが、実際は、F9P内で様々な計算処理を経て
出力されるので、出力時間がばらつきます。受信衛星数と処理条件で大きく違いますが、MovingBase用の処理だと
50msec±5msecほどばらつきます、しかし、衛星数の増減でこの範囲を超えることがあるので、
F9Pからのシリアル受信はばらつきを吸収できるようなテクニックが必要です。
テクニック1:120msec周期のデータを最後の119msecから1msecの間でまとめて受信処理する。
=>Teensy4でないと出来ない技ですが、ハードウェアシリアルのバッファを960バイト確保して、F9Pの1回出力全部
バッファにため込んでおいて、前回の受信時刻から119msec経過したらバッファから一挙に読んで解読処理します。、
テクニック2:バッファ全部読んでから、PVTヘッダを検索して、先頭になるようにSORTします。
コード
①受信部 basercv()
//+++++++++++++++++++++=================================================================================+ //+++++++++++++++++++++Base Recieve++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //+++++++++++++++++++++=================================================================================+ int basercv() { int bufcnt=0; if(Serial4.available()>300)//Serial4から一挙に受信 { i=0; j=0; rcvtime_1=rcvtime; rcvtime=millis(); while(Serial4.available()>0){//全部 dBuf0に読み込む if(Serial4.available()>0){ dBuf0[j]=Serial4.read(); j++; } }//All data read dN=j; for(k=0;k<dN;k++){ //PVTヘッダ(b5 62 01 07)検索してdBuf4を作るif(dBuf0[k]==0xB5 && dBuf0[k+1]==0x62 && dBuf0[k+2]==0x01 && dBuf0[k+3]==0x07){//PVT Header for(i=0;i<dN-k;i++){ dBuf4[i]=dBuf0[i+k]; } for(i=dN-k;i<k;i++){ dBuf4[i]=dBuf0[i]; } itow_base=dBuf4[6]+dBuf4[7]*256+dBuf4[8]*256*256+dBuf4[9]*256*256*256; //dBuf4からitow計算 //}
}//for k=0 return dN; |
●ログファイルの確認
Base:base_MM_DD_hh_mm.ubxファイル
IMUとADS:BA_MM_DD_hh_mm.binファイル
TimePulse同期:TP_MM_DD_hh_mm.txtファイルです。
itow3k:タイムパルスの3秒時点のitow時刻(タイムパルス時点のitow+120)
tpt3k:タイムパルスの3秒時点のmillis()時刻
bncnt0:BNOのデータカウンタ
bncntT:BNOデータ取得時刻
epochN:RTKエポックのカウンタ
下記順番で、TXTファイルにログして、後処理プログラムでデータ間の同期を行います。
一個頭でそろえれば、そのままいけるほど精度がでてます。
String tptstr=String(itow3k)+”,”+String(tpt3k)+”,”+String(bncnt0)+”,”+String(bncntT)+”,”+String(epochN);
②LOOP内でのbasercv()呼び出し
tw0=millis(); int sa=tw0-tw2;//前回の受信から経過時間 if(sa>119 ){//119msec経過していたら受信それまでは受信しない受信は1msec以内で終わる dN=basercv();//dBuf3に収納される960byteまで収納 tw2=millis();//受信時刻記録 } |
●以後
これで、ROVERを残して5デバイスのログと同期プラグラムできたので、実装を始めます。3Dプリントしまくります。
2月末までにテスト滑走目標でいきます。