📘

平衡5進数を使ってGPS信号ロスト中の位置推定を改善

に公開

B-QRE: 平衡5進数を使ってGPS信号ロスト中の位置推定を改善する

Balanced Quinary Rectification Engine — Proof of Concept

Author: MORO / 2026


なぜこれを書いたか

大きなターミナル駅の改札を出た瞬間、スマホのナビが止まる。

地下から地上に出るときも、ビルの谷間でも同じだ。GPS信号が途絶えた瞬間、多くのアプリは位置表示をその場で止める。 30秒後に信号を拾い直したとき、青い丸が突然別の場所にワープする。

「自分が今どっちを向いているかわからない」という問題は、精度の話ではなく信号ロスト中に何もしていないことが原因だ。

この記事では、平衡5進数(Balanced Quinary)の対称性を使って、信号ロスト中もセンサーで位置を推定し続けるアルゴリズム「B-QRE」を提案する。


平衡5進数とは何か

通常の5進数は {0, 1, 2, 3, 4} を使う。
平衡5進数は {-2, -1, 0, 1, 2} を使う。

ゼロを中心に正負が対称になっている。この性質が今回の鍵になる。

なぜこれがセンサーノイズ抑制に使えるのか

スマホの加速度センサーは常にわずかなランダムノイズを含んでいる。
このノイズを連続値のまま積分し続けると、誤差が積み重なって位置が少しずつずれていく(ドリフト)。

平衡5進数に量子化すると、ランダムノイズは {-2,-1,0,1,2} のどれかに丸められる。
状態集合がゼロ対称なので、ランダムノイズの期待値が厳密に0になり、長期的なドリフトが整数演算だけで抑制できる。

import numpy as np

def to_balanced_quinary(value, unit=0.5):
    """連続値を {-2, -1, 0, 1, 2} にマッピング"""
    raw = value / unit
    return int(np.sign(raw) * min(2, round(abs(raw))))

B-QREのアルゴリズム

処理フロー

[GPS有効区間]
  GPS観測値から移動方向・速度を学習
  → 平衡5進数状態として保持

[信号ロスト検知]
  デッドレコニングモードへ切り替え

[ロスト中]
  ジャイロで進行方向を更新
  加速度を平衡5進数に量子化して移動量を推定
  位置を更新し続ける

[信号回復]
  GPS実測位置へ収束

コア実装(Python)

import numpy as np

def to_balanced_quinary(value, unit=0.5):
    raw = value / unit
    return int(np.sign(raw) * min(2, round(abs(raw))))

def bqre_dead_reckoning(gps_x, gps_y, accel, gyro, gps_phase, total, dt=1.0, unit=0.6):
    est_x = np.zeros(total)
    est_y = np.zeros(total)
    heading = 0.0

    # GPS有効区間:観測値をそのまま使い、方向を学習
    for t in range(gps_phase):
        est_x[t] = gps_x[t]
        est_y[t] = gps_y[t]
        if t > 0:
            dx = gps_x[t] - gps_x[t-1]
            dy = gps_y[t] - gps_y[t-1]
            heading = np.arctan2(dx, dy)

    # ロスト区間:センサー + 平衡5進数で推定
    for t in range(gps_phase, total):
        heading += gyro[t] * dt                          # ジャイロで方向更新
        speed_state = to_balanced_quinary(accel[t], unit)  # 加速度を量子化
        est_speed = speed_state * unit
        est_x[t] = est_x[t-1] + est_speed * np.sin(heading) * dt
        est_y[t] = est_y[t-1] + est_speed * np.cos(heading) * dt

    return est_x, est_y

シミュレーション実験

設定

パラメータ
総時間 60秒(1秒/ステップ)
GPS有効区間 0〜29秒
信号ロスト区間 30〜59秒
真の移動速度 1.2 m/s(徒歩)
進行方向 北から東へ10度
GPS観測ノイズ 標準偏差 3.0 m
加速度ノイズ 標準偏差 0.15 m/s²
ジャイロノイズ 標準偏差 2 度/秒

比較対象

  • Model A(従来): 信号ロスト時に最後のGPS位置で停止
  • Model B(B-QRE): 平衡5進数量子化 + ジャイロによるデッドレコニング

結果

指標 Model A(停止) Model B(B-QRE)
ロスト30秒後の位置誤差 27.81 m 12.69 m
ロスト区間の平均誤差 12.04 m 9.77 m
最終誤差の改善 15.12 m 削減(約54%)

信号ロスト30秒後、Model Aは出発点から28 m近く離れた地点を示し続けるのに対し、B-QREは13 m以内に収まった。改札を出てどちらに進むかを判断するという用途であれば、この差は実用上の意義がある。


正直に書く:現時点での限界

本記事はProof of Conceptであり、実機データによる検証は未実施だ。以下の点は今後の課題として明示しておく。

  • unit = 0.6 m/s はシミュレーション上のチューニング値。実機では歩行速度・デバイスによって異なる
  • スパイクノイズ除去の文脈では、単純クリッピングに対して優位性が確認できなかった(別実験にて確認)
  • 急加速・急方向転換が多いシナリオでは離散状態の粗さが影響する可能性がある
  • 実機検証には Android GNSS Raw Measurements のログが必要

「改善率54%」は実機では変わる。この数値を根拠に採用判断しないでほしい。


今後やりたいこと

  • Android GNSS Raw Measurementsの実機ログで検証
  • unit の動的適応(移動速度に応じた自動調整)
  • EKFとのハイブリッド実装
  • 2次元・3次元への拡張
  • 連続スパイクノイズが多い環境での評価

リポジトリ

コード全文: [GitHub(URL後日追記)]
ライセンス: MIT

フィードバック・プルリクエスト歓迎。


© 2026 MORO. 宇宙の共有財産として公開する。


シリーズについて

本稿は「No sin, No cos, No Differential Equations」シリーズの第二弾です。

シリーズの趣旨: sin・cos・微分方程式を使わずに、工学的な問題を離散的・直感的な数理で解く試みです。本稿では np.arctan2() とジャイロ積分を使用しており、シリーズ名と完全には一致しません。これはPoC段階での実装上の妥協であり、今後の課題として三角関数不要な方向推定の実装を検討しています。


Zenn(第一弾): [URL後日追記]

© 2026 MORC.B13

Discussion