IGSの放送暦を使った測位衛星の位置計算

森下功啓製作所 ONLINE

[2014/2/28] Pythonで作った衛星座標の計算スクリプトをアップしました。
[2013/10/20] QZSに対応した最新版をアップしました。
[2013/10/13] 放送暦の解凍方法について記述を変更,図の修正を行いました。

IGSの放送暦を利用して測位衛星位置の計算をやってみました。 プログラムのコア部分には電子航法研究所(ENRI)の福島さんと坂井さんが入門用に公開されておられる GPS測位計算プログラム を利用させて頂いています。 このページは「GPS測位計算プログラム入門をやってみた」の続編と云う位置付けです。 プログラムの開発にはMicrosoft社が無料でリリースしているVisual C++ 2010 Express Editionを利用しています。

IGSから得られる放送暦とそのフォーマット   放送暦の利用アルゴリズム  プログラムのダウンロード  精密軌道暦と比較


link to INDEX

1. IGSから得られる放送暦

1.1 放送暦の入手

放送暦はいくつかのFTPサーバよりダウンロードが可能です。 FTPサーバについてはIGSのサイトに案内があります。 リンク先のページの内、Broadcast欄の一番右にある、CDDIS(US-MD),SOPAC(US-CA),IGN(FR)をクリックするとアドレスの案内があります。 その内CDDISのサイトのアドレスは、「ftp://cddis.gsfc.nasa.gov/gps/data/daily/yyyy/ddd/yyn/」となっています。 ただし、yyyyは年,dddは1月1日からの通算日,yyは西暦の下2桁を表しています。 例えば、「ftp://cddis.gsfc.nasa.gov/gps/data/daily/2010/010/10n/」です。 ダウンロードはブラウザからマウス使ってポチポチと手動でも可能ですが、専用のスクリプトが有ると便利です。

ファイル名は"brdcddd0.yyn"となっています。 yyは西暦の下2けたを表し、nはNavigationのnを表しています。 ただし、ファイルは圧縮されていますので、解凍(展開とも云う)が必要です。 お使いのマシンがWindowsであれば7-zipをお勧めします。

1.2 フォーマット

IGS(International GNSS Service?)が提供している放送暦を利用して衛星の位置を計算するために、放送暦のフォーマットを押さえておく必要があります。 IGSの提供する放送暦は図1.2.1に示す様な、RINEXというフォーマットになっています。 このRINEXフォーマットのデータは数年毎に細かい改訂が行われており、データの表記の仕方がバージョン毎に少しずつ異なります。 例えば、ここに示したものより古いフォーマットでは整数部分の"0"が省略されるなどです。

RINEXフォーマットの詳細についてはIGSのサイトを参照してください。(http://igscb.jpl.nasa.gov/components/formats.html

     2              NAVIGATION DATA                         RINEX VERSION / TYPE
CCRINEXN V1.6.0 UX  CDDIS               20-JUN-10 02:51     PGM / RUN BY / DATE 
IGS BROADCAST EPHEMERIS FILE                                COMMENT             
    0.5588E-08  0.1490E-07 -0.5960E-07 -0.1192E-06          ION ALPHA           
    0.8397E+05  0.9830E+05 -0.6554E+05 -0.5243E+06          ION BETA            
   -0.186264514923E-08-0.710542735760E-14    61440     1589 DELTA-UTC: A0,A1,T,W
    15                                                      LEAP SECONDS        
                                                            END OF HEADER       
 1 10  6 19  0  0  0.0-0.132149551064E-03-0.397903932026E-11 0.000000000000E+00
    0.490000000000E+02-0.360312500000E+02 0.483591572101E-08 0.288395691448E+01
   -0.193342566490E-05 0.481024384499E-02 0.534579157829E-05 0.515479243088E+04
    0.518400000000E+06-0.298023223877E-07-0.310813213882E+01-0.119209289551E-06
    0.965296028888E+00 0.279937500000E+03 0.877006962495E+00-0.818534095231E-08
    0.367872466222E-10 0.100000000000E+01 0.158800000000E+04 0.000000000000E+00
    0.200000000000E+01 0.630000000000E+02-0.190921127796E-07 0.490000000000E+02
    0.512880000000E+06 0.000000000000E+00 0.000000000000E+00 0.000000000000E+00
 2 10  6 19  0  0  0.0 0.265788286924E-03 0.329691829393E-11 0.000000000000E+00
    0.550000000000E+02 0.570625000000E+02 0.500878005738E-08 0.122865347467E+01
    0.315718352795E-05 0.957962975372E-02 0.925920903683E-05 0.515359644890E+04
    0.518400000000E+06 0.521540641785E-07-0.102519684372E+01 0.162050127983E-06
    0.939550794850E+00 0.188562500000E+03 0.308919237482E+01-0.826641599616E-08
   -0.478591367925E-10 0.100000000000E+01 0.158800000000E+04 0.000000000000E+00
    0.200000000000E+01 0.000000000000E+00-0.172294676304E-07 0.550000000000E+02
    0.511218000000E+06 0.400000000000E+01 0.000000000000E+00 0.000000000000E+00

                               to be continued
			
図1.2.1 RINEXフォーマットによる放送暦の例

1.3 データの整列規則

プログラムは放送暦の記録ファイルを読み込んだ後、RAM内に放送暦の情報を数値化して保存します。 その際、プログラム作成上の都合により読み込まれたデータはファイル先頭から順番に格納されます。 このデータを利用する上では、エフェメリスの放送時刻(TOM: Transmittion time of Message)に注意を払う必要があります。

IGSから得られる放送暦は実際のデータを見て頂くと分かるように、エポック順に並んでいます。 ここで云うエポックとは、記述された軌道情報の基準となる時刻の事です。 実際、図1.3.1に示す様にTOMに注目するとTOMが前後してしまっている事が分かります。 放送暦が放送時刻順に並んでいないため、RAMに蓄えた放送暦を格納した順で使うとTOMの古いものを使ってしまう可能性があります。

放送時刻の非時系列性
図1.3.1 2010/6/26~6/27間における放送時刻の非時系列性
(縦軸:GPS週秒によるTOM,横軸:データ番号(エポック順))
TOMが前後している事が分かる

link to INDEX

2. IGSの放送暦(エフェメリス)を使った衛星位置の計算プログラム

2.1 プログラムの説明

「GPS測位計算プログラム入門」がデフォルトで対応している処理は、ある受信機独自のフォーマットによる生のエフェメリスデータ(バイナリの16進表現)に対するものです。 従ってIGSのエフェメリスを読み込んで衛星位置算出に使えるようにする必要があります。 このプログラムは衛星位置の計算プログラムにENRI製計算エンジンを利用した上で、IGSより取得したGPSの放送暦(エフェメリス)を使った衛星位置計算を行います。 対応確認済みのRINEXバージョンは2002年以降のものですが、文字処理部分を工夫していますのでそれより以前のものでも構わないと思います。

このプログラムの第一の目的はエフェメリスの精度評価です。 従ってプログラムの計算の仕方や引数の与え方などはそれに最適化されています。 本プログラムを使用して求まるものは、あるエポック(任意)における衛星の重心位置座標(ECEF系)です。 IGSがリリースしている精密軌道暦(重心位置)と比較が可能です。

2.2 ENRIの計算プログラムの改造

オプション的ものですが、非常に長い期間の計算を一つのエフェメリスで行いたい場合の改造点について説明します。 ENRIの衛星位置計算プログラムでは、引数で渡されたエポックとエフェメリス情報のエポックとの差を計算における変数としています。 デフォルトのプログラムでは、この差の絶対値が一週間の604,800[s]の半分である302,400[s]を超えると一週間前後にずらします。 従って、同一のエフェメリスを使って1週間を超える計算を行う場合はソースコードの改造が必要です。

[2010/8/24 追記] と云うか、それ以前にエポック2.5~が3日程度経過すると計算結果が不正になる問題が有ることが分かりました。 どうすればいいのか、今の段階では分かりません。
link to INDEX

2.3 GPS衛星(NAVSTAR)の位置計算における,放送暦の利用アルゴリズム

位置計算のアルゴリズムは本家の「GPS測位計算プログラム入門」に譲るとして、ここではIGSの放送暦の利用に関するアルゴリズムについて説明します。 このプログラムの基本的な流れを図2.3.1と図2.3.2に示します。 先ず、引数として計算期間を受け取ります。 実行時に引数を受け取れなかった場合、scanf関数を使って計算期間の入力を求められます。 その後に計算ルーチンに入ります。 細かい点は以下のフローチャートを見て頂くとして、使用する上で注意の必要な事項について説明します。

計算に使う放送暦情報は、計算しようとするエポックより以前で放送されたデータの内最近のものを使います。

IGSのエフェメリスを使った衛星位置計算のアルゴリズム
図2.3.1 IGSのエフェメリスを使った衛星位置計算のアルゴリズム
“*”印の部分では、図2.3.2のシーケンスが実行されます。

IGSのエフェメリスを読み込むアルゴリズム
図2.3.2 IGSのエフェメリスを読み込むシーケンス

前述したTOMの不連続性に対処するため、デフォルト状態での計算ルーチンでは計算しようとしているエポックよりも約6時間分程度までの未来の情報が必要となります。 また、初回の計算のためには前日分のデータも必要となります。 従って、ある期間の計算を行おうとした場合、前後丸1日分の放送暦の用意も必要となります。

放送暦の置き場所
図2.3.3 解凍した放送暦は、実行ファイルのあるカレントディレクトリに作った[IGS eph files]フォルダ内に置いて下さい
link to INDEX

2.4 計算プログラムのダウンロード

2010/11のGPS/GNSSシンポジウム2010でENRIの坂井さんより実行形式ファイルを公開しても良いと快諾頂きました。 この場でお礼を申し上げます。 と云う訳で早速公開致します。 折角ですので坂井さんの本を宣伝したいと思います。 このプログラムを開発するにあたって度々参考にしている書籍で、坂井 丈泰 (著) 「GPSのための実用プログラミング」です。 Amazonで\3,465です。 ぜひ中古ではなく新品を購入しましょう。

GPSのための実用プログラミング
図2.4.1 GPSのための実用プログラミング (図はAmazonより)

リリース日 プログラムパッケージ 更新内容
2014/2/28 放送暦を基に衛星軌道を計算 with Python
使用言語:Python
エフェメリスの選択アルゴリズムが全く異なるのですが、参考までにPythonで実装した衛星座標の計算スクリプトへのリンクを張っておきます。 以後、GNSSに関するプログラムのほとんどはPythonで作る予定です。

開発環境:Windows 7 (64/32 bit)
2013/10/20 gnss_sat_position_VS2012.7z
使用言語:C++
バグの修正,準天頂衛星(QZS)への対応,出力ファイルフォーマットの変更,IGSの放送暦ファイルのフォーマットエラーへの対応(IGSの放送暦生成スクリプトにはバグがあると思う)を実施しました。 圧縮ファイルは、ソースコード,ビルド済みの実行形式ファイル,実行ファイルを簡単に利用するためのPowerShellスクリプト,データ処理用のPythonとRubyのスクリプト,説明書を含んでいます。 今回同梱している実行用のスクリプトはbatファイルではなく、PowerShellに変更しています。 これでパラメータの変更を行いやすくなっています。 また、出力されたファイルは、Rubyスクリプトを用いて処理することで、u-centerで衛星軌道を確認できるようになりました。 なお、今回のプログラムから、一部にC++の機能を利用しています。

開発環境:Windows 7 (64 bit), Visual Studio 2012 pro
開発環境が更新されていますのでご注意ください。

u-centerで表示した衛星軌道
u-centerで描画した、指定座標から見た測位衛星の軌跡
2011/2/11 sat_position_calculation_for_release_v2.7z
使用言語:C++
デフォルトの状態で、直ぐに計算が行えるようにバッチファイルの定数を調整しました。 また、既に計算した結果も含めていますので、実行前にどんなファイルが作成されるのか確認することも可能です。

開発環境:Windows7 (32bit), Visual C++ 2010 Express Edition
2010/11/9 SatPosCalcForRrelease.zip
使用言語:C++
初公開。
2010年の放送暦の一部を添付しています。 使用の際には放送暦は解凍の上で 実行形式ファイルと同じディレクトリに置いて下さい。
この圧縮ファイルは、計算に必要なコンパイル済みの実行形式ファイルと私&後輩で作ったソースコードを同梱しています。
この後の章での説明に使用しているプログラムより更新した物ですので、ファイルの出力状況が若干異なります。
[2010/11/19追記]リンクが張れていなかったのを修正しました。
[2011/1/10 追記]ファイル容量制限に引っ掛かって定期的に削除されていたので同梱する放送暦を減らしました。

開発環境:Windows7 (32bit), Visual C++ 2010 Express Edition
link to INDEX

2.5 計算プログラムの使用方法(@2011/2/11リリースのプログラムを用いた場合)

計算の実行は非常に簡単です。 先ず図2.5.1に有る様にバッチファイルをダブルクリックするだけです。 バッチファイルを実行後、図2.5.2の様に計算エポックが記入されたcsvファイルが出力されます。 その後、図2.5.3のに示す様にコマンドラインで衛星位置が計算されます。 最後には図2.5.4の様にlogフォルダ内に結果が出力されます。

計算パラメータは、計算開始日・計算終了日・インターバル(計算の間隔)・オフセット時間の4つです。 これらのパラメータを変更するには、図2.5.5に示す様にバッチファイルをテキストエディタで編集すればOKです。 図2.5.5の例では、2010/7/1から2010/7/4までの間で3600sec毎に計算することになります。

[注意1]:本プログラムは計算期間の前後1日分を含む放送暦が必要です。 もし、ファイルが存在しない場合でもエラーは出力されなかったと思います。
[注意2]:バッチファイルで指定できるインターバルは24時間以下である必要が有ります。


実行の仕方
図2.5.1 バッチファイルで実行します


設定に基づいて、計算エポックが出力される
図2.5.2 設定に基づいて、計算エポックがファイルに出力される

上手く行けばこの様に実行される
図2.5.3 上手く行けばこの様に実行される

計算結果
図2.5.4 計算結果はlogフォルダ内に出力されます

バッチファイルの編集
図2.5.5 計算パラメータは、バッチファイルをテキストエディタで編集すればOKです。

link to INDEX

3. 計算の試行と結果の処理(@2011/2/11リリースのプログラムを用いた場合)

3.1 計算の実行

2010/11/9付けでリリースしたプログラム(2.4節参照)を利用して、計算を行います。 ここでは、IGSのエフェメリスと比較がやり易いように、900秒毎にエポックを切り替えながら計算を行います。 図3.1.1に示す様に、計算期間を2010/9/8から2010/9/11とし、インターバルを900秒にセットしました。


計算パラメータの変更
図3.1.1 計算パラメータの変更

プログラムを実行すると、図3.2の様に計算結果がcsvファイル形式で出力されます。 「prn0_log.csv」には、全衛星のデータがエポック順に並んで出力されています。 その他のファイルは個々の衛星の位置情報です。

実行後の計算結果の出力状況
図3.1.2 実行後の計算結果出力状況

3.2 計算結果を表示してみる

標準で出てくる衛星座標はECEF座標系ですのでx,y,z表示です。 これを手っ取り早く表示して見せるためには、Rコマンダーを使うのが近道の一つです。

Rを使って3次元処理した
図3.2.1 PRN1-PRN8の軌道をRを使って表示 GPS時刻の703728000~約1日分
Rコマンダーを使った場合は8つまでしか層別表示できませんでした。
Rコマンダーはデータをx,y,zの順に並べて入力した場合、上図の様に左手系で表示することに注意が必要です。

次に、地上との関係を知りたいと思ってGoogle Earthで表示させたのが図3.2.2です。 出力されるx,y,z座標を緯度・経度・高度に直して、kmlフォーマットに成形すると容易に表示が出来ます。 地球をぐるぐる回して動かせるので面白いです。 ここで公開しているプログラムは衛星の座標をx,y,zで出力しますので、これをBLH(緯度・経度・標高)へ変換してさらにKMLフォーマットにしなくてはなりません。 これは結構面倒ですのでスクリプトを用意しました。 下記ページよりダウンロードして下さい。
ただし、BLHへの変換には近似式を使って、標高は楕円体高で代用しています。
[x,y,zをBLHへ変換するスクリプト]
[BLHをKMLへ変換するスクリプト]

kmlで表示した様子
図3.2.2 衛星の軌道をGoogle Earthで表示してみた
エポックや衛星番号は忘れてしまいました。


link to INDEX

4. 計算結果の精密軌道暦と比較(@2011/2/11リリースのプログラムを用いた場合)

4.1 誤差評価の方法

3章での計算で得られた結果を、IGSが公開している精密軌道暦と比較します。 精密軌道暦はIGSの「http://igscb.jpl.nasa.gov/components/prods_cb.html」よりダウンロードすることが出来ます。 GPS週番号をクリックして、その中から「igswwwwd.sp3.Z」をダウンロードして下さい。 ただし、wwwwはGPS週番号であり、dは曜日番号(日曜日が0)です。 ダウンロード後は放送暦をダウンロードした時と同様に解凍と拡張子から「.Z」を削除する作業を行って下さい。 精密軌道暦は計算結果の格納されたフォルダの中に、ディレクトリを作ってそこに格納しておきます。

精密暦の保管について
図4.1.1 精密軌道暦は、評価対象のcsvファイルのあるディレクトリの中に「IGS sp3 files」と言う名前のディレクトリを作ってその中に収めて下さい

図4.1.2に示す様に、「estimate_all.rb」と云うRubyのスクリプトを実行することで精度評価を行います。 このスクリプトについては以下よりダウンロードして下さい。
[精度評価スクリプトのダウンロード]

精度評価用のスクリプト
図4.1.2 評価用のRubyスクリプト

このスクリプトを実行すると図4.1.3の様に、「prn*_log_error.csv」と「eph_error_for_R.csv」と云うファイルが生成されます。 「prn*_log_error.csv」は個別の処理結果が格納されており、「eph_error_for_R.csv」はR(アール)と云う統計処理ソフトで読み込みやすい様に成形されたファイルになっています。

精度評価スクリプト実行後
図4.1.3 評価用スクリプトの実行後のディレクトリの様子

4.2 精密暦との比較結果

精密暦と比較した結果を図4.2.1~図4.2.4に示します。 横軸が時間で縦軸が各軸の誤差を表します。 図4.2.1には2010/7/7-2010/7/10におけるPRN2の衛星の軌道予測誤差をx,y,z成分で表示しています。 計算に使用される放送暦が切り替わるたびに計算値に差が出ているようですが・・・これで良いんですよね?


PRN2
図4.2.1 2010/7/7-2010/7/10におけるPRN2の衛星の軌道予測誤差をx,y,z成分で表示

次に、全衛星の結果を示します。 PRN番号と衛星のシリーズを比較すると、新型で有ればある程精度が良いようです。 また、同じブロックⅡRM衛星でも、打ち上げ時期が最近の物ほど精度が良いように見えます。 これは搭載周波数源の原子時計の性能向上によるものでしょうか…。

細かく見ると、殆どの衛星の予測誤差には減少又は増加の傾向が見られます。

全衛星を処理
全衛星のものを箱髭図にしてみる
図4.2.2 2010/7/7-2010/7/10における放送暦の絶対誤差を全衛星について計算した結果
PRN1についてはメンテ中であったため計算していない。

3日間の結果を見る限り、周期の長い変動が見られそうでしたので思いっきり長い期間の計算を行ってみました。 ここではPRN2とPRN8について図3.4と図3.5に示します。 この場合、たまたま同じ様な変動を示しています。 変動の周期を計算してみると月の満ち欠けの周期に近い物となっていました。 月と何か関係有るのでしょうか?

prn2 長期間
図4.2.3 長期間の放送暦の誤差をPRN2を例に表示 計算期間:2010/4/28-2010/7/28

PRN8 長期間
図4.2.4 長期間の放送暦の誤差をPRN8を例に表示 計算期間:2010/4/28-2010/7/28

4.3 蛇足:同じ放送暦を使い続けたら、どう予測精度が劣化するのか?

こちらはおまけで同じ放送暦を使い続けた場合にどの様に軌道の予測精度が劣化していくのかを計算した結果です。 基本的には、基準エポックから2~4時間経過すると誤差が急速に増大する様です。 また、最近の衛星であるほど誤差の大きさが小さい様な気がしました。

単一のエフェメリスを使い続ける場合の誤差
図4.3.1 単一のエフェメリスを使い続ける場合の絶対誤差 (PRN1を除く)
2010/7/7-2010/7/8途中までを表示

inserted by FC2 system