「動いてよい」と言われるまで動かない。倉庫ロボット制御基盤を、まずシミュレーションで作った記録

Amir Nouri 13分で読めます

これはOrreryの自社R&Dプロジェクトで、お客様からの受託案件ではありません。私たちが開発している倉庫ロボットの制御基盤が、シミュレーション上の倉庫で端から端まで動くようになりました。オペレーター向けの管理画面、現場で床全体を動かすエッジサーバー、そして機器そのもの。この3つがコマンド1つで立ち上がります。実際に動いている画面も、この記事の後半でお見せします。

最初にお伝えしておきます。この記事の数値と画面は、すべて開発機上のシミュレーションのものです。この基盤はどこにも公開・導入しておらず、実機のロボットもまだ動かしていません。 計画から「動く姿を見られるシステム」になるまでの道のり、測ったこと、まだ終わっていないことを、そのまま書きます。

倉庫フロアの線画。棚、レーンAとB、レーンを予約したフォークリフトagf-03、agf-07、コンベヤーplc-01、稼働中のアーム作業区画pnp-02、人が入ったためHOLD・R4と表示されたpnp-01。

基準サイトwh-sim-01(機器16台)。サイトのルールから描いた図で、画面写真ではありません。実際の画面はこの後に続きます。

課題:1つの床に、種類の違う機械が並ぶ

倉庫の床は、1つのシステムではありません。基準サイト「wh-sim-01」には、フォークリフト8台、ロボットアーム2台、カメラ3台、PLC2台、環境センサー1台の計16台があります。実際の現場ならメーカーも通信方式もばらばらで、同じ通路を人も歩きます。

求められたのは、すべてを1つの画面で見渡せること。1台にも全台にも指示を出せること。そしてネットワークやサーバー、ディスクが落ちても、動いてはいけない機械を動かさないことでした。

最初の判断:3つの層を、文書にした「契約」だけでつなぐ

基盤は3つの層に分け、層どうしは文書で定めた契約(やりとりの決まり)だけでつなぎました。

  • L1 管理画面とクラウド:ライブのフロアマップ、アラーム、指示、履歴と分析を複数拠点で。権限は7種類、画面は日本語と英語に対応しています。
  • L2 エッジ:現場で動くサーバーです。機器を受け入れ、床の最新の状態を保ち、フォークリフトがぶつからないよう経路を管理し、カメラ画像からパレットの作業を作ります。ノードやWANが落ちても止まりません。
  • L3 機器と、それを囲む世界:各機械に入るエージェントと、物理シミュレーション。バッテリー、電波の届かない場所、通路を歩く人、MuJoCoによるアームの物理、カメラ画像の生成まで再現します。ロボットの定義はコードではなくYAMLのデータです。

L1とL2の間はNATSとprotobufの「北側の契約」、L2とL3の間は独自プロトコルに加え、VDA 5050、MQTT上のJSON、OPC UA、RTSPを使う「南側の契約」で、通信は相互TLSです。ある層が別の層の中身を直接読み込もうとすると、ビルドが失敗するようにしてあります。

各層はまず代役を相手に単独で作り、試しました。そのうえで代役を1つずつ外します。ゲートI1では本物の管理画面を変更なしで本物のエッジにつなぎ、ゲートI2では機器のエージェントを模擬環境の代わりに本物のエッジへ接続しました(途中でエッジの引き継ぎを2回はさむ約45分の試験)。その後、make up-all で3つの層すべてが、代役なしで互いの上に立ち上がるようになりました。

計画から、動く姿を見られるシステムへ

図やテストの件数だけでは伝わらないことがあります。2026年10月18日、make up-all で動かしたシステムの画面を記録しました。Part 3の模擬フロア、Part 2の本物のエッジ、Part 1のクラウドと管理画面です。画面上の黄色い注記(英語)は私たちが加えたもので、それ以外は画面に映ったままです。

まずは世界そのものから。3Dビューアーは、Part 3の床を毎秒10回の更新でブラウザに描き、FoxgloveやLichtblickにも配信できます。

16台の機器が並ぶ模擬倉庫の3D表示。左のパネルに発生中の障害F24(arm-01)とF01(agf-03)、停止中のarm-01が表示され、arm-01とagf-03は赤。高い棚の裏にピンクの電波不感エリアがある。

わざと2つの障害を起こしたときの3Dビューアー。arm-01の作業区画に人が入り(F24)、agf-03の非常停止ボタンが押されています(F01)。左のパネルには、発生中の障害、停止中の機器、オフラインの機器が並びます。ピンクの部分は高さ6mの棚の裏にある電波不感エリアです。

カメラもシミュレーションです。だからこそ、画像認識を正直に試せます。カメラcam-01の映像はシード値から生成され、高さ6m、1ピクセルあたり床9.4mm。日光、影、レンズのぼけ、センサーのノイズまで再現します。画像ごとに深度、セグメンテーション、インスタンスマスク、各パレットの正確な位置と向きが付き、エッジのパレット検出はこの正解に対して3cm・2度以内であることが求められます。同じシード値なら、画像はバイト単位まで同じになります。

上から見た倉庫の床のカメラ画像。スロットからずれて回転したパレット、スロットにまっすぐ置かれたラップ巻きのパレット、床に塗られたスロットの枠、画面に入ってくるオレンジのフォークリフトと長い影。

cam-01の映像。スロットから0.40mずれて10.3°回転したパレット、slot-a2にまっすぐ置かれたラップ巻きのパレット、画面に入ってくるフォークリフト(AGF-1600)。影は方位268°、449ルクスの太陽によるものです。

深度画像。パレットが距離に応じた灰色の濃淡で表示されている。

深度:cam-01の同じフレームに付く正解データ。

セグメンテーション画像。パレットとフォークリフトが種類ごとの色の面で表示されている。

セグメンテーション:cam-01の同じフレームに付く正解データ。

インスタンス画像。パレットとフォークリフトが1つずつ別の色で表示されている。

インスタンス:cam-01の同じフレームに付く正解データ。

wh-sim-01での p3ctl dataset -seed 42 のフレーム0。どの画像にも、このような正解データが付きます。

オペレーター側では、サイトのすべての機器が1つのライブ一覧に並びます。表示する内容は機器の種類ごとに違い、フォークリフトならバッテリー・積荷・作業、アームならピック数とサイクル、カメラなら埋まっているスロット。管理画面が知らない種類の機器も、機器が送ってくるファクトシートから表示します。その裏で、エッジは稼働中の機器を自分の台帳で管理しており、台帳に追加した機器は実際に接続するまでOFFLINEのままです。

Simulated warehouse 01の機器一覧(LIVE表示)。フォークリフト、アーム、カメラ、コンベヤーPLC、環境センサーの各行に、状態、健全性、種類ごとの詳細が並ぶ。

オペレーターとしてサインインした機器一覧。フォークリフト8台、アーム2台、カメラ3台、コンベヤーPLC2台、環境センサー1台。サイトからの配信が止まると、LOSTとして全行が灰色になります。

エッジが提供する機器台帳の表。機器ごとに型式、シリアル、ファームウェア、接続状態が並び、古いファームウェアが1件示されている。

本物のエッジが提供する台帳(リビジョン2)。型式、シリアル、ファームウェア、エッジから見た接続状態が並びます。

2つ目の判断:機械は「動いてよい」と言われたときだけ動く

多くのシステムは、何か起きたときにロボットを止めます。私たちは考え方を逆にしました。機械は新しい許可(運転許可)を持っている間だけ新しい動作を始められる。つまり、サーバーからの連絡が途絶えること自体が「停止」になります。

エッジは500ミリ秒ごとに許可を送ります。許可は機器自身の時計で1秒間有効で、止めるべき機器の名前も含みます。エッジの停止、ブローカーの障害、回線の切断で許可が届かなくなれば、監視下の機器はすべて、最後の許可から1秒以内に停止します。

機器の時計での時系列図。許可が0.5秒ごとに送られ、それぞれ1秒間有効。1.5秒でエッジが失われ、最後の許可が切れた後に「ALL DEVICES HOLD」の赤い帯が続く。

運転許可のしくみ。バス上の500ミリ秒未満の途切れは見逃され、そのコストは最大で許可1回分です。

この許可の上に、R1〜R9の9つの監視ルールがあります。ライトカーテンやレーザースキャナーが作業区画の人を検知すると(R4)、アームは許可1回分、シミュレーションで約150ミリ秒のうちに停止し、ガードをリセットするまで止まったままです。機器からの連絡が途絶えると(R1)、アラームを上げ、その機器には何も送らず、フォークリフトは再び連絡が来るまで予約した床を確保し続けます。

ライブマップでは、こう見えます。まず、障害のない状態です。

wh-sim-01のライブフロアマップ。フォークリフトは矢印、コンベヤーつきの2つのアーム作業区画、入庫スロットの間のカメラ、凡例。

障害のない状態のwh-sim-01のライブマップ。

次に、nmzctl fault inject でエッジ経由の障害を2つ起こしました。agf-03の非常停止(F01)と、agf-04の電波不感(F05)です。

数秒後の同じライブマップ。非常停止が押されたagf-03が赤、位置情報が4秒前のまま灰色になったagf-04、タブにアラーム数、アームは稼働を継続。

agf-03は赤。agf-04は連絡が途絶えている間、決して「生きている」ようには見えません。最後の位置の古さ(ここでは4秒)とともに灰色になります。エッジはこれをLOSTと判断し、予約した床を確保し続けます(ルールR1)。アームは作業を続けています。

約1分後、F24でarm-01の作業区画に人を入れた後のアラーム画面です。

優先度順に並ぶアラーム画面。arm-01の作業区画への人の侵入と、その根拠となる監視ルール、アームとともに停止した作業区画、復帰したagf-04のアラームが確認待ちのまま残っている様子。

arm-01の作業区画のアラームには、根拠となる監視ルールが示されます。2回発生したアラームも1件として数え、作業区画はアームとともに停止します。agf-04は復帰していますが、そのアラームは人が自分の名前で確認するまで残ります。

危険をともなう操作は人が判断します。一時停止からの再開には再認証、全台の再開にはもう1人の承認が必要で、すべての指示は重複実行を防ぐキーとともに操作記録に残ります。

大事な前提があります。実際の現場では、作業区画そのものの安全回路が先に働き、私たちの停止は2段目です。このソフトウェアは監視を加えるもので、認証を受けた安全装置の代わりにはなりません。

証明する:上限を先に決め、障害はわざと起こす

性能の数値は、測る前に上限を文書で決め、最悪値をその上限と比べました。すべて開発機でのローカル計測です。

  • 全台一時停止から全機器の停止まで:約100ミリ秒(上限1秒)
  • エッジ1台に1,000台の機器、状態がクラウドに届くまで:p95で81ミリ秒(上限500ミリ秒)
  • オペレーター500人の同時閲覧、機器から画面まで:p95で153ミリ秒(上限500ミリ秒)
7つの指標について、最悪の計測値が上限の何%かを示す横棒グラフ。全台一時停止の約10%から、500セッションでの機器から画面までの31%まで。どの棒も100%よりはるかに手前で終わっている。

最悪の計測値が上限に占める割合(短いほど良い)。グラフの表記は英語です。

障害カタログには、非常停止や通路上の人から、電波不感、時計のずれ、証明書の期限切れまで25種類があります。どれも上の画面のように任意に起こすことができ、エッジの反応をシミュレーターが持つ正解と照らし合わせるテストがあります。独自に2種類も加えました。リポジトリの文書に記録された長時間試験では、シミュレーション上の8時間でフォークリフト20台が6,826回走行して一度も重ならず、72時間のWAN断では安全イベントを先頭に1件ずつ順番どおり再送でき(10回中10回成功)、エッジのリーダーをkill -9で強制終了しても3.4〜7.7秒で後継が引き継ぎ、リーダーが2つ同時に存在したことはありません。

2026年10月18日時点のソースから数えると、Go、TypeScript、C#で約1,700件のテスト関数があり、最も多いのは安全ロジックを持つエッジです。これは書かれたテストの数で、検証項目の数ではありません。また、この記事のために全テストを再実行してはいません。

領域別のテスト関数の数を示す横棒グラフ。エッジ841、キット257、機器と世界256、管理画面の単体テスト124、クラウド118、ブラウザテスト43、Unityツイン32、コンポーネントストーリー29。

領域別のテスト関数の数。安全ロジックを持つエッジが最多です。

まだ終わっていないこと

残っている項目です。

  • 公開・導入はしていません。 動いているのは私たちの開発機の上だけです。
  • 実機はまだです。 機器も人も電波も物理もシミュレーションで、カメラ画像も生成したものです。実機の入出力は、模擬の試験台でしか確かめていません。
  • CI(自動テストの仕組み)は止めています。 GitHubのワークフロー6本は用意済みですが、私たちの判断でいまは無効にしてあり、上記のテストはすべて手元で実行したものです。
  • 192時間の耐久試験は、きれいな形では終わっていません。 共有マシンで一度最後まで走り、メモリリークはありませんでした。その前の試行はホストの停滞とシミュレーターの不具合(修正済み)で失敗しており、専用マシンでの再実行がまだ残っています。
  • 細かな残り: 本物のエッジで動くブラウザテストは43件中約21件(残りは設計上スキップ)、基準ノートPCでのデジタルツインのフレームレートは未計測、経路計画は第1版、設計上の未決事項が3つあります。

なぜ、こうした開発をするのか

私たちは、自分たちの技術を磨くためにこうしたR&Dに取り組んでいます。ロボットを何十台も動かしている会社は多くありません。それでも、この開発で守った習慣は、中小企業のAI業務改善でもそのまま使えます。

  1. 先に契約を決める。 部分ごとに試し、入れ替えられるようにします。
  2. 動く姿を見せる。 障害時も含めて動いている様子を見られるシステムは、図よりも信頼できます。
  3. 途絶えたら止まる設計にする。 接続や確信を失った自動化は、続けずに止まって人に確認します。
  4. 危険な操作は人が承認する。 承認の手順と、本人の名前が残る操作記録を用意します。
  5. 測る前に上限を決め、終わっていないことも公開する。

こうした設計の考え方を御社の業務にも取り入れたい場合は、Orreryの 無料AI業務診断 をご利用ください。オンライン(最大60分)または訪問でお話を伺い、御社に合わせたAI導入プランをご提案します。

出典:私たちのエンジニアリング報告(2026年10月18日)。リポジトリのREADME、 TESTING.md 、各パートのREADMEにもとづきます。画面は2026年10月18日に make up-all のシミュレーションで記録したもので、障害はわざと起こし、その後解除しています。遅延・処理量の数値は開発機でのローカル計測です。

ご案内

業務の流れを教えてください。AIで一番時間が浮く場所をお見せします。

無料AI業務診断(30分)