地上局ソフトウェア設計 (Ground Station Architecture)¶
[!NOTE] ドキュメントのスコープ 本資料は、地上局(Ground Station)のシステム全体のプロセス分割、各コンポーネント間のデータ連携フロー、および複数レイヤー間の整合性を保つためのスキーマ駆動アーキテクチャの設計判断と合理的な根拠についてまとめたものです。フライトマイコン側のファームウェア実装コードや、ハードウェアの無線モジュールそのものの選定は対象外とします。
1. 一般論・基本原理の提示 (解空間の起源)¶
① 宇宙データシステムにおける「宇宙・地上セグメントの分離」¶
人工衛星運用システムでは、高信頼なテレメトリ(データ受信)とコマンド(送信制御)を実現するため、「地上局」が宇宙機とネットワークの中継を行います。一般的に、地上運用システムは以下のような歴史的・技術的原理に裏付けられています。
通信中継と処理APIの分離: 物理的な回線(無線/シリアル/TCP)を維持する「ブリッジ処理」と、人間やデータベースに対してサービスを提供する「API/UI処理」を切り離すことで、通信の中断をAPIサーバーから隠蔽します。
イベント駆動・Pub/Sub 中継: MQTTやROS、宇宙規格である CCSDS SLE に見られるように、メッセージブローカーを中央に配することで、送受信プロセス同士をお互いの稼働状況から疎結合化します。
2. 疎結合プロセス構成の設計比較 (解空間の探索)¶
【地上局プロセス構造】候補の比較¶
候補A(モノリシックデスクトップアプリ): 衛星のシリアル/TCPポートと直接通信し、同一スレッド内でデータ受信・CSV記録・GUI描画(Tkinter等)をすべてこなす単一アプリ。
候補B(疎結合デカップル構成) [採用]: 通信中継(
bridge.py)、バックエンドAPI(server.py)、メッセージブローカー(Mosquitto)、時系列DB(InfluxDB)、フロントエンドUI(React)に完全にプロセスを分割する。
評価項目 |
候補A (モノリシック) |
候補B (疎結合デカップル構成) [採用] |
|---|---|---|
障害の影響(UIクラッシュ時) |
致命的 (UIフリーズでデータ受信とDB保存が停止) |
極小 (UIが落ちてもブリッジ・DB保存は継続) |
一時的リンク切れへの耐性 |
低 (通信再試行中にUI描画スレッドがブロック) |
極めて高 (bridge.py が自律再試行しUIは無影響) |
データロギングの独立性 |
低 (画面描画ロジックと密結合) |
高 (ブローカーから受信したデータを直接DB保存) |
複数端末での同時監視 |
不可 (1ポート1接続の制限) |
容易 (MQTT/WebSocket経由で複数画面に同時配信) |
開発環境の構築コスト |
極小 (単一アプリを実行するだけ) |
高 (複数サーバー・DBの起動・設定が必要) |
3. 地上局のプロセス連携システム構成¶
本プロジェクトでは上記の比較に基づき、以下の疎結合デカップル構成(候補B)を採用しています。
flowchart TD
subgraph Sat["宇宙セグメント"]
sat_tcp[衛星 TCP サーバー\n:80 CMD / :81 TLM]
end
subgraph Ground["地上セグメント"]
subgraph Backend["バックエンドプロセス"]
bridge[bridge.py\nTCP ↔ MQTT 相互変換]
server[server.py\nFastAPI 統合サーバー]
end
subgraph Frontend["UIプロセス"]
ui[React App\nVite デブサーバー]
end
end
subgraph Infra["インフラストラクチャ層"]
mqtt[(Mosquitto / MQTT Broker)]
db[(InfluxDB / 時系列)]
fs[(Local FS / 画像JPG)]
end
%% データフロー
sat_tcp -- "TCP:81 (テレメトリ・画像)" --> bridge
bridge -- "Publish" --> mqtt
mqtt -- "Subscribe" --> server
server -- "書き込み (数値)" --> db
server -- "書き込み (画像保存)" --> fs
server -- "WebSocket 配信" --> ui
ui -- "REST POST (コマンド)" --> server
server -- "Publish CMD" --> mqtt
mqtt -- "Subscribe CMD" --> bridge
bridge -- "TCP:80 (コマンド)" --> sat_tcp
ui -- "REST GET (履歴表示・セッション再生)" --> server
server -- "データ取得クエリ" --> db
4. 意思決定と選定根拠 (Justifications)¶
① 障害の局所化とミッションデータ喪失の「防御的回避」¶
根拠: 合宿環境などでWi-Fiが一時的に切れたり、ブラウザ画面(React UI)がフリーズしたりした場合でも、衛星からの科学データ(テレメトリ)が欠損する最悪の事態を防ぐため、候補Bを採用しました。
bridge.pyが自動的にソケット再接続ハンドシェイクを行う間も、server.pyやInfluxDBは健全に動き続け、受信済みのデータを安全にログ保存し続けます(防御的設計)。
② スキーマ駆動開発 (Single Source of Truth) による結合バグの「防御的回避」¶
通信定義の不整合によるバグを防御的に回避するため、すべてのデータ定義を [telemetry_schema.json](file:///C:/Users/kazuki/Documents/GitHub/astrocamp-sat/shared/shared/telemetry_schema.json) で一元管理しています。
flowchart TD
SSoT[telemetry_schema.json\nマスターデータ定義]
SSoT --> Python[shared/shared/telemetry_def.py\n動的ロード・パース]
SSoT --> TS[frontend/src/types.ts\nTypeScript 型定義]
SSoT --> CPP[satelite/main.cpp\nsprintf 順序の整合]
Python --> BackendRun[FastAPI: パース・DB保存・バリデーション]
TS --> FrontendRun[React: グラフ軸マッピング・型安全な状態管理]
整合担保の仕組み:
Python バックエンド: 起動時にマスターJSONを動的解析し、InfluxDB保存用スキーマとWebSocketのシリアライザを自動構築します。
フロントエンド: チャートの凡例、物理単位、警告閾値をマスターJSONから自動マッピングします。
マイコンC++: 送信するテキストパケットフィールドの順序を、マスターJSONで定義された配列順に厳密に一致させます。
③ 時系列データベース(InfluxDB)による描画とクエリの高速化¶
根拠: 通常のリレーショナルDB(SQLite等)やCSV保存では、数万点の時系列ログから特定時間範囲を切り出してダウンサンプリングするクエリが低速であり、フロントエンドの描画をフリーズさせるリスクがあります。時系列特化の圧縮と時間インデックスを持つInfluxDBを用いることで、低CPU・低メモリ消費で高速なグラフ再生(検証性)を実現しています。
5. 合理的なブラックボックス化 (Rational Black-Boxing)¶
① MQTTブローカー(Mosquitto)の中継機能のブラックボックス化¶
各プロセス間のパケットキューイング、QoS制御(コマンドの確実な到達のためのQoS1など)、および接続切断時の自動再試行は、Mosquittoのブローカーモジュールをブラックボックスのインフラとして利用し、中継アルゴリズムの自作は行いません。
割り切りの根拠: 堅牢なパケット配信路をゼロから実装することはゼミ期間内に不可能であり、検証された既製品に信頼を置くことで、開発者のリソースを「衛星と地上局の間のテレコマ連携フロー設計」というコアミッションに集中させます。
② Viteデブサーバーによるビルドプロセスのブラックボックス化¶
フロントエンド(React/TypeScript)のホットリロード、トランスパイル、静的アセットバンドルなどのビルドチェーンは、Viteの設定テンプレートを完全なブラックボックスとして信頼し、カスタムなWebpack設定などは行いません。これにより、フロントエンドのデザインおよびデータ可視化ロジックの構築に注力します。