notes
ToolsDebug webui

Debug WebUI のアーキテクチャ

config-driven の debug UI パターン。settings ページで widget と launch/topic/service を bind、debug ページで実行、Foxglove layout も動的生成

要点: settings ページで「ボタンにこの launch を割り当てる」等の config を JSON で持ち、debug ページはそれを render して実行する pattern。launch spawner は backend + whitelist、topic/service/param は rosbridge、Foxglove layout は URL 経由で動的生成。

構成#

[Settings ページ]
  widget 定義を JSON で作成/編集
  各 widget に action を bind
    → backend storage に永続化

[Debug ページ]
  設定を fetch → widget を render
  クリック/変更 → backend API 呼び出し
    - launch: subprocess で spawn (whitelist)
    - topic/service/param: rosbridge WebSocket
    - Foxglove layout: 生成 URL で外部リンク

Widget の種類#

type用途action の中身
button単発トリガーlaunch spawn / service call / topic pub
slider連続値ros2 param set / topic pub (数値)
toggleON/OFFtopic pub (bool) / service call
monitor表示のみtopic subscribe → 数値/文字列表示
layout-linkFoxglove ジャンプ生成 layout URL に redirect

Config スキーマ例#

{
  "sections": [
    {
      "title": "Motor debug",
      "widgets": [
        {
          "id": "launch-motor-test",
          "type": "button",
          "label": "Launch motor test",
          "action": { "type": "launch", "pkg": "motor_test", "file": "steering.launch.py" }
        },
        {
          "id": "steering-angle",
          "type": "slider",
          "label": "steering angle",
          "min": -1.5, "max": 1.5, "step": 0.01,
          "action": { "type": "topic_pub", "topic": "/steering/target", "type_name": "std_msgs/msg/Float64" }
        },
        {
          "id": "estop",
          "type": "button",
          "label": "E-STOP",
          "style": "danger",
          "action": { "type": "service_call", "service": "/safety/estop", "type_name": "std_srvs/srv/Trigger" }
        }
      ]
    }
  ]
}

Backend の役割#

API内容
GET /configSettings JSON を返す
PUT /configSettings JSON を保存
POST /launchwhitelist 内の launch を spawn (PID 返す)
POST /launch/:pid/stop動作中 launch を kill
GET /launches動作中 launch の一覧
POST /foxglove-layoutscenario から layout JSON 生成

Topic/service/param は rosbridge が担当、backend は経由しない。

Foxglove layout 動的生成#

Foxglove は URL 経由で layout を読み込める:

https://app.foxglove.dev/?layoutURL=https://your-webui/layouts/motor-debug.json

Backend が /layouts/:scenario.json で JSON を生成:

  • テンプレート layout + topic 名を差し替え
  • 選択された scenario に応じて必要な panel を組み替える
  • 例: 「モータデバッグ」→ RawMessages + Plot(velocity) + Log

Layout JSON のスキーマは Foxglove の "Import from URL" 機能をブラウザで一度使い、export して雛形にするのが早い。

Launch spawner のセキュリティ#

Launch を web から起動するのは shell 経由なので必ず対策する:

  • whitelist: 起動可能な (pkg, launch_file) ペアを定義ファイルに列挙、それ以外は拒否
  • 引数 validate: numeric range、enum、regex で制限。arbitrary string 禁止
  • 権限: WebUI プロセスを root で走らせない、専用ユーザーに
  • ROS_DOMAIN_ID を limit: 本番 domain と debug domain を分離
  • プロセス管理: PID tracking、timeout 自動 kill、on shutdown 全 kill
  • 認証: WebUI 自体を Cloudflare Access 等で保護 (誰でもアクセスできない状態にする)

実装フェーズ (見積)#

合計 4-5 日程度。既存 UI を土台にすれば削減可能。

推奨: 段階リリース#

  1. まず Settings スキーマだけ確定 (機能追加せず yaml/json で編集)
  2. Debug page で rosbridge 経由の widget から作る (launch は後回し)
  3. Launch spawner は最後 (セキュリティ検討要)
  4. Foxglove layout 生成は独立させて後付け

いきなり全部作ると security 検討が浅くなる。rosbridge 経由部分だけなら数日で MVP が動く。

関連#

最終更新:

On this page