サービスロボット導入シミュレーション Log#11 | 詰まりの元は、ロボットを線に縛った作りだった
配膳ロボットを2台入れたファミレスを、Unity(建物や人を3Dで置いて動かせるソフト)の中で動かすと、2台が通路で向かい合ったまま動けなくなる場面が何度も出ていました。直しても直しても、詰まる場所が変わるだけでした。調べていくと、詰まりの元は、ロボットを決まった線の上しか走らせない Unity の作りでした。 実際の配膳ロボットは、店の地図の上で行き先までの道をその都度自分で引き、前に人やロボットがいれば止まるか回り込みます。Unity のロボットは、サイトから渡された1本の線をたどるだけで、横へ寄ることができませんでした。
この Unity の店は、サイトに置いている配膳ロボットの試算( https://pixelstomotors.com/series8 )と比べるために作っています。試算は、ロボットや人を点として動かす計算です。Unity は、同じ店の形・同じ人数・同じ客の数を、床・卓・人の体のある3Dの店で動かします。前の記事では、ロボットなしなら両者はほぼ合い、ロボットを入れたときだけ料理の待ちが大きくずれることが分かっていました。
今回は、そのずれの理由を調べるところから始めました(段階C)。一番大きかったのは、数字を数える側の問題です。ロボットが運んだ皿は、ロボットが往復を終えて受け渡し口に戻るまで「届いた」になっていませんでした。 料理は卓に置かれているのに、客はロボットが戻るまで食べ始めません。これだけで、料理の待ちが1皿あたり1.0〜1.3分長く出ていました。
それを直して回すと、今度は店が止まりました。2台が行き止まりの通路で向かい合い、600秒で打ち切られたあと、2台とも受け渡し口の同じ点に置き直されて重なりました。重なった2台は、お互いを「前にいるロボット」として止まり続けます。ここも直して、ようやく最後まで回るようになりました。
それでもロボットどうしの詰まりは残ります。店の形を変えようかという話から、なぜロボットどうしは譲り合えないのか、という問いになりました。答えは店の形ではなく、ロボットの動き方の作りにありました。
| やったこと | なぜ | 結果 |
|---|---|---|
試算とのずれを10項目に分け、理由を付けた | ずれを直し続けず、理由を調べるため | 一番大きいのは、皿の「届いた」を往復の終わりに数えていたこと |
皿を、卓に着いた時点で「届いた」にした | 試算と同じ数え方にするため | ロボットが運ぶ時間が2.90分から1.09分に |
打ち切ったロボットを、ほかの台と重ねて置かないようにした | 2台が重なって店が止まったため | 打ち切り11回で、重なりは0回 |
同じ乱数の種なら、同じ客が来るようにした | 動きが少しずれただけで、来る客が83組から105組に変わったため | ロボット2台と0台の回で、64組が同じ時刻・同じ人数で来た |
ロボットを線から外し、地図の上で自分で道を引く形にすると決めた | 実際の配膳ロボットはそう動くため | これから(次の版) |
下の図で、③の店の道の線と、ロボットが60秒以上止まった場所、店が止まった回の動きを切り替えて見られます。
作業ログ ― この記事で扱う範囲と、Unity の版
前の記事(LOG367)は、③(効率重視・入口が角の店)と⑦(③の通路を0.95mに狭めた店)で、ロボット0・1・2台を乱数の種3つずつ、合わせて18回回して台帳にまとめたところで終わりました。この記事は、その18回を使ってサイトとのずれを調べた段階Cから、ずれの直しを Unity に入れて確かめた所までです。
Unity のコードは Claude Code(Unity のコードを書く AI)が書き、Claude が記録を読んで原因を調べ、依頼文を作りました。Unity のメニューを押して回すのと、画面を見て詰まりに気づくのは手で行いました。版は Unity Version Control の Check-in の番号で書きます。
| 版 | 中身 | 動きが変わったか |
|---|---|---|
| cs:140 | 段階Bの18回を回した版(前の記事) | ― |
| cs:141 | v8:皿を卓に着いた時点で届いたにする/往復の記録の1行ずれを直す/押し直しの照らし合わせに版を入れる。v8b:打ち切りで重ねない/来る客を組ごとの乱数にする | 変わった |
この研究の段階は、前の記事で決めた3つです。
| 段階 | やること | この記事の時点 |
|---|---|---|
| A. 店を作る | ③⑦を Unity で建て、最後まで回り切らせる | cs:139 で終わり |
| B. 回して台帳にまとめる | 条件ごとに回し、1回ごとに台帳へ1行 | cs:140 で18回 |
| C. ずれを調べる | サイトと Unity の数字を並べ、ずれの理由を分け、何を直すかを決める(直すのは次の版) | 一覧 v1 を作った |
| 次の版 | C で決めた直しを入れ、18回を回し直す | 直しを入れて確かめた。回し直しは、ロボットの動き方を変えてから |
この記事の「変わったこと」に書く数字は、どれも Unity で回した記録から取った値です。「見込める効果」のうち、まだ回していないものは見込みとして書いています。
回した記録は3回です。どれも KIOXIA の r2r2r-data/service_sim/unity/ の下にあります。
| 回 | 版 | 条件 | 出力のフォルダ |
|---|---|---|---|
| 0859 | v8 だけ(Check-in 前) | ③・ロボット2台・種0 | 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped |
| 1004 | v8+v8b(cs:141) | ③・ロボット2台・種0 | 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 |
| 1020 | v8+v8b(cs:141) | ③・ロボット0台・種0 | 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 |
どの回も、スタッフ4人・1時間に42組・120分だけ客が来て全員が帰るまで回す・ロボットは料理を運ぶだけ・1往復で3卓まで、です。
段階C:ロボットが運んだ料理の待ちを、受け渡し口で待った時間と運んでいる時間に分けた
段階Bの18回のうち、ロボットを入れた12回で、ロボットが運んだ皿の待ちを分けました。料理ができてから届くまでを、受け渡し口でロボットを待った時間と、ロボットに載ってから届くまで(記録の「運ぶ」)に分けます。さらに「運ぶ」を、サイトの試算の計算式(卓までの道のり+卓から卓へ3m、走る速さ0.5m/秒、受け渡し25秒)で出した時間と並べました。
| 3回の平均(分) | 受け渡し口で待った | 運ぶ(記録の値) | うち戻るまでを数えた分 | 卓に着くまで(見積もり) | 試算の式で卓に着くまで | 1往復で止まった秒 | 立ち往生した往復 |
|---|---|---|---|---|---|---|---|
| ③ 1台 | 1.20 | 2.55 | 1.24 | 1.31 | 0.72 | 33秒 | 10% |
| ③ 2台 | 1.11 | 3.04 | 1.04 | 2.01 | 0.58 | 86秒 | 18% |
| ⑦ 1台 | 1.44 | 2.59 | 1.32 | 1.27 | 0.77 | 22秒 | 6% |
| ⑦ 2台 | 0.76 | 2.60 | 1.09 | 1.51 | 0.61 | 58秒 | 11% |
「卓に着くまで(見積もり)」は、記録の「運ぶ」から、着いたあとの受け渡し25秒と、残りの道のりを走る時間(Unity の速さで)を引いた値です。止まりは全部、着く前に起きたとして引いているので、「戻るまでを数えた分」は小さめに出ています。
ここで分かったのは3つです。
- 「運ぶ」の中に、卓に着いたあとロボットが受け渡し口へ戻るまでの時間が、1皿あたり1.0〜1.3分入っていました。Unity は、皿を往復の終わりに「届いた」にしていたためです
- 1往復で走る距離は、Unity が26〜36m、試算の式が25〜35mで、ほぼ同じでした。走っているときの速さは、Unity の方がむしろ速く(毎秒0.57〜0.58m)、試算は0.5mです
- 残りの差は止まっている時間です。試算は1往復で平均約2秒と見ています。Unity は22〜86秒で、2台のときは止まる時間の5〜6割が「もう1台のロボット」でした
人とロボットが止まった場所も数えました。ロボット1台のときは、客席の通路が4〜6割、受け渡し口の近くが2〜3割です。2台のときは、止まる時間の5〜6割、60秒止まって動けなくなった回のほとんどが「もう1台のロボット」でした。
ずれの一覧 v1:10項目を、数え方・サイトにない動き・Unity の作りの3つに分けた
設計書で決めてある3つの理由で、ずれを分けました。1は数え方の違い、2はサイトにない動き(すれ違い・混雑)、3は Unity の作りの問題です。
| # | ずれ | 大きさ | 理由 |
|---|---|---|---|
| 1 | ロボットが運んだ皿を、往復を終えて戻った時刻に「届いた」にしていた。客が食べ始めるのもその時刻 | 料理の待ち +1.0〜1.3分/皿 | 3 |
| 2 | ロボットが1往復で止まる時間が長く、立ち往生も多い | 止まり22〜86秒/往復(試算 約2秒)、立ち往生6〜18%(試算1%) | 1台は2、2台の台どうしは3の疑い |
| 3 | ロボットが運んだ料理の割合が低い | 62〜80%(試算72〜99%) | 2の結果 |
| 4 | ロボットの走る速さ | 毎秒0.57〜0.58m(試算0.5m) | 1。Unity の速さは測った値ではなく設定(最高0.6m) |
| 5 | ロボットなしで、卓が空くまでが短い | 片付け5.0〜5.5分(試算9.5〜10.2分) | まだ決められない。逃がし弁「卓を空けた」が片付けを飛ばしている疑い |
| 6 | 逃がし弁がまだ働いている | 2台で、あきらめた57〜113・移した46〜107・卓を空けた4〜45 | 3 |
| 7 | スタッフが運ぶ時間が長い | 0.43〜0.62分(試算 約0.18分) | 2。Unity は今いる所から受け渡し口へ歩く |
| 8 | スタッフの歩く距離が長い | 1人2.6〜3.2km(試算1.6〜2.9km) | 1と2 |
| 9 | 入店待ちが回によって大きくぶれる | 同じ条件で1.6〜15.1分 | 回数が足りない |
| 10 | 往復の記録(trips.csv)の皿の欄が、同じロボットの次の往復の行に書かれている | 記録だけ。動きには効かない | 3(記録) |
逃がし弁は、客が待ちきれずに帰る(あきらめた)、動けなくなった人を元の場所へ移す(移した)、客が座れない卓を空ける(卓を空けた)の3つです。店が止まらないように Unity に入れている仕組みで、多いほど、実際の店では起きない処理に頼っていることになります。
決めることは3つありました。
届いた時刻の直しと、往復の記録の直しを、次の版で先に入れてよい ロボットどうしが60秒向かい合う止まりは、Unity の作りの問題として扱ってよい 今のまま(Unity は最高0.6m、試算は0.5m)でよい(ここは手をつけない。帳尻合わせでやらないように、あくまでもサイトの数値が正です)
速さを Unity の0.6mに合わせれば、試算との差は少し縮みます。ただ、それは差を縮めるために値を動かすことで、どちらの数字も測った値ではありません。速さには手を付けず、サイトの数値を正のままにしました。
v8:ロボットが卓に着いた時点で、皿を「届いた」にする(cs:141)
Unity のロボットは、卓に着いた時点で「この卓には届いた」と数えていました(ServingRobotController の StopsCompleted)。ところが、皿を「届いた」にする処理(ServiceOps.DishArrived)は、往復の最後に受け渡し口へ戻ったとき(ServiceOps.OnRobotRunDone)にしか呼ばれていませんでした。客が食べ始めるのは「最初の料理が全部届いたとき」なので、ロボットが戻るまで客は食べ始めません。
直し方は、ロボットが卓に着いて受け渡しの25秒に入る瞬間に、その卓の皿を届いたにする形です。サイトの試算も、卓に着いた時点で届いたにして、そのあと受け渡しの25秒を数えています。打ち切りなどで届かなかった皿だけを、往復の最後に受け渡し口へ戻します。
あわせて、往復の記録の1行ずれも直しました。原因は、ロボットが往復を終えたときに呼ばれる処理の順番でした。記録を書く側(ExperimentRunner)が、皿を片づける側(ServiceOps)より先に呼ばれていたので、記録に1つ前の往復の皿が入っていました。皿を片づけ終えてから記録を書くように変え、往復を始めた時刻・載せた皿の番号・卓ごとに着いた時刻・客が食べ始めた時刻を記録に足しました。
- ねらい:ロボットが運んだ皿を、試算と同じ「卓に着いた時点」で数える
- 変わったこと:ロボットが運ぶ時間(載せてから届くまで)が、段階Bの③ロボット2台・種0の2.90分から、cs:141 の同じ条件の1.09分になった(来る客は v8b で変わっているので、同じ客での比べではない)
- 見込める効果:料理の待ちと、客が食べ始めて卓が空くまでの時間が、試算と同じ数え方で比べられる。18回を回し直したときに、料理の待ちのずれのうち数え方の分が消えているかで確かめる
押し直しの照らし合わせ(前の記事の最後に残した心配)も、この直しに入れました。台帳と照らし合わせるのは「店・ロボットの台数・乱数の種・Unity の版」の4つにし、出力のフォルダ名にも版を入れます。版が変われば同じ条件をもう一度回せ、同じ版なら日付が変わっても回し直しません。
v8 の確かめで店が止まった:2台が打ち切られ、受け渡し口の同じ点に重ねて置かれた
v8 を入れて③ロボット2台を1回回すと、店が回らなくなりました。

ずっと立ち往生してて、店が回ってないよ
モニターでは、ロボット2台がどちらも「もう1台のロボット」で止まっています。それなのに画面にはロボットが1台しか見えません。Play を抜けて記録を書き出し、段階Bの同じ回(③2台・種0・cs:140)と往復を1本ずつ並べました。
- 往復13本目(店の時刻で約1,290秒)までは、行った卓と順番が段階Bと同じで、距離もほぼ同じでした。皿が早く届く分だけ客の動きがずれ、14本目から別の卓へ向かうようになりました
- 往復15本目(1号機、T36→T39)と16本目(2号機、T39→T40→T5)が、右下の卓の列(T34〜T41)の前の行き止まりの通路で向かい合いました。1号機は x19.63・z2.21、2号機は x19.10・z2.27 で、1,414〜1,416秒から動けなくなっています。2台とも T39 に向かっていました
- Unity には、1往復が600秒を超えると打ち切り、ロボットを受け渡し口の点(x15.3・z5.95)へ置き直す作りがあります。1号機は1,948秒に打ち切られてその点に置かれ、まだそこにいるうちに、2号機も1,999秒に打ち切られて同じ点に置かれました。2台が重なりました
- 重なった2台は、お互いを前にいるロボットとして止まり続けます。スタッフが動かしに行っても離れません。60秒止まって動けなくなった370回のうち、359回が受け渡し口の点でした。ロボットが運んだ皿は全部で17皿で、それ以降は1皿もありません
- 店の時刻で299分まで回したところで止めました。入店待ちは平均56.7分、あきらめた客は596回でした
段階Bでも、同じ行き止まりのまわりで2台とも打ち切られた往復(16本目・17本目)がありました。そのときは、2台が受け渡し口の同じ点で止まり続けることはありませんでした。v8 の直しが間違っていたのではなく、cs:140 からある打ち切りの置き直し方の穴に、たまたま当たっていました。止まる前の皿の記録で、v8 の直し(届いた時刻・往復の記録)が正しく動いていることも確かめています。
同じ乱数の種でも、来る客が変わっていた(83組 → 105組)
止まった回には、もう1つ気になる数字がありました。来た組の数です。段階Bの同じ条件・同じ種では83組だったのに、この回は105組でした。
Unity は、来客の間隔・組の人数・料理ができるまで・食べる時間・ドリンクバーやトイレに立つ回数などを、1つの乱数の列から起きた順に引いていました。動きが1か所ずれると引く順番が変わり、そのあとに来る客まで変わります。これでは、版の前後を同じ客で比べられません。
v8b:打ち切りで重ねない/来る客を、来客だけの乱数と組ごとの乱数にする(cs:141)
2つを v8 に足して直しました。
- 打ち切りでロボットを置き直すとき、置く先の0.8m以内(ロボットの直径0.5m+余裕0.3m)にほかの台がいれば、そこには置かない。受け渡し口の点 → 待機場所1・2・3の順に見て、空いている最初の点に置く。置いた先は trips.csv の
reset_toに残す - 来客の間隔は来客だけの乱数から引く。組の人数・料理ができるまで・食べる時間・割れ物・呼び出し・ドリンクバー・トイレは、乱数の種と組の番号から作るその組だけの乱数から、決まった順で引く
打ち切りそのもの(600秒)は変えていません。行き止まりで2台が向かい合うこと自体も、この時点では直していません。
- ねらい:①打ち切りのあとに2台が重なって、店が止まり続けるのをなくす ②同じ種なら、ロボットの台数や版が違っても同じ客が来るようにする
- 変わったこと:①打ち切りは11回あり、置き直した先は受け渡し口10回・待機場所1が1回。置き直した直後に、その点で60秒止まった回は0回。店は最後まで回り切った ②ロボット2台の回と0台の回で、64組の来た時刻・人数が全部同じになった。食べる長さも64組とも同じ(記録の小数の丸めで、最大0.005秒の差)
- 見込める効果:版の前後と、ロボットの台数の違いを、同じ客で比べられる。差が出たら、それは客の違いではなく、店の回し方やロボットの動きの違いと言える
B を入れたので、cs:140 の段階Bの18回とは、同じ種でも来る客が変わります。比べるのは、18回を回し直してからにします。
確かめの2回:③ロボット2台と0台(cs:141)
| ロボット2台(1004) | ロボット0台(1020) | 参考:段階B ③2台 種0(cs:140) | サイトの試算(2台) | |
|---|---|---|---|---|
| 来た組 | 64 | 64 | 83 | 83.3(平均) |
| 最後まで回り切った | ○(180.4分) | ○(172.4分) | ○(179.6分) | ― |
| 入店待ち | 1.67分 | 1.49分 | 2.89分 | 0.83分 |
| 料理の待ち | 2.90分 | 0.80分 | 4.22分 | 1.01分 |
| ロボットが運んだ割合 | 64% | ― | 71% | 99% |
| ロボットの往復/打ち切り | 72/11 | ― | 99/7 | ― |
逃がし弁(あきらめた/移した/卓を空けた) | 61/54/19 | 1/9/0 | 100/59/35 | ― |
この種(種0)で来た客は64組です。試算の平均(83組)より少ないので、入店待ちや料理の待ちは少なめに出ています。段階Bの列は来る客が違うので、そのまま比べられません。
ロボット2台の回では、60秒止まって動けなくなった回が58回ありました。そのうち51回が「もう1台のロボット」です。場所は、左の細い通路の入口の前(x9.9・z4.6 と x10.3・z4.4 で20回)、右下の行き止まり(x16.9〜19.1・z2.3 で15回)、受け渡し口から客席へ上がる縦の通路(x13.1〜13.4 で16回)でした。
Claude Code の確かめで、1つだけ式が合わない所がありました。往復の終わりを「往復を始めた時刻+往復の時間(total_s)」で出すと、着いた時刻がそれより後になる皿が9皿ありました。total_s には、卓での受け渡しの25秒が入っていない決まりだったためです(cs:140 以前から、受け渡しは止まりにも時間にも数えない)。昔の記録と比べられるよう total_s はそのままにし、往復が実際に終わった時刻 trip_end_s を、次の依頼で記録に足すことにしました。
ロボットどうしの詰まり:店の形ではなく、ロボットを線に縛った作りが根本だった
確かめの回でも、2台が通路の入口で向かい合う場面が出ました。

なんか詰まってばっかだね。一旦この部屋の形はやめないか?先に進まないね
詰まっているのは店の形ではなく、ロボットどうしでした。段階Bでも、ロボット1台なら立ち往生した往復は6〜10%で、2台になると、止まる時間の5〜6割と60秒の止まりのほとんどが「もう1台のロボット」です。通路の入口や行き止まりはどの店にもあるので、店を変えても2台を走らせれば同じ所で詰まります。
なんで?人ではできるんでしょ?
人とロボットの譲り合いは、人が横へどくことで成り立っています(前の記事の cs:138・cs:139)。人は体が小さく、床のどこでも歩けるので、通路の脇へ一歩よければ済みます。ロボットは幅が0.5mあり、サイトから渡された道の線の上しか走れません。ロボットどうしにも「番号の大きい台が横へどく」決まりはありますが、横に0.6mの空きがないとどけず、1.2mの通路や行き止まりでは2台とも待ち続けます。また、「1本の通路に1台」の決まりは細い通路3本にしかなく、行き止まりや通路の入口は、向かい合ってから譲ろうとしていました。
サイトから渡された道の線の上しか走れません これがそもそもの原因じゃない?
広い所では、その通りでした。受け渡し口の前や通路の入口の前には2台がすれ違える床があるのに、2台とも同じ線の上を走るので正面から出会います。狭い所(1.2mの通路にロボット2台+すき間で1.3m以上要る、行き止まり)では、線をやめてもすれ違えないので、入る前に片方が待つしかありません。
もしくは道が少なすぎるか
③の道のデータを見ると、道は卓ごとに受け渡し口からの最短の1本だけで、行きも帰りも同じ線を通ります。42卓への道のうち23本が、下の横の通路(z4.312 の線)を共有していました。3本の細い通路は上の端も開いているのに、上の横の通路を通る道は4本だけです。行きと帰りを分けているのは、受け渡し口のすぐ前の1m(帰りの線を1m下にずらしたもの)だけでした。
ここで一度、道を一方通行の周回にする案(行きは下の通路から細い通路へ入り、帰りは上の通路へ抜けて受け渡し口へ戻る)を出しました。
現行のロボットってそもそも決まった線の上だけを動いているわけじゃないでしょ?
動ける範囲がマップで決まっている。 障害物や人に関してはカメラはセンサーで反射的、もしくは考えて判断して動いている んじゃないの?
実際の配膳ロボットは、導入のときに店の地図を作り、入ってはいけない所を決めます。BellaBot の公式の製品紹介では、位置の把握はレーザーとカメラを組み合わせた SLAM(地図を作りながら自分の位置をつかむ仕組み)で、通れる最小の幅は80cmです( https://academy.pudutech.com/en/docs/huan-le-song-chan-pin-jian-jie )。配膳ロボットの解説記事でも、店の地図の上で現在地を推定しながら、センサーで人や物を検知して止まる・迂回すると書かれています( https://www.ai-souken.com/article/what-is-serving-robot )。複数台でどう譲り合うかは、今回見た公式の製品紹介には書かれていませんでした。
Unity の「サイトから渡した線の上しか走れない」は、現実にない制約でした。10月22日に、Unity の NavMesh(床の形から自動で作る、歩ける範囲の地図)で道を決めるのをやめ、サイトが引いた線を渡す形に変えています。⑦の0.8mの通路で NavMesh の床が途切れ、入れない卓が出たこと、サイトの試算と同じ道のりで走らせたかったことが理由でした。そのとき、細い通路の問題だけを見て線で固め、現実のロボットの動き方と照らし合わせていませんでした。そのあとは、詰まりが出るたびに決まりを足していました。一方通行の周回の案も取り下げました。現実でも見えない壁で一方通行にはできるので、導入の設定を比べる段階で、選べるものとして後から足します。
次の版:サイトは地図を渡し、道はロボットが地図の上で自分で引く
| いま(cs:141) | 次の版 | |
|---|---|---|
| サイトが正として渡すもの | 卓ごとの道の線(routes) | ロボットの地図(入れる床・入ってはいけない所・止まる位置)。Unity の床の水色と同じもの |
| 道 | 決まった線をたどる | いる所から行き先まで、地図の上でその都度自分で引く |
| 人・ロボットがいたとき | 線の上で止まって待つ | 空いていれば回り込む/通れなければ道を引き直す/どこも通れなければ待つ |
| 1台しか通れない所 | 向かい合ってから譲ろうとして止まる | 引き直しても通れなければ、入る前に待つ |
道は、Unity の NavMesh ではなく、サイトの地図(店の形を確かめるのに使っている2.5cm刻みの床)の上で引きます。NavMesh で細い通路が途切れた問題を避けるためです。回り込みで走る距離は、サイトの距離(最短の道のり)から延びます。延びた分は「通路で起きること」として Unity が測る値にし、サイトの距離の定義は変えません。
- ねらい:ロボットの動き方を、実際の配膳ロボットと同じ「地図の上で自分で道を引き、人やロボットには止まる・回り込む・引き直す」にする
- 変わったこと:まだ入れていない(依頼文はこのあと作る)
- 見込める効果(見込み):広い所での台どうしの向かい合いがなくなり、60秒の止まり(確かめの回で58回、うち台どうし51回)と逃がし弁が減る。18回を回し直して、60秒の止まりの回数と逃がし弁の回数で確かめる
18回の回し直しは、動き方を変えてからにします。今のまま回しても、線に縛られた詰まりを測るだけになるからです。
段階の位置と、Unity の v1 の区切りの案
作業の途中で、いまどこにいるのか、何を目指しているのかを整理しました。段階Cはずれの一覧と対処を決めた所で終わっていて、v8・v8b は次の版の作業です。直すたびに新しい詰まりが見つかって作業が延びるのを避けるため、次の版で直すのは v8・v8b と、ロボットの動き方の3つに限ります。
Unity を作った目的は、サイトの試算が仮の値で置いている「通路で起きること」を測ることです。試算には、ロボットの実際の速さ・止まる起きやすさ・止まる長さ・立ち往生の起きやすさの4つが仮の値で入っています。Unity の数字に作りの問題が混ざったままサイトに入れると、作りの問題をサイトに持ち込むことになります。次の版のねらいは、それを取り除いて、通路で起きることだけが残った数字にすることで、サイトとの差を縮めること自体は目的にしていません。
Unity の v1(メジャーバージョン)の区切りの案は、「Unity で測る → サイトに入れる → 両方を並べる」を一度通したところです。まだ決めてはいません。
| # | 条件 | いま |
|---|---|---|
| 1 | ③⑦が最後まで回り切り、逃がし弁がほぼ0 | 未達(2台で あきらめた61・移した54・卓を空けた19) |
| 2 | ロボット0台で、Unity とサイトが合う | ほぼ達成 |
| 3 | Unity が4つの値をサイトと同じ定義で出し、乱数の種を変えても値が安定する | 途中 |
| 4 | その値をサイトに入れた試算と Unity を、ロボット1・2台で並べ、向きと大きさが合う | これから |
そのあとの区切りは、ほかの店(②④⑤⑥)に広げる v2、下げ膳や案内ロボットなど配膳以外の仕事に広げる v3、映像と記録を学習に使える形で書き出す版、と考えています。
データとコードの置き場所
| もの | 場所 |
|---|---|
| Unity の出力(3回) | KIOXIA r2r2r-data/service_sim/unity/ の下(フォルダ名は上の表) |
| 段階Cの分析のコードと出力 | KIOXIA r2r2r-data/service_sim/unity/stageC_v1/ |
店が止まった回と確かめの回を調べたコードと出力 | KIOXIA r2r2r-data/service_sim/unity/v8_check/ |
| ずれの一覧・設計書・依頼文 | iCloud サービスロボット導入シミュレーション/unity/(unity_stageC_gaps_v1.md・unity_design_v0.md・claude_code_request_v8_dish_arrival.md・claude_code_request_v8b_timeout_rng.md) |
| Unity のコード | /Users/shimazueiichi/Robotics_UX/Robotics_UX_New/Assets/ServiceSim/(Unity Version Control cs:141) |
店の形のデータ(③の道の線を含む) | GitHub PixelstoMotors/p2m-site の public/sim/layouts/unity/p1_efficient_corner.json(版 82023936eb99) |
回した記録のうち、人どうしの詰まりの記録(people_jams.csv)は、この記事では使っていないので載せていません。KIOXIA の同じフォルダにあります。それ以外の出力は、後ろにすべて載せます。
Claude Code への依頼文
この記事のコード・ログ・データは、1ファイルずつ下に置いています。全文はリンク先にあります。
ファイルの一覧(44本)
01_sec13.md ― 1. 依頼 v8:claude_code_request_v8_dish_arrival.md・3,275字
02_sec14.txt ― 08:43 v8 を入れた報告(Check-in 前)・3,666字
03_sec14.txt ― 09:45 v8b を入れた報告(Check-in 前)・3,519字
04_sec14.txt ― 10:37 確かめの2回と Check-in(cs:141)の報告・6,288字
05_stageC_v1_a2_output.txt ― stageC_v1/a2_output.txt・3,124字
06_stageC_v1_rows.json ― stageC_v1/rows.json・33,070字
07_stageC_v1_carry.json ― stageC_v1/carry.json・4,428字
08_v8_check_look_stopped_run_output.txt ― v8_check/look_stopped_run_output.txt・4,809字
09_unity_unity_stageC_gaps_v1.md ― unity/unity_stageC_gaps_v1.md・3,670字
10_sec18.txt ― Assets/ServiceSim/Editor/ServiceSimStageB.cs の差分・5,814字
11_sec18.txt ― Assets/ServiceSim/Experiment/TripLogger.cs の差分・4,123字
12_sec18.txt ― Assets/ServiceSim/Robot/ServingRobotController.cs の差分・5,405字
13_sec18.txt ― Assets/ServiceSim/Service/ServiceOps.cs の差分・5,476字
14_Assets_ServiceSim_Editor_ServiceSimLedger.cs.txt ― Assets/ServiceSim/Editor/ServiceSimLedger.cs・11,516字
15_Assets_ServiceSim_Editor_ServiceSimStageB.cs.txt ― Assets/ServiceSim/Editor/ServiceSimStageB.cs・31,546字
16_Assets_ServiceSim_Experiment_ExperimentRunner.cs.txt ― Assets/ServiceSim/Experiment/ExperimentRunner.cs・48,510字
17_Assets_ServiceSim_Experiment_TripLogger.cs.txt ― Assets/ServiceSim/Experiment/TripLogger.cs・73,138字
18_Assets_ServiceSim_Robot_ServingRobotController.cs.txt ― Assets/ServiceSim/Robot/ServingRobotController.cs・71,502字
19_Assets_ServiceSim_Service_ServiceOps.cs.txt ― Assets/ServiceSim/Service/ServiceOps.cs・61,250字
20_Assets_ServiceSim_Service_GroupManager.cs.txt ― Assets/ServiceSim/Service/GroupManager.cs・30,140字
21_unity_unity_design_v0.md ― unity/unity_design_v0.md・14,764字
22_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_su.json ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/summary.json・6,209字
23_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_tr.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/trips.csv・12,665字
24_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_st.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/stops.csv・75,247字
25_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_di.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/dishes.csv・21,527字
26_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_yi.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/yields.csv・26,315字
27_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_re.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/requeues.csv・10,112字
28_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_gi.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/give_ups.csv・69,445字
29_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_gr.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/groups.csv・11,014字
30_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_co.csv ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/contacts.csv・13,101字
31_s0_0859_stopped_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped_co.json ― 0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/conditions.json・10,045字
32_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_summary.json ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/summary.json・6,320字
33_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_trips.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/trips.csv・14,671字
34_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_stops.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/stops.csv・83,074字
35_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_dishes.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/dishes.csv・14,611字
36_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_yields.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/yields.csv・123,977字
37_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_give_ups.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/give_ups.csv・10,515字
38_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_groups.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/groups.csv・7,401字
39_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_contacts.csv ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/contacts.csv・6,943字
40_s0_1004_20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004_conditions.json ― 1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 / 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/conditions.json・10,054字
41_s0_1020_20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020_summary.json ― 1020(cs:141・③・ロボット0台):20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 / 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/summary.json・4,453字
42_s0_1020_20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020_dishes.csv ― 1020(cs:141・③・ロボット0台):20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 / 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/dishes.csv・14,084字
43_s0_1020_20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020_groups.csv ― 1020(cs:141・③・ロボット0台):20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 / 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/groups.csv・7,412字
44_s0_1020_20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020_conditions.json ― 1020(cs:141・③・ロボット0台):20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 / 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/conditions.json・10,054字
長い依頼文はファイルにして Mac に置き、Claude Code には「unity/{ファイル名} を読んで、その通りにしてください」とだけ送りました。確かめの途中で送った短い文は、チャットに書いたものをそのまま載せます。
1. 依頼 v8:claude_code_request_v8_dish_arrival.md
# 依頼 v8:ロボットが運んだ皿を「卓に着いた時点」で届いたにする/往復の記録を直す(2026-10-24)
段階C(unity_stageC_gaps_v1.md)で見つかった Unity の作りの問題を2つ直す。エイイチと決めたこと。
ロボットの速さ・止まり方・よけ方・料理の割り当てなど、ほかの動きは変えない。RobotSpec・PeopleSpec・ServiceSpec・SimParams の値も変えない。
**v7b(claude_code_request_v7b_stageB_resume.md)はこの依頼に入れたので、v7b は送らない。**
## 1. ロボットが運んだ皿を、卓に着いた時点で「届いた」にする
2. v8 の確かめ方への返事(チャットで送った文)
弱めた確かめ方でよい。dishes.csv に robot_id は足さない。
ただし「同じ dish_id が2つの往復に出ていない」は、requeues.csv にある皿(打ち切りで戻された皿)を除いて見る。その皿は、最初の往復で着いた時刻が -1 になっていることを確かめる。
いまエイイチが ③ ロボット2台を1回回している。終わったら5項目の確かめを回して、結果と Check-in の番号を報告してください。
3. 依頼 v8b:claude_code_request_v8b_timeout_rng.md
# 依頼 v8b:打ち切りで戻すときに重ねない/来る客を版に関係なくそろえる(2026-10-24)
v8 の確かめの1回(`20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped`)で店が止まった。原因は v8 の直しではなく、cs:140 からある作りの穴だった。エイイチと決めた2つを、v8 に足して直す(Check-in はまだしない。v8 と一緒にする)。
ロボットの速さ・止まり方・よけ方・料理の割り当て、各 Spec の値は変えない。v8 で直した所はそのまま。
## 起きたこと(記録から)
- 店の中 1,390 秒までは、段階Bの同じ回(20261023_stageB_fam_p1_r2_s0)と往復が1行ずつ同じだった。そこから v8 で皿が早く届いた分、動きがずれた
- 1,398〜1,415 秒:2台が右下の卓の列(T36〜T41)の前の行き止まりの通路(z≈2.2)で向かい合い、どちらも動けなくなった(1号機 x19.63・2号機 x19.10。どちらも T39 へ向かっていた)
- 2台とも maxTripSec(600秒)で打ち切られ、ServingRobotController の打ち切り(`TotalS > spec.maxTripSec` → `PlaceAt(_passPoint, …)`)で、**2台とも受け渡し口の同じ点に置かれて重なった**
- 重なった2台はお互いを「もう1台のロボット」として止まり続け、スタッフが動かしても離れない。動けなくなった370回のうち359回が受け渡し口の点(x15.3・z6.0)。そのあとロボットが運んだ皿は0
## A. 打ち切りでロボットを戻すとき、ほかの台と重ねない
- 打ち切りで置き直すとき、置く先の点の近く(ロボットの直径+余裕。目安0.8m以内)にほかの台がいれば、そこには置かない
- 置く先の順番:受け渡し口の点 → ロボットの待機場所(StoreBuilder の RobotStandbyPoints)を順に見て、ほかの台がいない最初の点。どこも空いていなければ、ほかの台からいちばん遠い待機場所
- 置き直した先を trips.csv の後ろに列 `reset_to` として残す(`pass` / `standby1` / `standby2` …。打ち切りでない往復は空)
- 打ち切りそのもの(600秒)と、打ち切った往復を timeout として1行に残すのは変えない
- 行き止まりで2台が向かい合うこと自体は、この依頼では直さない(回し直したあとに別に扱う)
## B. 来る客を、版や動きのずれに関係なくそろえる
いまは GroupManager の `_rng`(`seed * 7919 + 13`)1つから、来客の間隔・組の人数・料理ができるまで・食べる時間・割れ物の数・呼び出し・ドリンクバー・トイレ・待つ場所を、起きた順に引いている。動きが1か所ずれると引く順番が変わり、そのあとに来る客まで変わる(今回は来た組が 83 → 105)。これでは、版の前後を同じ客で比べられない。
- 来客の間隔(168行目・310行目の `ExponentialSec`)は、来客だけの乱数(例:`seed * 7919 + 101`)から引く
- 組ごとのこと(人数・料理ができるまで・食べる時間・割れ物の数・呼び出し・ドリンクバー・トイレ)は、その組だけの乱数(例:`seed` と組の番号から作る)から、決まった順で引く。いつ引いても、同じ組なら同じ値になるようにする
- 最初から座っている組(193行目あたり、`slot.seatCount` で人数を抑えている所)も同じ扱い
- 待つ場所を選ぶ(`RandomWaitingSpot`)など、客の中身でないものは今の `_rng` のままでよい
- 引く数の分布・決まり(ServiceSpec の値)は変えない。変わるのは「どの乱数の列から引くか」だけ
この直しで、cs:140 と同じ種でも来る客は変わる(段階Bの18回とは客がそろわない)。段階Bは18回を全部回し直すので、それでよい。
## 確かめ(Check-in の前に)
ServiceSim / Site Run で2回回す(エイイチが押す):③ ロボット2台・種0、③ ロボット0台・種0
- **B**:2回の groups.csv で、group_id・arrive_s・size が全部同じ(ロボットの台数が違っても同じ客が来る)。組ごとの食べる時間など、groups.csv から見られるものも並べて報告
- **A**:ロボット2台の回で、受け渡し口や待機場所で2台が0.5m以内に重なって止まり続けていない(stops.csv で、同じ点に「もう1台のロボット」で60秒の止まりが続いていない)。打ち切りがあれば reset_to が入っている
- **v8 の5項目**(前の確かめのとおり。requeues.csv の皿は「2つの往復に出ていない」から除き、最初の往復で着いた時刻が -1 であることを見る)
- どちらの回も最後まで回り切る(全員が店を出る)
## 報告
- 直したファイルと、変えた所の説明
- 確かめの結果(数字つき)と、2回の出力フォルダ名
- Check-in の番号(v8 と v8b をまとめて1回)
段階Bの18回は、私(Claude)が確かめの結果を見てから回してもらう。
4. A2 の見方の訂正(チャットで送った文)
1点訂正。A は打ち切ったあとの置き場所を直すだけで、行き止まりで2台が向かい合うことは直していない。打ち切りはまだ起きてよい。「打ち切り0回=直った」とは見ない。
A2 は次のように見る:
・置き直した直後に、置いた点(0.8m以内)で「もう1台のロボット」の60秒止まりが起きていない
・受け渡し口の点・待機場所で、2台が0.5m以内に重なったまま止まり続けていない
・行き止まりなど通路の途中での60秒止まりは、失敗に数えず、場所と回数だけ報告する
エイイチがいま2回回している。終わったら確かめを回して報告してください。
Claude Code の報告
Claude Code から返ってきた報告を、時刻の順にすべて載せます。
08:43 v8 を入れた報告(Check-in 前)
コードは出来て、両方のアセンブリがエラー・警告ゼロで通りました。ただし Check-in
はまだしていません — 指示書の 4 が「Check-in
の前に1回回して確かめる」なので、そこで止めています。
直したファイル
1. ロボットが運んだ皿を、卓に着いた時点で「届いた」に
09:45 v8b を入れた報告(Check-in 前)
v8b を v8 に足し終えました。Check-in はまだです(指示書どおり、確かめのあと v8
と一緒に1回で入れます)。
記録で原因を裏付けました
止まった回(..._0859_stopped)を読みました。指示書のとおりです。
┌────────┬─────────────────────────────────────────────────┐10:03 A2 の見方を直した報告
訂正を反映し、確かめの準備を終えて出力を見張っています(2件そろったら自動で知ら
せが来ます)。
A2 の見方を訂正どおりに直しました
「打ち切り0回=直った」とは見ません。 A は打ち切ったあとの置き場所だけを直すも
のなので、打ち切りはまだ起きてよい、として見ます。
┌──────────────────────────────────────────────────────┬───────────────────┐
│ 見るもの │ 失敗に数えるか │
├──────────────────────────────────────────────────────┼───────────────────┤
│ 見るもの │ 失敗に数えるか │
├──────────────────────────────────────────────────────┼───────────────────┤
│ A2-1 置き直した直後に、置いた点(0.8 m 以内)で「も │ ✅ 数える │
│ う1台のロボット」の60秒止まりが起きていない │ │
├──────────────────────────────────────────────────────┼───────────────────┤
│ A2-2 受け渡し口の点・待機場所で、2台が 0.5 m │ │
│ 以内に重なったまま止まり続けていない(止まりの時間が │ ✅ 数える │
│ 60秒以上重なっているかで見ます) │ │
├──────────────────────────────────────────────────────┼───────────────────┤
│ A2-3 行き止まりなど通路の途中での60秒止まり │ ❌ 数えない。場所 │
│ │ と回数だけ報告 │
└──────────────────────────────────────────────────────┴───────────────────┘
置き場所の座標はサイトの JSON から取りました:
受け渡し口の前(FoodPass) (15.30, 5.95)
ロボットの待機場所 1・2・3 (16.90, 6.05) (17.70, 6.05) (18.50, 6.05)
止まった回の多発点(15.3, 6.0)(16.9, 5.8)(17.7, 5.8)
と一致するので、判定の当て先は合っています。
ついでに分かったこと
確かめスクリプトを**止まった回(..._0859_stopped)**で試したところ、あれは v8
の回だったので、v8 の皿の直しはすでに全項目 OK でした。
a1 arrived_s が stop_arrived_s と一致 OK(合わない 0)
a2 往復の終わりより前 OK(超え 0)
b1 dish_ready_s が ready_s と一致 OK(合わない 0)←
前の往復の皿の混入が直っている
b2 同じ皿が2往復に出ていない(戻し除く) OK
b2' 戻された皿は最初の往復で -1 OK(戻された皿 6 / -1 でない 0)
b3 1行目の dishes が0でない OK(dishes = 1)← 前は0だった
c eat_start_s が一致(±1秒) OK(見た組 89 / 合わない 0)
d1/d2 二重の「届いた」なし OK(17 + 204 = 221 = 行数)
e carry_mean_min 0.4259 分 ← 段階B 2.9041 分
つまり残っているのは A(置き場所)と B(来る客)
の2つだけで、新しい2回で見るのはそこが中心になります。
いま見張っているもの
20261024_p1_efficient_corner_* で summary.json が揃った新しい2フォルダを待って
います(最大60分・5秒おき)。揃い次第、自動で確かめを回して
- B1/B2(2回で客がそろうか)
- A1/A2-1/A2-2(失敗に数える3つ)と A2-3(通路の途中の60秒止まり=報告のみ)
- v8 の5項目
- どちらも全員が店を出たか
を数字つきで報告します。そのあと v8 と v8b をまとめて1回で Check-in します。
10:37 確かめの2回と Check-in(cs:141)の報告
Check-in:cs:141(v8 と v8b をまとめて1回。保留は Mat_MonitorBoard の Private
2件だけ)
回した2回
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004 ロボット2台
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020 ロボット0台
どちらも全員が店を出ました(ロボット2台:店の中 180.4分・実時間段階Cの分析のコードと出力(KIOXIA stageC_v1/)
a1.py が18回の summary.json・trips.csv から条件ごとの数字を rows.json に集め、a2.py がロボットが運んだ皿の「運ぶ」を分けて carry.json に書き、a3.py が3回の平均を Unity と試算で並べ、a4.py が止まりの理由と場所を数えます。どれも Mac の device の shell で、KIOXIA の出力を読んで動かしました。
stageC_v1/a1.py
import csv,json,glob,os,statistics as st,collections
B=os.path.expanduser('~/mnt/KIOXIA/r2r2r-data/service_sim/unity')
C=os.path.expanduser('~/mnt/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/site_copy_82023936eb99/unity/')
dist={}
for st_,f in [('fam_p1','p1_efficient_corner'),('fam_p5','p5_crammed')]:
u=json.load(open(C+f+'.json')); dist[st_]=[t['dist'] for t in u['tables']]
rows=[]
for d in sorted(glob.glob(B+'/20261023_stageB_*')):
n=os.path.basename(d); store=n.split('_')[2]+'_'+n.split('_')[3]; rb=int(n.split('_r')[1][0]); sd=int(n[-1])
S=json.load(open(d+'/summary.json')); T=list(csv.DictReader(open(d+'/trips.csv'))); D=list(csv.DictReader(open(d+'/dishes.csv'))); G=list(csv.DictReader(open(d+'/groups.csv')))
r=dict(store=store,rb=rb,sd=sd)
sm,sr=S['site_metrics'],S['site_result']
for k in ['entry_wait_mean','dish_wait_mean','cold_share','turn_mean','staff_util','walk_km_per_staff','robot_share','seat_wait_mean','staff_wait_mean','blocked_wait_mean','guide_wait_mean','full_wait_mean','rescues','pauses','robot_util']:
r['u_'+k]=sm.get(k); r['s_'+k]=sr.get(k)
dp=S.get('dish_wait_parts',{})
for who in ['robot','staff']:
x=dp.get(who,{})
for k in ['dishes','pass_wait_mean_min','carry_mean_min','requeue_lost_mean_min','total_mean_min']: r[f'{who}_{k}']=x.get(k)
# same arrival time for different tables in one trip
if rb:
g=collections.defaultdict(set)
for x in D:
if x['carried_by']=='ロボット': g[x['arrived_s']].add(x['table_id'])
r['robot_arrival_groups']=len(g); r['multi_table_same_arrival']=sum(1 for v in g.values() if len(v)>1)
tr=S['trips']; r['trips']=tr['trips']; r['dist_per_trip']=tr['distance_m_total']/tr['trips']; r['trip_s_mean']=tr['total_s']/tr['trips']; r['stopped_s_mean']=tr['stopped_s']/tr['trips']
r['moving_s_mean']=r['trip_s_mean']-r['stopped_s_mean']; r['speed']=tr['robot_speed_mps']; r['stuck_trips']=tr['stuck_trips']; r['timeouts']=tr['timeouts']
r['stops']=S['stops']['count']; r['stuck_count']=S['stops']['stuck_count']
ntab=[len(t['table_ids'].split(';')) for t in T]; r['tables_per_trip']=st.mean(ntab)
# site-formula one trip: tables sorted by dist, legs + hop, handoff 25 each, return
sf=[]
for t in T:
ds=sorted(dist[store][int(i)-1] for i in t['table_ids'].split(';'))
sf.append((ds[-1]+3*(len(ds)-1))*2)
r['site_formula_dist_per_trip']=st.mean(sf)
r['stop_causes']={c['cause']:(c['count'],round(c['total_s'])) for c in S['stop_causes']}
r['staff_time_share']=S.get('staff_time_share'); r['gave_up']=S['sim_like']['gave_up']; r['warped']=S['sim_like']['warped']; r['table_freed']=S['sim_like']['table_freed']
rows.append(r)
json.dump(rows,open(os.path.expanduser('~/stc/rows.json'),'w'),ensure_ascii=False,indent=1)
print(len(rows))
stageC_v1/a2.py
import csv,json,glob,os,statistics as st,collections
B=os.path.expanduser('~/mnt/KIOXIA/r2r2r-data/service_sim/unity')
C=os.path.expanduser('~/mnt/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/site_copy_82023936eb99/unity/')
dist={}
for s_,f in [('fam_p1','p1_efficient_corner'),('fam_p5','p5_crammed')]:
dist[s_]=[t['dist'] for t in json.load(open(C+f+'.json'))['tables']]
HOP,V,HAND=3,0.5,25
out=[]
for d in sorted(glob.glob(B+'/20261023_stageB_*')):
n=os.path.basename(d); store='_'.join(n.split('_')[2:4]); rb=int(n.split('_r')[1][0]); sd=int(n[-1])
if not rb: continue
D=[x for x in csv.DictReader(open(d+'/dishes.csv')) if x['carried_by']=='ロボット']
T=list(csv.DictReader(open(d+'/trips.csv')))
vtrip=json.load(open(d+'/summary.json'))['trips']['robot_speed_mps']
g=collections.defaultdict(list)
for x in D: g[x['first_taken_s']].append(x)
distinct_arr=sum(1 for v in g.values() if len({x['arrived_s'] for x in v})>1)
est,site_arr,site_end,U,PW=[],[],[],[],[]
for k,v in g.items():
tabs=sorted({int(x['table_id']) for x in v}, key=lambda i:dist[store][i-1])
ds=[dist[store][i-1] for i in tabs]; m=len(ds)
# site-formula times
t=0;pos=0;arr={}
for j,(i,dd) in enumerate(zip(tabs,ds)):
t+=(dd-pos+(HOP if j else 0))/V; arr[i]=t; t+=HAND; pos=dd
end=t+pos/V
for x in v:
u=float(x['carry_s']); i=int(x['table_id'])
after=end-arr[i] # site-time after arrival
# scale moving part to Unity speed: after = handoffs + moving
hands_after=HAND*(m-tabs.index(i))
mov_after=(after-hands_after)*V/vtrip
est.append(max(u-hands_after-mov_after,0)); site_arr.append(arr[i]); site_end.append(end); U.append(u); PW.append(float(x['pass_wait_s']))
r=dict(store=store,rb=rb,sd=sd,trips=len(g),trips_with_distinct_arrivals=distinct_arr,
unity_carry=st.mean(U)/60, unity_carry_to_arrival_est=st.mean(est)/60, counting_excess=(st.mean(U)-st.mean(est))/60,
site_formula_carry_to_arrival=st.mean(site_arr)/60, site_formula_carry_to_end=st.mean(site_end)/60, pass_wait=st.mean(PW)/60)
out.append(r)
json.dump(out,open(os.path.expanduser('~/stc/carry.json'),'w'),ensure_ascii=False,indent=1)
for r in out: print({k:(round(v,2) if isinstance(v,float) else v) for k,v in r.items()})
stageC_v1/a2_output.txt
{'store': 'fam_p1', 'rb': 1, 'sd': 0, 'trips': 57, 'trips_with_distinct_arrivals': 1, 'unity_carry': 2.86, 'unity_carry_to_arrival_est': 1.61, 'counting_excess': 1.26, 'site_formula_carry_to_arrival': 0.73, 'site_formula_carry_to_end': 2.07, 'pass_wait': 1.35}
{'store': 'fam_p1', 'rb': 1, 'sd': 1, 'trips': 70, 'trips_with_distinct_arrivals': 0, 'unity_carry': 2.24, 'unity_carry_to_arrival_est': 1.04, 'counting_excess': 1.2, 'site_formula_carry_to_arrival': 0.7, 'site_formula_carry_to_end': 1.98, 'pass_wait': 0.99}
{'store': 'fam_p1', 'rb': 1, 'sd': 2, 'trips': 60, 'trips_with_distinct_arrivals': 0, 'unity_carry': 2.53, 'unity_carry_to_arrival_est': 1.27, 'counting_excess': 1.26, 'site_formula_carry_to_arrival': 0.74, 'site_formula_carry_to_end': 2.08, 'pass_wait': 1.24}
{'store': 'fam_p1', 'rb': 2, 'sd': 0, 'trips': 99, 'trips_with_distinct_arrivals': 1, 'unity_carry': 2.9, 'unity_carry_to_arrival_est': 1.9, 'counting_excess': 1.01, 'site_formula_carry_to_arrival': 0.56, 'site_formula_carry_to_end': 1.62, 'pass_wait': 1.1}
{'store': 'fam_p1', 'rb': 2, 'sd': 1, 'trips': 80, 'trips_with_distinct_arrivals': 1, 'unity_carry': 2.8, 'unity_carry_to_arrival_est': 1.77, 'counting_excess': 1.03, 'site_formula_carry_to_arrival': 0.57, 'site_formula_carry_to_end': 1.67, 'pass_wait': 0.88}
{'store': 'fam_p1', 'rb': 2, 'sd': 2, 'trips': 91, 'trips_with_distinct_arrivals': 1, 'unity_carry': 3.43, 'unity_carry_to_arrival_est': 2.35, 'counting_excess': 1.08, 'site_formula_carry_to_arrival': 0.6, 'site_formula_carry_to_end': 1.74, 'pass_wait': 1.36}
{'store': 'fam_p5', 'rb': 1, 'sd': 0, 'trips': 58, 'trips_with_distinct_arrivals': 0, 'unity_carry': 2.74, 'unity_carry_to_arrival_est': 1.45, 'counting_excess': 1.3, 'site_formula_carry_to_arrival': 0.75, 'site_formula_carry_to_end': 2.14, 'pass_wait': 1.46}
{'store': 'fam_p5', 'rb': 1, 'sd': 1, 'trips': 71, 'trips_with_distinct_arrivals': 1, 'unity_carry': 2.54, 'unity_carry_to_arrival_est': 1.24, 'counting_excess': 1.3, 'site_formula_carry_to_arrival': 0.76, 'site_formula_carry_to_end': 2.15, 'pass_wait': 1.47}stageC_v1/a3.py
import json,os,statistics as st,csv,glob,collections
R=json.load(open(os.path.expanduser('~/stc/rows.json')))
g=collections.defaultdict(list)
for r in R: g[(r['store'],r['rb'])].append(r)
ks=['entry_wait_mean','blocked_wait_mean','guide_wait_mean','full_wait_mean','seat_wait_mean','dish_wait_mean','cold_share','turn_mean','staff_util','walk_km_per_staff','robot_share','robot_util','rescues','pauses']
print('cond | '+' | '.join(ks))
for k in sorted(g):
xs=g[k]
def m(f):
v=[x[f] for x in xs if x.get(f) is not None]; return round(st.mean(v),2) if v else None
print(k, ' | '.join(f"{m('u_'+q)}/{m('s_'+q)}" for q in ks))
print()
for k in sorted(g):
xs=g[k]
print(k,'staffdish pass',round(st.mean([x['staff_pass_wait_mean_min'] or 0 for x in xs]),2),'carry',round(st.mean([x['staff_carry_mean_min'] or 0 for x in xs]),2),'n',[x['staff_dishes'] for x in xs],
'valves',[ (x['gave_up'],x['warped'],x['table_freed']) for x in xs], 'staffshare', {a:round(st.mean([x['staff_time_share'][a] for x in xs]),3) for a in xs[0]['staff_time_share']})
stageC_v1/a3_output.txt
cond | entry_wait_mean | blocked_wait_mean | guide_wait_mean | full_wait_mean | seat_wait_mean | dish_wait_mean | cold_share | turn_mean | staff_util | walk_km_per_staff | robot_share | robot_util | rescues | pauses
('fam_p1', 0) 2.72/3.18 | 0.92/2.45 | 0.4/0.4 | 0.2/0.15 | 1.12/2.6 | 0.89/0.65 | 0/0.0 | 5.02/9.46 | 0.76/0.75 | 3.15/2.77 | 0/0 | 0/0 | 0/0 | 0/0
('fam_p1', 1) 3.68/1.64 | 1.04/0.95 | 0.4/0.24 | 1.01/0.27 | 2.05/1.22 | 3.61/2.04 | 0.59/0.13 | 4.13/4.1 | 0.71/0.65 | 2.61/1.89 | 0.64/0.73 | 0.78/0.75 | 13.67/0.93 | 185/20.25
('fam_p1', 2) 4.77/0.83 | 1.45/0.36 | 1.09/0.2 | 0.95/0.1 | 2.4/0.45 | 4.46/1.01 | 0.59/0.01 | 5.41/3.54 | 0.78/0.62 | 2.57/1.6 | 0.68/0.99 | 0.69/0.6 | 57.33/1.6 | 381/44.2
('fam_p5', 0) 2.69/4.36 | 0.49/3.57 | 0.5/0.4 | 0.51/0.21 | 1.0/3.77 | 1.08/0.66 | 0.02/0.0 | 5.45/10.15 | 0.75/0.75 | 3.0/2.86 | 0/0 | 0/0 | 0/0 | 0/0
('fam_p5', 1) 7.86/1.33 | 2.68/0.73 | 0.6/0.26 | 3.34/0.16 | 6.02/0.89 | 3.74/2.1 | 0.65/0.14 | 5.25/4.36 | 0.75/0.65 | 2.86/1.98 | 0.62/0.72 | 0.78/0.75 | 6.67/0.85 | 193/20.2
('fam_p5', 2) 9.84/1.59 | 2.32/0.8 | 0.59/0.22 | 5.68/0.39 | 8.0/1.19 | 3.53/1.05 | 0.5/0.02 | 4.4/3.97 | 0.73/0.62 | 2.79/1.68 | 0.77/0.99 | 0.68/0.61 | 47.33/1.57 | 447/43.25
('fam_p1', 0) staffdish pass 0.46 carry 0.43 n [196, 200, 214] valves [(10, 11, 22), (9, 11, 22), (7, 14, 22)] staffshare {'待機': 0.244, '案内': 0.139, '料理': 0.177, '呼び出し': 0.044, '会計': 0.175, '片付け': 0.221}
('fam_p1', 1) staffdish pass 2.55 carry 0.54 n [94, 45, 87] valves [(58, 43, 23), (37, 37, 6), (36, 36, 23)] staffshare {'待機': 0.294, '案内': 0.149, '料理': 0.094, '立ち往生': 0.006, '呼び出し': 0.053, '会計': 0.174, '片付け': 0.23}
('fam_p1', 2) staffdish pass 3.29 carry 0.62 n [61, 65, 67] valves [(100, 59, 35), (74, 46, 21), (113, 73, 33)] staffshare {'待機': 0.224, '案内': 0.166, '立ち往生': 0.038, '呼び出し': 0.058, '料理': 0.112, '会計': 0.164, '片付け': 0.238}
('fam_p5', 0) staffdish pass 0.63 carry 0.44 n [222, 173, 188] valves [(9, 23, 31), (10, 12, 14), (6, 19, 24)] staffshare {'待機': 0.253, '案内': 0.134, '料理': 0.181, '呼び出し': 0.047, '会計': 0.171, '片付け': 0.214}
('fam_p5', 1) staffdish pass 2.63 carry 0.52 n [89, 94, 84] valves [(43, 49, 23), (56, 60, 35), (40, 56, 22)] staffshare {'待機': 0.247, '案内': 0.162, '料理': 0.094, '呼び出し': 0.056, '立ち往生': 0.007, '会計': 0.181, '片付け': 0.252}
('fam_p5', 2) staffdish pass 2.7 carry 0.58 n [69, 44, 52] valves [(106, 107, 45), (57, 46, 4), (69, 84, 33)] staffshare {'待機': 0.274, '案内': 0.15, '立ち往生': 0.029, '料理': 0.069, '呼び出し': 0.07, '会計': 0.17, '片付け': 0.238}
stageC_v1/a4.py
import csv,glob,os,collections,json
B=os.path.expanduser('~/mnt/KIOXIA/r2r2r-data/service_sim/unity')
agg=collections.defaultdict(lambda:collections.Counter())
for d in sorted(glob.glob(B+'/20261023_stageB_*')):
n=os.path.basename(d); store='_'.join(n.split('_')[2:4]); rb=int(n.split('_r')[1][0])
if not rb: continue
tr=sum(1 for _ in open(d+'/trips.csv'))-1
agg[(store,rb)]['trips']+=tr
for s in csv.DictReader(open(d+'/stops.csv')):
x,z=float(s['x']),float(s['z'])
# pass area: near pass point; corner from summary
place='細い通路' if s['in_narrow']=='1' else ('角(受け渡し口と客席の間)' if 10.5<=x<=13.5 and 3.5<=z<=5.8 else ('受け渡し口の近く' if x>13.5 and z<6.5 else '客席の通路'))
k=(store,rb); dur=float(s['duration_s'])
agg[k][('cause',s['cause'])]+=dur; agg[k][('place',place)]+=dur; agg[k]['total']+=dur; agg[k][('stuck',s['cause'])]+= (1 if dur>=59.9 else 0)
for k,c in sorted(agg.items()):
tot=c['total']
print(k,'trips',c['trips'],'stop_s/trip',round(tot/c['trips'],1))
print(' 理由', sorted([(kk[1],round(v/tot*100)) for kk,v in c.items() if isinstance(kk,tuple) and kk[0]=='cause'],key=lambda x:-x[1]))
print(' 場所', sorted([(kk[1],round(v/tot*100)) for kk,v in c.items() if isinstance(kk,tuple) and kk[0]=='place'],key=lambda x:-x[1]))
print(' 60秒止まり', sorted([(kk[1],v) for kk,v in c.items() if isinstance(kk,tuple) and kk[0]=='stuck' and v],key=lambda x:-x[1]))
stageC_v1/a4_output.txt
('fam_p1', 1) trips 188 stop_s/trip 26.0
理由 [('スタッフとすれ違った', 35), ('人が立ち止まっていた', 32), ('お客さんとすれ違った', 28), ('分からない', 5), ('椅子・荷物・ベビーカー', 0)]
場所 [('客席の通路', 57), ('受け渡し口の近く', 32), ('角(受け渡し口と客席の間)', 11)]
60秒止まり [('人が立ち止まっていた', 18), ('スタッフとすれ違った', 16), ('お客さんとすれ違った', 6), ('分からない', 1)]
('fam_p1', 2) trips 272 stop_s/trip 60.2
理由 [('もう1台のロボット', 51), ('人が立ち止まっていた', 17), ('スタッフとすれ違った', 15), ('お客さんとすれ違った', 14), ('分からない', 3), ('椅子・荷物・ベビーカー', 0)]
場所 [('客席の通路', 63), ('受け渡し口の近く', 26), ('角(受け渡し口と客席の間)', 10)]
60秒止まり [('もう1台のロボット', 94), ('人が立ち止まっていた', 34), ('スタッフとすれ違った', 29), ('お客さんとすれ違った', 14), ('分からない', 2)]
('fam_p5', 1) trips 199 stop_s/trip 16.1
理由 [('お客さんとすれ違った', 39), ('スタッフとすれ違った', 27), ('人が立ち止まっていた', 26), ('分からない', 6), ('椅子・荷物・ベビーカー', 2)]
場所 [('客席の通路', 42), ('細い通路', 27), ('受け渡し口の近く', 20), ('角(受け渡し口と客席の間)', 10)]
60秒止まり [('人が立ち止まっていた', 9), ('スタッフとすれ違った', 7), ('お客さんとすれ違った', 4)]
('fam_p5', 2) trips 336 stop_s/trip 42.2
理由 [('もう1台のロボット', 65), ('人が立ち止まっていた', 13), ('お客さんとすれ違った', 12), ('スタッフとすれ違った', 7), ('分からない', 2), ('椅子・荷物・ベビーカー', 0)]
場所 [('客席の通路', 44), ('受け渡し口の近く', 38), ('角(受け渡し口と客席の間)', 12), ('細い通路', 5)]
60秒止まり [('もう1台のロボット', 111), ('人が立ち止まっていた', 17), ('スタッフとすれ違った', 10), ('お客さんとすれ違った', 4)]
stageC_v1/rows.json
[
{
"store": "fam_p1",
"rb": 0,
"sd": 0,
"u_entry_wait_mean": 1.9311,
"s_entry_wait_mean": 3.1814,
"u_dish_wait_mean": 0.9608,stageC_v1/carry.json
[
{
"store": "fam_p1",
"rb": 1,
"sd": 0,
"trips": 57,
"trips_with_distinct_arrivals": 1,
"unity_carry": 2.863260819892473,店が止まった回と確かめの回を調べたコードと出力(KIOXIA v8_check/)
v8_check/look_stopped_run.py
"""v8 の確かめの1回(0859_stopped)で店が止まった原因を調べる(2026-10-24)。
段階Bの同じ回(20261023_stageB_fam_p1_r2_s0)と往復を並べ、60秒の止まりの場所を数える。"""
import csv, json, collections, os, sys
B = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
NEW = B + '/20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped'
OLD = B + '/20261023_stageB_fam_p1_r2_s0'
s = json.load(open(NEW + '/summary.json'))
r = s['site_run']; m = s['site_metrics']
print('== 止まった回の summary')
print('everyone_left', r['everyone_left'], 'total_minutes', r['total_minutes'], 'groups', m['groups'])
print('entry_wait_mean', m['entry_wait_mean'], 'dish_wait_mean', m['dish_wait_mean'], 'robot_share', m['robot_share'])
print('trips', s['trips'])
print('stops', s['stops'])
print('stop_causes', [(c['cause'], c['count'], round(c['total_s'])) for c in s['stop_causes']])
print('\n== 往復を段階Bの同じ回と並べる(距離・時間が同じなら、そこまでは同じ動き)')
T1 = list(csv.DictReader(open(OLD + '/trips.csv')))
T2 = list(csv.DictReader(open(NEW + '/trips.csv')))
for i in range(min(18, len(T1), len(T2))):
a, b = T1[i], T2[i]
same = (a['distance_m'], a['total_s']) == (b['distance_m'], b['total_s'])
print(i + 1, '段階B', a['robot_id'], a['table_ids'], a['distance_m'], a['total_s'], a['timeout'],
'| 今回', b['robot_id'], b['run_start_s'], b['table_ids'], b['stop_arrived_s'], b['distance_m'], b['total_s'], b['timeout'],
'| 同じ' if same else '| 違う')
print('\n== 今回の止まり(はじめの40行)')
S = list(csv.DictReader(open(NEW + '/stops.csv')))
for x in S[:40]:
print(x['robot_id'], x['trip_id'], x['t_s'], x['x'], x['z'], x['cause'], x['cause_detail'], x['duration_s'], x['resolved'])
print('\n== 60秒の止まりの場所(0.1m に丸め)')
long_ = [x for x in S if float(x['duration_s']) > 59]
print(len(long_), collections.Counter((round(float(x['x']), 1), round(float(x['z']), 1)) for x in long_).most_common(6))
print('最後の60秒止まりの時刻', long_[-1]['t_s'])
print('\n== 来た組(段階B と今回)')
for name, d in [('段階B', OLD), ('今回', NEW)]:
G = list(csv.DictReader(open(d + '/groups.csv')))
a = [float(g['arrive_s']) for g in G]
print(name, len(G), '組', '最後に来た', max(a))
v8_check/look_stopped_run_output.txt
== 止まった回の summary
everyone_left False total_minutes 299.0989 groups 71
entry_wait_mean 56.667 dish_wait_mean 24.4809 robot_share 0.0769
trips {'trips': 68, 'timeouts': 54, 'stuck_trips': 54, 'distance_m_total': 369.5854, 'total_s': 33060.77, 'stopped_s': 32425.85, 'robot_speed_mps': 0.5821, 'pause_s_mean': 13.8866, 'pause_count': 64, 'pause_rate_note': 'hop_m は role=site_only で Unity は読まないため出さない。割り出すときは stops.count ÷(distance_m_total ÷ hop_m)', 'stuck_rate_note': '同じ理由で出さない。stops.stuck_count ÷(distance_m_total ÷ hop_m)'}
stops {'count': 434, 'stuck_count': 370, 'partial_path_count': 0, 'stop_s_total': 23107}
stop_causes [('分からない', 18, 135), ('もう1台のロボット', 401, 22321), ('お客さんとすれ違った', 1, 1), ('椅子・荷物・ベビーカー', 2, 1), ('人が立ち止まっていた', 10, 559), ('スタッフとすれ違った', 2, 89)]
== 往復を段階Bの同じ回と並べる(距離・時間が同じなら、そこまでは同じ動き)v8_check/look_check_runs.py
"""v8・v8b(cs:141)の確かめの2回と、③の道の線を見る(2026-10-24)。"""
import csv, json, collections, os
B = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
R2 = B + '/20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004'
R0 = B + '/20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020'
OLD = B + '/20261023_stageB_fam_p1_r2_s0'
LAYOUT = os.path.expanduser('~/mnt/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/site_copy_82023936eb99/unity/p1_efficient_corner.json')
for name, d in [('ロボット2台', R2), ('ロボット0台', R0), ('段階B ③2台 種0(cs:140)', OLD)]:
s = json.load(open(d + '/summary.json')); r = s['site_run']; m = s['site_metrics']; sr = s['site_result']
print('==', name, os.path.basename(d))
print(' everyone_left', r['everyone_left'], 'total_minutes', round(r['total_minutes'], 1), 'groups', m['groups'], '(試算', sr['groups'], ')')
for k in ['entry_wait_mean', 'dish_wait_mean', 'robot_share', 'cold_share', 'staff_util', 'walk_km_per_staff']:
print(' ', k, m.get(k), '試算', sr.get(k))
print(' 逃がし弁 あきらめた/移した/卓を空けた', r['gave_up'], r['warped'], r['table_freed'])
print(' trips', s['trips'].get('trips'), 'timeouts', s['trips'].get('timeouts'), 'stuck_trips', s['trips'].get('stuck_trips'))
print(' robot dish parts', json.dumps(s.get('dish_wait_parts', {}).get('robot'), ensure_ascii=False))
print('\n== 2回で来た客が同じか')
G2 = list(csv.DictReader(open(R2 + '/groups.csv'))); G0 = list(csv.DictReader(open(R0 + '/groups.csv')))
k = lambda g: (g['group_id'], g['arrive_s'], g['size'])
print(len(G2), len(G0), '同じ' if [k(g) for g in G2] == [k(g) for g in G0] else '違う')
eat = lambda g: round(float(g['eat_end_s']) - float(g['eat_start_s']), 2)
print('食べる長さが同じ組', sum(1 for a, b in zip(G2, G0) if eat(a) == eat(b)), '/', len(G2))
print('\n== ロボット2台の回:打ち切りの置き直し先と、60秒の止まりの場所')
T = list(csv.DictReader(open(R2 + '/trips.csv')))
print('reset_to', collections.Counter(t['reset_to'] for t in T if t['timeout'] == '1'))
S = [x for x in csv.DictReader(open(R2 + '/stops.csv')) if float(x['duration_s']) > 59]
print('60秒の止まり', len(S), '回', round(sum(float(x['duration_s']) for x in S)), '秒')
print('理由', collections.Counter(x['cause'] for x in S).most_common())
print('場所', collections.Counter((round(float(x['x']), 1), round(float(x['z']), 1)) for x in S).most_common(8))
print('\n== ③の道の線(サイトの routes.from_pass)')
u = json.load(open(LAYOUT)); fp = u['routes']['from_pass']
low = [t for t, v in fp.items() if any(abs(p[1] - 4.312) < 0.03 for p in v['points'])]
top = [t for t, v in fp.items() if any(p[1] > 12 for p in v['points'])]
print('卓の数', len(fp), '/下の横の通路 z4.312 を通る道', len(low), '/上の横の通路(z>12)を通る道', len(top))
print('細い通路', [(a['id'], a['ends']) for a in u['aisles']])
print('右下の列(T34〜T41)の止まる位置', [(t['id'], t['stop']) for t in u['tables'] if t['id'] in ('T34', 'T35', 'T36', 'T37', 'T38', 'T39', 'T40', 'T41')])
v8_check/look_check_runs_output.txt
== ロボット2台 20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004
everyone_left True total_minutes 180.4 groups 64 (試算 83.275 )
entry_wait_mean 1.6699 試算 0.8336
dish_wait_mean 2.8994 試算 1.0102
robot_share 0.6438 試算 0.9914
cold_share 0.3563 試算 0.014
staff_util 0.6416 試算 0.6158
walk_km_per_staff 2.3467 試算 1.6027
逃がし弁 あきらめた/移した/卓を空けた 61 54 19
trips 72 timeouts 11 stuck_trips 16
robot dish parts {"dishes": 103, "pass_wait_mean_min": 0.772, "carry_mean_min": 1.0945, "requeue_lost_mean_min": 0.8126, "total_mean_min": 2.6791, "requeued_per_dish": 0.0777, "requeued_total": 8}
== ロボット0台 20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020
everyone_left True total_minutes 172.4 groups 64 (試算 84.2 )
entry_wait_mean 1.4944 試算 3.1814
dish_wait_mean 0.8037 試算 0.653
robot_share 0 試算 0
cold_share 0 試算 0.0004
staff_util 0.6616 試算 0.7511
walk_km_per_staff 2.8029 試算 2.7655
逃がし弁 あきらめた/移した/卓を空けた 1 9 0
trips 0 timeouts 0 stuck_trips 0
robot dish parts {"dishes": 0, "pass_wait_mean_min": 0, "carry_mean_min": 0, "requeue_lost_mean_min": 0, "total_mean_min": 0, "requeued_per_dish": 0, "requeued_total": 0}
== 段階B ③2台 種0(cs:140) 20261023_stageB_fam_p1_r2_s0
everyone_left True total_minutes 179.6 groups 83 (試算 83.275 )
entry_wait_mean 2.892 試算 0.8336
dish_wait_mean 4.2197 試算 1.0102
robot_share 0.7053 試算 0.9914
cold_share 0.5507 試算 0.014
staff_util 0.8095 試算 0.6158
walk_km_per_staff 2.5281 試算 1.6027
逃がし弁 あきらめた/移した/卓を空けた 100 59 35
trips 99 timeouts 7 stuck_trips 16
robot dish parts {"dishes": 146, "pass_wait_mean_min": 1.1023, "carry_mean_min": 2.9041, "requeue_lost_mean_min": 0.1397, "total_mean_min": 4.1461, "requeued_per_dish": 0.0137, "requeued_total": 2}
== 2回で来た客が同じか
64 64 同じ
食べる長さが同じ組 61 / 64
== ロボット2台の回:打ち切りの置き直し先と、60秒の止まりの場所
reset_to Counter({'pass': 10, 'standby1': 1})
60秒の止まり 58 回 3482 秒
理由 [('もう1台のロボット', 51), ('お客さんとすれ違った', 5), ('人が立ち止まっていた', 1), ('スタッフとすれ違った', 1)]
場所 [((9.9, 4.6), 11), ((10.3, 4.4), 9), ((16.9, 2.4), 6), ((13.4, 7.4), 6), ((19.1, 2.3), 6), ((13.2, 8.0), 5), ((13.1, 10.0), 5), ((17.4, 2.3), 3)]
== ③の道の線(サイトの routes.from_pass)
卓の数 42 /下の横の通路 z4.312 を通る道 23 /上の横の通路(z>12)を通る道 4
細い通路 [('A01', [[1.8, 3.8], [1.8, 13.0]]), ('A02', [[5.5, 4.0], [5.5, 14.85]]), ('A03', [[9.2, 4.0], [9.2, 14.85]])]
右下の列(T34〜T41)の止まる位置 [('T34', [15.238, 2.188]), ('T35', [15.862, 2.188]), ('T36', [16.963, 2.188]), ('T37', [18.062, 2.188]), ('T38', [19.162, 2.188]), ('T39', [20.263, 2.188]), ('T40', [21.362, 2.188]), ('T41', [22.463, 2.188])]
look_check_runs_output.txt の「食べる長さが同じ組 61 / 64」は、記録の小数を0.01秒に丸めて比べたためで、残りの3組の差は最大0.005秒でした(2回の groups.csv の eat_end_s − eat_start_s の差。いちばん大きいのは組60の 2491.714 と 2491.709)。
ずれの一覧(unity_stageC_gaps_v1.md)
unity/unity_stageC_gaps_v1.md
# 段階C:サイトの試算と Unity のずれの一覧 v1(2026-10-24)
元のデータ:段階Bの18回(cs:140・店の形 82023936eb99・試算 v2.7)。③⑦ × ロボット0・1・2台 × 種0・1・2。
分析のコードと結果:KIOXIA `r2r2r-data/service_sim/unity/stageC_v1/`(a1〜a4.py・rows.json・carry.json・*_output.txt)。
理由の分け方は設計書 0.5 章:1 数え方の違い/2 サイトにない動き(すれ違い・混雑)/3 Unity の作りの問題。
対処を実際に入れるのは次の版。この一覧では決めるところまで。
## 1. 合っていたものUnity のコードの差分(cs:140 → cs:141)
cs:140 の全文は前の記事(LOG367)に載せたものです。GroupManager.cs は前の記事に全文を載せていなかったので、差分はなく、下の cs:141 の全文だけを載せます。
Assets/ServiceSim/Editor/ServiceSimLedger.cs の差分
--- cs:140/Editor/ServiceSimLedger.cs
+++ cs:141/Editor/ServiceSimLedger.cs
@@ -123,7 +123,7 @@
return false;
}
- /// <summary>もう台帳にある出力フォルダの名前をぜんぶ返す(続きから回すのに使う)</summary>
+ /// <summary>もう台帳にある出力フォルダの名前をぜんぶ返す(2度書きの歯止めに使う)</summary>
public static HashSet<string> DoneFolders(string path)
{
HashSet<string> done = new HashSet<string>();
@@ -149,6 +149,59 @@
}
}
}
+ catch (Exception e)
+ {
+ Debug.LogWarning("[ServiceSim] 台帳を読めませんでした: " + e.Message);
+ }
+ return done;
+ }
+
+ /// <summary>
+ /// 回した回を照らし合わせるキー(依頼 v8 の 3)。
+ ///
+ /// **店・ロボットの台数・乱数の種・Unity の版** でそろえる。
+ /// 出力フォルダ名(日付入り)では照らし合わせない。
+ /// ・同じ版・同じ条件・同じ種の行があれば、日付が違っても回さない
+ /// ・版が違えば回す(直したあとに同じ18回をもう一度回すため)
+ /// </summary>
+ public static string RunKey(string store, int robots, int seed, string unityCs)
+ {
+ return (store ?? "") + "|r" + robots + "|s" + seed + "|" + (unityCs ?? "");
+ }
+
+ /// <summary>台帳にある回のキーをぜんぶ返す(続きから回すのに使う)</summary>
+ public static HashSet<string> DoneKeys(string path)
+ {
+ HashSet<string> done = new HashSet<string>();
+ if (!File.Exists(path)) return done;
+
+ int cStore = IndexOf("store");
+ int cRobots = IndexOf("robots");
+ int cSeed = IndexOf("seed");
+ int cCs = IndexOf("unity_cs");
+ int cStatus = IndexOf("status");
+
+ try
+ {
+ using (StreamReader r = new StreamReader(path, new UTF8Encoding(false)))
+ {
+ r.ReadLine();
+ string line;
+ while ((line = r.ReadLine()) != null)
+ {
+ if (line.Length == 0) continue;
+ string[] f = line.Split(',');
+ int need = Mathf.Max(Mathf.Max(cStore, cRobots), Mathf.Max(cSeed, cCs));
+ if (need >= f.Length) continue;
+ if (cStatus < f.Length && f[cStatus].Length == 0) continue;
+
+ int robots, seed;
+ if (!int.TryParse(f[cRobots], out robots)) continue;
+ if (!int.TryParse(f[cSeed], out seed)) continue;
+ done.Add(RunKey(f[cStore], robots, seed, f[cCs]));
+ }
+ }
+ }
catch (Exception e)
{
Debug.LogWarning("[ServiceSim] 台帳を読めませんでした: " + e.Message);
Assets/ServiceSim/Editor/ServiceSimStageB.cs の差分
--- cs:140/Editor/ServiceSimStageB.cs
+++ cs:141/Editor/ServiceSimStageB.cs
@@ -92,33 +92,36 @@
BuildOrder(out condIdx, out seeds);
string ledger = ServiceSimLedger.PathOf(plan);
- HashSet<string> done = ServiceSimLedger.DoneFolders(ledger);
string day = DateTime.Now.ToString("yyyyMMdd");Assets/ServiceSim/Experiment/ExperimentRunner.cs の差分
--- cs:140/Experiment/ExperimentRunner.cs
+++ cs:141/Experiment/ExperimentRunner.cs
@@ -462,6 +462,12 @@
void SpawnRobots(int count)
{
+ // 往復の記録は、ServiceOps が片づけを終えてから書く(依頼 v8 の 2)。
+ // ロボットの TripCompleted を直に受けると、呼ばれる順番によって
+ // LastBatchOf が1つ前の往復の皿を返していた
+ ops.RunRecorded -= OnRunDone;
+ ops.RunRecorded += OnRunDone;
+
ops.ClearRobots();
for (int i = robotsRoot.childCount - 1; i >= 0; i--) Destroy(robotsRoot.GetChild(i).gameObject);
_robots.Clear();
@@ -481,7 +487,6 @@
? standby[i % standby.Count]
: pass + new Vector3(0f, 0f, -0.8f * i);
c.PlaceAt(start, Quaternion.LookRotation(Vector3.back, Vector3.up));
- c.TripCompleted += OnRunDone;
_robots.Add(c);
ops.RegisterRobot(c);
}
@@ -658,6 +663,18 @@
row.dishArrivedS = arrived;
row.undelivered = undelivered;
+ // ---- 後ろに足した列(依頼 v8 の 2。今ある列の並びは変えない)----
+ row.runStartS = startS;
+
+ int[] dishIds = new int[batch.Count];
+ for (int i = 0; i < batch.Count; i++) dishIds[i] = batch[i].id;
+ row.dishIds = dishIds;
+
+ float[] stopArrived = new float[r.StopArrivedS.Count];
+ for (int i = 0; i < stopArrived.Length; i++) stopArrived[i] = r.StopArrivedS[i];
+ row.stopArrivedS = stopArrived;
+ row.resetTo = r.ResetTo; // 打ち切りで置き直した先(依頼 v8b の A)
+
// ---- 往復ごとの測り(v5 3章・設計書2章の4つ)----
// 実際に走れた速さは、止まっていた分を除いた時間で出す(止まり込みの平均は別物)
float movingS = r.TotalS - r.StoppedS;
@@ -1019,6 +1036,7 @@
r.arriveS = g.arriveS;
r.guideStartS = g.guideStartS;
r.seatedS = g.seatedS;
+ r.eatStartS = g.eatStartS; // 食べ始めた時刻(依頼 v8 の 2)
r.eatEndS = g.eatEndS;
r.payStartS = g.payStartS;
r.payS = g.payS;
Assets/ServiceSim/Experiment/TripLogger.cs の差分
--- cs:140/Experiment/TripLogger.cs
+++ cs:141/Experiment/TripLogger.cs
@@ -57,6 +57,22 @@
/// <summary>止まりの回数と秒数を、狭い通路の中と外に分けたもの(⑦の読み分け用)</summary>
public int stopsInNarrow, stopsOutNarrow;
public float stoppedInNarrowS, stoppedOutNarrowS;
+
+ // ---- 後ろに足した列(依頼 v8 の 2。今ある列の並びは変えない)----Assets/ServiceSim/Robot/ServingRobotController.cs の差分
--- cs:140/Robot/ServingRobotController.cs
+++ cs:141/Robot/ServingRobotController.cs
@@ -336,6 +336,21 @@
/// <summary>この走りで寄る卓の数</summary>
public int RunStopCount { get { return _stops.Count; } }
+ readonly List<float> _stopArrivedS = new List<float>();
+Assets/ServiceSim/Service/ServiceOps.cs の差分
--- cs:140/Service/ServiceOps.cs
+++ cs:141/Service/ServiceOps.cs
@@ -279,6 +279,15 @@
readonly Dictionary<ServingRobotController, List<DishOrder>> _lastBatch =
new Dictionary<ServingRobotController, List<DishOrder>>();
+ /// <summary>
+ /// 止まる所の番号 → その所で降ろす皿(依頼 v8 の 1)。Unity のコード(cs:141 の時点)
/Users/shimazueiichi/Robotics_UX/Robotics_UX_New/Assets/ServiceSim/ のうち、cs:141 で書き換わったファイルの全文です。
Assets/ServiceSim/Editor/ServiceSimLedger.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using UnityEngine;
namespace ServiceSim.EditorToolsAssets/ServiceSim/Editor/ServiceSimStageB.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using UnityEditor;
using UnityEditor.SceneManagement;
using UnityEngine;Assets/ServiceSim/Experiment/ExperimentRunner.cs
using System.Collections.Generic;
using System.IO;
using UnityEngine;
namespace ServiceSim
{
/// <summary>
/// 条件を回して記録する。1回の Play の中で、条件を順に通せる(段階3の Run All)。Assets/ServiceSim/Experiment/TripLogger.cs
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using UnityEngine;
namespace ServiceSimAssets/ServiceSim/Robot/ServingRobotController.cs
using System;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;
namespace ServiceSim
{
/// <summary>Assets/ServiceSim/Service/ServiceOps.cs
using System.Collections.Generic;
using UnityEngine;
namespace ServiceSim
{
/// <summary>料理1皿</summary>
public class DishOrder
{Assets/ServiceSim/Service/GroupManager.cs
using System.Collections.Generic;
using UnityEngine;
namespace ServiceSim
{
/// <summary>
/// 客を「1組ごとに、入ってから出るまで」で動かす(試算の group() と同じ流れ)。
///Unity の設計書(unity_design_v0.md)
unity/unity_design_v0.md
# 配膳ロボット:通路で何が起きるかを Unity で測る(設計 v0)
作成:2026-10-20
対象:サービスロボット導入シミュレーション(配膳ロボット)
実装:Claude Code(Unity)/設計・結果の読み込み・試算への反映:Claude
## 0. 何について正か(2026-10-22 エイイチと決めた)
回した記録
回ごとの出力のファイルです(people_jams.csv を除く)。
0859(v8 だけ・③・ロボット2台・止めた回):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/summary.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 09:21:35",
"note": "speed_mps = distance_m / (total_s - stopped_s)。stopped_s には、動けなくなった60秒と、スタッフを待った秒数(stuck_wait_s)、通路の入口で待った秒数も入る。pause_s は stop_durations_s(自分で動き出した止まりだけ)の分布。site_metrics はサイトの meta.metrics と同じ名前・同じ定義。入店待ちの分け方もサイトの試算と同じで、blocked_wait は片付け待ちの卓の数だけ待っている列の前から順に足した分、full_wait は seat_wait − blocked_wait、staff_wait は blocked_wait + guide_wait。pauses と rescues は、サイト側が unity_measures の仮の値から出した数なので出どころが違う。",
"sim_like": {"dish_wait_mean": 24.4809, "dish_wait_p90": 36.2371, "cold_share": 0.8597, "seat_wait_mean": 40.0518, "turn_mean": 0, "robot_share": 0.0769, "robot_dishes": 17, "staff_dishes": 204, "requeued_dishes": 159, "late_staff_dishes": 204, "late_staff_share": 0.9231, "robot_first_wait_s": 120, "yields": 363, "yields_by_robot": 353, "yields_by_staff": 10, "yields_by_guest": 0, "yields_stepped_aside": 360, "yields_in_corner": 3, "yields_passed": 14, "yield_wait_s": 10621.08, "yield_wait_mean_s": 29.2592, "staff_yields": 10, "staff_yield_wait_s": 101.4495, "staff_yield_mean_s": 10.145, "staff_yield_share_of_staff_time": 0.0014, "staff_time_total_s": 72307.23, "corner_stops": 2, "corner_stop_s": 4.6, "corner_stop_count_share": 0.0046, "corner_stop_time_share": 0.0002, "corner_range": "x 10.5-13.5 / z 3.5-5.8", "groups": 71, "people_jams": 4571, "robot_blocked_jams": 4568, "robot_blocked_jam_share": 0.9993, "chair_pulls": 150, "robot_contacts": 205, "robot_yield_waits": 10, "robot_yield_wait_s": 101.4516, "robot_yield_detours": 0, "register_crowd_max": 9, "register_crowd_mean": 3.2725, "register_pay_count": 0, "register_pay_not_at_back": 0, "register_pay_off_spot": 0, "register_pay_offset_mean_m": 0, "register_pay_offset_max_m": 0, "register_back_intruders": 0, "register_back_intruder_s": 0, "drink_bar_queued": 5, "drink_bar_gave_up": 0, "drink_bar_wait_mean": 0.8121, "drink_bar_wait_p90": 0.9565, "gave_up": 596, "warped": 200, "table_freed": 71, "people_jam_total_s": 5631.292, "walkers_mean": 13.2994, "measured_minutes": 299.0989},
"site_metrics": {"entry_wait_mean": 56.667, "full_wait_mean": 38.9753, "staff_wait_mean": 16.4429, "blocked_wait_mean": 0, "guide_wait_mean": 16.4429, "seat_wait_mean": 40.0518, "dish_wait_mean": 24.4809, "dish_wait_p90": 36.2371, "cold_share": 0.8597, "turn_mean": 0, "walk_km_per_staff": 3.9147, "staff_util": 0.9352, "robot_util": 0.952, "robot_share": 0.0769, "rescues": 378, "pauses": 64, "groups": 71},
"site_run": {"site_run": true, "condition_id": "fam_p1_s4_r2_a42", "arrivals_minutes": 120, "total_minutes": 299.0989, "everyone_left": false, "aisle_deferrals": 3, "staff_first_yield": true, "robot_stuck_detours": 0, "rescues_done": 359, "rescue_wait_s": 9136.463, "gave_up": 596, "warped": 200, "table_freed": 71},
"site_result": {"dish_wait_mean": 1.0102, "dish_wait_p90": 2.0803, "cold_share": 0.014, "seat_wait_mean": 0.4546, "turn_mean": 3.5399, "walk_km_per_staff": 1.6027, "staff_util": 0.6158, "robot_util": 0.6013, "robot_share": 0.9914, "robot_bus_share": 0, "collects": 0, "rescues": 1.6, "pauses": 44.2, "fragile_robot": 41.9, "groups": 83.275, "entry_wait_mean": 0.8336, "blocked_wait_mean": 0.3575, "guide_wait_mean": 0.2015, "staff_wait_mean": 0.559, "full_wait_mean": 0.0971},20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/run_info.json
{
"run_label": "site_v5",
"written_at": "2026-10-24 09:21:35",
"condition_id": "fam_p1_s4_r2_a42",
"store_kind": "StoreLayout_p1_efficient_corner",
"time_mode": "FixedStep",
"time_scale": 1,
"capture_delta_time": 0.05,
"aisle_width_m": 1.2,
"delivery_offset_m": 0,
"delivery_offset_used_m": 0,
"crowd": "normal",
"robots": 2,
"seed": 0,
"trips_requested": 0,
"trips_done": 68,
"stopped_early": true,
"one_robot_per_aisle": true,
"yield_order_enabled": true,
"unity_cs": "",
"pending_changes": "",
"staff_first_yield": true,
"sim_seconds": 17945.93,
"wall_seconds": 1303.414,
"speedup": 13.7684,
"frame_delta_s": {"count": 359346, "mean": 0.0499, "min": 0.02, "p50": 0.05, "p90": 0.05, "p99": 0.05, "max": 0.05},
"robot_step_m": {"count": 359346, "mean": 0.0013, "min": 0, "p50": 0, "p90": 0, "p99": 0.03, "max": 0.03},
"people_step_m": {"count": 359346, "mean": 0.0435, "min": 0, "p50": 0.04, "p90": 0.05, "p99": 0.05, "max": 19.2837},
"frames_over_005m": 0,
"frames_over_005m_ratio": 0,
"people_frames_over_005m": 56960,
"people_frames_over_005m_ratio": 0.1585,
"chair_pulls": 150,
"chair_pulls_by_reason": {"座る": 18, "食事中": 74, "ドリンクバー": 25, "戻って座る": 16, "トイレ": 7, "会計": 10}
}
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/trips.csv
condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s
fam_p1_s4_r2_a42,1.2,normal,2,0,1,1,3,38.3101,71.5498,6.6,2,0.95;5.65,0,0,0,1,0.5307,1,3,1,536.9124,569.8044,0,0.5898,0,0,0,0,2,0,6.6,536.9624,1,569.8044
fam_p1_s4_r2_a42,1.2,normal,2,0,2,2,2,36.8251,67.1995,4.45,2,0.95;3.5,0,0,0,1,0.5393,1,2;1,2,567.9048;552.5586,637.4379;665.0811,0,0.5869,0,0,0,0,2,0,4.45,601.2967,3;2,637.4379;665.0811
fam_p1_s4_r2_a42,1.2,normal,2,0,1,3,1,30.9003,57.6994,5.1,2,0.95;4.15,0,0,0,1,0.3,1,1,1,708.4205,735.114,0,0.5875,0,0,0,0,2,0,5.1,708.4705,4,735.114
fam_p1_s4_r2_a42,1.2,normal,2,0,2,4,3,40.71,74.0999,4.6,3,0.95;2.65;1,0,0,0,1,0.4785,1,3,1,716.9684,775.4042,0,0.5858,0,0,0,0,3,0,4.6,735.164,5,775.4042
fam_p1_s4_r2_a42,1.2,normal,2,0,1,5,2,34.5302,59.0494,0.95,1,0.95,0,0,0,0,0.403,0,2,1,858.7338,888.4266,0,0.5943,0,0,0,0,1,0,0.95,858.7838,6,888.4266
fam_p1_s4_r2_a42,1.2,normal,2,0,2,6,34,11.04,19.9,0.95,1,0.95,0,0,0,0,2.7933,0,34,1,921.1186,931.766,0,0.5826,0,0,0,0,1,0,0.95,921.1686,7,931.766
fam_p1_s4_r2_a42,1.2,normal,2,0,1,7,35,9.42,17.2,0.95,1,0.95,0,0,0,0,2.3669,0,35,1,934.3654,952.111,0,0.5797,0,0,0,0,1,0,0.95,942.8633,8,952.11120261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/stops.csv
condition_id,seed,robot_id,trip_id,t_s,x,z,aisle,in_narrow,cause,cause_detail,path_blocked,duration_s,resolved,clearance_left_cm,clearance_right_cm,min_gap_cm,blocked_s,no_path_s,yield_s,clear_wait_s,replans,solve_from,solve_to,solve_status,solve_corners,off_mesh_m
fam_p1_s4_r2_a42,0,1,1,537,16.9,6.05,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.9;6.05,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,1,615.05,10.0485,4.362,,0,もう1台のロボット,ServingRobot02,0,5.65,自分で動き出した,18.8092,231.2592,18.8092,4.7,0,0,0.95,0,2.055;4.533,12.388;4.312,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,2,2,601.35,17.7,6.05,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,17.7;6.05,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,2,2,615.05,10.7707,4.39,,0,もう1台のロボット,ServingRobot01,0,3.5,自分で動き出した,234.0106,16.0017,16.0017,2.4,0,0,1.1,0,10.771;4.39,10.771;3.462,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,3,708.55,16.8515,5.8239,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.852;5.824,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,3,761.85,2.6119,4.5162,,0,もう1台のロボット,ServingRobot02,0,4.15,自分で動き出した,3.3874,275,3.3874,3.2,0,0,0.95,0,2.064;4.528,12.463;4.312,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,2,4,735.25,17.6548,5.8279,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,17.655;5.828,15.3;5.95,PathComplete,2,0.02520261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/dishes.csv
condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle
fam_p1_s4_r2_a42,0,1,3,3,0,536.9124,536.9624,569.8044,ロボット,0.05,32.842,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,3,2,2,0,567.9048,601.2967,637.4379,ロボット,33.3919,36.1412,0,0,0,0,0,1
fam_p1_s4_r2_a42,0,2,1,1,0,552.5586,601.2967,665.0811,ロボット,48.7381,63.7844,0,0,0,0,0,1
fam_p1_s4_r2_a42,0,4,1,1,0,708.4205,708.4705,735.114,ロボット,0.05,26.6435,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,5,3,3,0,716.9684,735.164,775.4042,ロボット,18.1956,40.2402,0,0,0,0,0,1
fam_p1_s4_r2_a42,0,6,2,2,0,858.7338,858.7838,888.4266,ロボット,0.05,29.6428,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,7,34,4,0,921.1186,921.1686,931.766,ロボット,0.05,10.5974,0,0,0,0,0,020261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/yields.csv
condition_id,seed,t_s,who,rank,to_whom,x,z,aisle,place,in_corner,waited_s,stepped_aside,passed
fam_p1_s4_r2_a42,0,614.0436,スタッフ:Staff02,1,ロボット1号機,12.3922,4.5382,,,1,1,1,1
fam_p1_s4_r2_a42,0,616.443,ロボット2号機,0,ロボット1号機,10.7707,4.39,,,1,5.4,1,1
fam_p1_s4_r2_a42,0,644.7361,スタッフ:Staff01,1,ロボット2号機,0.8,2.0339,,,0,47.6496,0,1
fam_p1_s4_r2_a42,0,712.1696,スタッフ:Staff01,1,ロボット1号機,12.8812,5.1965,,,1,4.25,1,1
fam_p1_s4_r2_a42,0,762.9072,ロボット2号機,0,ロボット1号機,3.157,4.32,,,0,5,1,1
fam_p1_s4_r2_a42,0,782.2025,スタッフ:Staff02,1,ロボット1号機,14.9498,4.6904,,,0,4.6,1,1
fam_p1_s4_r2_a42,0,810.8955,スタッフ:Staff01,1,ロボット2号機,6.4605,3.6476,,,0,3.5,1,120261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/requeues.csv
condition_id,seed,t_s,dish_id,table_id,robot_id,fragile,ready_s,waited_s,requeued_so_far,why
fam_p1_s4_r2_a42,0,1999.145,20,39,2,0,1390.701,608.4436,1,打ち切り
fam_p1_s4_r2_a42,0,1999.145,18,40,2,0,1354.716,644.4287,1,打ち切り
fam_p1_s4_r2_a42,0,1999.145,19,5,2,0,1383.644,615.5005,1,打ち切り
fam_p1_s4_r2_a42,0,2599.48,36,41,1,0,1858.307,741.1731,1,打ち切り
fam_p1_s4_r2_a42,0,2599.48,37,9,1,0,1908.156,691.3245,1,打ち切り
fam_p1_s4_r2_a42,0,2599.48,38,16,1,0,1918.516,680.9644,1,打ち切り
fam_p1_s4_r2_a42,0,2599.831,20,39,2,0,1390.701,1209.13,2,打ち切り20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/give_ups.csv
condition_id,seed,t_s,who,job,table_id,to_x,to_z,x,z,aisle,waited_s,action
fam_p1_s4_r2_a42,0,1559.566,スタッフ,立ち往生を動かす,0,18.841,2.3385,18.3703,2.3982,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1707.06,スタッフ,立ち往生を動かす,0,18.8428,2.072,18.5713,1.7567,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1967.013,スタッフ,立ち往生を動かす,0,18.8538,2.4013,18.4198,2.55,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,2048.893,スタッフ,料理を運ぶ,7,15.3,5.95,15.8836,6.25,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,2051.896,スタッフ,料理を運ぶ,8,15.3,5.95,15.9586,5.6205,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,2109.002,スタッフ,料理を運ぶ,7,15.3,5.95,16.0304,6.0552,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,2129.772,スタッフ,料理を運ぶ,10,15.3,5.95,16.0317,5.8473,,60.0494,あきらめた20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/groups.csv
condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s
fam_p1_s4_r2_a42,0,1,4,0,0,56.4194,56.4194,119.8727,3329.868,3329.893,-1,3930.529,1.0576,0,Done,735.164
fam_p1_s4_r2_a42,0,2,3,0,0,95.8213,95.8213,161.6753,2836.699,2836.712,-1,3437.348,1.0976,0,Done,888.4766
fam_p1_s4_r2_a42,0,3,4,0,0,103.0217,103.0217,172.2259,2613.846,2613.895,-1,3214.531,1.1534,0,Done,775.4542
fam_p1_s4_r2_a42,0,4,2,0,0,334.1619,334.1619,408.2938,3294.625,5030.526,-1,5628.232,1.2355,0,Done,1558.665
fam_p1_s4_r2_a42,0,5,1,0,0,424.5898,424.5898,499.5215,3412.896,3412.924,-1,4013.56,1.2489,0,Done,1285.298
fam_p1_s4_r2_a42,0,6,4,0,0,434.8373,434.8373,504.9202,2695.907,4012.059,-1,4610.174,1.168,0,Done,1287.4
fam_p1_s4_r2_a42,0,7,1,0,0,485.9749,485.9749,563.6059,3304.24,3304.268,-1,3904.904,1.2939,0,Done,1358.01920261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/contacts.csv
condition_id,seed,t_s,x,z,aisle,place,who,careless,robot_id,gap_cm
fam_p1_s4_r2_a42,0,1572.078,18.6293,2.55,,,スタッフ:Staff04,0,2,9.3868
fam_p1_s4_r2_a42,0,1826.076,18.6296,2.55,,,スタッフ:Staff01,0,2,9.3588
fam_p1_s4_r2_a42,0,2079.273,15.7582,6.25,,,スタッフ:Staff01,0,1,9.7701
fam_p1_s4_r2_a42,0,2116.309,14.8394,6.25,,,スタッフ:Staff02,0,1,9.9716
fam_p1_s4_r2_a42,0,2250.09,15.3,5.95,,,スタッフ:Staff04,0,1,-45
fam_p1_s4_r2_a42,0,2317.455,15.3,5.95,,,スタッフ:Staff03,0,1,-45
fam_p1_s4_r2_a42,0,2393.429,15.3,5.95,,,スタッフ:Staff04,0,1,-4520261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_0859_stopped/conditions.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 09:21:36",
"unity_version": "2022.3.62f3",
"trips_csv_columns": "condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s",
"groups_csv_columns": "condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s",
"dishes_csv_columns": "condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle",
"settings": {1004(cs:141・③・ロボット2台):20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/summary.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 10:18:23",
"note": "speed_mps = distance_m / (total_s - stopped_s)。stopped_s には、動けなくなった60秒と、スタッフを待った秒数(stuck_wait_s)、通路の入口で待った秒数も入る。pause_s は stop_durations_s(自分で動き出した止まりだけ)の分布。site_metrics はサイトの meta.metrics と同じ名前・同じ定義。入店待ちの分け方もサイトの試算と同じで、blocked_wait は片付け待ちの卓の数だけ待っている列の前から順に足した分、full_wait は seat_wait − blocked_wait、staff_wait は blocked_wait + guide_wait。pauses と rescues は、サイト側が unity_measures の仮の値から出した数なので出どころが違う。",
"sim_like": {"dish_wait_mean": 2.8994, "dish_wait_p90": 4.8089, "cold_share": 0.3563, "seat_wait_mean": 0, "turn_mean": 5.4215, "robot_share": 0.6438, "robot_dishes": 103, "staff_dishes": 57, "requeued_dishes": 8, "late_staff_dishes": 57, "late_staff_share": 0.3563, "robot_first_wait_s": 120, "yields": 1588, "yields_by_robot": 258, "yields_by_staff": 1018, "yields_by_guest": 312, "yields_stepped_aside": 378, "yields_in_corner": 139, "yields_passed": 781, "yield_wait_s": 4798.306, "yield_wait_mean_s": 3.0216, "staff_yields": 1018, "staff_yield_wait_s": 1667.517, "staff_yield_mean_s": 1.638, "staff_yield_share_of_staff_time": 0.0385, "staff_time_total_s": 43332.91, "corner_stops": 32, "corner_stop_s": 171.6496, "corner_stop_count_share": 0.0653, "corner_stop_time_share": 0.0305, "corner_range": "x 10.5-13.5 / z 3.5-5.8", "groups": 64, "people_jams": 575, "robot_blocked_jams": 519, "robot_blocked_jam_share": 0.9026, "chair_pulls": 159, "robot_contacts": 99, "robot_yield_waits": 1339, "robot_yield_wait_s": 2712.421, "robot_yield_detours": 9, "register_crowd_max": 9, "register_crowd_mean": 1.7297, "register_pay_count": 64, "register_pay_not_at_back": 1, "register_pay_off_spot": 11, "register_pay_offset_mean_m": 0.1267, "register_pay_offset_max_m": 5.9849, "register_back_intruders": 0, "register_back_intruder_s": 0, "drink_bar_queued": 19, "drink_bar_gave_up": 2, "drink_bar_wait_mean": 0.6648, "drink_bar_wait_p90": 1.003, "gave_up": 61, "warped": 54, "table_freed": 19, "people_jam_total_s": 975.4451, "walkers_mean": 7.6196, "measured_minutes": 180.4234},
"site_metrics": {"entry_wait_mean": 1.6699, "full_wait_mean": 0, "staff_wait_mean": 0.4729, "blocked_wait_mean": 0, "guide_wait_mean": 0.4729, "seat_wait_mean": 0, "dish_wait_mean": 2.8994, "dish_wait_p90": 4.8089, "cold_share": 0.3563, "turn_mean": 5.4215, "walk_km_per_staff": 2.3467, "staff_util": 0.6416, "robot_util": 0.6511, "robot_share": 0.6438, "rescues": 57, "pauses": 433, "groups": 64},
"site_run": {"site_run": true, "condition_id": "fam_p1_s4_r2_a42", "arrivals_minutes": 120, "total_minutes": 180.4234, "everyone_left": true, "aisle_deferrals": 33, "staff_first_yield": true, "robot_stuck_detours": 610, "rescues_done": 55, "rescue_wait_s": 2201.514, "gave_up": 61, "warped": 54, "table_freed": 19},
"site_result": {"dish_wait_mean": 1.0102, "dish_wait_p90": 2.0803, "cold_share": 0.014, "seat_wait_mean": 0.4546, "turn_mean": 3.5399, "walk_km_per_staff": 1.6027, "staff_util": 0.6158, "robot_util": 0.6013, "robot_share": 0.9914, "robot_bus_share": 0, "collects": 0, "rescues": 1.6, "pauses": 44.2, "fragile_robot": 41.9, "groups": 83.275, "entry_wait_mean": 0.8336, "blocked_wait_mean": 0.3575, "guide_wait_mean": 0.2015, "staff_wait_mean": 0.559, "full_wait_mean": 0.0971},20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/run_info.json
{
"run_label": "site_v5",
"written_at": "2026-10-24 10:18:23",
"condition_id": "fam_p1_s4_r2_a42",
"store_kind": "StoreLayout_p1_efficient_corner",
"time_mode": "FixedStep",
"time_scale": 1,
"capture_delta_time": 0.05,
"aisle_width_m": 1.2,
"delivery_offset_m": 0,
"delivery_offset_used_m": 0,
"crowd": "normal",
"robots": 2,
"seed": 0,
"trips_requested": 0,
"trips_done": 72,
"stopped_early": false,
"one_robot_per_aisle": true,
"yield_order_enabled": true,
"unity_cs": "",
"pending_changes": "",
"staff_first_yield": true,
"sim_seconds": 10825.4,
"wall_seconds": 828.3748,
"speedup": 13.0682,
"frame_delta_s": {"count": 216980, "mean": 0.0499, "min": 0.02, "p50": 0.05, "p90": 0.05, "p99": 0.05, "max": 0.05},
"robot_step_m": {"count": 216980, "mean": 0.0169, "min": 0, "p50": 0.03, "p90": 0.03, "p99": 0.03, "max": 0.03},
"people_step_m": {"count": 216980, "mean": 0.0531, "min": 0, "p50": 0.0486, "p90": 0.05, "p99": 0.05, "max": 21.6641},
"frames_over_005m": 0,
"frames_over_005m_ratio": 0,
"people_frames_over_005m": 57265,
"people_frames_over_005m_ratio": 0.2639,
"chair_pulls": 159,
"chair_pulls_by_reason": {"座る": 16, "食事中": 33, "ドリンクバー": 37, "戻って座る": 38, "トイレ": 4, "会計": 16, "退店": 15}
}
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/trips.csv
condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s,reset_to
fam_p1_s4_r2_a42,1.2,normal,2,0,1,1,34,9.48,17.3,0.95,1,0.95,0,0,0,0,0.2884,0,34,1,491.4735,500.8712,0,0.5798,0,0,0,0,1,0,0.95,491.5235,1,500.8712,
fam_p1_s4_r2_a42,1.2,normal,2,0,1,2,1,30.9003,52.9995,0.95,1,0.95,0,0,0,0,0.3569,0,1,1,646.8356,673.5291,0,0.5937,0,0,0,0,1,0,0.95,646.8856,2,673.5291,
fam_p1_s4_r2_a42,1.2,normal,2,0,1,3,2,34.5302,59.0494,0.95,1,0.95,0,0,0,0,0.7552,0,2,1,730.2652,759.9579,0,0.5943,0,0,0,0,1,0,0.95,730.3152,3,759.9579,
fam_p1_s4_r2_a42,1.2,normal,2,0,1,4,34,9.45,18.35,1.5,2,0.95;0.55,0,0,0,1,0.2361,0,34,1,857.1842,867.5817,0,0.5608,0,0,0,0,2,0,1.5,857.2342,4,867.5817,
fam_p1_s4_r2_a42,1.2,normal,2,0,1,5,35,9.42,17.2,0.95,1,0.95,0,0,0,0,1.5284,0,35,1,989.202,998.4997,0,0.5797,0,0,0,0,1,0,0.95,989.252,5,998.4997,
fam_p1_s4_r2_a42,1.2,normal,2,0,2,6,36,11.94,21.4,0.95,1,0.95,0,0,0,0,1.5205,0,36,1,1005.098,1016.545,0,0.5839,0,0,0,0,1,0,0.95,1005.148,6,1016.545,
fam_p1_s4_r2_a42,1.2,normal,2,0,1,7,2,34.5302,67.1995,8,3,0.95;6.25;0.8,0,0,0,1,0.007,1,2,1,1023.694,1061.18,0,0.5833,0,0,0,0,3,0,8,1031.501,7,1061.18,20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/stops.csv
condition_id,seed,robot_id,trip_id,t_s,x,z,aisle,in_narrow,cause,cause_detail,path_blocked,duration_s,resolved,clearance_left_cm,clearance_right_cm,min_gap_cm,blocked_s,no_path_s,yield_s,clear_wait_s,replans,solve_from,solve_to,solve_status,solve_corners,off_mesh_m
fam_p1_s4_r2_a42,0,1,1,491.55,16.9,6.05,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.9;6.05,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,2,646.95,16.8519,5.8225,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.852;5.822,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,3,730.4,16.852,5.8243,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.852;5.824,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,4,857.35,16.8518,5.8241,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.852;5.824,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,4,862.4,15.4612,5.1393,,0,お客さんとすれ違った,,0,0.55,自分で動き出した,275,275,275,0,0,0,0.55,0,15.521;5.932,15.238;2.188,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,1,5,989.4,16.8534,5.8273,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,16.853;5.827,15.3;5.95,PathComplete,2,0.025
fam_p1_s4_r2_a42,0,2,6,1005.3,17.7,6.05,,0,分からない,,0,0.95,自分で動き出した,275,275,275,0,0,0,0.95,0,17.7;6.05,15.3;5.95,PathComplete,2,0.02520261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/dishes.csv
condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle
fam_p1_s4_r2_a42,0,1,34,1,0,491.4735,491.5235,500.8712,ロボット,0.05,9.3477,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,2,1,2,0,646.8356,646.8856,673.5291,ロボット,0.05,26.6435,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,3,2,3,0,730.2652,730.3152,759.9579,ロボット,0.05,29.6428,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,4,34,1,0,857.1842,857.2342,867.5817,ロボット,0.05,10.3475,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,5,35,4,0,989.202,989.252,998.4997,ロボット,0.05,9.2477,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,6,36,5,0,1005.098,1005.148,1016.545,ロボット,0.05,11.3972,0,0,0,0,0,0
fam_p1_s4_r2_a42,0,7,2,3,0,1023.694,1031.501,1061.18,ロボット,7.8072,29.679,0,0,0,0,0,020261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/yields.csv
condition_id,seed,t_s,who,rank,to_whom,x,z,aisle,place,in_corner,waited_s,stepped_aside,passed
fam_p1_s4_r2_a42,0,497.522,スタッフ:Staff02,1,ロボット1号機,16.0877,3.1321,,,0,2.15,1,1
fam_p1_s4_r2_a42,0,667.4805,スタッフ:Staff01,1,ロボット1号機,2.8645,4.3534,,,0,4.6,1,1
fam_p1_s4_r2_a42,0,860.7333,スタッフ:Staff01,1,ロボット1号機,15.499,3.993,,,0,1.6,1,1
fam_p1_s4_r2_a42,0,862.8828,スタッフ:Staff01,1,ロボット1号機,15.9736,4.0837,,,0,1.95,1,1
fam_p1_s4_r2_a42,0,1078.547,客:Guest(Clone),2,ロボット1号機,1.8973,6.8273,A01,,0,2.75,0,1
fam_p1_s4_r2_a42,0,1082.851,客:Guest(Clone),2,ロボット1号機,2.0465,8.3029,A01,,0,1.5,0,1
fam_p1_s4_r2_a42,0,1085.904,客:Guest(Clone),2,ロボット1号機,2.0971,8.2883,A01,,0,1.15,0,120261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/requeues.csv
condition_id,seed,t_s,dish_id,table_id,robot_id,fragile,ready_s,waited_s,requeued_so_far,why
fam_p1_s4_r2_a42,0,2087.881,16,39,1,0,1443.753,644.1284,1,打ち切り
fam_p1_s4_r2_a42,0,2087.881,18,40,1,0,1473.532,614.3494,1,打ち切り
fam_p1_s4_r2_a42,0,2087.881,17,4,1,0,1454.513,633.3679,1,打ち切り
fam_p1_s4_r2_a42,0,5668.773,100,21,2,1,5071.017,597.7559,1,打ち切り
fam_p1_s4_r2_a42,0,6266.529,100,21,2,1,5071.017,1195.512,2,打ち切り
fam_p1_s4_r2_a42,0,6280.424,110,38,1,0,5620.662,659.7627,1,打ち切り
fam_p1_s4_r2_a42,0,6280.424,109,3,1,0,5607.812,672.6123,1,打ち切り
fam_p1_s4_r2_a42,0,7928.013,138,12,2,0,7136.218,791.7949,1,打ち切り
20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/give_ups.csv
condition_id,seed,t_s,who,job,table_id,to_x,to_z,x,z,aisle,waited_s,action
fam_p1_s4_r2_a42,0,1158.625,客,ドリンクバー,2,1.912,6.613,2.3204,4.4924,,60,移した
fam_p1_s4_r2_a42,0,1236.401,客,ドリンクバー,2,1.912,6.613,5.3188,4.456,,60,移した
fam_p1_s4_r2_a42,0,1624.579,スタッフ,立ち往生を動かす,0,16.5925,2.5122,16.2997,2.8193,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1751.053,スタッフ,料理を運ぶ,39,20.263,2.188,16.6722,1.7308,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1796.697,スタッフ,立ち往生を動かす,0,16.6118,2.5633,16.1747,2.3881,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1814.164,スタッフ,料理を運ぶ,39,20.263,2.188,16.6585,1.7349,,60.0494,あきらめた
fam_p1_s4_r2_a42,0,1856.806,スタッフ,立ち往生を動かす,0,16.6067,2.5507,16.1748,2.3853,,60.0494,あきらめた20261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/groups.csv
condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s
fam_p1_s4_r2_a42,0,1,2,34,2,60.9694,60.9694,135.1736,3171.729,3171.739,3359.072,3359.072,1.2367,0,Done,867.6317
fam_p1_s4_r2_a42,0,2,4,1,4,128.9233,128.9233,191.6771,3064.755,3064.784,3257.122,3257.122,1.0459,0,Done,1123.34
fam_p1_s4_r2_a42,0,3,4,2,4,215.1285,215.1285,279.3253,2473.656,2517.05,2618.349,2618.349,1.0699,0,Done,1061.23
fam_p1_s4_r2_a42,0,4,2,35,2,399.8959,399.8959,475.5274,3556.784,3556.814,3658.464,3658.464,1.2605,0,Done,1449.258
fam_p1_s4_r2_a42,0,5,2,36,2,418.3914,418.3914,495.5725,3008.475,3008.479,3153.921,3153.921,1.2864,0,Done,1367.178
fam_p1_s4_r2_a42,0,6,4,0,0,435.1373,435.1373,512.3184,3969.122,3969.167,4070.466,4070.466,1.2864,0,Done,1624.93
fam_p1_s4_r2_a42,0,7,4,0,0,592.3489,592.3489,660.1823,3981.958,3981.979,4172.541,4172.541,1.1306,0,Done,2195.13620261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/contacts.csv
condition_id,seed,t_s,x,z,aisle,place,who,careless,robot_id,gap_cm
fam_p1_s4_r2_a42,0,1078.497,1.8969,6.8223,A01,,客:Guest(Clone),0,1,-0.1714
fam_p1_s4_r2_a42,0,1105.273,11.1565,4.0585,,,スタッフ:Staff02,1,2,9.1448
fam_p1_s4_r2_a42,0,1621.777,16.958,1.9976,,,客:Guest(Clone),0,1,-1.5931
fam_p1_s4_r2_a42,0,1790.992,16.958,1.9976,,,客:Guest(Clone),0,1,-1.5931
fam_p1_s4_r2_a42,0,2853.528,9.4805,4.9857,A03,,スタッフ:Staff04,0,2,9.7346
fam_p1_s4_r2_a42,0,2900.074,5.8,5.112,A02,,スタッフ:Staff01,0,2,9.6802
fam_p1_s4_r2_a42,0,2919.493,5.5031,4.2222,,,客:Guest(Clone),0,2,9.853520261024_p1_efficient_corner_fam_p1_s4_r2_a42_s0_1004/conditions.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 10:18:24",
"unity_version": "2022.3.62f3",
"trips_csv_columns": "condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s,reset_to",
"groups_csv_columns": "condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s",
"dishes_csv_columns": "condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle",
"settings": {1020(cs:141・③・ロボット0台):20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/summary.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 10:32:58",
"note": "speed_mps = distance_m / (total_s - stopped_s)。stopped_s には、動けなくなった60秒と、スタッフを待った秒数(stuck_wait_s)、通路の入口で待った秒数も入る。pause_s は stop_durations_s(自分で動き出した止まりだけ)の分布。site_metrics はサイトの meta.metrics と同じ名前・同じ定義。入店待ちの分け方もサイトの試算と同じで、blocked_wait は片付け待ちの卓の数だけ待っている列の前から順に足した分、full_wait は seat_wait − blocked_wait、staff_wait は blocked_wait + guide_wait。pauses と rescues は、サイト側が unity_measures の仮の値から出した数なので出どころが違う。",
"sim_like": {"dish_wait_mean": 0.8037, "dish_wait_p90": 1.508, "cold_share": 0, "seat_wait_mean": 0, "turn_mean": 3.1356, "robot_share": 0, "robot_dishes": 0, "staff_dishes": 160, "requeued_dishes": 0, "late_staff_dishes": 0, "late_staff_share": 0, "robot_first_wait_s": 120, "yields": 0, "yields_by_robot": 0, "yields_by_staff": 0, "yields_by_guest": 0, "yields_stepped_aside": 0, "yields_in_corner": 0, "yields_passed": 0, "yield_wait_s": 0, "yield_wait_mean_s": 0, "staff_yields": 0, "staff_yield_wait_s": 0, "staff_yield_mean_s": 0, "staff_yield_share_of_staff_time": 0, "staff_time_total_s": 41413.03, "corner_stops": 0, "corner_stop_s": 0, "corner_stop_count_share": 0, "corner_stop_time_share": 0, "corner_range": "x 10.5-13.5 / z 3.5-5.8", "groups": 64, "people_jams": 62, "robot_blocked_jams": 0, "robot_blocked_jam_share": 0, "chair_pulls": 176, "robot_contacts": 0, "robot_yield_waits": 0, "robot_yield_wait_s": 0, "robot_yield_detours": 0, "register_crowd_max": 8, "register_crowd_mean": 1.973, "register_pay_count": 64, "register_pay_not_at_back": 0, "register_pay_off_spot": 0, "register_pay_offset_mean_m": 0, "register_pay_offset_max_m": 0, "register_back_intruders": 0, "register_back_intruder_s": 0, "drink_bar_queued": 20, "drink_bar_gave_up": 1, "drink_bar_wait_mean": 0.6272, "drink_bar_wait_p90": 0.8266, "gave_up": 1, "warped": 9, "table_freed": 0, "people_jam_total_s": 64.7, "walkers_mean": 7.7253, "measured_minutes": 172.4463},
"site_metrics": {"entry_wait_mean": 1.4944, "full_wait_mean": 0, "staff_wait_mean": 0.3091, "blocked_wait_mean": 0, "guide_wait_mean": 0.3091, "seat_wait_mean": 0, "dish_wait_mean": 0.8037, "dish_wait_p90": 1.508, "cold_share": 0, "turn_mean": 3.1356, "walk_km_per_staff": 2.8029, "staff_util": 0.6616, "robot_util": 0, "robot_share": 0, "rescues": 0, "pauses": 0, "groups": 64},
"site_run": {"site_run": true, "condition_id": "fam_p1_s4_r0_a42", "arrivals_minutes": 120, "total_minutes": 172.4463, "everyone_left": true, "aisle_deferrals": 0, "staff_first_yield": true, "robot_stuck_detours": 0, "rescues_done": 0, "rescue_wait_s": 0, "gave_up": 1, "warped": 9, "table_freed": 0},
"site_result": {"dish_wait_mean": 0.653, "dish_wait_p90": 1.3663, "cold_share": 0.0004, "seat_wait_mean": 2.602, "turn_mean": 9.4605, "walk_km_per_staff": 2.7655, "staff_util": 0.7511, "robot_util": 0, "robot_share": 0, "robot_bus_share": 0, "collects": 0, "rescues": 0, "pauses": 0, "fragile_robot": 0, "groups": 84.2, "entry_wait_mean": 3.1814, "blocked_wait_mean": 2.4548, "guide_wait_mean": 0.3997, "staff_wait_mean": 2.8545, "full_wait_mean": 0.1472},20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/run_info.json
{
"run_label": "site_v5",
"written_at": "2026-10-24 10:32:58",
"condition_id": "fam_p1_s4_r0_a42",
"store_kind": "StoreLayout_p1_efficient_corner",
"time_mode": "FixedStep",
"time_scale": 1,
"capture_delta_time": 0.05,
"aisle_width_m": 1.2,
"delivery_offset_m": 0,
"delivery_offset_used_m": 0,
"crowd": "normal",
"robots": 0,
"seed": 0,
"trips_requested": 0,
"trips_done": 0,
"stopped_early": false,
"one_robot_per_aisle": true,
"yield_order_enabled": true,
"unity_cs": "",
"pending_changes": "",
"staff_first_yield": true,
"sim_seconds": 10346.78,
"wall_seconds": 723.6796,
"speedup": 14.2975,
"frame_delta_s": {"count": 207370, "mean": 0.0499, "min": 0.02, "p50": 0.05, "p90": 0.05, "p99": 0.05, "max": 0.05},
"robot_step_m": {"count": 207370, "mean": 0, "min": 0, "p50": 0, "p90": 0, "p99": 0, "max": 0},
"people_step_m": {"count": 207370, "mean": 0.0577, "min": 0, "p50": 0.05, "p90": 0.05, "p99": 0.05, "max": 22.5693},
"frames_over_005m": 0,
"frames_over_005m_ratio": 0,
"people_frames_over_005m": 70625,
"people_frames_over_005m_ratio": 0.3406,
"chair_pulls": 176,
"chair_pulls_by_reason": {"座る": 19, "食事中": 39, "ドリンクバー": 45, "トイレ": 4, "戻って座る": 31, "会計": 19, "退店": 19}
}
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/trips.csv
condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s,reset_to
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/stops.csv
condition_id,seed,robot_id,trip_id,t_s,x,z,aisle,in_narrow,cause,cause_detail,path_blocked,duration_s,resolved,clearance_left_cm,clearance_right_cm,min_gap_cm,blocked_s,no_path_s,yield_s,clear_wait_s,replans,solve_from,solve_to,solve_status,solve_corners,off_mesh_m
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/dishes.csv
condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle
fam_p1_s4_r0_a42,0,1,34,1,0,491.4735,491.4735,507.6196,スタッフ,0,16.1461,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,2,1,2,0,646.8356,646.8356,673.879,スタッフ,0,27.0434,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,3,2,3,0,730.2652,730.2652,758.7083,スタッフ,0,28.4431,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,4,34,1,0,857.1842,857.1842,876.3795,スタッフ,0,19.1953,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,5,35,4,0,989.202,989.202,1005.648,スタッフ,0,16.446,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,6,36,5,0,1005.098,1005.098,1023.394,スタッフ,0,18.2955,0,0,1,0,0,0
fam_p1_s4_r0_a42,0,7,2,3,0,1023.694,1023.694,1052.171,スタッフ,0,28.4774,0,0,1,0,0,020261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/yields.csv
condition_id,seed,t_s,who,rank,to_whom,x,z,aisle,place,in_corner,waited_s,stepped_aside,passed
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/requeues.csv
condition_id,seed,t_s,dish_id,table_id,robot_id,fragile,ready_s,waited_s,requeued_so_far,why
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/give_ups.csv
condition_id,seed,t_s,who,job,table_id,to_x,to_z,x,z,aisle,waited_s,action
fam_p1_s4_r0_a42,0,2624.255,客,ドリンクバー,4,1.912,10.312,2.15,6.8194,A01,60,移した
fam_p1_s4_r0_a42,0,2983.105,客,トイレ,40,21.362,2.188,17.6539,2.5101,,60,移した
fam_p1_s4_r0_a42,0,4785.537,客,ドリンクバー,22,18.8,3.9,9.388,12.688,A03,0,あきらめた
fam_p1_s4_r0_a42,0,6231.217,客,ドリンクバー,3,1.912,8.462,2.2415,4.6585,A01,60,移した
fam_p1_s4_r0_a42,0,6298.703,客,ドリンクバー,3,1.912,8.462,2.0555,4.8995,A01,60,移した
fam_p1_s4_r0_a42,0,6438.255,客,トイレ,39,20.263,2.188,18.0549,2.365,,60,移した
fam_p1_s4_r0_a42,0,6734.444,客,ドリンクバー,4,1.912,10.312,1.9287,9.7365,A01,60,移した
fam_p1_s4_r0_a42,0,6740.171,客,ドリンクバー,6,1.912,6.812,2.3258,4.5503,,60,移した
fam_p1_s4_r0_a42,0,6931.621,客,ドリンクバー,8,1.912,10.513,1.9767,9.0513,A01,60,移した
fam_p1_s4_r0_a42,0,6936.501,客,ドリンクバー,8,1.912,10.513,2.1266,5.6671,A01,60,移した
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/groups.csv
condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s
fam_p1_s4_r0_a42,0,1,2,34,2,60.9694,60.9694,135.1736,3180.527,3180.547,3285.4,3285.4,1.2367,0,Done,876.4295
fam_p1_s4_r0_a42,0,2,4,1,4,128.9233,128.9233,191.6771,3029.621,3029.65,3136.655,3136.655,1.0459,0,Done,1088.206
fam_p1_s4_r0_a42,0,3,4,2,4,215.1285,215.1285,279.3253,2464.647,2514.097,2615.997,2615.997,1.0699,0,Done,1052.221
fam_p1_s4_r0_a42,0,4,2,35,2,399.8959,399.8959,475.5274,3508.487,3508.517,3685.09,3685.09,1.2605,0,Done,1400.961
fam_p1_s4_r0_a42,0,5,2,36,2,418.3914,418.3914,495.5725,2925.594,2925.599,3046.467,3046.467,1.2864,0,Done,1284.297
fam_p1_s4_r0_a42,0,6,4,3,4,435.1373,435.1373,512.3184,3851.357,3851.402,4026.673,4026.673,1.2864,0,Done,1507.165
fam_p1_s4_r0_a42,0,7,4,4,4,592.3489,592.3489,660.1323,3274.117,3274.139,3477.687,3477.687,1.1297,0,Done,1487.29520261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/contacts.csv
condition_id,seed,t_s,x,z,aisle,place,who,careless,robot_id,gap_cm
20261024_p1_efficient_corner_fam_p1_s4_r0_a42_s0_1020/conditions.json
{
"run_name": "family_v0",
"written_at": "2026-10-24 10:32:58",
"unity_version": "2022.3.62f3",
"trips_csv_columns": "condition_id,aisle_width_m,crowd,robots,seed,robot_id,trip_id,table_id,distance_m,total_s,stopped_s,n_stops,stop_durations_s,stuck,timeout,wait_aisle_s,max_decel_mps2,min_clearance_m,met_robot,table_ids,dishes,dish_ready_s,dish_arrived_s,undelivered,speed_mps,stuck_count,stuck_wait_s,via_narrow,stops_in_narrow,stops_out_narrow,stopped_in_narrow_s,stopped_out_narrow_s,run_start_s,dish_ids,stop_arrived_s,reset_to",
"groups_csv_columns": "condition_id,seed,group_id,size,table_id,table_seats,arrive_s,guide_start_s,seated_s,eat_end_s,pay_start_s,pay_s,left_s,waited_min,warmup,state,eat_start_s",
"dishes_csv_columns": "condition_id,seed,dish_id,table_id,group_id,fragile,ready_s,first_taken_s,arrived_s,carried_by,pass_wait_s,carry_s,requeue_lost_s,requeued,staff_from_start,robot_wait_expired,late_staff_pickup,deferred_for_aisle",
"settings": {