中国の測位衛星BeiDou(北斗)のB2b信号 その1
はじめに
中国の測位衛星BeiDou(北斗)の第3世代衛星(BDS-3)は、新しい測位信号とともに、測位精度を高める信号PPP-B2b(precise point positioning-B2b signal)を放送しています。このPPP-B2b信号の復号に挑戦します。
B2b信号
BDS-3シリーズは、中軌道(MEO: medium earth orbit)衛星、傾斜対地同期軌道(IGSO: inclied geosynchronous orbit)衛星、および、静止軌道(GEO: geostationary orbit)衛星の3軌道衛星からなります。
みちびき公式ページ内にまとめられている測位衛星リストから、BDS-3シリーズ衛星のPRN(擬似ランダム雑音: psuedo random noise)番号をピックアップすると、C19
C20
C21
C22
C23
C24
C25
C26
C27
C28
C29
C30
C32
C33
C34
C35
C36
C37
C41
C42
C43
C44
C45
C46
がMEO、C38
C39
C40
がIGSO、 C59
C60
C61
がGEOです。
ここで興味のあるB2b信号は、BDS-3シリーズ衛星から、周波数1207.14 MHz、帯域幅20.46 MHz、シンボルレート1 ksym/sのBPSK(10)にて放送されています。BDS-3のB2b信号からは、MEOとIGSOにおいては新しい航法メッセージB-CNAV3が、GEOにおいては単独精密測位メッセージPPP-B2bが、それぞれ放送されます。私の持っている受信機のうち、Pocket SDRとSeptentrio mosaic-X5は、このB2b信号を受信できます。初期値から設定変更したmosaic-X5受信機では、PPP-B2bメッセージを放送するC59
やC60
が確認できました。
mosaic-X5受信機のB2b信号サンプルがQZS L6 Toolにあります。そのトップディレクトリから、次のようにB2b信号の受信機生データBDSRawB2b
を確認できます。
python/septread.py -c < sample/20230819-081730hasbds.sept | lv
B-CNAV3とPPP-B2bとの間でのフォーマットは共通です。メッセージ内容は、6ビットのメッセージタイプ(Mestype)で区別されます。B-CNAV3として、メッセージタイプ番号10、30、および、40が利用されます。また、PPP-B2bとしては、メッセージタイプ番号1、2、3、4、5、6、7、および無情報(ヌル)メッセージの63が用いられます。
両者ともに、メッセージ長は1,000シンボルなので、1秒間に1メッセージが伝送されます。メッセージには、16シンボルのプリアンブル(メッセージの先頭を検出するために用います)、6シンボルのPRN(ありがたい!)、そしてMestypeを含む972シンボルの本文が伝送されます。この本文には、低密度パリティ検査(LDPC: low density parity check)符号という、くり返し復号に基づく誤り訂正符号が適用されています。
誤り訂正を行うためには、冗長な情報の伝達が必要です。この伝送には、符号語中にメッセージとパリティが明らかに分離されているブロック符号と、過去メッセージから一定規則で符号語を作成するたたみ込み符号があります。LDPC符号はブロック符号に分類されますので、とりあえずはLDPC復号をしなくてもメッセージを抽出できるかもしれません。
くり返し復号は、誤り訂正後の残留誤りをランダム化して、再びの誤り訂正効果を高めるアイディアに基づく方法です。このようなものとして、ターボ符号とLDPC符号が有名ですが、1000ビット以上ではLDPC符号、それ以下ではターボ符号が、よく用いられます。LDPC符号は、受信語を分割して、並列処理できることから、高速イーサネットなどにも採用されています。
LDPC検査行列
しかしながら、B2b信号では、情報ビットを6ビットごとにまとめて、誤り訂正を行う多値LDPC符号を用いています。多くのLDPC符号は2値のものなので、このB2b信号を扱うには努力が求められます。
このパリティ検査行列は、仕様書BDS-SIS-ICD-PPP-B2b-1.0の6.1.3節に書かれています。この行列は81行162列からなる巨大なものです。一方、その多くの要素はゼロであり、任意の1行の162列要素に着目したとき、値を持つものは4要素しかありません。そこで、仕様書では、ゼロ以外を示す場所の行列Hindexと、その要素値Helementにて、この検査行列Hを表しています。図6.2には、このHindexとHelementからHを作成するフローチャートがありますが、ちょっとわかりにくいです。
このフローチャートをもとに、パリティ検査行列を求めるコードを作成しました。単なる行列のスライスですので、2次元行列が扱えればどのような言語でも良いのですが、ここではRustで記述してみました。cargo new bds-b2b
にてディレクトリを作成し、自動的に作成されたsrc/main.rs
に次のようなコードを書き込み、cargo run
で実行しました。
fn main() {
let h_i = [
[ 19, 67, 109, 130 ],
..
[ 9, 51, 90, 132 ],
];
let h_e = [
[ 46, 45, 44, 15 ],
..
[ 22, 15, 12, 33 ],
];
let mut h = [[0; 162]; 81];
for i in 0..81 {
for j in 0..4 {
let row = i;
let col = h_i[i][j];
h[row][col] = h_e[i][j];
}
}
for row in 0..81 {
println!("{:?},", h[row]);
}
}
行列部分を省略していないコードとその実行結果をgithubにおきました。巨大な行列が表示されます。
64値LDPC符号の復号
次にすべきことは、仕様書のAnnexにあるNon-binary LDPC encoding and decoding methodを読み、理解して、コードを作成することです。Section 1に符号化例と復号例があります。検証のために、これをPCに打ち込むことが必要でしょう。
Section 2に、この非2元LDPC復号の2つの方法が書かれています。第1の方法extended min-sum methodは、チェックノードへのメッセージパッシングを対数尤度比(LLR: logarithmic likelihood ratio)を求めて計算する、2元LDPC復号では一般的な方法です。ここでは64元での方法について書かれていますので、ガロア体での計算です。しかしながら、途中で説明を投げ出している印象があります。
第2の方法fixed path decoding methodは、私がこの著者のおすすめの方法と感じるもので、fixed path deviation value vectorというものを用いる方法です。しかし、特定条件で変更する複雑な排他的論理和計算や、長い集合計算から、私には具体的な計算方法が想像できずに、ちょっと心が折れました。
大まかには、推定誤りシンボル数で誤り訂正の能力を変更する方法、例えば、Weldonの差集合巡回符号(difference-set cyclic codes、1966年)のような考えを応用したものと推測しています。連続値を取るLLRを離散化しているのかもしれません。
しかし、なぜ64値LDPC符号を採用したのでしょうか。私には、多値化することにより符号長が短くなり、誤り訂正の性能上や効率上のメリットがないように思うのです。どのような動機があるのかを考えてみたいと思います。
このfixed path decoding methodの論文を探して読解を進める一方、ブロック符号の特長である情報ビットがそのまま現れる性質を利用して、とりあえずデコーダを書いてB2bメッセージを読んでみようと思います。まだ、先は長いです。
関連記事
- BeiDou(北斗)B2b信号のライブストリーム 13th November 2023