これはOrreryの自社R&Dプロジェクトで、お客様からの受託案件ではありません。私たちが開発している倉庫ロボットの制御基盤が、シミュレーション上の倉庫で端から端まで動くようになりました。オペレーター向けの管理画面、現場で床全体を動かすエッジサーバー、そして機器そのもの。この3つがコマンド1つで立ち上がります。実際に動いている画面も、この記事の後半でお見せします。
最初にお伝えしておきます。この記事の数値と画面は、すべて開発機上のシミュレーションのものです。この基盤はどこにも公開・導入しておらず、実機のロボットもまだ動かしていません。 計画から「動く姿を見られるシステム」になるまでの道のり、測ったこと、まだ終わっていないことを、そのまま書きます。
基準サイト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にも配信できます。
わざと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の同じフレームに付く正解データ。
インスタンス:cam-01の同じフレームに付く正解データ。
wh-sim-01での p3ctl dataset -seed 42 のフレーム0。どの画像にも、このような正解データが付きます。
オペレーター側では、サイトのすべての機器が1つのライブ一覧に並びます。表示する内容は機器の種類ごとに違い、フォークリフトならバッテリー・積荷・作業、アームならピック数とサイクル、カメラなら埋まっているスロット。管理画面が知らない種類の機器も、機器が送ってくるファクトシートから表示します。その裏で、エッジは稼働中の機器を自分の台帳で管理しており、台帳に追加した機器は実際に接続するまでOFFLINEのままです。
オペレーターとしてサインインした機器一覧。フォークリフト8台、アーム2台、カメラ3台、コンベヤーPLC2台、環境センサー1台。サイトからの配信が止まると、LOSTとして全行が灰色になります。
本物のエッジが提供する台帳(リビジョン2)。型式、シリアル、ファームウェア、エッジから見た接続状態が並びます。
2つ目の判断:機械は「動いてよい」と言われたときだけ動く
多くのシステムは、何か起きたときにロボットを止めます。私たちは考え方を逆にしました。機械は新しい許可(運転許可)を持っている間だけ新しい動作を始められる。つまり、サーバーからの連絡が途絶えること自体が「停止」になります。
エッジは500ミリ秒ごとに許可を送ります。許可は機器自身の時計で1秒間有効で、止めるべき機器の名前も含みます。エッジの停止、ブローカーの障害、回線の切断で許可が届かなくなれば、監視下の機器はすべて、最後の許可から1秒以内に停止します。
運転許可のしくみ。バス上の500ミリ秒未満の途切れは見逃され、そのコストは最大で許可1回分です。
この許可の上に、R1〜R9の9つの監視ルールがあります。ライトカーテンやレーザースキャナーが作業区画の人を検知すると(R4)、アームは許可1回分、シミュレーションで約150ミリ秒のうちに停止し、ガードをリセットするまで止まったままです。機器からの連絡が途絶えると(R1)、アラームを上げ、その機器には何も送らず、フォークリフトは再び連絡が来るまで予約した床を確保し続けます。
ライブマップでは、こう見えます。まず、障害のない状態です。
障害のない状態のwh-sim-01のライブマップ。
次に、nmzctl fault inject でエッジ経由の障害を2つ起こしました。agf-03の非常停止(F01)と、agf-04の電波不感(F05)です。
agf-03は赤。agf-04は連絡が途絶えている間、決して「生きている」ようには見えません。最後の位置の古さ(ここでは4秒)とともに灰色になります。エッジはこれをLOSTと判断し、予約した床を確保し続けます(ルールR1)。アームは作業を続けています。
約1分後、F24でarm-01の作業区画に人を入れた後のアラーム画面です。
arm-01の作業区画のアラームには、根拠となる監視ルールが示されます。2回発生したアラームも1件として数え、作業区画はアームとともに停止します。agf-04は復帰していますが、そのアラームは人が自分の名前で確認するまで残ります。
危険をともなう操作は人が判断します。一時停止からの再開には再認証、全台の再開にはもう1人の承認が必要で、すべての指示は重複実行を防ぐキーとともに操作記録に残ります。
大事な前提があります。実際の現場では、作業区画そのものの安全回路が先に働き、私たちの停止は2段目です。このソフトウェアは監視を加えるもので、認証を受けた安全装置の代わりにはなりません。
証明する:上限を先に決め、障害はわざと起こす
性能の数値は、測る前に上限を文書で決め、最悪値をその上限と比べました。すべて開発機でのローカル計測です。
- 全台一時停止から全機器の停止まで:約100ミリ秒(上限1秒)
- エッジ1台に1,000台の機器、状態がクラウドに届くまで:p95で81ミリ秒(上限500ミリ秒)
- オペレーター500人の同時閲覧、機器から画面まで:p95で153ミリ秒(上限500ミリ秒)
最悪の計測値が上限に占める割合(短いほど良い)。グラフの表記は英語です。
障害カタログには、非常停止や通路上の人から、電波不感、時計のずれ、証明書の期限切れまで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件のテスト関数があり、最も多いのは安全ロジックを持つエッジです。これは書かれたテストの数で、検証項目の数ではありません。また、この記事のために全テストを再実行してはいません。
領域別のテスト関数の数。安全ロジックを持つエッジが最多です。
まだ終わっていないこと
残っている項目です。
- 公開・導入はしていません。 動いているのは私たちの開発機の上だけです。
- 実機はまだです。 機器も人も電波も物理もシミュレーションで、カメラ画像も生成したものです。実機の入出力は、模擬の試験台でしか確かめていません。
- CI(自動テストの仕組み)は止めています。 GitHubのワークフロー6本は用意済みですが、私たちの判断でいまは無効にしてあり、上記のテストはすべて手元で実行したものです。
- 192時間の耐久試験は、きれいな形では終わっていません。 共有マシンで一度最後まで走り、メモリリークはありませんでした。その前の試行はホストの停滞とシミュレーターの不具合(修正済み)で失敗しており、専用マシンでの再実行がまだ残っています。
- 細かな残り: 本物のエッジで動くブラウザテストは43件中約21件(残りは設計上スキップ)、基準ノートPCでのデジタルツインのフレームレートは未計測、経路計画は第1版、設計上の未決事項が3つあります。
なぜ、こうした開発をするのか
私たちは、自分たちの技術を磨くためにこうしたR&Dに取り組んでいます。ロボットを何十台も動かしている会社は多くありません。それでも、この開発で守った習慣は、中小企業のAI業務改善でもそのまま使えます。
- 先に契約を決める。 部分ごとに試し、入れ替えられるようにします。
- 動く姿を見せる。 障害時も含めて動いている様子を見られるシステムは、図よりも信頼できます。
- 途絶えたら止まる設計にする。 接続や確信を失った自動化は、続けずに止まって人に確認します。
- 危険な操作は人が承認する。 承認の手順と、本人の名前が残る操作記録を用意します。
- 測る前に上限を決め、終わっていないことも公開する。
こうした設計の考え方を御社の業務にも取り入れたい場合は、Orreryの 無料AI業務診断 をご利用ください。オンライン(最大60分)または訪問でお話を伺い、御社に合わせたAI導入プランをご提案します。
出典:私たちのエンジニアリング報告(2026年10月18日)。リポジトリのREADME、 TESTING.md 、各パートのREADMEにもとづきます。画面は2026年10月18日に make up-all のシミュレーションで記録したもので、障害はわざと起こし、その後解除しています。遅延・処理量の数値は開発機でのローカル計測です。