中国の測位衛星BeiDou(北斗)のB2b信号 その1

category: gnss

はじめに

中国の測位衛星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メッセージを放送するC59C60が確認できました。

PPP-B2b signal on mosaic-X5 receiver

mosaic-X5受信機のB2b信号サンプルがQZS L6 Toolにあります。そのトップディレクトリから、次のようにB2b信号の受信機生データBDSRawB2bを確認できます。

python/septread.py -c < sample/20230819-081730hasbds.sept | lv

BeiDou B2b signal appeared on a mosaic-X5 receiver

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というものを用いる方法です。しかし、特定条件で変更する複雑な排他的論理和計算や、長い集合計算から、私には具体的な計算方法が想像できずに、ちょっと心が折れました。

fixed path decoding method

大まかには、推定誤りシンボル数で誤り訂正の能力を変更する方法、例えば、Weldonの差集合巡回符号(difference-set cyclic codes、1966年)のような考えを応用したものと推測しています。連続値を取るLLRを離散化しているのかもしれません。

fixed path decoding method

しかし、なぜ64値LDPC符号を採用したのでしょうか。私には、多値化することにより符号長が短くなり、誤り訂正の性能上や効率上のメリットがないように思うのです。どのような動機があるのかを考えてみたいと思います。

このfixed path decoding methodの論文を探して読解を進める一方、ブロック符号の特長である情報ビットがそのまま現れる性質を利用して、とりあえずデコーダを書いてB2bメッセージを読んでみようと思います。まだ、先は長いです。


関連記事