SCOUT × MulmoChat

GUI Chat Protocol for Robot Operation Interface — Architecture Design v1.0

01 全体アーキテクチャ

MulmoChatの思想「LLMはUXオーケストレーター」をSCOUT運用に適用。
LLMは判断・演出のみ。ロボット制御は公式APIに委譲。表示はGUI Chat Protocolで拡張。

User Layer — オペレータ
🎤 音声 / テキスト入力
「Bルートで巡回して」「なぜ止まった?」などの自然言語指示
📱 チャットUI(ブラウザ)
MulmoChat互換UIが動く場所。PC/タブレット/スマホ
🖼️ GUI Viewer群
フォーム・画像・地図・状態パネルなどがチャット内に出現
GUI Chat Protocol(JSON)
LLM Layer — 判断・演出
🧠 LLM(Claude / GPT等)
状況を判断し、ツールを呼ぶ。差し替え可能
📋 System Prompt(Role定義)
「SCOUT巡回オペレーター」ロール。使えるツール群を定義
🔧 Tool Definitions
後述の8つのSCOUT専用ツール定義(function calling形式)
function call / tool_use(JSON)
Bridge Layer — PC上のPython中間サーバー
🌐 WebSocket / HTTP API
チャットUI ↔ Bridge間通信。FastAPI / Flask等
🤖 Tool Executor(Python)
LLMのfunction callを受け取り、ROSサービスに変換・実行
📸 状態取得エンジン
カメラ画像・odom・nav_status・system_eventを常時取得
📊 イベント判定 / FSM
異常検知→失敗分類→LLMへ通知のパイプライン
ROS Service Call(rosservice / rospy)
SCOUT ROS Layer — 公式スタック
/UtilNode
algo_move(距離指令), algo_roll(角度指令), ai_detect設定
/NavPathNode
nav_path_start, nav_get_status, nav_cancel, nav_exit
/CoreNode
システムイベント、電池、温度等
/AppNode /CloudNode
公式アプリ・クラウド側との連携(干渉しない)
内部制御(安全フック込み)
Hardware Layer — SCOUT実機
⚙️ MotorNode
モーター制御(直接触らない)
📷 カメラ
前方カメラ画像(VPR・状況把握用)
📡 センサ群
IMU, odometry, ToF, 段差, バンパー等
🔋 バッテリー
電圧・充電状態

02 SCOUT用ツール定義(GUI Chat Protocol)

LLMが呼べるツール群。各ツールは「LLM返却データ」+「UI提示データ」を同時に返す。

監視

getScoutStatus

SCOUTの現在状態を取得。nav_get_status + odom + battery + カメラ画像をまとめて返す。

UI提示: 状態パネル(画像+位置+バッテリー+Nav状態)

LLM返却: JSON(status, position, battery_pct, error_flags)

行動

startPatrol

指定ルート(Teachデータ)で巡回開始。nav_path_start を実行。

UI提示: ルートマップ+進行状況バー

LLM返却: "patrol started, route: B, ETA: 3min"

行動

stopPatrol

巡回を安全に停止。nav_cancel を実行。

UI提示: 停止確認+現在位置表示

LLM返却: "patrol stopped at waypoint 7/12"

介入

moveCorrection

前後補正。algo_move(yDistance, speed) を実行。

UI提示: 補正量の図示+Before/Afterカメラ画像

LLM返却: "moved +0.2m forward, ret: 0"

介入

rotateCorrection

姿勢補正。algo_roll(angle, speed) を実行。

UI提示: 回転角の図示+Before/Afterカメラ画像

LLM返却: "rotated +15 degrees, ret: 0"

提示

presentDiagnosis

異常発生時の診断情報をリッチに提示。カメラ画像+Teach画像対比+信頼度+推奨行動をパネル化。

UI提示: 診断ドキュメント(画像比較+根拠+選択肢)

LLM返却: "failure_type: localization_drift, confidence: 0.32"

収集

askOperatorDecision

オペレータに判断を求める選択式UI。停止/後退/再試行/別ルート/遠隔操作など。

UI提示: 選択肢フォーム(putQuestions相当)

LLM返却: "operator chose: retry_from_waypoint_5"

提示

showTeachRoutes

登録済みTeachルート一覧を表示。ルート名・距離・最終実行日・成功率。

UI提示: ルートリスト(presentDocument相当)

LLM返却: "3 routes available: A(120m), B(85m), C(200m)"

03 失敗復帰フロー(Repeat中の異常時)

▶ シナリオ: Repeat中にローカライゼーション信頼度が低下
1
SCOUT: 異常イベント発生

Bridge層のイベント判定が nav_status + VPR信頼度の低下を検知 → SCOUTを一時停止(nav_cancel)

2
Bridge → LLM: 状況レポート送信

現在カメラ画像・Teach時の対応画像・VPR一致度・odometry偏差をJSONで送信

3
LLM: presentDiagnosis を呼ぶ

状況を分析し、画像比較パネル+信頼度+「なぜ止まったか」の自然言語説明を生成

4
UI: 診断パネルがチャット内に出現

オペレータは画像を見比べ、状況を「理解」できる(従来のログ読みと決定的に違う)

5
LLM: askOperatorDecision を呼ぶ

選択肢を提示:「① 再試行」「② 0.3m後退して再試行」「③ 次のwaypointへスキップ」「④ 巡回中止」

6
オペレータ: 選択肢をクリック

例:「② 0.3m後退して再試行」を選択

7
LLM: moveCorrection → startPatrol を順次呼ぶ

algo_move(yDistance: -0.3) 実行後、nav_path_start で巡回再開

8
Bridge: 復帰ログを構造化記録

失敗種別・診断内容・オペレータ選択・復帰結果 → 評価用データセットになる

04 従来構成との比較

比較軸 従来(rqt / Webダッシュボード) LLMテキストのみ SCOUT × MulmoChat
異常時の状況把握 ログを読む・画面を探す LLMが文章で説明 画像比較+根拠+説明がチャット内に出現
オペレータ介入 手順書→手動操作 テキストで「後退して」→曖昧 構造化された選択肢→APIに直結
対話と操作の関係 別ウィンドウ テキストのみ 対話の流れの中にUIが溶ける
非エンジニアの運用 困難 可能だがUI貧弱 自然言語+GUI選択で誰でも可能
ログ・記録 rosbag(巨大・検索困難) テキストログ 構造化インタラクションログ(評価に直結)
拡張性 UIの再開発が必要 プロンプト変更のみ ツール+Viewer追加で無限拡張

05 実装ロードマップ

Phase 1: 最小動作デモ

2-3週間
  • Python FastAPIでBridge Server構築
  • getScoutStatus ツール1つだけ実装
  • 簡易チャットUI(Streamlit or Gradio)
  • LLM(Claude API)にツール定義を渡す
  • 「SCOUTの状態を見せて」で画像+状態が出る

Phase 2: 行動ツール追加

2-3週間
  • startPatrol / stopPatrol 実装
  • moveCorrection / rotateCorrection 実装
  • 「Bルートで巡回して」で実際に動く
  • 「0.2m前進して」で algo_move 実行
  • 安全制約のバリデーション追加

Phase 3: 失敗復帰UX

3-4週間
  • イベント判定FSM実装
  • presentDiagnosis / askOperatorDecision 実装
  • 失敗シナリオ5-8種の分類と対応UI
  • 構造化ログの記録と出力
  • VPR信頼度との連携

Phase 4: 評価・論文

4-6週間
  • 比較実験(従来UI vs テキストLLM vs 本システム)
  • TTR・成功率・NASA-TLX計測
  • デモ動画の撮影
  • 論文執筆(HRI / Field Robotics向け)
  • オープンソース公開準備

06 Phase 1 最小構成(今すぐ始められる)

重要な設計判断: MulmoChatのVue.js製コードを直接使うのではなく、 GUI Chat Protocolの「思想」をPython + あなたの既存環境に適用します。 MulmoChatはTypeScript/Vue前提ですが、プロトコルの核心は「function callの返り値にUI提示データを載せる」ことです。 これはPython + 簡易Webフレームワークでも完全に再現できます。
# ── ファイル構成 ── scout_mulmochat/ ├── bridge_server.py # FastAPI サーバー(メイン) ├── ros_client.py # rospy でSCOUTと通信 ├── tools/ │ ├── __init__.py │ ├── get_status.py # getScoutStatus ツール │ ├── patrol.py # startPatrol / stopPatrol │ ├── correction.py # moveCorrection / rotateCorrection │ └── diagnosis.py # presentDiagnosis / askOperatorDecision ├── llm_client.py # Claude/GPT API呼び出し(tool_use対応) ├── state_monitor.py # 状態監視スレッド ├── interaction_log.py # 構造化ログ記録 └── frontend/ └── app.py # Gradio or Streamlit チャットUI
# ── bridge_server.py(概念コード) ── from anthropic import Anthropic tools = [ { "name": "getScoutStatus", "description": "SCOUTの現在状態を取得する。画像・位置・バッテリー・Nav状態を返す", "input_schema": { "type": "object", "properties": {} } }, { "name": "moveCorrection", "description": "SCOUTを指定距離だけ前後に移動させる。正=前進、負=後退", "input_schema": { "type": "object", "properties": { "distance_m": { "type": "number", "description": "移動距離(m)。-1.0〜1.0" }, "speed": { "type": "number", "description": "速度(m/s)。デフォルト0.15" } } } } ] # LLMがtool_useを返したら → 実行 → 結果を2種類で返す def execute_tool(tool_name, tool_input): if tool_name == "getScoutStatus": status = ros_client.get_status() # ROSから取得 image = ros_client.get_camera_image() # カメラ画像 return { "llm_response": f"status={status['nav']}, battery={status['battery']}%", "gui_data": { # ← これがGUI Chat Protocolの核心 "type": "status_panel", "image": image, "nav_status": status['nav'], "battery": status['battery'], "position": status['odom'] } }

07 設計原則(守るべき3つ)

LLMは判断のみ

制御は絶対にROSに委譲
  • LLMがcmd_velを直接出すことは絶対にしない
  • algo_move / algo_rollの安全制約を尊重
  • 距離・角度に上限バリデーションを入れる
  • LLMが暴走してもロボットは安全

UIは対話に溶かす

別ウィンドウは作らない
  • 画像・選択肢・状態パネルはチャット内に表示
  • ダッシュボードを作らない(対話フローが主)
  • 状況に応じてUIが出たり消えたりする
  • 会話のタイムラインが「運用ログ」になる

すべてログに残す

評価データを自動生成
  • 失敗イベント → 診断 → 選択 → 結果を構造化
  • タイムスタンプ・画像・判断理由を記録
  • 論文の評価データに直結する設計
  • TTR・介入回数・成功率が自動計算可能