Newer
Older
RobotCar / docs / 03_TECH / TECH_02_システム構成仕様.txt
========================================================================
システム構成仕様 (System Architecture Specification)
========================================================================


1. 概要 (Overview)
------------------------------------------------------------------------

    1-0. 目的

    ライントレース自律走行を実現するために,Raspberry Pi と PC が
    それぞれ担う処理と,両者間の通信の流れを定義する.


    1-1. 全体構成

    Raspberry Pi はカメラ画像の取得・画像処理・操舵量計算・モーター制御を
    すべて担当し,PC はモニタリング GUI・パラメータ調整・手動操作を担当する.
    制御ループが Pi 内で完結するため,通信遅延の影響を受けない.

        Raspberry Pi                        PC
        ────────────                        ──
        カメラ撮影                          テレメトリ受信
            │                               │
        画像処理・線検出                    映像・状態表示
            │                               │
        操舵量計算(3手法切替)             パラメータ調整
            │                               │
        モーター制御                        コマンド送信
            │                           (モード切替・手動操作)
            └──── テレメトリ ──────>          │
            ┌──── コマンド受信 <──────        │


2. Raspberry Pi 側の処理 (Raspberry Pi Processing)
------------------------------------------------------------------------

    2-1. カメラ画像の取得

    ・Picamera2 を使用してグレースケール(Y8 フォーマット)でフレームを取得する.
        ※ グレースケールで取得することで,転送データ量を BGR 比で 1/3 に削減する.

    2-2. 画像処理・線検出

    ・取得した画像を 40×30 に縮小し,黒線の位置を検出する.
    ・5 種類の検出手法を GUI から切り替えて使用できる:
        - 現行(CLAHE + 固定閾値)
        - 案A(Black-hat 中心)
        - 案B(二重正規化)
        - 案C(最高ロバスト)
        - 案D(谷検出+追跡)
    ・各手法の処理パイプラインは異なるが,
        出力は共通のデータ構造(位置偏差・傾き・二値画像等)に統一される.
    ・詳細は `TECH_01_操舵量計算仕様.txt` および
        `TECH_04_線検出精度向上方針.txt` を参照する.

    2-3. 操舵量計算

    ・3 種類の制御手法を GUI から切り替えて使用できる:
        - PD 制御: 位置偏差・傾き・微分項で操舵,曲率で速度を調整
        - 2点パシュート制御: 近い点と遠い点の偏差で操舵,曲がり度合いで速度を調整
        - Theil-Sen PD 制御: Theil-Sen 直線近似と PD 制御のハイブリッド,
            傾きで速度を調整
    ・レートリミッターで急激な操舵変化を抑制する.
    ・十字路判定: SVM 分類器で十字路を検出し,直進に切り替える.
    ・コースアウト復帰: 一定時間線を検出できない場合に復帰動作を行う.
    ・詳細は `TECH_01_操舵量計算仕様.txt` を参照する.

    2-4. モーター制御

    ・計算した throttle,steer を `MotorDriver.set_drive()` に渡し,
        左右モーターを制御する.
    ・差動2輪駆動の計算:
        - left  = throttle + steer
        - right = throttle - steer
    ・極性補正・PWM 出力も既存コードに従う.

    2-5. テレメトリ送信

    ・毎フレーム,以下のテレメトリを PC に送信する:
        - カメラ画像(JPEG 圧縮)
        - 操舵量(throttle,steer)
        - 検出結果(検出成否,位置偏差,傾き)
        - 十字路判定結果,復帰状態,処理 FPS
        - 二値画像(デバッグ用)
    ・ZMQ PUB/SUB + CONFLATE で,古いフレームを自動破棄する.

    2-6. コマンド受信

    ・PC からのコマンドを非ブロッキングで受信する:
        - mode: "auto"(自律走行),"manual"(手動操作),"stop"(停止)
        - 手動モード時の throttle,steer
        - パラメータ更新(画像処理・操舵・復帰パラメータ)
        - 十字路判定の有効/無効
    ・PC が切断しても,auto モードなら自律走行を継続する.


3. PC 側の処理 (PC Processing)
------------------------------------------------------------------------

    3-1. テレメトリの受信

    ・Pi から送信されたテレメトリ(画像+検出結果+操舵量)を受信する.

    3-2. GUI 表示

    ■ カメラ映像表示
    ・受信した画像をリアルタイムで表示する.
    ・デバッグオーバーレイを重ねて表示できる.
    ・詳細は `TECH_03_デバッグオーバーレイ仕様.txt` を参照する.

    ■ 自動操縦の切り替え
    ・自動操縦の ON / OFF を切り替えるボタンを設ける.
    ・ON: Pi に "auto" コマンドを送信し,自律走行を開始する.
    ・OFF: Pi に "manual" コマンドを送信し,手動操作に切り替える.

    ■ パラメータ調整
    ・PD 制御パラメータ(Kp,Kh,Kd 等)をリアルタイムに変更できる
        UI を設ける.
    ・二値化パラメータ(二値化閾値,CLAHE 強度等)も
        リアルタイムに変更できる.
    ・変更したパラメータはコマンドとして Pi に送信し,即座に反映される.

    ■ パラメータ保存・読み込み
    ・調整したパラメータをタイトル・メモ付きで JSON に保存できる.
    ・保存済みパラメータをコンボボックスから選択・読み込みできる.
    ・確認ダイアログ付きの削除機能を備える.

    ■ 手動操作
    ・自動操縦 OFF 時に,ユーザーが手動で車体を操作できる.
    ・キー入力を throttle,steer に変換し,コマンドとして Pi に送信する.


4. 設計方針 (Design Policy)
------------------------------------------------------------------------

    4-1. 操舵量計算の独立性

    操舵量の計算ロジックは,タイム短縮やコースアウト防止のために
    試行錯誤で改善していくことを前提とする.
    そのため,操舵量計算を他の処理から独立させ,計算式やアルゴリズムの
    変更が通信・モーター制御・GUI のコードに影響しない構成とする.

    ・入力: グレースケールのカメラ画像(NumPy 配列)
    ・出力: throttle(float: -1.0 ~ +1.0),steer(float: -1.0 ~ +1.0)

    この入出力を維持する限り,計算の中身(偏差の取り方,制御式,
    速度調整の方法等)を自由に変更できる.

    4-2. 制御ループの完結性

    画像取得からモーター制御までの制御ループを Pi 内で完結させ,
    通信遅延の影響を排除する.PC はモニタリングとパラメータ調整のみを
    担当し,制御のクリティカルパスには含まれない.


5. 通信の流れ (Communication Flow)
------------------------------------------------------------------------

    5-1. 全体のループ

    Pi 側の制御ループ(毎フレーム):
        1. Pi: カメラでフレームを取得する.
        2. Pi: 画像処理・線検出を行う.
        3. Pi: 操舵量を計算する(自動時).
        4. Pi: モーターを制御する.
        5. Pi → PC: テレメトリを送信する.
        6. Pi: PC からのコマンドを確認する.

    PC 側のループ(タイマー駆動):
        1. PC: テレメトリを受信して映像・状態を表示する.
        2. PC → Pi: コマンドを送信する(モード切替・手動操作・パラメータ更新).

    5-2. 通信プロトコル

    ■ テレメトリ(Pi → PC,ZMQ PUB/SUB)
    ・メッセージ形式:
        - 4 バイト: JSON ヘッダ長(uint32 LE)
        - N バイト: JSON テレメトリ(操舵量・検出結果・状態)
        - 4 バイト: カメラ画像長(uint32 LE)
        - M バイト: JPEG 圧縮カメラ画像
        - 残り: JPEG 圧縮二値画像(デバッグ用,省略可)
    ・JSON テレメトリのフィールド:
        - v: プロトコルバージョン(config.TELEMETRY_VERSION と一致必須)
        - ts: 送信時刻(Unix タイムスタンプ)
        - throttle, steer: 現在の操舵量
        - detected: 線検出の成否
        - pos_error: 位置偏差
        - heading: 線の傾き
        - is_intersection: 十字路判定結果
        - is_recovering: 復帰動作中か
        - fps: Pi 側の処理 FPS
        - intersection_available: 十字路分類器の読み込み済み状態
        - compute_ms: 操舵計算の平均処理時間(ミリ秒)
    ・PC 側はバージョン不一致のメッセージを破棄する.

    ■ コマンド(PC → Pi,ZMQ PUB/SUB)
    ・JSON 形式:
        - mode: "auto" | "manual" | "stop"
        - throttle, steer: 手動モード時の操舵量
        - steering_method: "pd" | "pursuit" | "ts_pd"
        - image_params: 画像処理パラメータの辞書
        - pd_params: PD 制御パラメータの辞書
        - pursuit_params: Pursuit 制御パラメータの辞書
        - steering_params: Theil-Sen PD 制御パラメータの辞書
        - recovery_params: 復帰パラメータの辞書
        - intersection_enabled: 十字路判定の有効/無効
        - intersection_throttle: 十字路通過時の速度

    5-3. 通信要件

    ・双方向通信: Pi → PC(テレメトリ),PC → Pi(コマンド).
    ・テレメトリ: CONFLATE により最新フレームのみ保持(古いデータを自動破棄).
    ・コマンド: 非ブロッキング受信で制御ループを阻害しない.
    ・PC 切断時: Pi は最後のモードで動作を継続する.
        auto モードなら自律走行を続け,stop モードなら停止を維持する.