クラウド経由の VLA でロボットたちを操る
2026-06-02 | Author: 井上 昌幸
はじめに
みなさん、突然ですが「Physical AI」と聞いて何を思い浮かべますか ?
ロボットアームが自律的に物をつかむ、そのための VLA(Vision-Language-Action)モデル、模倣学習、強化学習 ── 多くの方がこうしたキーワードを連想するかもしれませんね。
実は AWS では Physical AI をもっと広く捉えています。一言で言うと、知覚・理解・推論・学習を統合して物理世界と相互作用するシステム全般 です。
今回は、この広い意味での Physical AI を AWS サービスと小型ロボットで体験してみよう!ということで、AI エージェントが複数の ロボットをオーケストレーションして荷物を運ぶデモを作りました。まずはこのデモ動画を見てください。
builders.flash メールメンバー登録
クラウド経由の VLA
Physical AI の紹介記事やハンズオンの多くは、ロボットなどエッジデバイス側に VLA モデルを載せると思います。一方、すべてのロボットが VLA を動かせるほどリッチな GPU やメモリを持っているわけではないですよね。今回のような小型ロボットはもちろん、多くの場合エッジデバイスのリソースは限られています。
仮に VLA が載るリッチなロボットだとしても、各ロボットの主観カメラだけでは視野に限界があります。棚の後ろにある障害物、離れた別のロボットの位置や移動方向、全体の位置関係 ── これらは主観カメラだけで常に把握できるわけではありません。
一方、上からフィールドを見下ろす俯瞰カメラがあればどうでしょう。個々のロボットが知り得ない情報も含めて、AI が統合して判断できるようになります。
- Vision : 俯瞰カメラでフィールド全体の状況を得る
- Language : クラウドの LLM がフィールドの状況を理解し、ハイレベルなタスクを計画する
- Action : ロボットに指示を出し、物理世界を操作する
よく見ると、これって VLA のループそのものですよね。つまり、VLA モデルを各ロボット上で動かすのではなく、クラウド経由で 実現しているわけです。これによって、ロボット上に VLA モデルがあればそれを補完できますし、VLA モデルを載せられないロボットでもこれだけで賢く動けるようになります。
デモの準備
実際にデモを試す場合は以下が必要です。
- toio 2 台以上 + toio マット
- USB カメラ
- エッジ PC (今回は M1 Mac を使用)
- AWS アカウント
- ソースコード一式 (ダウンロードはこちら »)
toio は専用マット上で座標取得や指定座標への移動を API で指示できます。マットの下に黒い枠または背景紙を敷くと認識精度がよくなります。USB カメラは上から toio マットを見下ろすように設置します。セットアップ手順の詳細は ダウンロード した README.md を参照してください。
アーキテクチャ
全体のアーキテクチャはこんな感じです。AWS IoT Core をメッセージバスとして使用し、ロボットへの指示、AI の思考過程のリアルタイム表示などを MQTT トピックでまかなっています。
全体の流れ
全体の流れは以下のようになります。
- map_parser がカメラでフィールドの状況を撮影し、YOLOE(後述) でオブジェクトを検出、 toio マットを 5×7 に区切ったグリッドマップを生成、MQTT で AWS IoT Core に publish (toio/map)
- IoT Rule が AWS Lambda を起動。Strands Agent が Amazon Bedrock (Claude Sonnet) を使ってグリッドマップを分析し、ロボットへのタスク割り当てを判断。さらに Strands Agent は複数ロボットの衝突しない経路を計画する CBS Solver をツールとして呼び出し、衝突回避経路を計算。
- 計算された経路 (waypoints) を MQTT で publish(toio/waypoints)
- Bedrock の思考過程は MQTT でリアルタイムにストリーミング (toio/agent/thinking)
- walker が waypoints を受信し、BLE でロボットの API をコール。荷物を押して目標位置に運ぶ。
- 移動完了後、map_parser が再度マップを送信。残りの荷物がなくなるまで処理をループする。
大まかに、エッジ側の物体検知とクラウド側の運行計画の 2 層構造になっていることがわかりますね。それぞれ詳しく見ていきましょう。
エッジでの物体検出
エッジ側では、カメラ映像からロボット、荷物、障害物を検出する必要があります。
通常、物体検出の ML モデルを使おうとすると、オブジェクトごとに大量のラベル付きデータを用意して学習させる必要があります。これがなかなか大変です。
今回は YOLOE の Visual Prompts という機能を使いました。Visual Prompts を使うと、参照画像を 1 枚用意して、検出したいオブジェクトにバウンディングボックスを描くだけです。ワンショットでのラベル付けが完了し、学習なしでオブジェクトを検出できます。この作業は同梱のスクリプト (tools/capture_reference.py と tools/draw_bbox.py) で行えます。
エッジの Mac (M1) 上で 4 ~ 5 FPS 程度で処理できるので、ほぼリアルタイムにフィールドの状況を認識し続けることができます。
グリッドマップに変換
検出結果は 5×7 のグリッドマップに変換されます。各セルには「空き」「ロボット」「荷物」「障害物」のラベルが入ります。
{
"grid": [
["__", "__", "__", "GT", "__", "__", "__"],
["BT", "__", "__", "__", "PA", "__", "__"],
["__", "__", "BL", "__", "BL", "__", "__"],
["__", "__", "PA", "__", "PA", "__", "__"],
["__", "RT", "__", "__", "__", "__", "__"]
],
"legend": {
"RT": {"name": "Red Toio", "type": "robot"},
"BT": {"name": "Blue Toio", "type": "robot"},
"GT": {"name": "Green Toio", "type": "robot"},
"PA": {"name": "Package", "type": "cargo"},
"BL": {"name": "Block", "type": "obstacle"}
}
}
このグリッドマップが、クラウド側の AI エージェントへの入力になります。カメラ映像という非構造データを、AI が扱いやすい構造化データに変換する ── これが map_parser の役割です。画像をそのまま LLM に送るのではなくコンパクトな JSON にすることで、クラウド側の処理負荷やレスポンスタイムも抑えられます。
クラウドでの運行計画
クラウド側では、Lambda 上の Strands Agents SDK で構築した AI エージェントがグリッドマップを受け取って判断します。
LLM が担うのは運行計画 (タスクプランニング) です。具体的には:
- 「荷物を端に片付けて」という指示を、具体的な座標として解釈する
- どのロボットにどの荷物を割り当てるか判断する (最寄りの荷物を割り当てる等)
- 障害物の配置を考慮して、到達可能なゴールを選ぶ
- 荷物が目標位置を塞いでいる場合、先にそれを動かす判断をする
- 複数ロボット同時運行で経路が見つからなかった場合、 1 台ずつ動かすようにフォールバック
- 荷物がロボットより多い場合、複数ラウンドに分けて片付ける
実際の経路計算は LLM ではなく CBS Solver に任せます。これは Strands Agents SDK の @tool として実装されています。LLM がタスクを決めると、ツール呼び出しで CBS Solver を起動し、衝突回避経路を計算します。
Multi-Agent Path Finding
複数のロボットが同時に動いて衝突しない経路を見つける問題は、MAPF (Multi-Agent Path Finding) として知られています。このデモでは、MAPF の代表的なアルゴリズムである CBS (Conflict-Based Search) を使っています。
CBS は以下のような二段階の探索で構成されます。
- 低レベル探索 : 各ロボットの最短経路を個別に計算する (通常の A* 探索)
- 高レベル探索 : 計算された経路同士に衝突がないかチェックする。衝突があれば制約を追加して、低レベル探索をやり直す
これだけだとよくわからないですね。もう少し具体的に見てみましょう。まず、各ロボットが他のロボットを無視して最短経路を計算します。当然、経路が交差してしまうことがあります。例えば「ステップ 3 でロボット A とロボット B が同じセルにいる」という衝突が見つかったとします。
CBS はここで「ロボット A はステップ 3 にそのセルを使ってはいけない」という時刻付きの制約を追加して、ロボット A の経路だけを再計算します。再計算の結果、今度は別の場所で衝突が起きるかもしれません。その場合はさらに制約を追加して再計算 ── これを衝突がなくなるまで繰り返します。
全ロボットの経路を一度に計算するのではなく、衝突が見つかった箇所だけをピンポイントで修正していく。これが CBS の効率の良さです。
通常の MAPF/CBS では、ロボットがゴール地点に移動するだけです。しかし今回はゲームの「倉庫番 (Sokoban) 」のように、ロボットが荷物を押して運びます。つまり、ロボットと荷物が同時に動くため、状態空間が「ロボット位置」だけでなく「 (ロボット位置, 荷物位置) 」のペアになります。
複数のロボットがそれぞれ荷物を押しながら、互いにぶつからず、障害物も避ける ── いわばマルチエージェント倉庫番です。通常の MAPF よりも複雑な問題ですが、CBS の枠組みを拡張することで解くことができます。
MAPF についてもっと詳しく知りたい方は、マルチエージェント経路計画の紹介という記事が非常にわかりやすいのでおすすめです。
AI エージェントの思考過程
実際に AI エージェントがどのように考えているか、MQTT でストリーミングされた思考過程を見てみましょう。
マップを分析します。
0 1 2 3 4 5 6
0 __ __ __ GT __ __ __
1 BT __ __ __ PA __ __
2 __ __ BL __ BL __ __
3 __ __ PA __ PA __ __
4 __ RT __ __ __ __ __
- ロボット: GT(0,3)、BT(1,0)、RT(4,1)
- パッケージ: PA(1,4)、PA(3,2)、PA(3,4)
- 障害物: BL(2,2)、BL(2,4)
- ゴール: 左上に 3 個詰める
戦略 (1回目)
- 🔵 BT → PA(3,2) → (0,0)
- 🔴 RT → PA(3,4) → (0,1)
- 🟢 GT → PA(1,4) → (0,2)
CBS Solver 呼び出し: 解なし。ゴール位置の割り当てが噛み合わず競合する。
戦略 (2回目) — 担当を入れ替えて再試行
- 🟢 GT → PA(1,4) → (0,0)
- 🔵 BT → PA(3,2) → (0,1)、BL(2,2) を迂回
- 🔴 RT → PA(3,4) → (0,2)
CBS Solver 呼び出し: 解あり (GT:11steps, BT:12steps, RT:15steps)
3台が並列で動き、BL を迂回しながらパッケージを左上に集結する。
マップを分析します。
0 1 2 3 4 5 6
0 PA PA PA RT __ __ __
1 GT BT __ __ __ __ __
2 __ __ BL __ BL __ __
3 __ __ __ __ __ __ __
4 __ __ __ __ __ __ __
PA はすでに (0,0)、(0,1)、(0,2) に揃っている。移動は不要。
ALL_DONE
1 回目の試行では CBS Solver が解を見つけられませんでしたが、エージェントが自律的に目標位置を微調整して再試行し、 2 回目で解が見つかっています。
この後ロボットが実際に動いて、三つの荷物を運んだところでラウンド 1 が完了。その後、 map_parser が再度マップを送信し、完了状態をチェックします。ここで、もし荷物がロボットより多くて、まだ残っている場合は、全て運び終わるまでラウンドを繰り返して箱を隅に片付けます。
この「考えて、試して、ダメなら別の方法を試す」というプロセスが、まさに AI エージェントの強みです。固定的なルールベースのシステムでは、こうした柔軟な対応は難しいでしょう。
まとめ
筆者プロフィール
井上 昌幸
アマゾン ウェブ サービス ジャパン合同会社
IoT Specialist Solutions Architect
Internet of Things と Robotics 界隈で面白い事を探しながら、今日もこつこつリアルな世界とクラウドを繋いでいます。あなたのとっておきのアイデアを AWS と一緒にカタチにしましょう。