---
title: "サービスロボット導入シミュレーション Log#19 | 大きい店でも、詰まるのは片付けだった"
slug: large-store-cleanup-bottleneck
date: 2026-10-28
day: 397
meta_description: "配膳ロボットを足すと入店待ちは縮むが、大きなファミレスで詰まるのはレジではなく片付けと案内だった。46卓の店をUnityの3Dで再現し、ロボットの抜け道を店の形で作って確かめた。"
tags: [サービスロボット導入シミュレーション, 配膳ロボット, 飲食店, Unity, シミュレーション, 店の形, 店舗レイアウト]
series: "導入シミュレーション"
---

配膳ロボットを足すと入店待ちは縮みますが、大きなファミレスで詰まるのは会計のレジではなく、食べ終えた卓の片付けと空いた席への案内でした。46卓・200席の店を Unity の3Dで再現したシミュレーションで、配膳ロボットを走らせて確かめました。ロボットを1台、2台と足すと、お客さんが席に着くまでの待ちは8.1分、6.6分、5.5分と縮みました。ここまでは、サイトに公開している試算と同じ向きです。ところが、店が詰まる場所が試算と違いました。試算ではレジに会計の列ができて詰まります。3Dの店ではレジはそれほど詰まらず、**詰まっていたのは、食べ終えた卓の片付けと、空いた席への案内のほうでした。**

配膳ロボットを入れると店がどう変わるかを、2つのやり方で調べています。1つはサイトの試算で、卓までの距離・料理の数・スタッフの人数から、待ち時間を計算します。もう1つは Unity（ゲームを作る道具）で作った3Dのファミレスで、お客さん・スタッフ・ロボットを1人ずつ動かすシミュレーションです。試算を正とし、3Dの店は「通路で実際に何が起きるか」を測る役です。これまで42卓の店（③と⑦）と28卓の小さい店（④）で回してきました。今回は、いちばん大きい⑤（ゆったり型・入口が正面の中央）に広げました。

⑤は、建てる前に図面を見た段階で、1つ問題が見つかりました。真ん中の島（背中合わせのソファ席の列）の上の端と、料理が出てくるパントリーの間が0.25mしかありませんでした。ロボットは料理を受け取ったあと、左側の卓へまっすぐ抜けられません。左の卓へ行くロボットは全部、島の下を回り、入口とレジの前を通っていました。お客さんが入ってくる所、会計に並ぶ所、待合の前を、料理を載せたロボットが横切る形です。

そこで、試算と3Dの店の両方の元になっている「店の形」を直しました。島の上の2卓を外して右の壁ぞいへ移し、キッチン側（パントリー・キッチン・洗い場・更衣室・受け渡し口・ロボットの待機場所）をまとめて左へ1.5mずらしました。卓の数と席の数は変わりません。島の上とパントリーの間は約2.1mになり、受け渡し口から左側へまっすぐ抜けられるようになりました。

| やったこと | なぜ | 結果 |
|---|---|---|
| ③⑦の基準データを v5 に切り替えた | ロボットが往復のあと待機場所へ戻る作りを標準にしたため | 受け渡し口の近くの30秒以上の止まりが、③156→86回・⑦133→76回 |
| ⑤の図面を見て、店の形を直した | 島の上が0.25mで、左へ行くロボットが入口とレジの前を通っていた | 入口・レジの前を通る道が46卓中24卓→10卓。卓までの距離は平均13.7m→12.5m |
| ⑤の試算だけ計算し直した | 卓の位置が変わったため | 料理の待ちはどの台数も少し短く。会計待ちはレジ1つで13〜19分 |
| 3Dの店に⑤を建てた | 店の形のデータに、入口のない通路が1本あった | サイト側の作り方を直して建った |
| ⑤を種10個ずつ、計30回回した | 1回ずつでは来る客の数がぶれるため | 入口・レジの前の止まりは2台で3回。詰まりは片付けと案内に移った |

3Dの店で回した結果は、次のとおりです（種10個の中央値。右は試算）。

| | ロボット0台 | 1台 | 2台 |
|---|---|---|---|
| 入店待ち（分） | 8.1 / 6.2 | 6.6 / 3.4 | 5.5 / 3.7 |
| そのうち、席は空いているのに待った（分） | 6.5 / 1.5 | 4.6 / 0.8 | 3.4 / 0.7 |
| 会計待ち（分） | 5.7 / 18.8 | 7.2 / 13.0 | 7.0 / 13.0 |
| 料理の待ち（分） | 1.1 / 0.6 | 2.6 / 2.1 | 2.2 / 1.2 |
| ロボットが運んだ皿の割合 | − | 0.67 / 0.69 | 0.82 / 0.98 |

試算では、食べ終えたお客さんがレジの順番を待つ間、卓に座ったままでいます。レジが1つしかないと会計待ちが13〜19分に延び、その分だけ卓が空かず、次のお客さんが待ちます。3Dの店では会計待ちは7分前後で、代わりに「席は空いているのに待った」時間が試算の4〜8倍になりました。スタッフ4人の手が、片付けと案内に回りきっていません。42卓の③⑦でも同じ形のずれが出ていて、店の大きさを変えても残りました。

この記事の後半は、作業ログです。⑤の前に済ませた③⑦の基準データの切り替え、図面の直し、試算の計算し直し、3Dの店に建てるまでの2回の失敗、30回分の結果を、依頼文・報告・コード・出力とあわせて載せます。

配膳ロボットを自分の店に入れたらどうなるかは、このシリーズの試算をもとにした別のページで試せます。

【バナー】serving-robot-one-less-staff


## 作業ログ ― ③⑦の基準データを v5 に切り替えた

3Dの店は、夜のあいだに同じ条件を何十回も回し、前に決めた「基準データ」と比べて、作りが壊れていないかを自動で判定しています。④を調べたときに、ロボットが往復を終えても受け渡し口の前に止まったままになる作りの誤りが見つかり、「往復を終えたら待機場所へ戻る」作りを入れました。これを③⑦の標準にし、③⑦を60回回し直して、基準データ v5 の候補にしました。

この記事で書く効果は、すべて3Dの店で測った値です。直す前に回していない所は、そう断って書きます。

### 依頼文：待機場所へ戻るを標準にし、③⑦をv5候補で回す（20261028_15）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 240
---
# 依頼：待機場所へ戻るを標準にし、判定を切り替えごとに分け、③⑦を60回回す（基準データ v5 の候補・2026-10-28）

エイイチの決定（2026-10-28 06:33）：前の2つの報告（20261031_night_p2_standby.txt・20261101_night_37_standby_ruleB.txt）を受けて
1. 待機場所へ戻るを標準（既定 入）にする
2. 案B（受け渡し口は1台ずつ・同じ卓は1台）は切のまま。作りは消さない
3. 判定（judge_night.py）を、切り替え（すれ違い・待機場所へ戻る・案B）の入切ごとに分けて比べる形にする
4. ③⑦を「すれ違い入・待機場所へ戻る 入・案B 切」で60回回し、基準データ v5 の候補にする（v5 にするかはエイイチが決める）

サイト（正）を直した（p2m-site commit eb03d73）：params の schema 0.4。`unity_rules` に `standby_return`（true）を足し、`pass_one_robot`・`same_table_one_robot` を false にした。試算の数字・条件・店の形の版（39257d16b68a）は変わっていない。

台帳の退避は Claude が済ませた：`/Volumes/KIOXIA/r2r2r-data/service_sim/unity/archive/unity_ledger_v1_prenight_20261102/unity_ledger_v1.csv`（505行・md5 c7031e3824b9aa6b137668d44e87db64）

## 始める前に確かめること（違えば回さずに報告して終わる）

1. Unity エディタが起動していない
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 台帳の md5 が上の退避と同じ
4. ServiceSim の保留が 0（cs:33 head）
5. https://pixelstomotors.com/sim/serving-robot-params.json の meta.schema_version が serving-robot-params/0.4（まだ 0.3 なら数分おきに取り直す。30分たっても 0.3 なら報告して終わる）

## やること

1. 公開版の params をプロジェクトに写す。`unity_rules` 以外が今の写しと同じか確かめる
2. 待機場所へ戻る・案Bの既定を、params の `unity_rules` の値から決める形にする（standby_return 入・案B 切）。`-ssStandbyReturn`・`-ssRuleB`・make_queue / night_runner の `--standby-return`・`--rule-b` で、回ごとに入切を上書きできるのは今のまま。エディタのメニュー（Site Run など）も同じ既定にする
   - 出力フォルダ名の字：今は入のとき `_sbret` が付く。既定が入になっても、入のときは今までどおり `_sbret` を付ける（名前から作りが分かるように）
3. judge_night.py：回ごとの run_info.json（または queue）にある切り替え（すれ違い・待機場所へ戻る・案B）の入切を条件の一部として扱い、基準データの中で**同じ条件・同じ入切の回とだけ**比べる。同じ入切の回が基準に無ければ「基準なし」。判定の決まり（何を超えたら何に振り分けるか）は変えない。基準データの既定（v4・20261029_night_cs26_*）も変えない
   - 確かめ：夜 20261101（待機場所 入・案B 入）を判定し直すと、v4 と入切が違うので60回とも「基準なし」になること。夜 20261029（v4）を自分自身に当てると今までどおり「正常」60になること（/tmp に出す。night/ の記録は上書きしない）
4. 何も指定しないときの make_queue が、③⑦の60回・すれ違い入・待機場所へ戻る 入・案B 切になることを確かめる
5. check-in して、画面なしの実行ファイルを作り直す（保留 0）
6. 夜の名前 20261102 で、何も指定しない make_queue の60回を回す（同時4本・記録は night/20261102/）。回している間はほかの作業をしない
7. 台帳の行数（505 → 565 のはず）と先頭505行の md5 が退避と同じかを確かめる
8. 作業フォルダに queue の一時ファイルを残さない

## 変えないもの

- 店の形・人の動き・速さ・物理の設定・すれ違いの作り・待機場所へ戻る作りの中身（cs:33）・案Bの作り
- 台帳の列（59列）と今までの行。今までの night/ の記録

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261102_night_37_v5candidate.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。

- 始める前の確かめ5つの結果
- 入れた cs 番号・build_id と保留の有無・変えたファイル
- 判定の直しと、3 の確かめ2つの結果
- runner_log のまとめ・台帳の行数と md5
- 店 × 台数ごとの種10個の中央値（最小〜最大）を、v4（20261029・待機場所 切）と、夜 20261101（待機場所 入・案B 入）と並べる：入店待ち・料理の待ち・ロボットが運んだ皿の割合・往復の数・30秒以上の止まり（1往復あたり）・動けなくなった（60秒）・瞬間移動・打ち切り・冷めた皿の割合。試算の値も並べる
- 2台の30秒以上の止まりの、受け渡し口の点から 2.5 m 以内の数（待機場所での止まりを除いた数も）を、v4・20261101 と並べる
- ロボットを1台増やしたときの向き（入店待ち・料理の待ち）が、種の過半数で試算と同じか逆か
- 全員が帰らなかった回・失敗した回があればその名前
- 決めてほしいこと（なければ「なし」）
```

### 報告：20261102_night_37_v5candidate.txt

```text
====================================================================
待機場所へ戻るを標準にし、判定を入切ごとに分け、③⑦を60回回した（夜 20261102・基準データ v5 の候補）
依頼：20261028_15_待機場所へ戻るを標準に_③⑦をv5候補で回す.md
実行ファイル：build_id cs34_20261028_0642（ServiceSim/cs:34・保留なし）
回した時刻：2026-10-28 06:42〜07:43
====================================================================

結論

  ・案B と待機場所へ戻るの既定を params の unity_rules で決めるようにした（schema 0.4 では 待機場所へ戻る 入・案B 切）。
    回ごとに上書きする仕組み（-ssStandbyReturn・-ssRuleB・--standby-return・--rule-b）は今のまま使える。
  ・judge_night.py は、すれ違い・待機場所へ戻る・案B の入切を条件の一部として扱うようにした。
    確かめは2つとも思ったとおりだった（20261101 は60回とも「基準なし」、20261029 を自分自身に当てると「正常」60回）。
  ・60回とも completed・終了コード 0・全員が帰った。失敗した回・止まった回はない。
  ・2台の回は、v4 とほぼ同じか少し良い。20261101（案B 入）で増えた打ち切りや止まりは出なかった。
    受け渡し口の近くでの30秒以上の止まりは、v4 よりはっきり少ない。
  ・judge.md の結果は「基準なし」60回。基準 v4 は待機場所へ戻るが切なので、比べる相手がいない。
    これは決めた形のとおり。


====================================================================
1. 始める前の確かめ（5つとも合格。06:3x ごろ）
====================================================================

  1. Unity エディタ：起動していない
  2. /Volumes/KIOXIA：マウントされている。unity_ledger_v1.lock：なし
  3. 台帳：505 行、md5 c7031e3824b9aa6b137668d44e87db64（退避
     archive/unity_ledger_v1_prenight_20261102/unity_ledger_v1.csv と同じ）
  4. ServiceSim の保留：0（cm status：cs:33 head・変更なし）
  5. 公開版 params の meta.schema_version：serving-robot-params/0.4（1回目で 0.4 だった）
     unity_rules：standby_return true・pass_one_robot false・pass_clear_m 1.5・same_table_one_robot false


====================================================================
2. 入れた cs・実行ファイル・変えたファイル
====================================================================

  check-in：cs:34（保留 0）
  実行ファイル：Builds/headless/build_info.json は build_id cs34_20261028_0642・unity_cs ServiceSim/cs:34・
    pending_changes 空。実行ファイルの中の params は 0.4（0.3 の字は入っていない）。
  check-in の前に、画面なしで Unity を開いてコンパイルを確かめた（エラーなし）。

  params の写し：公開版をそのまま Assets/ServiceSim/Experiment/serving-robot-params.json に写した。
    前の写しと違うのは meta.schema_version（0.3 → 0.4）と unity_rules だけで、ほかは同じだった
    （試算の版 v2.8・店の形の版 39257d16b68a は変わらない）。

  変えたファイル（9つ）
    Assets/ServiceSim/Experiment/serving-robot-params.json … 公開版 0.4 の写し
    Assets/ServiceSim/Experiment/SimParams.cs … 既定を読む関数を2つ足した（StandbyReturnDefault・RuleBDefault）
    Assets/ServiceSim/Experiment/ExperimentRunner.cs … Job.ruleB・Job.standbyReturn を「指定なし（null）＝ params の既定」
        にした。サイトの条件でない回は、指定がなければ今までどおり切
    Assets/ServiceSim/Experiment/HeadlessRun.cs … -ssRuleB・-ssStandbyReturn が無いときは params の既定で決める
        （フォルダ名の _ruleb・_sbret もその値で付ける）
    Assets/ServiceSim/Editor/ServiceSimSiteRun.cs … Site Run のメニューも params の既定で回す。入の回はフォルダ名に _sbret
    Assets/ServiceSim/Editor/ServiceSimStageB.cs … Stage B のまとめて回すメニューも params の既定で回す。
        入の回はフォルダ名の末尾に _ruleb・_sbret を付ける
    tools/make_queue.py … --rule-b・--standby-return を付けないときは params の unity_rules で決める。
        queue に rules_from（arg / params）と params_schema を書く
    tools/night_runner.py … queue に入切が無い回は params の既定で決める（前は切）
    tools/judge_night.py … 下の 3 章

  案B の入切の決め方（作りの説明）
    ・指定なし：pass_one_robot・same_table_one_robot の値をそのまま使う。どちらかが true なら案B 入（今は両方 false なので切）
    ・入と指定した回：受け渡し口は1台ずつ・同じ卓は1台 の両方を入れる。離れる距離 pass_clear_m は params の 1.5 m を使う。
      params が 0.3 のころは両方 true だったので、20261101 と同じ動きになる。
      0.4 で両方 false になったので、params の値をそのまま読むと「入と指定しても何も効かない」ことになる。
      それを避けるためにこの形にした（決めてほしいこと 1）
    ・切と指定した回：両方切


====================================================================
3. 判定の直しと確かめ
====================================================================

  直したこと
    ・条件の名前に standby_return・rule_b を足した（店・スタッフ・来客・mode・trays・すれ違い・待機場所へ戻る・案B・台数）
    ・入切は、回ごとの run_info.json にある pass_by.enabled・standby_return.enabled・rule_b.enabled から取る
      （項目が無い回は切とする。その作りがまだ無かった版の回）
    ・基準データの中で、条件も入切も同じ回とだけ比べる。同じ入切の回が無ければ「基準なし」
    ・judge.md の頭に、今回の回の入切と基準の回の入切を1行で出す。条件の名前にも3つの入切を出す
    ・変えていないもの：振り分けの決まり（線・何を超えたら何に振り分けるか）、基準の既定 20261029_night_cs26_*

  確かめ（どちらも /tmp に出した。night/ の記録は書き換えていない）
    ・夜 20261101（待機場所 入・案B 入）を判定し直した → /tmp/judge_check_20261101
      基準なし 60（正常 0・試算を見直す候補 0・Unity の作り 0・回の失敗 0）　… 思ったとおり
    ・夜 20261029（v4）を自分自身に当てた → /tmp/judge_check_20261029_self
      正常 60（ほかは 0）　… 思ったとおり

  make_queue を何も指定せずに作った queue（4 の確かめ）
    60回＝6条件（fam_p1・fam_p5 × 0・1・2台）× 種 0〜9、60回とも すれ違い入・案B 切・待機場所へ戻る 入。
    rules_from は rule_b・standby_return とも params、params_schema は serving-robot-params/0.4。


====================================================================
4. 回した内容と runner_log のまとめ
====================================================================

  make_queue.py --out /tmp/queue_20261102.json（何も指定しない）
  night_runner.py --queue /tmp/queue_20261102.json --night 20261102 --parallel 4 --no-retry
    （--no-retry は前の夜 20261101 にそろえた）
  出力フォルダ：20261102_night_cs34_fam_{p1|p5}_r{0|1|2}_s{0〜9}_passon_sbret
  記録：night/20261102/（runner_log.txt・runs.csv・queue.json・judge.md・judge.csv・logs/）

  completed 60 回／失敗 0／止まった回 0／終了コード 0 が 60 回
  実時間は平均 3.9 分、いちばん長い回は 4.9 分（20261102_night_cs34_fam_p5_r2_s4_passon_sbret）
  起動したときの同時本数は、4本が56回、3本が2回、2本と1本が1回ずつ
  judge.md の結果：基準なし 60（v4 は待機場所へ戻るが切なので、同じ入切の基準がない）

  プロジェクトの queue.json は触っていない（md5 07f2acccf5b13abbf1a96148fbc70e9f のまま。
  2026-10-27 からある古いファイル）。作業フォルダには新しい queue を置いていない。


====================================================================
5. 台帳
====================================================================

  505 → 565 行（退避の行数＋60）。先頭 505 行の md5 c7031e3824b9aa6b137668d44e87db64（退避と同じ）
  新しい 60 行：status はすべて completed、everyone_left はすべて 1、unity_cs はすべて ServiceSim/cs:34。
  鍵ファイルは残っていない。


====================================================================
6. 店 × 台数ごとの種10個（中央値（最小〜最大））
====================================================================

  書き方：単位は分。割合は 0〜1。列の取り方は前の報告（20261101_night_37_standby_ruleB.txt）と同じ。
  30秒以上の止まり＝stops.csv の duration_s が 30 秒以上の行の数。1往復あたり＝それ÷trips。
  並び：v4（20261029・待機場所 切・案B 切）／ 20261101（待機場所 入・案B 入）／ 今回 20261102（待機場所 入・案B 切）／ 試算
  試算の値は台帳の site_entry_wait_mean・site_dish_wait_mean・site_robot_share（どの種でも同じ値）

  ③ fam_p1・0台
    入店待ち            4.21（1.50〜15.25）／ 4.22（1.56〜15.12）／ 4.09（1.51〜14.80）／ 3.30
    料理の待ち          0.94（0.80〜1.08） ／ 0.97（0.80〜1.06） ／ 0.98（0.77〜1.05） ／ 0.46
    ロボットが運んだ皿  0 ／ 0 ／ 0 ／ 0
    往復・30秒以上の止まり・動けなくなった・打ち切り  3つの夜とも、すべて 0
    瞬間移動            12（9〜19）／ 10.5（6〜15）／ 10.5（7〜15）
    冷めた皿の割合      0.000（0.000〜0.008）／ 0.000（0.000〜0.010）／ 0.000（0.000〜0.015）

  ③ fam_p1・1台
    入店待ち            3.01（1.44〜11.46）／ 4.10（1.37〜14.56）／ 5.00（1.42〜13.24）／ 2.60
    料理の待ち          2.40（2.01〜2.64） ／ 2.44（1.97〜2.80） ／ 2.48（2.11〜3.24） ／ 1.95
    ロボットが運んだ皿  0.710（0.648〜0.762）／ 0.676（0.610〜0.806）／ 0.706（0.589〜0.738）／ 0.720
    往復の数            69.5（60〜90）／ 67.5（60〜80）／ 65.5（59〜84）
    30秒以上の止まり    7.5（2〜16）／ 9（1〜17）／ 6（2〜22）
     （1往復あたり）    0.107（0.029〜0.262）／ 0.141（0.015〜0.221）／ 0.083（0.027〜0.361）
    動けなくなった      4（0〜12）／ 5.5（0〜15）／ 3.5（1〜14）
    瞬間移動            50（24〜61）／ 45（39〜61）／ 49（43〜61）
    打ち切り            0（0〜1）／ 0（0〜2）／ 0（0〜1）
    冷めた皿の割合      0.300（0.164〜0.358）／ 0.265（0.138〜0.360）／ 0.286（0.150〜0.417）

  ③ fam_p1・2台
    入店待ち            4.17（1.45〜12.78）／ 4.13（1.50〜16.42）／ 3.99（1.40〜13.93）／ 1.18
    料理の待ち          1.62（1.12〜3.40） ／ 2.54（1.73〜5.23） ／ 1.95（1.09〜3.24） ／ 0.95
    ロボットが運んだ皿  0.920（0.709〜0.975）／ 0.560（0.079〜0.888）／ 0.832（0.694〜0.988）／ 0.991
    往復の数            130（95〜164）／ 85（30〜122）／ 119.5（98〜151）
    30秒以上の止まり    38（11〜55）／ 49.5（9〜111）／ 24.5（10〜44）
     （1往復あたり）    0.255（0.116〜0.335）／ 0.470（0.164〜2.523）／ 0.173（0.086〜0.411）
    動けなくなった      25（6〜43）／ 40.5（7〜105）／ 18（5〜31）
    瞬間移動            66（43〜86）／ 45.5（19〜66）／ 60（24〜76）
    打ち切り            3（1〜15）／ 10（1〜19）／ 4.5（0〜10）
    冷めた皿の割合      0.132（0.050〜0.209）／ 0.235（0.086〜0.518）／ 0.163（0.031〜0.228）

  ⑦ fam_p5・0台
    入店待ち            4.48（1.58〜15.36）／ 4.41（1.56〜15.24）／ 4.49（1.55〜15.25）／ 2.76
    料理の待ち          0.98（0.84〜1.01） ／ 0.99（0.85〜1.10） ／ 0.96（0.81〜1.08） ／ 0.45
    ロボットが運んだ皿  0 ／ 0 ／ 0 ／ 0
    往復・30秒以上の止まり・動けなくなった・打ち切り  3つの夜とも、すべて 0
    瞬間移動            14（11〜18）／ 16（12〜20）／ 13（10〜21）
    冷めた皿の割合      0.000（0.000〜0.012）／ 0.002（0.000〜0.029）／ 0.000（0.000〜0.012）

  ⑦ fam_p5・1台
    入店待ち            3.84（1.53〜13.54）／ 3.00（1.36〜14.01）／ 3.22（1.56〜14.63）／ 1.81
    料理の待ち          2.44（1.76〜3.15） ／ 2.46（2.04〜2.70） ／ 2.51（2.19〜2.86） ／ 1.97
    ロボットが運んだ皿  0.666（0.544〜0.825）／ 0.686（0.628〜0.744）／ 0.669（0.625〜0.746）／ 0.721
    往復の数            69（55〜87）／ 66（57〜82）／ 67.5（58〜78）
    30秒以上の止まり    10（2〜26）／ 7（2〜15）／ 8（4〜17）
     （1往復あたり）    0.124（0.029〜0.473）／ 0.106（0.027〜0.197）／ 0.127（0.055〜0.293）
    動けなくなった      6（1〜22）／ 3.5（1〜12）／ 5.5（1〜9）
    瞬間移動            48（29〜66）／ 46.5（32〜62）／ 48.5（31〜58）
    打ち切り            0（0〜2）／ 0（0〜2）／ 0（0〜1）
    冷めた皿の割合      0.304（0.106〜0.461）／ 0.301（0.169〜0.342）／ 0.328（0.244〜0.418）

  ⑦ fam_p5・2台
    入店待ち            4.81（1.43〜10.86）／ 4.02（1.48〜16.05）／ 3.56（1.49〜14.76）／ 1.97
    料理の待ち          1.52（1.02〜2.57） ／ 2.86（1.56〜5.35） ／ 1.61（1.18〜2.41） ／ 0.98
    ロボットが運んだ皿  0.919（0.768〜0.979）／ 0.663（0.074〜0.800）／ 0.916（0.799〜0.969）／ 0.991
    往復の数            136（116〜174）／ 85（26〜128）／ 124（111〜164）
    30秒以上の止まり    27（10〜39）／ 31.5（1〜113）／ 26.5（11〜39）
     （1往復あたり）    0.200（0.074〜0.311）／ 0.323（0.027〜4.346）／ 0.197（0.097〜0.351）
    動けなくなった      17（2〜28）／ 24.5（0〜107）／ 16.5（3〜28）
    瞬間移動            61（35〜82）／ 39.5（13〜71）／ 62.5（33〜85）
    打ち切り            3（1〜10）／ 10（2〜19）／ 3.5（0〜6）
    冷めた皿の割合      0.101（0.031〜0.191）／ 0.274（0.087〜0.616）／ 0.117（0.044〜0.234）

  0台の瞬間移動は、台帳の warped の値をそのまま出した（前の報告と同じく、どこまで数えている列かは確かめていない）。


====================================================================
7. 2台の30秒以上の止まりのうち、受け渡し口の点から 2.5 m 以内のもの
====================================================================

  受け渡し口の点は (15.3, 5.95)。「待機場所での止まり」は、店の形の RobotStandby の四角の中で記録された止まりとした
  （③⑦とも 3つ：x 16.5〜17.3・17.3〜18.1・18.1〜18.9、z 5.65〜6.45）。待機場所を除いた数は、それを引いた数。
  v4 は待機場所へ戻るが切なので、待機場所の四角の中での止まりは 0 だった（除いても数は同じ）。

                       v4                  20261101            今回 20261102
  ③ 2.5 m 以内 計      156（344 のうち）   431（508 のうち）   86（230 のうち）
     中央値            18.5（1〜27）        37.5（7〜109）       6.5（1〜19）
     種0〜9            19,1,27,15,20,19,21,15,1,18
                                           59,18,109,41,86,9,44,34,7,24
                                                               2,5,15,17,1,19,2,8,16,1
    待機場所を除く 計  156                 244                 46
     中央値            18.5（1〜27）        2（0〜102）          3（0〜15）
     種0〜9            （上と同じ）         59,5,102,0,73,2,0,0,1,2
                                                               1,3,4,15,1,9,0,3,10,0

  ⑦ 2.5 m 以内 計      133（248 のうち）   323（423 のうち）   76（247 のうち）
     中央値            13（3〜27）          16（1〜110）         4（1〜24）
     種0〜9            5,14,3,14,7,27,12,23,7,21
                                           13,28,97,18,1,110,8,13,21,14
                                                               5,3,1,24,17,13,4,4,1,4
    待機場所を除く 計  133                 203                 45
     中央値            13（3〜27）          0.5（0〜103）        1.5（0〜23）
     種0〜9            （上と同じ）         1,0,97,0,1,103,1,0,0,0
                                                               0,2,0,23,8,8,2,0,1,1


====================================================================
8. ロボットを1台増やしたときの向き（種10個。今回 20261102）
====================================================================

  向きの決め方は judge_night.py と同じ（5% と 0.2 分より小さい変化は「変わらない」）。
  書き方：試算と同じ向きだった種の数／逆の向きだった種の数／変わらなかった種の数

  ③ 0→1台  入店待ち（試算は短くなる）  同じ 4／逆 2／変わらない 4 … 過半数（6）に届かないが、同じ向きが多い
            料理の待ち（試算は長くなる）同じ 10／逆 0          … 過半数が試算と同じ
  ③ 1→2台  入店待ち（試算は短くなる）  同じ 5／逆 1／変わらない 4 … 過半数（6）に届かないが、同じ向きが多い
            料理の待ち（試算は短くなる）同じ 7／逆 0／変わらない 3 … 過半数が試算と同じ
  ⑦ 0→1台  入店待ち（試算は短くなる）  同じ 6／逆 2／変わらない 2 … 過半数が試算と同じ
            料理の待ち（試算は長くなる）同じ 10／逆 0          … 過半数が試算と同じ
  ⑦ 1→2台  入店待ち：試算は 1.81→1.97 分（差 0.16 分が線の 0.2 分より小さい）ので「変わらない」扱い。
            judge と同じく向きは比べない。Unity は 短くなる 5・長くなる 4・変わらない 1
            料理の待ち（試算は短くなる）同じ 8／逆 0／変わらない 2 … 過半数が試算と同じ
  → 種の過半数で試算と逆になったところはない（judge.md の「向きが逆」も なし）。

  参考：同じ数え方で、前の2つの夜
    v4      ③1→2台 入店待ち 同じ 1／逆 6／変わらない 3（過半数が逆）。
            ③1→2台 料理の待ち 同じ 8／逆 2。ほかは今回と同じ形
    20261101 ③1→2台 料理の待ち 同じ 5／逆 5、⑦1→2台 料理の待ち 同じ 3／逆 5（逆が多い）


====================================================================
9. 全員が帰らなかった回・失敗した回
====================================================================

  なし


====================================================================
10. 決めてほしいこと
====================================================================

  1. 案B を「入」と指定したときの中身。いまは、params の pass_one_robot・same_table_one_robot が false でも、
     指定で入れた回は両方を入れる形にした。0.3 のころの 20261101 と同じ動きになる。
     params の値をそのまま使う形だと、0.4 では入と指定しても何も効かないため、この形にした。この形でよいか。
  2. 夜 20261102 を基準データ v5 にするか（依頼文のとおりエイイチが決める）。
     v5 にする場合は、judge_night.py の BASELINE_DEFAULT（今は 20261029_night_cs26_*）を変えるかも決めてほしい。
     今のままだと、これからの夜（待機場所 入）は毎回「基準なし」になる。
  3. プロジェクトの作業フォルダに、2026-10-27 からある古い queue.json（md5 07f2acccf5b13abbf1a96148fbc70e9f。
     待機場所・案B の項目が無い）が残っている。今回は触っていない。消すかどうか。
```

### 待機場所へ戻ると、受け渡し口の近くの止まりが半分になった

- ねらい：往復を終えたロボットが受け渡し口の前に居座り、次のロボットを止めないようにする
- 変わったこと：2台の回で、受け渡し口の点から2.5m以内の30秒以上の止まり（種10個の合計）が、③156→86回・⑦133→76回。待機場所で待っている分を除くと③46回・⑦45回
- 見込める効果：③⑦では受け渡し口の前の詰まりが主な止まりではなくなった。代わりに③はロボットが運んだ皿の割合が0.92→0.83に下がり、待機場所へ戻る時間の分だけ往復が減った（130→119.5回）

判定の作り（judge_night.py）は、切り替え（すれ違い・待機場所へ戻る・案B）の入切ごとに、同じ入切の回とだけ比べる形に直してもらいました。入切の違う夜を比べて「ずれた」と判定しないためです。

### 基準データ v1〜v5候補は、何を変えるたびに、どう動いたか

v5 にする前に、v1 からの流れを並べて確かめました。台帳（1回1行の記録）から、版ごと・店ごと・台数ごとの中央値を出しました。

| 版 | 回した回数 | 前の版から変えたこと |
|---|---|---|
| v1 | 18回（種3つ） | ロボットがサイトの地図の上で自分で道を引くようにした（cs:143・試算 v2.7） |
| v2 | 18回（種3つ） | 逃がし弁「卓を空けた」を直した。試算 v2.8（レジ）を読むようにした |
| v3 | 60回（種10個） | 新しいプロジェクトに分け、画面なしで夜に回すようにした（すれ違い切） |
| v4 | 60回 | すれ違いを入にした |
| v5候補 | 60回 | 待機場所へ戻るを入にした（案B は切） |

| ロボット2台 | ③ 料理の待ち（分） | ③ 運んだ割合 | ③ 動けなくなった（60秒） | ⑦ 料理の待ち（分） | ⑦ 運んだ割合 | ⑦ 動けなくなった（60秒） |
|---|---|---|---|---|---|---|
| v1 | 1.53（試算1.01） | 0.90（0.99） | 24 | 1.53（1.01） | 0.94（0.99） | 25 |
| v2 | 1.43（0.95） | 0.89（0.99） | 19 | 1.45（0.98） | 0.92（0.99） | 21 |
| v3 | 1.49 | 0.93 | 20.5 | 1.38 | 0.94 | 21.5 |
| v4 | 1.62 | 0.92 | 25 | 1.52 | 0.92 | 17 |
| v5候補 | 1.95 | 0.83 | 18 | 1.61 | 0.92 | 16.5 |

v1→v2 が一番大きな変わり目でした。v1 は逃がし弁が片付けを飛ばしていて、ロボット0台の入店待ちが試算の半分以下（③1.7分・試算4.0分）でした。v2 からは Unity の入店待ちが試算より長くなり、その向きは v5候補まで変わっていません。v2→v3 で種を3つから10個にすると、v2 の⑦1台の入店待ち8.2分は5.0分になりました。種が少ないための外れ値でした。v3 から先は、料理の待ちと運んだ割合はほぼ横ばいで、すれ違いと待機場所の切り替えで変わったのは止まり方でした。料理の待ちが試算の1.5〜2倍、運んだ割合が少し低い、という大きさのずれは、どの版でも残っています。

この流れを見て、エイイチは夜 20261102 を基準データ v5 にすると決めました。

#### 比べたスクリプト compare_baselines.py

```python
"""基準データ v1〜v5候補を、店×台数ごとに中央値で並べる（2026-10-28。台帳 unity_ledger_v1.csv から）
使い方: cd /Volumes/KIOXIA/r2r2r-data/service_sim/unity && python3 compare_baselines.py"""
import csv, statistics as st
r = list(csv.DictReader(open('unity_ledger_v1.csv')))
B = {'v1': lambda f, x: x['unity_cs'] == 'cs:143', 'v2': lambda f, x: x['unity_cs'] == 'cs:144',
     'v3': lambda f, x: f.startswith('20261027_night_cs21') and 'passon' not in f,
     'v4': lambda f, x: f.startswith('20261029_night_cs26'), 'v5候補': lambda f, x: f.startswith('20261102_night_cs34')}
def m(v):
    v = [float(a) for a in v if a not in ('', None)]
    return f"{st.median(v):.2f}" if v else "-"
for st_ in ['fam_p1', 'fam_p5']:
    for rb in ['0', '1', '2']:
        print(f"## {st_} {rb}台")
        for k, fn in B.items():
            xs = [x for x in r if fn(x['run_folder'], x) and x['store'] == st_ and x['robots'] == rb]
            if not xs:
                continue
            g = lambda c: m([x[c] for x in xs])
            print(f" {k:5} n={len(xs):2} 入店{g('entry_wait_mean')}(試{g('site_entry_wait_mean')}) 料理{g('dish_wait_mean')}(試{g('site_dish_wait_mean')}) 割合{g('robot_share')}(試{g('site_robot_share')}) 往復{g('trips')} 止まり{g('stuck_count')} 打切{g('timeouts')} 卓空{g('table_freed')} 試算版{xs[0]['params_model']} 形{xs[0]['layout_generation'][:6]}")
```

#### compare_baselines.py の出力

```text
## fam_p1 0台
 v1    n= 3 入店1.74(試3.99) 料理0.94(試0.65) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空24.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店3.90(試3.30) 料理0.94(試0.46) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v3    n=10 入店4.08(試3.30) 料理0.94(試0.46) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v4    n=10 入店4.21(試3.30) 料理0.94(試0.46) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v5候補  n=10 入店4.09(試3.30) 料理0.98(試0.46) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形39257d
## fam_p1 1台
 v1    n= 3 入店1.67(試1.82) 料理2.51(試2.03) 割合0.69(試0.73) 往復65.00 止まり4.00 打切0.00 卓空8.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店3.30(試2.60) 料理2.39(試1.95) 割合0.72(試0.72) 往復66.00 止まり4.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v3    n=10 入店4.56(試2.60) 料理2.43(試1.95) 割合0.67(試0.72) 往復67.00 止まり8.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v4    n=10 入店3.01(試2.60) 料理2.40(試1.95) 割合0.71(試0.72) 往復69.50 止まり4.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v5候補  n=10 入店5.00(試2.60) 料理2.48(試1.95) 割合0.71(試0.72) 往復65.50 止まり3.50 打切0.00 卓空0.00 試算版v2.8 形39257d
## fam_p1 2台
 v1    n= 3 入店2.01(試1.08) 料理1.53(試1.01) 割合0.90(試0.99) 往復124.00 止まり24.00 打切2.00 卓空16.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店2.03(試1.18) 料理1.43(試0.95) 割合0.89(試0.99) 往復122.00 止まり19.00 打切2.00 卓空1.00 試算版v2.8 形8a5b2f
 v3    n=10 入店3.04(試1.18) 料理1.49(試0.95) 割合0.93(試0.99) 往復136.50 止まり20.50 打切2.00 卓空1.00 試算版v2.8 形8a5b2f
 v4    n=10 入店4.17(試1.18) 料理1.62(試0.95) 割合0.92(試0.99) 往復130.00 止まり25.00 打切3.00 卓空0.50 試算版v2.8 形8a5b2f
 v5候補  n=10 入店3.99(試1.18) 料理1.95(試0.95) 割合0.83(試0.99) 往復119.50 止まり18.00 打切4.50 卓空0.00 試算版v2.8 形39257d
## fam_p5 0台
 v1    n= 3 入店1.87(試4.78) 料理1.07(試0.65) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空25.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店6.16(試2.76) 料理1.08(試0.45) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v3    n=10 入店4.22(試2.76) 料理0.98(試0.45) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v4    n=10 入店4.48(試2.76) 料理0.98(試0.45) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v5候補  n=10 入店4.49(試2.76) 料理0.96(試0.45) 割合0.00(試0.00) 往復0.00 止まり0.00 打切0.00 卓空0.00 試算版v2.8 形39257d
## fam_p5 1台
 v1    n= 3 入店1.75(試2.14) 料理2.68(試2.16) 割合0.63(試0.71) 往復61.00 止まり7.00 打切0.00 卓空19.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店8.22(試1.81) 料理2.27(試1.97) 割合0.72(試0.72) 往復77.00 止まり8.00 打切0.00 卓空3.00 試算版v2.8 形8a5b2f
 v3    n=10 入店4.98(試1.81) 料理2.45(試1.97) 割合0.69(試0.72) 往復70.00 止まり6.50 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v4    n=10 入店3.84(試1.81) 料理2.44(試1.97) 割合0.67(試0.72) 往復69.00 止まり6.00 打切0.00 卓空0.00 試算版v2.8 形8a5b2f
 v5候補  n=10 入店3.22(試1.81) 料理2.51(試1.97) 割合0.67(試0.72) 往復67.50 止まり5.50 打切0.00 卓空0.00 試算版v2.8 形39257d
## fam_p5 2台
 v1    n= 3 入店2.04(試1.14) 料理1.53(試1.01) 割合0.94(試0.99) 往復129.00 止まり25.00 打切2.00 卓空20.00 試算版v2.7 形8a5b2f
 v2    n= 3 入店4.06(試1.97) 料理1.45(試0.98) 割合0.92(試0.99) 往復140.00 止まり21.00 打切1.00 卓空2.00 試算版v2.8 形8a5b2f
 v3    n=10 入店2.89(試1.97) 料理1.38(試0.98) 割合0.94(試0.99) 往復135.50 止まり21.50 打切1.50 卓空0.50 試算版v2.8 形8a5b2f
 v4    n=10 入店4.81(試1.97) 料理1.52(試0.98) 割合0.92(試0.99) 往復136.00 止まり17.00 打切3.00 卓空0.00 試算版v2.8 形8a5b2f
 v5候補  n=10 入店3.56(試1.97) 料理1.61(試0.98) 割合0.92(試0.99) 往復124.00 止まり16.50 打切3.50 卓空0.00 試算版v2.8 形39257d
```

### 依頼文：基準データ v5 に切り替える（20261028_16）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 60
---
# 依頼：夜 20261102 を基準データ v5 にし、判定の基準の既定を v5 に変える（2026-10-28）

エイイチの決定（2026-10-28 09:29）：前の報告（20261102_night_37_v5candidate.txt）の「決めてほしいこと」への答え
1. 案B を「入」と指定した回は、受け渡し口は1台ずつ・同じ卓は1台の**両方を入れる**形のままでよい（20261101 と同じ動き）。作りは変えない
2. 夜 20261102（③⑦・すれ違い入・待機場所へ戻る 入・案B 切・60回・cs:34）を**基準データ v5** にする。judge_night.py の基準の既定を v4（20261029_night_cs26_*）から v5（20261102_night_cs34_*）に変える
3. 作業フォルダに 2026-10-27 からある古い `queue.json` を消す

回は回さない（判定の確かめだけ）。

## 始める前に確かめること（違えば何もせずに報告して終わる）

1. Unity エディタが起動していない・夜の回が動いていない
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 台帳が 565 行

## やること

1. judge_night.py の基準の既定を v5（20261102_night_cs34_*）にする。`--baseline` などで v4 を指定すれば今までどおり v4 と比べられる形は残す。判定の決まり（何を超えたら何に振り分けるか）・切り替えの入切ごとに分ける作りは変えない
2. 確かめ（出力は /tmp。night/ の記録は上書きしない）
   - 夜 20261102 を既定で判定すると「正常」60回になること
   - 夜 20261029 を既定で判定すると、待機場所へ戻るの入切が違うので60回とも「基準なし」になること
   - `--baseline` で v4 を指定して夜 20261029 を判定すると、今までどおり「正常」60回になること
3. KIOXIA の `service_sim/unity/night/20261102/` に `BASELINE_v5.md` を新しく置く（既存のファイルは触らない）。書くこと：基準データ v5 であること・決めた日（2026-10-28）・cs:34 と build_id・試算 v2.8・店の形の版 39257d16b68a（③⑦の形は 8a5b2f6a016a と同じ。④の直しで番号だけ変わった）・切り替えの入切（すれ違い入・待機場所へ戻る 入・案B 切）・回の数（③⑦ × 0/1/2台 × 種0〜9）・前の基準（v1 stageB_cs143／v2 stageB_cs144／v3 夜20261027 のすれ違い切／v4 夜20261029）を1行ずつ
4. 作業フォルダ直下の古い `queue.json`（2026-10-27 から残っているもの）を消す。night/ の中の queue.json は消さない。消す前に中身の先頭数行と日付を報告に書く
5. 変えたスクリプトを check-in する（保留 0）。画面なしの実行ファイルの作り直しは不要（Unity 側を変えないため）

## 変えないもの

- Unity の作り・params・店の形・台帳の列と行・今までの night/ の記録

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261028_baseline_v5.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。

- 始める前の確かめの結果
- 変えたファイル・cs 番号
- 2 の確かめ3つの結果
- 消した queue.json の中身の先頭と日付
- 決めてほしいこと（なければ「なし」）
```

### 報告：20261028_baseline_v5.txt

```text
20261028_baseline_v5 報告（依頼：20261028_16_基準データv5に切り替え.md）

■ やったこと
1. 始める前の確かめ
   - Unity エディタは起動していない（Unity Hub のみ動いている）。夜の回も動いていない
   - /Volumes/KIOXIA はマウントされている。unity_ledger_v1.lock はない
   - 台帳 unity_ledger_v1.csv は 565 行
   → 3つとも合っていたので作業を進めた
2. judge_night.py の基準の既定を v4（20261029_night_cs26_*）から v5（20261102_night_cs34_*）に変えた
   - --baseline '20261029_night_cs26_*' で今までどおり v4 と比べられる（v4 の glob を BASELINE_V4 として残し、--help にも出す）
   - 判定の決まり（何を超えたら何に振り分けるか）と、切り替えの入切ごとに分ける作りは変えていない
3. 確かめ（出力は /tmp。night/ の記録は上書きしていない。night/20261102・night/20261029 の judge.* の日時は元のまま）
   - 夜 20261102 を既定で判定：正常 60回（/tmp/bl5_a）
   - 夜 20261029 を既定で判定：基準なし 60回（待機場所へ戻るが 切 で、v5 は 入 のため）（/tmp/bl5_b）
   - 夜 20261029 を --baseline '20261029_night_cs26_*'（v4）で判定：正常 60回（/tmp/bl5_c）
4. KIOXIA の service_sim/unity/night/20261102/BASELINE_v5.md を新しく置いた（既存のファイルは触っていない）
   書いたこと：基準データ v5・決めた日 2026-10-28・cs:34・build_id cs34_20261028_0642・試算 v2.8・
   店の形の版 39257d16b68a（③⑦の形は 8a5b2f6a016a と同じ）・入切（すれ違い入・待機場所へ戻る入・案B切）・
   回の数（③⑦ × 0/1/2台 × 種0〜9 の60回）・前の基準 v1〜v4 を1行ずつ
5. 作業フォルダ直下の古い queue.json を消した（night/ の中の queue.json は消していない）
   - 日付：2026-10-27 10:19:06・14570 バイト。Plastic では Private（ignore.conf で無視される対象。版の管理には入っていない）
   - 中身は night/20261029/queue.json と同じ（cmp で一致）
   - 先頭：
     "schema": "servicesim-night-queue/0.1"
     "label": "night"
     "params_model": "v2.8"
     "layout_generation": "8a5b2f6a016a"
     "params_source": "Assets/ServiceSim/Experiment/serving-robot-params.json"
     "seeds": [0〜9]
     "conditions": fam_p1_s4_r0/r1/r2_a42・fam_p5_s4_r0/r1/r2_a42
     "pass_by": "on"・"count": 60
6. check-in：tools/judge_night.py → cs:35（保留 0）。画面なしの実行ファイルは作り直していない（Unity 側を変えていないため）
   回は回していない

■ 変えたファイル
- ServiceSim/tools/judge_night.py（cs:35）
- KIOXIA service_sim/unity/night/20261102/BASELINE_v5.md（新規）
- ServiceSim/queue.json（削除。版の管理の外）

■ 決めてほしいこと
なし
```


## 作業ログ ― ⑤の条件をサイトの試算から書き出した

⑤は46卓・200席の店です。3Dの店で回す条件は、③⑦④と同じ決め方にしました。スタッフは試算の真ん中の人数（4人）、来客は普通のペース（1時間46組）、ロボット0・1・2台、料理を運ぶだけ（下げ膳はしない）、1往復で3卓、レジは1つです。

試算では、⑤はレジが1つだと会計待ちが11〜18分になり、「レジが詰まる」の印が付きます。3Dの店でもレジが詰まるかを見るため、レジは③⑦④と同じ1つのままにしました。

### Unity が読む条件を書き出すスクリプト export_params.py（⑤を足した版）

```python
"""試算（haizen_sim.py）の条件と店の回し方の値を、Unity が読む JSON に書き出す（2026-10-22。v2.8 で2026-10-25 にレジの数を足した）。

「何について正か」（unity_design_v0.md の 0 章）で、条件と店の回し方の決まり・時間・数字の定義はサイトが正。
Unity はこの JSON を読み、値を手で写さない（LOG359 のずれ9「値の手写し」をなくすため）。

使い方: python3 export_params.py results.json <出力先>   （出力先は p2m-site の public/sim/serving-robot-params.json）
- common：店に共通の値。role が "unity_measures" の値は Unity で測ってサイトに戻すための仮の値なので、Unity は読まない
- stores：Unity で回す店（fam_p1・fam_p5・fam_p2・fam_p3）の値。registers はレジの数（v2.8）
- unity_conditions：Unity で回す条件（店ごとに3つ。③⑦④⑤で12条件）と、同じ条件の試算の結果（40回の平均）。Unity の店はレジの内側に店員が1人だけなので、レジは1つ
"""
import json
import sys

import haizen_sim as h

res_path, out = sys.argv[1], sys.argv[2]
R = json.load(open(res_path, encoding="utf-8"))
gen = {g["generation"] for g in json.load(open(h.LAYOUT_DIR + "/summary.json", encoding="utf-8"))}
assert len(gen) == 1, gen

ROLE = {
    "robot_speed": "unity_measures", "pause_rate": "unity_measures", "pause_s": "unity_measures", "stuck_rate": "unity_measures",
    "hop_m": "site_only",          # 試算の近似（1往復で複数卓を回るときの寄り道）。Unity は実際の道を走るので使わない
    "sustain": "site_only", "warmup_min": "site_only", "util_sample_s": "site_only", "model": "site_only",
}
NOTE = {
    "unity_measures": "Unity で測ってサイトに戻すための仮の値。Unity は読まない",
    "site_only": "試算の中だけの設定。Unity は使わない",
    "site_rule": "サイトが正。Unity はこの値を使う",
}
common = {k: {"value": v, "role": ROLE.get(k, "site_rule")} for k, v in h.COMMON.items()}

UNITY_STORES = ["fam_p1", "fam_p5", "fam_p2", "fam_p3"]   # ④は2026-10-27に追加（スタッフ2人・28組/時）。⑤は2026-10-28に追加（スタッフ4人・46組/時）
UNITY_REGISTERS = 1
stores = {}
for k in UNITY_STORES:
    s = dict(h.STORES[k])
    stores[k] = s

conds = []
rows = {h.key(r): r for r in R["rows"]}
for k in UNITY_STORES:
    s = h.STORES[k]
    staff = s["staff"][1]           # 真ん中の人数
    arr = s["arrivals"][1]          # 普通
    for robots in (0, 1, 2):
        c = {"store": k, "staff": staff, "robots": robots, "arrivals_per_h": arr, "mode": "serve",
             "trays": 3 if robots else 1, "fragile_by": "any",   # ロボット0台の試算は trays=1 で持っている（使い方・段の数は関係ない）
             "registers": UNITY_REGISTERS}
        r = rows[h.key(c)]
        conds.append({"condition": c, "site_result": {m: r[m] for m in r if m not in c}})

D = {
    "meta": {
        "schema_version": "serving-robot-params/0.4",
        "model": h.COMMON["model"], "reps": h.REPS, "ng_min": h.NG_MIN, "layout_generation": gen.pop(),
        "source": "p2m-site の public/sim/serving-robot.html と同じ試算（haizen_sim.py）と結果（results.json）",
        "roles": NOTE,
        "time_window": "空の店から始め、peak_min 分だけ選んだペースで来客し、全員が帰るまで回す（max_extra_min で打ち切り）",
        "registers": "会計はレジ1つにつき1組ずつ（pay_s 秒）。食べ終えた組は卓に座ったまま順番を待つ。Unity の条件はすべてレジ1つ（v2.8）",
        "metrics": {
            "entry_wait_mean": "入店待ち：店に来てから案内されて卓に着くまで（分）",
            "full_wait_mean": "そのうち満席で待った時間（分）",
            "staff_wait_mean": "そのうち席は空いているのに片付け・案内が追いつかず待った時間（分）。ng_min 以上なら「店が回らない」",
            "dish_wait_mean": "料理ができてから卓に届くまで（分）", "dish_wait_p90": "同じく上位10%の境目（分）",
            "cold_share": "cold_min 分を超えて届いた皿の割合", "turn_mean": "客が帰ってから卓が使えるまで（分）",
            "walk_km_per_staff": "スタッフ1人が歩いた距離（km）", "staff_util": "スタッフの手がふさがっている割合",
            "robot_util": "ロボットがふさがっている割合", "robot_share": "ロボットが運んだ皿の割合",
            "rescues": "立ち往生でスタッフが動かしに行った回数", "pauses": "一時停止の回数", "groups": "入れた組の数",
            "pay_wait_mean": "食べ終えてから会計が始まるまで（分）。レジの順番とスタッフの手が空くのを待つ（v2.8）",
        },
    },
    "common": common,
    # 2026-10-27 エイイチと決めた回し方の決まり（案B）。試算の数字には効かない（試算の料理は卓の区別がなく、受け渡し口で積む時間も0秒で順番待ちがないため）。
    # 受け渡し口でのロボットどうしのぶつかりは通路で起きることなので Unity が測る。Unity はこの値を使う（切り替えで入れ、まず④で確かめる）
    "unity_rules": {
        # 2026-10-28 エイイチと決めた：待機場所へ戻るを標準に。案B（受け渡し口は1台ずつ・同じ卓は1台）は切に戻す
        # （④・③⑦の夜で、待機場所が受け渡し口から1.5m以内にあるため2台が互いを待ち、往復が減ったため。待機場所との距離の決め方を考え直すまで使わない）
        "standby_return": {"value": True, "role": "site_rule",
                           "note": "往復を終えたロボットは、受け渡し口の点で止まらず、店の形の RobotStandby（1台に1つ）へ下がって待つ"},
        "pass_one_robot": {"value": False, "role": "site_rule",
                           "note": "（切）受け渡し口の前に入れるロボットは1台だけ。前の1台が出発点から pass_clear_m 離れるまで、次の1台は待機場所で待つ"},
        "pass_clear_m": {"value": 1.5, "role": "site_rule", "note": "仮の値（pass_one_robot が切のあいだは使わない）"},
        "same_table_one_robot": {"value": False, "role": "site_rule",
                                 "note": "（切）その卓へ向かっているロボットがいる間は、その卓の料理を別のロボットに積まない"},
    },
    "stores": stores,
    "unity_conditions": conds,
}
json.dump(D, open(out, "w", encoding="utf-8"), ensure_ascii=False, indent=1)
print(out, len(conds), "conditions / generation", D["meta"]["layout_generation"])
for c in conds:
    print(" ", c["condition"], {m: c["site_result"].get(m) for m in ("entry_wait_mean", "staff_wait_mean", "dish_wait_mean", "pay_wait_mean")})
```

### 依頼文：⑤を建てて確かめる（20261028_17）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 180
---
# 依頼：⑤ ゆったり・入口が正面の店（fam_p3）を Unity に建て、1回ずつ回して確かめる（2026-10-28）

エイイチの決定（2026-10-28 13:04）：③⑦の標準を基準データ v5 で固めたので、別の店へ広げる。④のときと同じく、今回は⑤だけ。

サイト（正）はもう直した（p2m-site commit e12866e）。
- `public/sim/serving-robot-params.json`：Unity で回す店に fam_p3 を足した。unity_conditions は9件 → 12件。③⑦④の9件・common・unity_rules・meta は前と同じ。試算は v2.8 のまま計算し直していない
- ⑤の3条件：スタッフ4人・46組/時・ロボット0・1・2台・上げ膳・1往復3卓（0台は trays 1）・レジ1つ
- 店の形：`public/sim/layouts/unity/p3_relaxed_center.json` と `p3_relaxed_center_map.json`（generation 39257d16b68a。③⑦④と同じ版。前から公開済み）。46卓・200席
- 試算でも、⑤はレジ1つだと会計待ちが11〜18分で「レジが詰まる」。Unity でもレジが詰まるのは試算どおりなので、それだけで手を止めなくてよい
- 台帳の退避は Claude が済ませた：`/Volumes/KIOXIA/r2r2r-data/service_sim/unity/archive/unity_ledger_v1_pre_p3check_20261028/unity_ledger_v1.csv`（565行・md5 7f636cb533be1ee07caabb8782455f15）

## 始める前に確かめること（違えば手を止めて報告）

1. Unity エディタが起動していない（起動していたら閉じずに報告して終わる）
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 台帳の md5 が上の退避と同じ
4. ServiceSim の保留が 0（cs:35 head）
5. https://pixelstomotors.com/sim/serving-robot-params.json の unity_conditions が12件（まだ9件なら数分おきに取り直す。30分たっても9件なら報告して終わる）

## やること

1. サイトの params と⑤の店の形2つを、③⑦④と同じやり方でプロジェクトに写す（手で値を写さない）。generation が 39257d16b68a でそろっているか確かめる
2. ⑤を③⑦④と同じコード・同じ規則で建てる（地図の上で自分で道を引く動き方・すれ違い入・待機場所へ戻る 入・案B 切・店員優先のよけ方・逃がし弁・モニター、すべて今の標準のまま）。⑤のためだけの手直しはしない
   - スタッフ4人・46卓・レジ1つの組み合わせで足りないもの（待機場所の数、スタッフが待つ点、並ぶ点など）があれば、③⑦④の規則のまま置けるかを確かめる
   - ⑤の店の形のせいで建てられない・回らないところ（届かない卓、待機場所・レジ・スタッフが待つ点・並ぶ点が置けない、NavMesh の切れ目など）があっても、Unity 側で形を直さない。場所と理由を「決めてほしいこと」に書く（直すならサイトが先）
3. make_queue.py で `--stores fam_p3` が使えることを確かめる。**指定しないときは今までどおり ③⑦の60回**（params の条件が12件に増えても60回のまま）。judge_night.py は変えない（⑤は基準データがないので「基準なし」になってよい）
4. check-in して、画面なしの実行ファイルを作り直す（保留 0）
5. 確かめの3回を回す：⑤ × ロボット0・1・2台 × 種0、今の標準（すれ違い入・待機場所へ戻る 入・案B 切）。夜の回と混ざらないラベル `p3check` で。同時に回す本数は4のまま
   - 台帳には3行が足される（追記だけ）。終わったら行数（565 → 568 のはず）と、先頭565行の md5 が退避と同じかを確かめる
6. make_queue の dry-run で、何も指定しないとき③⑦の60回のままであることを確かめる（台帳に書かない）
7. 作業フォルダに queue の一時ファイルを残さない

## 変えないもの

- 店の回し方・人とロボットの動き・速さ・Stiffness などの物理の設定・同時に回す本数（N=4）
- 台帳の列（59列）と今までの行。今までの night/ と出力の記録
- 本番の夜は回さない（⑤の夜は、確かめの結果をエイイチが見てから決める）

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261028_HHMM_p3_build_check.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。

- 始める前の確かめ5つの結果
- 入れた cs 番号・build_id と保留の有無・変えたファイル
- ⑤を建てて分かったこと（卓の数46・止まる位置・待機場所・レジ・スタッフが待つ点・並ぶ点が置けたか、置けなかった所）
- 3回それぞれ：最後まで回ったか・全員帰ったか・実時間・入れた組の数・入店待ち・そのうち席は空いているのに待った時間・料理の待ち・会計待ち・ロボットが運んだ皿の割合・往復の数・30秒以上の止まり（1往復あたり）・動けなくなった（60秒）・卓を空けた・瞬間移動・打ち切り。試算の同じ条件の値（params の site_result）と並べる。差の理由の調べはしなくてよい
- 2台の回の30秒以上の止まりのうち、受け渡し口の点から 2.5 m 以内の数（待機場所での止まりを除いた数も）
- 台帳の行数と先頭565行の md5
- dry-run で③⑦が60回のままか
- **エイイチが画面で⑤を見る手順**（Unity を開いてから、どのシーン・メニューで⑤の、どの条件を流せるか。短く）
- 決めてほしいこと（なければ「なし」）
```

### 報告：20261028_1338_p3_build_check.txt

```text
====================================================================
⑤ ゆったり・入口が正面の店（fam_p3）を建てて確かめる … 始める前の確かめ 5 で止めた
依頼：20261028_17_店5を建てて確かめる.md
2026-10-28 13:38
====================================================================

結論

  ・公開されている serving-robot-params.json の unity_conditions が、30分たっても9件のままだった。
    依頼のとおり、ここで手を止めた。
  ・プロジェクト・台帳・KIOXIA のどれも変えていない。check-in も実行ファイルの作り直しも、回すこともしていない。


====================================================================
1. 始める前の確かめ
====================================================================

  1. Unity エディタ：起動していない（Unity Hub だけが起動していた）… 合格
  2. /Volumes/KIOXIA：マウントされている。unity_ledger_v1.lock：なし … 合格
  3. 台帳 unity_ledger_v1.csv：565 行・md5 7f636cb533be1ee07caabb8782455f15
     （退避 archive/unity_ledger_v1_pre_p3check_20261028/ と同じ）… 合格
  4. ServiceSim の保留：0（cs:35 head）… 合格
  5. https://pixelstomotors.com/sim/serving-robot-params.json の unity_conditions … 不合格
     13:08 から 13:38 まで2分おきに16回取り直し、すべて9件だった（キャッシュよけの ?t= 付き）。
     最後の 13:38 に取ったもの：
       unity_conditions 9件・meta.schema_version serving-robot-params/0.4・試算 v2.8・
       stores に fam_p3 がない
       etag "ca2bd8e9f2c8152ea675e463cd1055ab"・cf-cache-status HIT
       md5 3d7a6002cc91b3dc5abe9a91462f53de（プロジェクトの今の写し
       Assets/ServiceSim/Experiment/serving-robot-params.json と同じ）
     → p2m-site commit e12866e の中身は、まだ公開に出ていないように見える。
       Cloudflare のキャッシュが残っているのか、公開の手順が済んでいないのかは、ここからは分からない。


====================================================================
2. 先に見ておいたこと（何も変えていない。読んだだけ）
====================================================================

  公開を待つあいだに、同じ版（39257d16b68a）で前に取った控え
  unity/site_copy_39257d16b68a/unity/p3_relaxed_center.json と、今のコードを読んだ。
  公開版を取り直したら、もう一度確かめる。

  ・⑤の形の場所の点：受け渡し口・返却口・パントリー・入口・待合・トイレ・レジ1・
    会計の列3・レジ内1・ドリンクバー（立つ点4・列3）・ロボットの待機場所3・スタッフが待つ点2
  ・スタッフが待つ点が2つしかない（スタッフは4人）。③は6つ、④は4つ（スタッフ2人）。
    今のコード（StaffAgent.StandbyPoint）は「何人目 ÷ 点の数 の余り」で割り当てるので、
    ⑤は2人ずつ同じ点に割り当てられる。建てられないわけではないが、
    同じ点に2人が向かうことになる（決めてほしいこと 2）。
  ・ロボットの待機場所は3つで、2台には足りる。レジ1つ・会計の列3つは③⑦④と同じ数。
  ・make_queue.py の --stores は params に載っている店なら名前で選べる作りなので、
    params に fam_p3 が入れば、コードを変えずに --stores fam_p3 が使えるはず。
    何も指定しないときは DEFAULT_STORES（fam_p1・fam_p5）だけを並べる。


====================================================================
3. 入れた cs・build_id・変えたファイル
====================================================================

  なし（cs:35 のまま・保留 0。実行ファイルは cs34_20261028_0642 のまま）。
  台帳：565 行・md5 7f636cb533be1ee07caabb8782455f15 のまま。鍵ファイルなし。
  作業フォルダに queue の一時ファイルは置いていない。

  4〜7 章（建てて分かったこと・3回の結果・2.5 m 以内の止まり・dry-run）はやっていない。


====================================================================
4. エイイチが画面で⑤を見る手順
====================================================================

  まだメニューがないので、今は見られない。
  ⑤を足したあとは、④と同じく次の形になる予定：
    ServiceSim → JSON Store → ⑤ p3_relaxed_center を建てて確かめる
    ServiceSim → Site Run → ⑤ スタッフ4人・ロボット0台 / 1台 / 2台


====================================================================
5. 決めてほしいこと
====================================================================

  1. サイトの公開を確かめてください（commit e12866e の params が pixelstomotors.com に出ていない）。
     出たのを確かめてから、この依頼をもう一度渡してください。
  2. ⑤はスタッフが待つ点が2つで、スタッフ4人のうち2人ずつが同じ点に割り当てられる
     （今の規則のまま）。このまま進めてよいか、サイトで点を足すかを決めてください。
     決めないままもう一度渡された場合は、今の規則のまま建てて、報告に書きます。
```

### サイトの公開が一度失敗し、3Dの店は待ちぼうけになった

Claude Code（Mac で Unity を動かす係）は、サイトに⑤の条件が出るのを2分おきに30分待ち、出なかったので手を止めました。GitHub に送った変更は、Cloudflare（サイトを配る所）のビルドが一度失敗していて、公開されていませんでした。手元で同じビルドを回すと通ったので、一時的な失敗だったと考えています。次に送った変更（⑤の店の形の直し）のビルドは通り、そこで⑤の条件も公開されました。


## 作業ログ ― 図面を見て、島の上の0.25mの隙間に気づいた

3Dの店で1回目の確かめを待っている間に、エイイチが⑤の図面を見て、入口のまわりを指しました。

> 図面見たけど、ここが狭くてすぐ詰まるね。

> こっちに抜けられるようにしないと全体回らないよきっと

2つ目に指したのは、真ん中の島の上の端とパントリーの間でした。店の形のデータで測ると、島の上の端（仕切りの上端）が y=9.15m、パントリーの下の端が y=9.4m で、間は0.25mでした。島の右の端（x=9.3m）は、パントリーの左の端（x=9.0m）より右まで出ていて、角からも抜けられません。

ロボットの道（受け渡し口の前から各卓へ、ふだん走らせる1.0m以上の道）を描くと、左側の卓へ行く道は全部、受け渡し口から斜め下へ下り、レジの横と入口の前を通って、島の下から回り込んでいました。

【画像】LOG397_01_store5_routes_before.png 直す前の⑤の図面とロボットの道。受け渡し口から左側の卓へ行く道が、真ん中の島の下を回り、レジと入口の前を通っている

### 外した2卓をどこへ置くか、案を4つ描いた

島の上を空けるには、島の上の2卓を外せば足ります。外した2卓をどこへ置くかで、案を描いて比べました。

【画像】LOG397_02_store5_options_1_2.png 今の形と、案1（右上の壁ぞいへ2卓）、案2（左の島を上へ1列のばす）。赤い点線が外す卓、緑が足す卓、青い矢印が新しく抜けられる道

【画像】LOG397_03_store5_options_3_4.png 案3（真ん中の島を離れた4人テーブル3卓にする）と案4（真ん中の島をなくし、左上の奥に6人席を2つ置く）

エイイチは、右上の空きを見て言いました。

> 右上のスペースが勿体無いけどどうにかできない？

> 案1をベースにキッチンや洗い場などの全体を左にずらしたら？

案1は、右の壁ぞいの4人席の列を上へ2卓のばす案です。ただ、そのままだと一番上の卓が更衣室・社員トイレの真横になります。キッチン側をまとめて左へずらすと、更衣室が右上の卓から離れ、受け渡し口も混みやすい左側へ寄ります。ずらす幅は1.5mにしました。キッチンの左の端と左の島（右の端 x=5.25m）の間に2.25mの通路が残る幅です。2.75mまでずらすと、この通路が1.0mまで狭まります。

【画像】LOG397_04_store5_option1_shift.png 案1と、案1にキッチン側をまるごと左へ1.5mずらした版の比べ

【図解】LOG397_store5_shortcut.html

- ねらい：受け渡し口から左側の卓へ、入口とレジの前を通らずに行ける道を作る
- 変わったこと：島の上とパントリーの間が0.25m→約2.1m。卓までの距離は平均13.7m→12.5m、最長23.2m→18.8m。卓46・席200は同じ
- 見込める効果：受け渡し口から各卓への道のうち、入口・レジの前（y が3.4mより下で、x が9.3〜16.4m）を通るものが、46卓中24卓→10卓に減った（残る10卓は、入口の左右の6人席と、左下の席）。直す前の形では3Dの店を回していないので、止まりの前後の比べはない。直したあとの30回で、2台の回の入口・レジの前の30秒以上の止まりは3回だった

#### 入口・レジの前を通る道を数えたスクリプト count_routes.py

```python
"""⑤の受け渡し口から各卓への道（店の形の routes.from_pass）のうち、入口・レジの前を通るものを数える（2026-10-28）
入口・レジの前：y が 3.4 m より下で、x が 9.3〜16.4 m（真ん中の島の下の端より下、左下の6人席の右の端から右下の6人席の左の端まで）
使い方: python3 count_routes.py <直す前の unity/p3_relaxed_center.json> <直した後の unity/p3_relaxed_center.json>"""
import json, sys


def seg_in(p, q):
    for i in range(51):
        x = p[0] + (q[0] - p[0]) * i / 50
        y = p[1] + (q[1] - p[1]) * i / 50
        if y < 3.4 and 9.3 <= x <= 16.4:
            return True
    return False


for tag, path in (("直す前", sys.argv[1]), ("直した後", sys.argv[2])):
    m = json.load(open(path, encoding="utf-8"))
    fp = m["routes"]["from_pass"]
    hit = [k for k, v in fp.items() if any(seg_in(a, b) for a, b in zip(v["points"], v["points"][1:]))]
    print(tag, "卓", len(fp), "入口・レジの前を通る", len(hit), hit)
    print("  T14 への道", fp["T14"]["points"])
```

#### count_routes.py の出力

```text
直す前 卓 46 入口・レジの前を通る 24 ['T01', 'T02', 'T03', 'T04', 'T05', 'T06', 'T07', 'T08', 'T09', 'T10', 'T11', 'T12', 'T13', 'T14', 'T15', 'T16', 'T17', 'T18', 'T19', 'T39', 'T40', 'T41', 'T42', 'T43']
  T14 への道 [[14.0, 8.85], [9.638, 3.013], [9.463, 2.913], [8.188, 2.713], [6.688, 2.738], [6.288, 3.163], [6.263, 3.312], [6.038, 7.262]]
直した後 卓 46 入口・レジの前を通る 10 ['T01', 'T02', 'T03', 'T07', 'T08', 'T39', 'T40', 'T41', 'T42', 'T43']
  T14 への道 [[12.5, 8.85], [6.038, 8.788]]
```

#### 案1・案2を描いたスクリプト plan.py

```python
import json, matplotlib; matplotlib.use('Agg')
import matplotlib.pyplot as plt, matplotlib.patches as P
from matplotlib import font_manager as fm
fp=fm.FontProperties(fname='/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc')
L=json.load(open('/home/claude/p2m-site/public/sim/layouts/p3_relaxed_center.json'))['layout']
def draw(ax,title,remove=(),add=(),hl=None):
    ax.add_patch(P.Rectangle((0,0),26,17,fill=False,lw=2))
    for r in L['rooms']:
        x0,y0,x1,y1=r['rect']; ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='#e4e4e0',ec='#999'))
        ax.text((x0+x1)/2,(y0+y1)/2,r['label'],ha='center',va='center',fontproperties=fp,fontsize=6)
    for t in L['tables']:
        if t['id'] in remove:
            ax.add_patch(P.Rectangle((t['x'],t['y']),t['w'],t['h'],fill=False,ec='#c33',ls='--',lw=1.2)); continue
        ax.add_patch(P.Rectangle((t['x'],t['y']),t['w'],t['h'],fc='w',ec='k',lw=.8))
        ax.text(t['x']+t['w']/2,t['y']+t['h']/2,str(t['seats']),ha='center',va='center',fontsize=6)
    for (x,y,w,h) in add:
        ax.add_patch(P.Rectangle((x,y),w,h,fc='#cfe8cf',ec='#2a7a2a',lw=1.2)); ax.text(x+w/2,y+h/2,'4',ha='center',va='center',fontsize=6)
    if hl: ax.annotate('',xy=hl[1],xytext=hl[0],arrowprops=dict(arrowstyle='->',color='#2a5cc8',lw=2))
    ax.add_patch(P.Rectangle((12,-.3),3,.3,fc='w',ec='w')); ax.text(13.5,-.8,'入口',ha='center',fontproperties=fp,fontsize=8)
    ax.set_xlim(-.5,26.5); ax.set_ylim(-1.2,17.5); ax.set_aspect('equal'); ax.axis('off'); ax.set_title(title,fontproperties=fp,fontsize=10)
fig,axs=plt.subplots(1,3,figsize=(18,5.2))
draw(axs[0],'今：島の上がパントリーとの間 0.25m（左へ抜けられない）',hl=((14,8.6),(9.6,8.6)))
draw(axs[1],'案1：島の上の2卓を外し、右上の壁ぞいへ2卓',remove=('T19','T22'),add=[(24.8,12.5,1.2,1.85),(24.8,14.35,1.2,1.85)],hl=((14,8.6),(6,8.6)))
draw(axs[2],'案2：島の上の2卓を外し、左の島を上へ1列のばす',remove=('T19','T22'),add=[(2.7,10.8,1.2,1.85),(4.05,10.8,1.2,1.85)],hl=((14,8.6),(6,8.6)))
plt.tight_layout(); plt.savefig('p3_options.png',dpi=130)
```

#### 案3・案4を描いたスクリプト plan2.py

```python
exec(open('plan.py').read().split('fig,axs')[0])
mid=('T17','T18','T19','T20','T21','T22')
fig,axs=plt.subplots(1,2,figsize=(12,5.2))
draw(axs[0],'案3：真ん中の島を、離れた4人テーブル3卓に（45卓・196席）',remove=mid,
     add=[(7.4,3.6,1.2,1.2),(7.4,5.4,1.2,1.2),(7.4,7.2,1.2,1.2),(2.7,10.8,1.2,1.85),(4.05,10.8,1.2,1.85)],hl=((14,8.9),(6,8.9)))
draw(axs[1],'案4：真ん中の島をなくし、左上の奥に6人席を2つ（44卓・196席）',remove=mid,
     add=[(2.7,10.8,1.2,1.85),(4.05,10.8,1.2,1.85)],hl=((14,8.9),(6,8.9)))
for x in (5.3,7.15):
    axs[1].add_patch(P.Rectangle((x,15.2),1.85,1.8,fc='#cfe8cf',ec='#2a7a2a',lw=1.2)); axs[1].text(x+.925,16.1,'6',ha='center',va='center',fontsize=6)
plt.tight_layout(); plt.savefig('p3_options2.png',dpi=130)
```

#### キッチン側をずらした版を描いたスクリプト plan3.py

```python
exec(open('plan.py').read().split('fig,axs')[0])
import copy
S=1.5
for r in L['rooms']:
    if r['kind']=='back' and r['label']!='レジ内':
        r['rect']=[r['rect'][0]-S,r['rect'][1],r['rect'][2]-S,r['rect'][3]]
def extra(ax):
    for lab,(x0,y0,x1,y1) in [('受け渡し口',(12.5-S,9.4,15.5-S,9.8)),('ロボット待機',(15.7-S,8.55,18.1-S,9.35))]:
        ax.add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='#333' if lab=='受け渡し口' else 'none',ec='#333',ls='-' if lab=='受け渡し口' else '--'))
fig,axs=plt.subplots(1,2,figsize=(12,5.2))
L0=json.load(open('/home/claude/p2m-site/public/sim/layouts/p3_relaxed_center.json'))['layout']
import builtins
Lsh=L; 
L=L0; draw(axs[0],'案1（キッチンはそのまま）',remove=('T19','T22'),add=[(24.8,12.5,1.2,1.85),(24.8,14.35,1.2,1.85)],hl=((14,8.6),(6,8.6)))
for lab,(x0,y0,x1,y1) in [('',(12.5,9.4,15.5,9.8))]: axs[0].add_patch(P.Rectangle((x0,y0),x1-x0,y1-y0,fc='#333'))
L=Lsh; draw(axs[1],'案1＋キッチン側をまるごと左へ1.5m',remove=('T19','T22'),add=[(24.8,12.5,1.2,1.85),(24.8,14.35,1.2,1.85)],hl=((12.5,8.6),(6,8.6)))
extra(axs[1])
plt.tight_layout(); plt.savefig('p3_option1_shift.png',dpi=130)
```


## 作業ログ ― ⑤の店の形を直し、⑤だけ試算を計算し直した

店の形は、p2m-site の tools/sim_layouts/ にある作り方のコードから出ています。サイトの試算と3Dの店は、どちらもここから出たデータを読みます。直すのはこのコードの⑤の部分だけです。作り直したあと、②③④⑥⑦の出力が版の番号以外まったく同じであることを、ファイルごとに比べて確かめました。

### 店の形の作り方 famires_gen2.py の⑤の部分（直した版）

```python
def p3_relaxed_center():
    W, D = 26.0, 17.0
    # 厨房側（パントリー・キッチン・洗い場・保存・更衣室・受け渡し口・待機場所）をまとめて左へ1.5m（2026-10-28 エイイチと決めた。
    # 右上を客席に使い、受け渡し口を混みやすい左側へ寄せる。キッチンの左と左の島の間は2.25m残る）
    rooms, walls, dish, sb, start = boh_top(W, D, 7.5, 17.5, 9.4, staff=[17.5, 14.5, 21.5, 17.0])
    toilet, twalls, tdoor = toilet_block([0.0, 14.6, 3.0, 17.0], "right", W, D)   # 左上の角。入口は右向き
    walls += twalls
    rooms += [toilet,
              *register([11.2, 0.3, 11.9, 2.8], [10.4, 0.3, 11.2, 2.8]),   # 入口の横に縦向き（前の通路をふさがない）
              dict(label="待合", rect=[15.4, 0.3, 15.9, 2.3], kind="guest"),   # 入口の右に縦向き（6人席の前をふさがない）
              dict(label="ドリンクバー", rect=[15.0, 4.6, 18.6, 5.3], kind="drink")]
    t = strip(0.0, 1.4, "v", 6, walls=walls)          # 左の壁ぞい（ボックスごとに仕切り・トイレの手前で止める）
    t += island(2.7, 3.4, "v", 5, walls=walls)
    # 真ん中の島は2段（2026-10-28 エイイチと決めた。前は3段で、上の端とパントリーの間が0.25mしかなく、
    # 受け渡し口から左側へ抜けられず、左の卓へ行くロボットが全部入口とレジの前を回っていた。上の2卓は右上の壁ぞいへ移した）
    t += island(6.75, 3.4, "v", 2, walls=walls)
    t += strip(24.8, 1.4, "v", 8, walls=walls)        # 右の壁ぞい（2026-10-28 に上へ2卓のばした。前は6卓）
    t += island(20.75, 3.4, "v", 5, walls=walls)
    t += strip(1.6, 0.0, "h", 4, seats=6, walls=walls)    # 家族用の6人ボックス（下の壁ぞい・左）
    t += strip(16.4, 0.0, "h", 4, seats=6, walls=walls)   # 同（右）。入口の右側
    return dict(name="⑤ ゆったり型・入口が正面の中央", style="ゆったり", outer=dict(w=W, d=D),
                entrance=dict(side="bottom", a0=12.0, a1=15.0), rooms=rooms, walls=walls, toilet_doors=[tdoor],
                dish_up=dish, robot_standby=sb, start=start, tables=t)
```

【画像】LOG397_05_store5_routes_after.png 直したあとの⑤の図面とロボットの道。受け渡し口から島の上を通って左側へ抜けている

### 卓までの距離が変わったので、⑤の3,066条件だけ計算し直した

試算は、店の種類・スタッフの人数・ロボットの台数・来客のペースなどの組み合わせ32,850条件を、1条件40回ずつ回した平均です。前提が変わった⑤の3,066条件だけを計算し直し、ほかは前の結果を使い回しました。Claude のクラウドの作業環境（2コア）で約25分でした。

#### haizen_sim.py の実行ログ

```text
32850 conditions, 29784 reused, 3066 to run
  100/3066
  200/3066
  300/3066
  400/3066
  500/3066
  600/3066
  700/3066
  800/3066
  900/3066
  1000/3066
  1100/3066
  1200/3066
  1300/3066
  1400/3066
  1500/3066
  1600/3066
  1700/3066
  1800/3066
  1900/3066
  2000/3066
  2100/3066
  2200/3066
  2300/3066
  2400/3066
  2500/3066
  2600/3066
  2700/3066
  2800/3066
  2900/3066
  3000/3066
32850 conditions written
```

#### 直す前と後の試算を比べたスクリプト compare_p3_site.py

```python
"""⑤の試算を、店の形を直す前（results_before.json）と後（results.json）で比べる（2026-10-28）
使い方: python3 compare_p3_site.py   （haizen_sim.py と同じフォルダで）"""
import json, haizen_sim as h
A = {h.key(r): r for r in json.load(open('results_before.json'))['rows']}
B = {h.key(r): r for r in json.load(open('results.json'))['rows']}
ch = {}
for k in B:
    if A[k] != B[k]:
        ch[k[0]] = ch.get(k[0], 0) + 1
print(ch)
s = h.STORES['fam_p3']
for st in s['staff']:
    for rb in (0, 1, 2):
        c = {'store': 'fam_p3', 'staff': st, 'robots': rb, 'arrivals_per_h': 46, 'mode': 'serve', 'trays': 3 if rb else 1, 'fragile_by': 'any', 'registers': 1}
        a = A[h.key(c)]; b = B[h.key(c)]
        print(st, rb, ' '.join(f"{m}:{a[m]:.2f}→{b[m]:.2f}" for m in ('entry_wait_mean', 'staff_wait_mean', 'dish_wait_mean', 'pay_wait_mean', 'robot_share')))
```

#### compare_p3_site.py の出力

```text
{'fam_p3': 3066}
3 0 entry_wait_mean:17.51→16.28 staff_wait_mean:9.69→8.99 dish_wait_mean:1.09→0.93 pay_wait_mean:24.18→23.12 robot_share:0.00→0.00
3 1 entry_wait_mean:8.21→8.44 staff_wait_mean:3.11→2.19 dish_wait_mean:2.38→2.28 pay_wait_mean:22.01→22.13 robot_share:0.73→0.75
3 2 entry_wait_mean:5.22→5.34 staff_wait_mean:1.35→1.20 dish_wait_mean:1.25→1.13 pay_wait_mean:19.22→20.01 robot_share:0.98→0.99
4 0 entry_wait_mean:5.44→6.22 staff_wait_mean:1.67→1.50 dish_wait_mean:0.63→0.57 pay_wait_mean:18.04→18.81 robot_share:0.00→0.00
4 1 entry_wait_mean:3.58→3.42 staff_wait_mean:0.82→0.77 dish_wait_mean:2.22→2.14 pay_wait_mean:13.77→12.95 robot_share:0.67→0.69
4 2 entry_wait_mean:2.40→3.67 staff_wait_mean:0.56→0.69 dish_wait_mean:1.35→1.24 pay_wait_mean:11.20→13.00 robot_share:0.97→0.98
5 0 entry_wait_mean:3.15→2.50 staff_wait_mean:0.71→0.64 dish_wait_mean:0.38→0.34 pay_wait_mean:12.39→12.98 robot_share:0.00→0.00
5 1 entry_wait_mean:3.02→2.50 staff_wait_mean:0.61→0.56 dish_wait_mean:2.09→2.03 pay_wait_mean:10.76→10.95 robot_share:0.65→0.66
5 2 entry_wait_mean:1.38→2.35 staff_wait_mean:0.37→0.44 dish_wait_mean:1.33→1.23 pay_wait_mean:8.70→10.51 robot_share:0.97→0.98
```

スタッフ4人・1時間46組（3Dの店で回す条件）では、料理の待ちはどの台数も少し短くなりました（0.63→0.57・2.22→2.14・1.35→1.24分）。卓までの距離が縮んだ分です。2台で入店待ちが2.4→3.7分に延びたのは、会計待ちが11.2→13.0分に延びたためです。試算では、食べ終えた組が卓に座ったままレジの順番を待つので、会計待ちが延びると卓が空かず、入店待ちも延びます。

### ページの⑤だけを差し替えるスクリプト update_page_p3.py

公開中の試算のページは、全条件の結果と店の平面図を1つのデータとして持っています。⑤の行だけが変わったことを確かめてから結果を入れ替え、⑤の平面図を作り直しました。前の店の形から作った平面図が公開中のページと一致することを先に確かめ、作り方が同じであることを担保しています。

```python
"""⑤の店の形を直したとき（2026-10-28）、公開中の試算のページの⑤だけを差し替える。
使い方: python3 update_page_p3.py <公開中のページ> <新しい results.json> <前の p3 の店の形> <新しい p3 の店の形> <新しい summary.json> <出力するページ>
- const D の r（結果）：⑤（fam_p3）の行だけが変わっていることを確かめてから、全部を新しい結果に入れ替える
- const D の stores.fam_p3：卓までの距離（dist_m・dist_mean）を新しい値に
- const D の plans.fam_p3：⑤は卓の数の並びと厨房の位置が変わったので、平面図をまるごと作り直す
  （作り方は build_page_v23.py と同じ。前の店の形から作った平面図が、公開中のページと同じになることを先に確かめる）
- const D の layout_generation：新しい版の番号に
ほかの店・費用の欄・画面の文は変えない"""
import json, sys
import haizen_sim as h

live, res, old_lay, new_lay, summ, out = sys.argv[1:7]
s = open(live, encoding="utf-8").read()
N = json.load(open(res, encoding="utf-8"))
assert N["common"] == json.loads(json.dumps(h.COMMON))
lines = [l for l in s.split("\n") if l.startswith("const D = ")]
assert len(lines) == 1
D = json.loads(lines[0][len("const D = "):].rstrip(";"))
cond = D["k"][:8]
mets = D["k"][8:-1]
conds = list(h.conditions())
assert len(N["rows"]) == len(conds) == len(D["r"])
rows, changed = [], {}
for c, r, o in zip(conds, N["rows"], D["r"]):
    assert all(r[k] == c[k] for k in cond)
    row = [r[k] for k in cond] + [round(r[k], 3) for k in mets] + [1 if r["staff_wait_mean"] >= h.NG_MIN else 0]
    assert o[:8] == row[:8]
    if o != row:
        changed[c["store"]] = changed.get(c["store"], 0) + 1
    rows.append(row)
print("結果が変わった行:", changed)
assert set(changed) <= {"fam_p3"}, changed
D["r"] = rows

st = h.STORES["fam_p3"]
D["stores"]["fam_p3"]["dist_m"] = list(st["dist_m"])
D["stores"]["fam_p3"]["dist_mean"] = round(sum(st["dist_list"]) / len(st["dist_list"]), 1)
assert D["stores"]["fam_p3"]["tables"] == st["tables"] == 46
print("⑤の距離:", D["stores"]["fam_p3"]["dist_m"], D["stores"]["fam_p3"]["dist_mean"])

q = lambda a: [round(v, 2) for v in a]
def plan(path):
    L = json.load(open(path, encoding="utf-8"))["layout"]
    W, Dd = L["outer"]["w"], L["outer"]["d"]
    return json.loads(json.dumps({
        "w": W, "d": Dd,
        "outline": L.get("outline") or [[0, 0], [W, 0], [W, Dd], [0, Dd]],
        "rooms": [q(r["rect"]) + [r["kind"], r["label"]] for r in L["rooms"] if r["kind"] != "outside"],
        "walls": [q(w["rect"]) for w in L["walls"]],
        "tables": [q([t["x"], t["y"], t["x"] + t["w"], t["y"] + t["h"]]) + [t["seats"]] for t in L["tables"]],
        "dish": [q(d["rect"]) for d in L["dish_up"]],
        "standby": q(L["robot_standby"]["rect"]),
        "ent": [L["entrance"]["side"], L["entrance"]["a0"], L["entrance"]["a1"]],
    }))
assert plan(old_lay) == D["plans"]["fam_p3"], "前の店の形から作った平面図が公開中のページと違う"
D["plans"]["fam_p3"] = plan(new_lay)
print("⑤の平面図を作り直した（卓", len(D["plans"]["fam_p3"]["tables"]), "）")

gens = {g["generation"] for g in json.load(open(summ, encoding="utf-8"))}
assert len(gens) == 1
D["layout_generation"] = gens.pop()
s = s.replace(lines[0], "const D = " + json.dumps(D, ensure_ascii=False, separators=(",", ":")) + ";")
open(out, "w", encoding="utf-8").write(s)
print("書いた:", out, "版", D["layout_generation"])
```

【画像】LOG397_06_store5_page_plan.png 公開中の試算のページに出る、直したあとの⑤の平面図


## 作業ログ ― 3Dの店が⑤を建てられなかった：通路の端の点が外壁の上にあった

### 依頼文：直した⑤を建てて確かめる（20261028_18）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 180
---
# 依頼：直した⑤（fam_p3）を Unity に建て、1回ずつ回して確かめる（2026-10-28・前の依頼 17 のやり直し）

前の依頼 17 は、サイトの公開が止まっていた（Cloudflare のビルドが一度失敗した）ため、始める前の確かめ5で止まった。今は公開されている。

その間にエイイチと⑤の店の形を直した（p2m-site commit a423a89。店の形の版 39257d16b68a → 80a101e91410）。
- 真ん中の島（4人席）を3段 → 2段。外した上の2卓は、右の壁ぞいの列を上へのばして置いた（卓46・席200のまま）
- 厨房側（パントリー・キッチン・洗い場・保存・更衣室・受け渡し口・ロボットの待機場所・スタッフが待つ点）をまとめて左へ1.5m
- 理由：前は島の上の端とパントリーの間が0.25mしかなく、受け渡し口から左側へ抜けられず、左の卓へ行くロボットが全部入口とレジの前を回っていた。今は約2.1m
- ⑤の試算だけ計算し直した（③⑦④の数字は変わっていない。③⑦④の店の形は版の番号だけ変わり、中身は同じ）
- params：unity_conditions 12件（⑤の3件が新しい試算の値）・layout_generation 80a101e91410。common・unity_rules・③⑦④の9件は前と同じ
- ⑤の条件：スタッフ4人・46組/時・ロボット0・1・2台・上げ膳・1往復3卓（0台は trays 1）・レジ1つ。試算でもレジ1つだと会計待ちが13〜19分で「レジが詰まる」。Unity でレジが詰まっても試算どおりなので、それだけで手を止めなくてよい
- 前の報告の「決めてほしいこと」2（⑤のスタッフが待つ点が2つ）：直した形でも2つ（パントリーの左右の端）。**今回は2人ずつ同じ点に割り当てるままでよい**（点を足す規則を変えると③⑦④の点も変わり得るため。結果を見てから決める）
- 台帳の退避は前と同じ：`/Volumes/KIOXIA/r2r2r-data/service_sim/unity/archive/unity_ledger_v1_pre_p3check_20261028/unity_ledger_v1.csv`（565行・md5 7f636cb533be1ee07caabb8782455f15）

## 始める前に確かめること（違えば手を止めて報告）

1. Unity エディタが起動していない（起動していたら閉じずに報告して終わる）
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 台帳の md5 が上の退避と同じ
4. ServiceSim の保留が 0
5. https://pixelstomotors.com/sim/serving-robot-params.json の meta.layout_generation が 80a101e91410、unity_conditions が12件（違えば数分おきに取り直す。30分たっても違えば報告して終わる）

## やること

1. サイトの params と、③⑦④⑤の店の形（`public/sim/layouts/unity/` の p1・p5・p2・p3 の `.json` と `_map.json`）を、今までと同じやり方でプロジェクトに写す（手で値を写さない）。generation が 80a101e91410 でそろっているか確かめる。③⑦④は、中身が前の写しと版の番号以外同じであることを確かめる
2. ⑤を③⑦④と同じコード・同じ規則で建てる（地図の上で自分で道を引く動き方・すれ違い入・待機場所へ戻る 入・案B 切・店員優先のよけ方・逃がし弁・モニター、すべて今の標準のまま）。⑤のためだけの手直しはしない
   - ⑤の店の形のせいで建てられない・回らないところ（届かない卓、待機場所・レジ・並ぶ点が置けない、NavMesh の切れ目など）があっても、Unity 側で形を直さない。場所と理由を「決めてほしいこと」に書く（直すならサイトが先）
3. make_queue.py で `--stores fam_p3` が使えることを確かめる。**指定しないときは今までどおり ③⑦の60回**。judge_night.py は変えない（⑤は基準データがないので「基準なし」になってよい）
4. check-in して、画面なしの実行ファイルを作り直す（保留 0）
5. 確かめの3回を回す：⑤ × ロボット0・1・2台 × 種0、今の標準のまま。ラベル `p3check`。同時に回す本数は4のまま
   - 台帳には3行が足される（追記だけ）。終わったら行数（565 → 568 のはず）と、先頭565行の md5 が退避と同じかを確かめる
6. make_queue の dry-run で、何も指定しないとき③⑦の60回のままであることを確かめる（台帳に書かない）
7. 作業フォルダに queue の一時ファイルを残さない

## 変えないもの

- 店の回し方・人とロボットの動き・速さ・Stiffness などの物理の設定・同時に回す本数（N=4）
- 台帳の列（59列）と今までの行。今までの night/ と出力の記録
- 本番の夜は回さない（⑤の夜は、確かめの結果をエイイチが見てから決める）

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261028_HHMM_p3_build_check2.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。

- 始める前の確かめ5つの結果
- 入れた cs 番号・build_id と保留の有無・変えたファイル
- ⑤を建てて分かったこと（卓の数46・止まる位置・待機場所・レジ・スタッフが待つ点・並ぶ点が置けたか、置けなかった所）
- 3回それぞれ：最後まで回ったか・全員帰ったか・実時間・入れた組の数・入店待ち・そのうち席は空いているのに待った時間・料理の待ち・会計待ち・ロボットが運んだ皿の割合・往復の数・30秒以上の止まり（1往復あたり）・動けなくなった（60秒）・卓を空けた・瞬間移動・打ち切り。試算の同じ条件の値（params の site_result）と並べる。差の理由の調べはしなくてよい
- 2台の回の30秒以上の止まりの場所：受け渡し口の点から 2.5 m 以内の数（待機場所での止まりを除いた数も）と、入口・レジの前（y が 3.4 m より下で、x が 9.3〜16.4 m）の数
- 台帳の行数と先頭565行の md5
- dry-run で③⑦が60回のままか
- **エイイチが画面で⑤を見る手順**（Unity を開いてから、どのシーン・メニューで⑤の、どの条件を流せるか。短く）
- 決めてほしいこと（なければ「なし」）
```

### 報告：20261028_1401_p3_build_check2.txt

```text
====================================================================
直した⑤（fam_p3）を建てて確かめる … ⑤が建たないので、建てる段で止めた
依頼：20261028_18_直した店5を建てて確かめる.md（依頼 17 のやり直し）
2026-10-28 14:01
====================================================================

結論

  ・始める前の確かめ5つは、すべて合格だった。
  ・サイトの params と ③⑦④⑤の店の形を写した。版はすべて 80a101e91410 でそろっていた。
    ③⑦④の中身は、前の写しと版の番号以外は同じだった。
  ・⑤を③⑦④と同じコードで建てようとしたら、**Unity の読み込みで「JSON と合わないもの 14 件」となり、建たなかった**。
    原因は⑤の JSON で、右の壁ぞいの細い通路 A03 の入口（entrance）が null になっていること。
    A03 を通る 13 卓（T21〜T28・T34〜T38）が読み込めない。
    店の形（サイト側）のデータが原因なので、依頼のとおり Unity 側では直していない（決めてほしいこと 1）。
  ・そのため、check-in・実行ファイルの作り直し・確かめの3回は、どれもしていない。
    台帳は 565 行のまま。本番の夜も回していない。
  ・保留を残さないよう、プロジェクトは cs:35 の状態に戻した（保留 0）。
    足した分（メニュー・.asset・シーンの1行）は控えに残したので、サイトが直れば同じ形でもう一度入れられる。


====================================================================
1. 始める前の確かめ（5つとも合格）
====================================================================

  1. Unity エディタ：起動していない（Unity Hub だけが起動していた）
  2. /Volumes/KIOXIA：マウントされている。unity_ledger_v1.lock：なし
  3. 台帳 unity_ledger_v1.csv：565 行・md5 7f636cb533be1ee07caabb8782455f15（退避と同じ）
  4. ServiceSim の保留：0（cs:35）
  5. 公開中の serving-robot-params.json：meta.layout_generation 80a101e91410・
     unity_conditions 12 件・stores は fam_p1 / fam_p5 / fam_p2 / fam_p3（1回目で合った）


====================================================================
2. 写したもの（やること 1）
====================================================================

  写し元：https://pixelstomotors.com/sim/（2026-10-28 13:57 に取得）
    控え：unity/site_copy_80a101e91410/（params・summary.json・layouts/unity/ の6店の JSON と地図）
  版の番号：params の layout_generation、p1・p5・p2・p3 の JSON と地図の meta.generation、
            summary.json の6店すべてが 80a101e91410
  ③⑦④（p1・p5・p2 の JSON と地図の6本）：前の写し（site_copy_39257d16b68a）と比べて、
            generation 以外の違いは 0
  summary.json：違うのは⑤の robot_dist_mean（13.7 → 12.5）と robot_dist_max（23.17 → 18.8）だけ
  params：common・unity_rules・stores の fam_p1 / fam_p5 / fam_p2、unity_conditions の 0〜8 番は前と同じ。
          足されたのは stores.fam_p3 と unity_conditions の 9〜11 番（⑤の 0・1・2 台）。
          meta で変わったのは layout_generation だけ

  プロジェクトへは cp でそのまま写した（手で値を写していない）。
  ただし 3 章のとおり⑤が建たなかったので、プロジェクトは cs:35 の写しに戻してある。


====================================================================
3. ⑤を建てて分かったこと（やること 2）
====================================================================

  やったこと
    ④のときと同じ形で⑤を足し、Unity を画面なしで開いて
    「ServiceSim → JSON Store → ⑤ p3_relaxed_center を建てて確かめる」を走らせた
    （-batchmode -executeMethod ServiceSim.EditorTools.ServiceSimJsonStore.CheckP3）。
    組み立ては通った（error CS 0）。

  結果：建たなかった
    JsonStoreLayout が「JSON と合わないものが 14 件あるので建てませんでした」として止まった。
      - aisles[2].entrance が [x, y] ではありません（A03 の entrance が null）
      - T21・T22・T23・T24・T25・T26・T27・T28・T34・T35・T36・T37・T38：
        aisles に無い通路 "A03"（上の1件で A03 を読み込めなかったため）
    店ができないので、ほかの確かめ（止まる位置が NavMesh に乗るか・道のりの照合・
    待機場所・レジ・スタッフが待つ点・並ぶ点・NavMesh の切れ目）は走っていない。
    Map Planner の確かめ A も、同じ読み込みを通るので回していない。

  原因（⑤の JSON の中身）
    A03（右の壁ぞいの列の通路・幅 1.5 m）
      今の版   rect [23.3, 1.4, 24.8, 16.2]・端の点 (24.05, 0.6) と (24.05, 17.0)・
               end_dist [null, null]・entrance null
      前の版   rect [23.3, 1.4, 24.8, 12.65]・端の点 (24.05, 0.6) と (24.05, 13.45)・
               end_dist [null, 14.325]・entrance (24.05, 13.45)
    右の列を上へのばしたので、通路の上の端の点（通路の端から 0.8 m 外）が y = 17.0、
    つまり外壁の上の線の上に来た。下の端（y = 0.6）は前から行けない所なので、
    両方の端に受け渡し口から行けず、サイトの解析が entrance を null にしている。
    Unity の読み込みは「細い通路には入口が1つある」という前提で作ってある。

    参考：卓そのものへの道は JSON の routes にある（例 T21：受け渡し口から normal・13.9 m）。
    地図（map.json）の読み込みは通っていて、マスの数は JSON の counts と一致、
    止まる位置は読めた 33 卓すべて通れるマスの上、受け渡し口はふだんの道のマス、
    待機場所3つは「通れる幅だけ」のマス（④と同じ）だった。

  JSON の上で数えた点（建てていないので、置けたかどうかは未確認）
    卓 46・席 200（summary.json）／場所の点：受け渡し口・返却口・パントリー・入口・待合・トイレ・
    レジ 1・会計の列 3・レジ内 1・ドリンクバー（立つ点 4・列 3）・ロボットの待機場所 3・スタッフが待つ点 2
    スタッフが待つ点は (7.25, 10.0) と (17.75, 10.0)（パントリーの左右の端）。今回の決まりどおり、
    建てば 2 人ずつ同じ点に割り当てられる（コードは変えていない）。


====================================================================
4. 入れた cs・build_id・変えたファイル
====================================================================

  check-in：していない（cs:35 のまま・保留 0）
  画面なしの実行ファイル：作り直していない（build_id cs34_20261028_0642 のまま）

  一度変えて、cs:35 に戻したもの（控え：claude_code_reports/20261028_1401_p3_build_check2_pending/）
    Assets/ServiceSim/Experiment/serving-robot-params.json（公開版の写し）
    Assets/ServiceSim/Store/Layouts/summary.json・p1/p5/p2 の JSON と地図（公開版の写し）
    Assets/ServiceSim/Store/Layouts/p3_relaxed_center.json・_map.json（＋.meta）… 足して、消した
    Assets/ServiceSim/Store/StoreLayout_p3_relaxed_center.asset（＋.meta）… 足して、消した
      ④の .asset を写し、JSON・地図・名前・写し元を差し替えた。通路の幅は JSON と同じ 1.5 m
    Assets/ServiceSim/Editor/ServiceSimSetup.cs     P3LayoutPath と HeadlessRun.layouts に⑤
    Assets/ServiceSim/Editor/ServiceSimSiteRun.cs   ⑤の3条件（unity_conditions の 9・10・11）
    Assets/ServiceSim/Editor/ServiceSimJsonStore.cs 「⑤ p3_relaxed_center を建てて確かめる」・試算の値の確かめに⑤
    Assets/ServiceSim/Editor/ServiceSimMapPlanner.cs「⑤ 確かめ A」
    Assets/ServiceSim/Scenes/ServiceSim_Family.unity HeadlessRun.layouts に⑤（1行）
    Assets/ServiceSim/Store/Materials/Mat_RobotKeepout.mat
      Unity が書き直したが中身は cs:35 と同じだった。これも戻した
    控えには、変えたファイルそのものと cs:35 との差分（changes_vs_cs35.diff）、
    Unity のログ（unity_batch_checkP3.log）を置いた。
    公開版の params と店の形は unity/site_copy_80a101e91410/ にある。
    シーンと ProjectSettings は、Unity を開く前と同じだった（NavMeshAreas の書き足しも無かった）。

  ずっと残したもの（プロジェクトの外）
    unity/site_copy_80a101e91410/（README.txt つき）
    claude_code_reports/20261028_1401_p3_build_check2_pending/


====================================================================
5. make_queue.py（やること 3・6。台帳には書いていない）
====================================================================

  コードは変えていない。写した params（12 件）で /tmp に作って確かめた
  （このとき 1 回だけ。プロジェクトを戻したあとは、cs:35 の 9 件の params に戻っている）。
    --stores fam_p3 --seeds 0 --label p3check
      → fam_p3_s4_r0_a46・r1_a46・r2_a46 の 3 回（すれ違い入・待機場所へ戻る入・案B切、
         0 台は trays 1・1 台と 2 台は trays 3・レジ 1）
    何も指定しない
      → fam_p1・fam_p5 × 0・1・2 台 × 種 0〜9 ＝ 60 回。
         night/20261102/queue.json（v5 の夜）と、回の並びと中身が同じ（label を除く）
  judge_night.py は変えていない。
  作業フォルダに queue の一時ファイルは置いていない（/tmp にだけ作った）。


====================================================================
6. 確かめの3回（やること 5）
====================================================================

  回していない（⑤が建たないため）。
  画面なしの実行ファイルでも、同じ読み込み（JsonStoreLayout）で止まるので、
  今のまま回しても3回とも店が建たずに終わる。


====================================================================
7. 台帳
====================================================================

  行数 565（変わらず）・md5 7f636cb533be1ee07caabb8782455f15（退避と同じ）。鍵ファイルなし。


====================================================================
8. エイイチが画面で⑤を見る手順
====================================================================

  今は見られない（⑤はプロジェクトに入っていない）。
  サイトの形が直って入れたあとは、④と同じく次のとおり：
    1. Unity Hub から ServiceSim を開き、シーン Assets/ServiceSim/Scenes/ServiceSim_Family.unity を開く
    2. 建てるだけで見る：ServiceSim → JSON Store → ⑤ p3_relaxed_center を建てて確かめる
    3. 回して見る：ServiceSim → Site Run → ⑤ スタッフ4人・ロボット0台 / 1台 / 2台
       （Play に入って回り、終わると自動で抜ける。出力は KIOXIA に出る）


====================================================================
9. 決めてほしいこと
====================================================================

  1. ⑤の右の壁ぞいの通路 A03 の入口が null になっている件（3 章）。
     どちらで直すかを決めてください。
     (a) サイト側：右の列の上の端（rect の y 16.2）を下げて、通路の上の端の点を壁から離す、
         または通路の端の点の置き方（壁に当たるときの扱い）を直して、entrance が入るようにする。
         直したら版の番号が変わるので、params と ③⑦④の版の番号もそろえて出し直しになる
     (b) Unity 側：入口が null の細い通路を読めるようにする（コードの規則の変更。
         ③⑦④には null の通路が無いので動きは変わらないはずだが、⑤のための手直しになる）
     依頼の決まり（直すならサイトが先）に従い、どちらもしていません。
  2. 直ったあとは、この依頼をもう一度渡してください。控え（pending フォルダ）にある
     メニュー・.asset・シーンの1行は、版が変わっても名前が同じならそのまま使えます。
```

### 右の壁ぞいの列を奥の壁までのばしたら、通路の入口が「なし」になった

3Dの店は、ボックス席の列と列の間の通路（細い通路）ごとに、両端の0.8m外に「入口の点」を置き、受け渡し口から近い方をその通路の入口にしています。右の壁ぞいの列を上へ2卓のばしたので、列の上の端は y=16.2m になり、上の入口の点は y=17.0m、つまり奥の外壁の線の上に来ました。下の入口の点（y=0.6m）は、もともと6人席にふさがれて行けません。両端とも行けないので、作り方のコードはこの通路の入口を「なし」と書き出し、3Dの店はその通路を使う13卓を読めずに止まりました。

実際には、この通路は右の島の下からも上からも横に入れます。端の点の置き方の決まりが、列が壁まで届く形を想定していませんでした。直し方は3つ考え、サイト側の決まりを直す案をエイイチが選びました。両端とも行けないときだけ、端の点を通路の中へ0.1mずつ戻し、最初に行ける所に置き直します。片方でも行ける通路は前と同じなので、②③④⑥⑦の出力は版の番号以外変わりません。試算はこの点を使わないので、試算の数字も変わりません。

#### 店の形の作り方 unity_export.py の aisle_entrances（直した版）

```python
def aisle_entrances(aisles, grid, dist, dist_pass):
    """両端の入口の点の、受け渡し口の前からの道のり（ふだんの幅の道。行けなければ通れる幅の道）。短い方を entrance にする"""
    def reach(x, y):
        cy, cx = grid.cell(x, y)
        if 0 <= cy < grid.ny and 0 <= cx < grid.nx:
            for D in (dist, dist_pass):
                if D is not None and np.isfinite(D[cy, cx]):
                    return r2(D[cy, cx])
        return None

    for a in aisles:
        ds = [reach(x, y) for x, y in a["ends"]]
        if all(d is None for d in ds):
            # 両端とも行けないとき（端の点が外壁や別の卓に当たる）は、それぞれの端の点を通路の中へ0.1mずつ戻し、
            # 最初に行ける所に置き直す（2026-10-28 エイイチと決めた。⑤の右の壁ぞいの列を奥の壁までのばしたら、上の端の点が
            # 外壁の線の上に来て、通路の横から入れるのに入口なしになった）。片方でも行ける通路は今までどおりで変えない
            k = 1 if a["axis"] == "v" else 0
            (x0, y0), (x1, y1) = a["ends"]
            span = abs((y1 - y0) if k else (x1 - x0))
            for i in (0, 1):
                p, q = list(a["ends"][i]), a["ends"][1 - i]
                step = 0.1 if q[k] > p[k] else -0.1
                n = 1
                while n * 0.1 < span - 1e-6:
                    c = list(p)
                    c[k] = r2(p[k] + step * n)
                    d = reach(*c)
                    if d is not None:
                        a["ends"][i], ds[i] = c, d
                        break
                    n += 1
        a["end_dist"] = ds
        ok = [i for i, d in enumerate(ds) if d is not None]
        a["entrance"] = a["ends"][min(ok, key=lambda i: ds[i])] if ok else None
```

直した結果、この通路の入口は (24.05, 2.1)、右の島の下から入る所になりました。

### 依頼文：直した⑤を建てて確かめる・やり直し（20261028_19）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 180
---
# 依頼：直した⑤（fam_p3）を Unity に建て、1回ずつ回して確かめる（2026-10-28・依頼 18 のやり直し）

前の依頼 17 は、サイトの公開が止まっていた（Cloudflare のビルドが一度失敗した）ため、始める前の確かめ5で止まった。今は公開されている。

その間にエイイチと⑤の店の形を直した（p2m-site commit a423a89。店の形の版 39257d16b68a → 80a101e91410）。
- 真ん中の島（4人席）を3段 → 2段。外した上の2卓は、右の壁ぞいの列を上へのばして置いた（卓46・席200のまま）
- 厨房側（パントリー・キッチン・洗い場・保存・更衣室・受け渡し口・ロボットの待機場所・スタッフが待つ点）をまとめて左へ1.5m
- 理由：前は島の上の端とパントリーの間が0.25mしかなく、受け渡し口から左側へ抜けられず、左の卓へ行くロボットが全部入口とレジの前を回っていた。今は約2.1m
- ⑤の試算だけ計算し直した（③⑦④の数字は変わっていない。③⑦④の店の形は版の番号だけ変わり、中身は同じ）
- params：unity_conditions 12件（⑤の3件が新しい試算の値）・layout_generation d7bb919590d4。common・unity_rules・③⑦④の9件は前と同じ
- ⑤の条件：スタッフ4人・46組/時・ロボット0・1・2台・上げ膳・1往復3卓（0台は trays 1）・レジ1つ。試算でもレジ1つだと会計待ちが13〜19分で「レジが詰まる」。Unity でレジが詰まっても試算どおりなので、それだけで手を止めなくてよい
- 前の報告の「決めてほしいこと」2（⑤のスタッフが待つ点が2つ）：直した形でも2つ（パントリーの左右の端）。**今回は2人ずつ同じ点に割り当てるままでよい**（点を足す規則を変えると③⑦④の点も変わり得るため。結果を見てから決める）
- 台帳の退避は前と同じ：`/Volumes/KIOXIA/r2r2r-data/service_sim/unity/archive/unity_ledger_v1_pre_p3check_20261028/unity_ledger_v1.csv`（565行・md5 7f636cb533be1ee07caabb8782455f15）

依頼 18 の報告（20261028_1401_p3_build_check2.txt）の「決めてほしいこと」1 への答え：**(a) サイト側で直した**（エイイチと決めた）。
- 店の形の作り方（unity_export.py）で、両端とも行けない細い通路だけ、端の点を通路の中へ0.1mずつ戻して最初に行ける所に置くようにした（p2m-site commit b1b2c4c）
- ⑤の A03 は ends が [24.05, 2.1]・[24.05, 16.6]、entrance が [24.05, 2.1]（右の島の下から通路に入れる）。A01・A02 は前と同じ
- 店の形の版 80a101e91410 → d7bb919590d4。変わったのは unity/p3_relaxed_center.json の A03 だけで、ほかのファイル（⑤の _map.json も）は版の番号以外同じ。試算と params の数字は変わらない（params は meta.layout_generation だけ）
- 依頼 18 で足して控えた分（claude_code_reports/20261028_1401_p3_build_check2_pending/）は、そのまま使ってよい

## 始める前に確かめること（違えば手を止めて報告）

1. Unity エディタが起動していない（起動していたら閉じずに報告して終わる）
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 台帳の md5 が上の退避と同じ
4. ServiceSim の保留が 0
5. https://pixelstomotors.com/sim/serving-robot-params.json の meta.layout_generation が d7bb919590d4、unity_conditions が12件（違えば数分おきに取り直す。30分たっても違えば報告して終わる）

## やること

1. サイトの params と、③⑦④⑤の店の形（`public/sim/layouts/unity/` の p1・p5・p2・p3 の `.json` と `_map.json`）を、今までと同じやり方でプロジェクトに写す（手で値を写さない）。generation が d7bb919590d4 でそろっているか確かめる。③⑦④は、中身が前の写しと版の番号以外同じであることを確かめる
2. ⑤を③⑦④と同じコード・同じ規則で建てる（地図の上で自分で道を引く動き方・すれ違い入・待機場所へ戻る 入・案B 切・店員優先のよけ方・逃がし弁・モニター、すべて今の標準のまま）。⑤のためだけの手直しはしない
   - ⑤の店の形のせいで建てられない・回らないところ（届かない卓、待機場所・レジ・並ぶ点が置けない、NavMesh の切れ目など）があっても、Unity 側で形を直さない。場所と理由を「決めてほしいこと」に書く（直すならサイトが先）
3. make_queue.py で `--stores fam_p3` が使えることを確かめる。**指定しないときは今までどおり ③⑦の60回**。judge_night.py は変えない（⑤は基準データがないので「基準なし」になってよい）
4. check-in して、画面なしの実行ファイルを作り直す（保留 0）
5. 確かめの3回を回す：⑤ × ロボット0・1・2台 × 種0、今の標準のまま。ラベル `p3check`。同時に回す本数は4のまま
   - 台帳には3行が足される（追記だけ）。終わったら行数（565 → 568 のはず）と、先頭565行の md5 が退避と同じかを確かめる
6. make_queue の dry-run で、何も指定しないとき③⑦の60回のままであることを確かめる（台帳に書かない）
7. 作業フォルダに queue の一時ファイルを残さない

## 変えないもの

- 店の回し方・人とロボットの動き・速さ・Stiffness などの物理の設定・同時に回す本数（N=4）
- 台帳の列（59列）と今までの行。今までの night/ と出力の記録
- 本番の夜は回さない（⑤の夜は、確かめの結果をエイイチが見てから決める）

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261028_HHMM_p3_build_check3.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。

- 始める前の確かめ5つの結果
- 入れた cs 番号・build_id と保留の有無・変えたファイル
- ⑤を建てて分かったこと（卓の数46・止まる位置・待機場所・レジ・スタッフが待つ点・並ぶ点が置けたか、置けなかった所）
- 3回それぞれ：最後まで回ったか・全員帰ったか・実時間・入れた組の数・入店待ち・そのうち席は空いているのに待った時間・料理の待ち・会計待ち・ロボットが運んだ皿の割合・往復の数・30秒以上の止まり（1往復あたり）・動けなくなった（60秒）・卓を空けた・瞬間移動・打ち切り。試算の同じ条件の値（params の site_result）と並べる。差の理由の調べはしなくてよい
- 2台の回の30秒以上の止まりの場所：受け渡し口の点から 2.5 m 以内の数（待機場所での止まりを除いた数も）と、入口・レジの前（y が 3.4 m より下で、x が 9.3〜16.4 m）の数
- 台帳の行数と先頭565行の md5
- dry-run で③⑦が60回のままか
- **エイイチが画面で⑤を見る手順**（Unity を開いてから、どのシーン・メニューで⑤の、どの条件を流せるか。短く）
- 決めてほしいこと（なければ「なし」）
```

### 報告：20261028_1440_p3_build_check3.txt

```text
====================================================================
直した⑤（fam_p3）を建てて、1回ずつ回して確かめた（3回目）
依頼：20261028_19_直した店5を建てて確かめる_やり直し.md（依頼 18 のやり直し）
2026-10-28 14:40　check-in：cs:36　build_id cs36_20261028_1435（保留 0）
====================================================================

結論

  ・始める前の確かめ5つは、すべて合格だった。
  ・公開版（版 d7bb919590d4）の params と ③⑦④⑤の店の形を写した。版はすべてそろっていた。
    ③⑦④は前の写しと版の番号以外同じ。⑤の JSON は A03 の端の点・end_dist・entrance だけが変わっていた（依頼の説明どおり）。
  ・⑤は③⑦④と同じコードで建った（合わないもの なし）。卓 46・席 200、止まる位置 46 / 46 が NavMesh の上、
    受け渡し口から全卓へ道がつながり、入口から全卓の席へ歩ける。確かめ A（地図で道を引く）も全卓・待機場所3つとも引けた。
  ・check-in（cs:36）して画面なしの実行ファイルを作り直し、確かめの3回（⑤ × 0・1・2台 × 種0）を回した。
    3回とも completed・全員帰った。打ち切りは 2台の回で 5。
  ・台帳 565 → 568 行（追記だけ）。先頭 565 行の md5 は退避と同じ。
  ・何も指定しない make_queue は③⑦の60回のまま。


====================================================================
1. 始める前の確かめ（5つとも合格。14:28 ごろ）
====================================================================

  1. Unity エディタ：起動していない（Unity Hub だけが起動していた）
  2. /Volumes/KIOXIA：マウントされている。unity_ledger_v1.lock：なし
  3. 台帳 unity_ledger_v1.csv：565 行・md5 7f636cb533be1ee07caabb8782455f15（退避と同じ）
  4. ServiceSim の保留：0（cs:35 head）
  5. 公開中の serving-robot-params.json：meta.layout_generation d7bb919590d4・unity_conditions 12 件
     （1回目の取得で合った）


====================================================================
2. 写したもの（やること 1）
====================================================================

  写し元：https://pixelstomotors.com/sim/（2026-10-28 14:30 に curl で取得）
    控え：unity/site_copy_d7bb919590d4/（params・summary.json・layouts/unity/ の6店の JSON と地図）
  版の番号：params の layout_generation、6店の JSON と地図の meta.generation、summary.json がすべて d7bb919590d4
  前の写し（site_copy_80a101e91410）との違い
    params・summary.json・p0/p1/p2/p4/p5 の JSON と地図・p3 の地図：版の番号だけ
    p3_relaxed_center.json：版の番号のほかは A03 だけ
      ends [24.05, 0.6]・[24.05, 17.0] → [24.05, 2.1]・[24.05, 16.6]
      end_dist [null, null] → [14.863, 16.077]
      entrance null → [24.05, 2.1]
  プロジェクトの③⑦④（p1・p5・p2 の JSON と地図）は cs:35 のものと比べて generation 以外の違い 0。
  params は cs:35 と比べて layout_generation・unity_conditions（9 → 12 件）・stores.fam_p3 が足されただけ。
  summary.json の違いは⑤の robot_dist_mean・robot_dist_max だけ。
  どれも cp でそのまま写した（手で値を写していない）。


====================================================================
3. 入れた cs・build_id・変えたファイル
====================================================================

  check-in：cs:36（保留 0）
  画面なしの実行ファイル：build_id cs36_20261028_1435 / unity_cs ServiceSim/cs:36 / pending_changes 空
                         Build Finished, Result: Success・error CS 0

  変えたファイル（cs:36）
    Assets/ServiceSim/Experiment/serving-robot-params.json   公開版の写し
    Assets/ServiceSim/Store/Layouts/summary.json             公開版の写し
    Assets/ServiceSim/Store/Layouts/p1_efficient_corner(.json/_map.json)・p5_crammed・p2_efficient_narrow
                                                              公開版の写し（版の番号だけ変わった）
    Assets/ServiceSim/Store/Layouts/p3_relaxed_center.json・_map.json（＋.meta）  足した
    Assets/ServiceSim/Store/StoreLayout_p3_relaxed_center.asset（＋.meta）        足した
      依頼 18 の控えのまま。fetchedAt だけ「2026-10-28 14:30:00 JST（版 d7bb919590d4）」に直した
    Assets/ServiceSim/Editor/ServiceSimSetup.cs       P3LayoutPath・HeadlessRun.layouts に⑤
    Assets/ServiceSim/Editor/ServiceSimSiteRun.cs     ⑤の3条件（unity_conditions の 9・10・11）
    Assets/ServiceSim/Editor/ServiceSimJsonStore.cs   「⑤ p3_relaxed_center を建てて確かめる」・版と試算の値の確かめに⑤
    Assets/ServiceSim/Editor/ServiceSimMapPlanner.cs  「⑤ 確かめ A」
    Assets/ServiceSim/Scenes/ServiceSim_Family.unity  HeadlessRun.layouts に⑤（1行）
    コードと .asset・シーンの1行は、依頼 18 の控え（20261028_1401_p3_build_check2_pending/）をそのまま使った。
    入れる前に、cs:35 との差分が控えの changes_vs_cs35.diff と同じ行数であることを確かめた。

  手で戻したもの（check-in していない）
    建てて確かめる処理を回すと ProjectSettings/NavMeshAreas.asset に「New Agent」が3つ書き足されたので
    cm undo で戻した（④のときと同じ）。Mat_RobotKeepout.mat も書き直されたが中身は同じだったので戻した。

  make_queue.py・night_runner.py・judge_night.py は変えていない。


====================================================================
4. ⑤を建てて分かったこと（JSON Store「⑤ を建てて確かめる」・Map Planner「⑤ 確かめ A」）
====================================================================

  数         卓：Unity 46 / JSON 46 / summary.json 46 で一致。席 200 で一致
             細い通路 3 本（A01・A02・A03、いずれも 1.5 m）。外寸 26 × 17 m
             地図のマスの数は JSON の counts と一致。合わないもの：なし
  止まる位置  46 か所すべてロボット用の NavMesh の上（乗らない 0）。地図でも 46 卓すべて通れるマス
  道順       受け渡し口から全 46 卓、すべての区間がつながった。
             JSON の dist との差は平均 −0.56 m・最大 0.97 m（T24）。30% を超えた卓は 0
  席         入口から全 46 卓の席に着く点まで歩ける（入れない卓 0）
  場所の点    24 か所すべて NavMesh に乗った（乗らない 0）。置けなかった所はない
               受け渡し口・返却口・パントリー (12.5, 8.85)／入口 (13.5, 0.5)／待合 (15.65, 2.7)／トイレ (3.6, 15.8)
               レジ 1 (12.3, 1.55)・会計の列 3 (12.8 / 13.3 / 13.8, 1.55)・レジの内側 (10.8, 1.55)
                 レジの内側は人用・ロボット用とも受け渡し口から 7.51 m で行ける
               ドリンクバー（立つ点 4・列 3）
               ロボットの待機場所 3：(14.6, 8.95)・(15.4, 8.95)・(16.2, 8.95)
                 地図では3つとも「通れる幅だけ」のマス（④と同じ）。確かめ A で3つとも道が引けた
               スタッフが待つ点 2：(7.25, 10.0)・(17.75, 10.0)（パントリーの左右の端）
                 依頼のとおり、規則は変えず 2 人ずつ同じ点に割り当てるまま
  行き止まり  細い通路を1本ずつふさいでも、ほかの全卓に届く（ロボット・人とも）
  確かめ A   引けない卓 0 / 46。狭い道を使う卓 0（サイトの routes も 0 で一致）。
             長さの比 最小 0.928 / 平均 1.011 / 最大 1.036

  気づいたこと（直していない。店の形のことなので、直すならサイトが先）
    ・細い通路の「焼いた面のいちばん狭いところ」：A01 0 m・A03 0.48 m（計算上はロボット用 1 m）。
      確かめは「直す必要あり」と出すが、道順・止まる位置・行き止まりの確かめはすべて通っており、回でも全卓に運べた。
      焼いた面の幅の測り方が⑤の通路の形（長い列）に合っていない可能性もある。調べていない
    ・人用の NavMesh に、受け渡し口からつながっていない面が 39.32 m2 ある（ロボット用は 0.8 m2）。
      例：左下の角 (0.6, 0.85)・(0.98, 0.55)、左上 (1.45, 13.0)・(2.23, 12.9)・(3.38, 12.92) のあたり。
      入口から全卓の席へは歩けるので、回には効いていないと見ている（④は 0 m2 だった）
  書き出し（unity/screens/）
    20261028_p3_relaxed_center_json_check.txt / _table_dist.csv
    20261028_1434_map_planner_checkA_p3.txt / map_plan の CSV


====================================================================
5. 確かめの3回（⑤ × 0・1・2台 × 種0・すれ違い入・待機場所へ戻る入・案B切・ラベル p3check・同時 3 本）
====================================================================

  python3 tools/make_queue.py --stores fam_p3 --seeds 0 --label p3check --out /tmp/p3c3/queue_p3check.json
  python3 tools/night_runner.py --queue /tmp/p3c3/queue_p3check.json --parallel 4 --night 20261028
      --label p3check --record-name 20261028_p3check
  出力 20261028_p3check_cs36_fam_p3_r{0,1,2}_s0_passon_sbret
  記録 night/20261028_p3check/（runner 終了コード 0・completed 3・失敗 0）
  judge.md：基準なし 3（⑤の基準データがないため。依頼のとおり）

  左が Unity、右が試算（params の site_result）。単位は分。割合は 0〜1
                                   0台                 1台                 2台
  最後まで回ったか                 completed           completed           completed
  全員帰ったか                     はい                はい                はい
  実時間                           2.8 分              2.9 分              3.1 分
  （参考）店の時間                 177.5 分            180.5 分            182.9 分
  入れた組の数                     71 / 93.4           71 / 91.3           71 / 95.0
  入店待ち                         1.75 / 6.22         1.50 / 3.42         1.83 / 3.67
   うち席は空いているのに待った     0 / 1.20            0 / 0.64            0 / 0.60
  料理の待ち                       1.16 / 0.57         2.42 / 2.14         2.51 / 1.24
  会計待ち                         2.42 / 18.81        2.81 / 12.95        3.39 / 13.00
  ロボットが運んだ皿の割合         0 / 0               0.758 / 0.686       0.781 / 0.980
  往復の数                         0                   65                  104
  30秒以上の止まり                 0                   2                   9
   （1往復あたり）                 0                   0.031               0.087
  動けなくなった（60秒）           0                   1                   7
  卓を空けた（逃がし弁）           0                   1                   3
  瞬間移動                         12                  47                  45
  打ち切り                         0                   0                   5
  （参考）あきらめた               0                   28                  47
  （参考）冷めた皿の割合           0.011 / 0           0.309 / 0.125       0.270 / 0.026
  （参考）待機場所へ戻った／出た   0 / 0               65 / 65             99 / 100（戻れず受け渡し口へ 0）

  目立つ点（差の理由は調べていない。依頼のとおり）
    ・入れた組の数が3回とも 71 組で、試算（91〜95 組）より少ない（④でも 48 対 56 だった）
    ・会計待ちは Unity 2.4〜3.4 分で、試算の 13〜19 分のような「レジが詰まる」形にはならなかった
      （入れた組が少ないことと関わっていそう）
    ・0台の回でも瞬間移動が 12 ある

  2台の回の 30 秒以上の止まり（9 回）の場所
    受け渡し口の点 (12.5, 8.85) から 2.5 m 以内        2 回（もう1台のロボット 1・スタッフとすれ違った 1）
     うち待機場所での止まりを除いた数                  2 回
       （待機場所＝店の形の RobotStandby の四角：x 14.2〜15.0・15.0〜15.8・15.8〜16.6、y 8.55〜9.35。
        この四角の中での止まりは 0）
    入口・レジの前（y 3.4 m より下・x 9.3〜16.4 m）     0 回
    理由ごと（9 回）：スタッフとすれ違った 5・人が立ち止まっていた 3・もう1台のロボット 1


====================================================================
6. 台帳
====================================================================

  行数：565 → 568（3 行足した。追記だけ。3行とも unity_cs ServiceSim/cs:36・layout_generation d7bb919590d4）
  先頭 565 行の md5：7f636cb533be1ee07caabb8782455f15（退避と同じ）
  列は今までどおり（新しい3行は 59 列）。鍵ファイルは残っていない


====================================================================
7. make_queue（台帳には書いていない）
====================================================================

  --stores fam_p3 --seeds 0 --label p3check → fam_p3_s4_r{0,1,2}_a46 の 3 回
    （0台 trays 1・1台と2台 trays 3・レジ 1・すれ違い入・待機場所へ戻る入・案B切）
  何も指定しない（cs:36 のあとで /tmp に作った）
    → fam_p1・fam_p5 × 0・1・2 台 × 種 0〜9 ＝ 60 回。
       night/20261102/queue.json（v5 の夜）と、回の並びと中身が同じ（label を除く）
  make_queue.py には --dry-run が無いので、/tmp に作って中身を見る形で確かめた。
  night_runner の dry-run は、night/ に記録フォルダができるので回していない。
  作業フォルダに queue の一時ファイルは置いていない（/tmp/p3c3/ にだけ作った）。最後の保留 0（cs:36 head）。


====================================================================
8. エイイチが画面で⑤を見る手順
====================================================================

  1. Unity Hub から ServiceSim（/Users/shimazueiichi/Robotics_UX/ServiceSim）を開き、
     シーン Assets/ServiceSim/Scenes/ServiceSim_Family.unity を開く
  2. 建てるだけで見る：ServiceSim → JSON Store → ⑤ p3_relaxed_center を建てて確かめる
  3. 回して見る：ServiceSim → Site Run → ⑤ スタッフ4人・ロボット0台 / 1台 / 2台
     Play に入って回り、終わると自動で抜ける。すれ違い入・待機場所へ戻る入・案B切（今の標準）。
     種は ExperimentPlan の trialSeed。出力は KIOXIA に出る（台帳には書かない）
  ※ 2台の回が、ロボット2台の動きをいちばん見やすい


====================================================================
9. 決めてほしいこと
====================================================================

  1. ⑤の夜を回すかどうか（依頼のとおり、本番の夜は回していない）。
  2. 入れた組の数が 71 組で、試算（91〜95 組）より少ない。会計待ちも試算のように詰まらなかった。
     このまま⑤の夜を回すか、先に理由を調べるか。
  3. スタッフが待つ点が2つ（2人ずつ同じ点）のまま続けるか。今回の結果で決める約束だった。
  4. 4 章の気づいたこと（細い通路 A01・A03 の焼いた面の幅、人用 NavMesh のつながっていない面 39 m2）を
     調べるかどうか。回には効いていないように見えるが、店の形のことなので、直すならサイトが先。
```

1回ずつ（種0）では、入れた組の数が3回とも71組で、試算の91〜95組より少なく出ました。会計待ちも2〜3分で、試算のようにレジが詰まりませんでした。種0は③⑦でも来る客が少ない種でした。理由を先に調べず、種10個の夜で見ることにしました。スタッフが待つ点が2つしかない件（4人で2つを分ける）と、建てたときの確かめで出た2つの表示（細い通路の幅、人用の歩ける面のつながっていない所）は、今は直さず記録だけにしました。


## 作業ログ ― ⑤を種10個ずつ回すと、詰まっていたのは片付けと案内だった

### 依頼文：⑤の夜を回す（20261028_20）

````markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 180
---
# 依頼：⑤の夜（30回）を回す（2026-10-28）

エイイチが「⑤の夜を回す」と決めた（2026-10-28 15:36）。⑤（fam_p3・店の形 d7bb919590d4）× ロボット0・1・2台 × 種0〜9、今の標準（すれ違い入・待機場所へ戻る 入・案B 切）。
依頼 19 の報告（20261028_1440_p3_build_check3.txt）の「決めてほしいこと」への答え：
- 1：回す（この依頼）
- 2：入れた組の数が71組と少ない件は、先に調べず、この夜の種10個で見る
- 3：スタッフが待つ点は2つ（2人ずつ同じ点）のまま
- 4：細い通路の幅の表示と、人用の NavMesh のつながっていない面は、今は直さず記録だけ

台帳の退避は Claude が済ませた。
- 退避先：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/archive/unity_ledger_v1_prenight_20261028_p3/unity_ledger_v1.csv
- 568 行・md5 7ecd602ae377cb6fd213f5cdc306ff8d

## 始める前に確かめること（1つでも違えば回さずに報告して終わる）

1. Unity エディタが起動していない（起動していたら閉じずに報告して終わる）
2. /Volumes/KIOXIA がマウントされている。鍵ファイル unity_ledger_v1.lock がない
3. 本物の台帳の md5 が上の退避と同じ
4. ServiceSim の保留が 0 で、実行ファイルの build_info が cs36_20261028_1435・保留なし

## 回す

作業フォルダで、次の2つを順に実行する。night_runner.py は終わるまで待つ。

```
python3 tools/make_queue.py --stores fam_p3 --out queue_p3.json
python3 tools/night_runner.py --queue queue_p3.json --parallel 4 --night 20261103 --record-name 20261103_p3
```

- 夜の名前は 20261103。記録は night/20261103_p3/ に置く。オプションの名前が違えば、同じ意味になるように合わせる
- 並ぶのは 30 回（⑤ × 0・1・2台 × 種0〜9・すれ違い入・待機場所へ戻る 入・案B 切）であることを、回す前に queue_p3.json で確かめる。30 回でなければ回さずに報告
- 回している間は、ほかの作業をしない。Assets・tools・設定ファイルを開かない・変えない。Unity を開かない
- Ctrl+C で止めない。途中で止まっても、同じ夜を回し直さない（そのまま報告する）
- 終わったら queue_p3.json を作業フォルダに残さない（night/20261103_p3/ に写しがあればそれでよい）

## 報告

依頼箱の結果に加えて、claude_code_reports に 20261103_night_p3.txt として書く（場所：~/Library/Mobile Documents/com~apple~CloudDocs/デスクトップ/ADAPT DESIGN/じぶんの/PixelstoMotors/デジタルツイン学習R2R2R/サービスロボット導入シミュレーション/unity/claude_code_reports/）。
- 始める前の確かめ4つの結果
- runner_log のまとめ（completed の回数・失敗・止まった回・最長の実時間）
- 台帳の行数（568 → 598 になるはず）と、先頭 568 行の md5 が退避と同じか
- 全員が帰らなかった回があれば、その回の名前（原因の調べはしない）
- 台数ごと（0・1・2台）の種10個の中央値と最小・最大：入店待ち・そのうち席は空いているのに待った時間・料理の待ち・会計待ち・入れた組の数・ロボットが運んだ皿の割合・往復の数・30秒以上の止まり（1往復あたり）・動けなくなった（60秒）・瞬間移動・打ち切り・卓を空けた・冷めた皿の割合。試算の値（params の site_result）も並べる
- 種ごとの入れた組の数（種0〜9。台数で変わらなければ1行でよい）と、試算の組の数（約93組）との比
- 2台の30秒以上の止まりを、理由ごと・場所ごと（受け渡し口の点から 2.5 m 以内／待機場所／入口・レジの前＝y が 3.4 m より下で x が 9.3〜16.4 m／スタッフが待つ点の近く 1.0 m 以内／そのほか）に、種10個の合計で
- ロボットを1台増やしたときの向き（入店待ち・料理の待ち）が、種の過半数で試算と同じか逆か（judge と同じ数え方）
- judge.md ができたか（⑤は基準がないので「基準なし」でよい。中身の判断はしない）
````

この依頼は、30回の途中で依頼箱の見張り係（Claude Code に依頼を渡す Mac の仕組み）を入れ替えたため、「失敗」の扱いになりました。30回を回す本体は止まらずに最後まで回り、台帳にも30行が足されました。書かれなかったのは Claude Code の報告だけなので、Claude が台帳と回の記録からまとめを書きました。

### 夜の実行ログ runner_log.txt

```text
2026-10-28 15:39:02  === 夜の実行係を始めます（night 20261103・同時 4 本・上限 90.0 分）===
2026-10-28 15:39:02  並べた回: queue_p3.json（30 回）
2026-10-28 15:39:02  台帳: /Volumes/KIOXIA/r2r2r-data/service_sim/unity/unity_ledger_v1.csv（59 列）
2026-10-28 15:39:02  版: ServiceSim/cs:36（Builds/headless/build_info.json）→ 出力フォルダの字 cs36
2026-10-28 15:39:02  並べた回の試算の版: v2.8 / 店の形の版: d7bb919590d4
2026-10-28 15:39:02  スリープを止めました（caffeinate pid 88774）
2026-10-28 15:39:02  並べた回を写しました: /Volumes/KIOXIA/r2r2r-data/service_sim/unity/night/20261103_p3/queue.json
2026-10-28 15:39:02  並べた回 30 / もう completed の回を飛ばす 0 / 回す 30
2026-10-28 15:39:02  始めました（1本目・同時 1）: fam_p3_s4_r0_a46 種0 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s0_passon_sbret（pid 88775）
2026-10-28 15:39:07  始めました（2本目・同時 2）: fam_p3_s4_r1_a46 種0 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s0_passon_sbret（pid 88793）
2026-10-28 15:39:12  始めました（3本目・同時 3）: fam_p3_s4_r2_a46 種0 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s0_passon_sbret（pid 88800）
2026-10-28 15:39:17  始めました（4本目・同時 4）: fam_p3_s4_r0_a46 種1 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s1_passon_sbret（pid 88802）
2026-10-28 15:42:33  おわり: 20261103_night_cs36_fam_p3_r0_s0_passon_sbret / completed / 終了コード 0 / 実時間 3.5 分
2026-10-28 15:42:33  始めました（5本目・同時 4）: fam_p3_s4_r1_a46 種1 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s1_passon_sbret（pid 88912）
2026-10-28 15:42:48  おわり: 20261103_night_cs36_fam_p3_r1_s0_passon_sbret / completed / 終了コード 0 / 実時間 3.7 分
2026-10-28 15:42:48  始めました（6本目・同時 4）: fam_p3_s4_r2_a46 種1 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s1_passon_sbret（pid 88917）
2026-10-28 15:43:18  おわり: 20261103_night_cs36_fam_p3_r2_s0_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 15:43:18  始めました（7本目・同時 4）: fam_p3_s4_r0_a46 種2 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s2_passon_sbret（pid 88942）
2026-10-28 15:43:28  おわり: 20261103_night_cs36_fam_p3_r0_s1_passon_sbret / completed / 終了コード 0 / 実時間 4.2 分
2026-10-28 15:43:28  始めました（8本目・同時 4）: fam_p3_s4_r1_a46 種2 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s2_passon_sbret（pid 88944）
2026-10-28 15:46:48  おわり: 20261103_night_cs36_fam_p3_r1_s1_passon_sbret / completed / 終了コード 0 / 実時間 4.3 分
2026-10-28 15:46:48  始めました（9本目・同時 4）: fam_p3_s4_r2_a46 種2 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s2_passon_sbret（pid 89092）
2026-10-28 15:47:33  おわり: 20261103_night_cs36_fam_p3_r2_s1_passon_sbret / completed / 終了コード 0 / 実時間 4.8 分
2026-10-28 15:47:33  始めました（10本目・同時 4）: fam_p3_s4_r0_a46 種3 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s3_passon_sbret（pid 89149）
2026-10-28 15:47:58  おわり: 20261103_night_cs36_fam_p3_r0_s2_passon_sbret / completed / 終了コード 0 / 実時間 4.7 分
2026-10-28 15:47:58  始めました（11本目・同時 4）: fam_p3_s4_r1_a46 種3 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s3_passon_sbret（pid 89173）
2026-10-28 15:48:23  おわり: 20261103_night_cs36_fam_p3_r1_s2_passon_sbret / completed / 終了コード 0 / 実時間 4.9 分
2026-10-28 15:48:23  始めました（12本目・同時 4）: fam_p3_s4_r2_a46 種3 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s3_passon_sbret（pid 89195）
2026-10-28 15:51:23  おわり: 20261103_night_cs36_fam_p3_r0_s3_passon_sbret / completed / 終了コード 0 / 実時間 3.8 分
2026-10-28 15:51:23  始めました（13本目・同時 4）: fam_p3_s4_r0_a46 種4 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s4_passon_sbret（pid 89339）
2026-10-28 15:52:03  おわり: 20261103_night_cs36_fam_p3_r1_s3_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 15:52:03  始めました（14本目・同時 4）: fam_p3_s4_r1_a46 種4 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s4_passon_sbret（pid 89361）
2026-10-28 15:52:53  おわり: 20261103_night_cs36_fam_p3_r2_s3_passon_sbret / completed / 終了コード 0 / 実時間 4.5 分
2026-10-28 15:52:53  始めました（15本目・同時 4）: fam_p3_s4_r2_a46 種4 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s4_passon_sbret（pid 89402）
2026-10-28 15:52:58  おわり: 20261103_night_cs36_fam_p3_r2_s2_passon_sbret / completed / 終了コード 0 / 実時間 6.2 分
2026-10-28 15:52:58  始めました（16本目・同時 4）: fam_p3_s4_r0_a46 種5 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s5_passon_sbret（pid 89413）
2026-10-28 15:55:53  おわり: 20261103_night_cs36_fam_p3_r0_s4_passon_sbret / completed / 終了コード 0 / 実時間 4.5 分
2026-10-28 15:55:53  始めました（17本目・同時 4）: fam_p3_s4_r1_a46 種5 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s5_passon_sbret（pid 89515）
2026-10-28 15:56:28  おわり: 20261103_night_cs36_fam_p3_r0_s5_passon_sbret / completed / 終了コード 0 / 実時間 3.5 分
2026-10-28 15:56:28  始めました（18本目・同時 4）: fam_p3_s4_r2_a46 種5 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s5_passon_sbret（pid 89533）
2026-10-28 15:56:33  おわり: 20261103_night_cs36_fam_p3_r1_s4_passon_sbret / completed / 終了コード 0 / 実時間 4.5 分
2026-10-28 15:56:33  始めました（19本目・同時 4）: fam_p3_s4_r0_a46 種6 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s6_passon_sbret（pid 89538）
2026-10-28 15:58:18  おわり: 20261103_night_cs36_fam_p3_r2_s4_passon_sbret / completed / 終了コード 0 / 実時間 5.4 分
2026-10-28 15:58:18  始めました（20本目・同時 4）: fam_p3_s4_r1_a46 種6 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s6_passon_sbret（pid 89595）
2026-10-28 15:59:58  おわり: 20261103_night_cs36_fam_p3_r1_s5_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 15:59:58  始めました（21本目・同時 4）: fam_p3_s4_r2_a46 種6 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s6_passon_sbret（pid 89675）
2026-10-28 16:00:59  おわり: 20261103_night_cs36_fam_p3_r2_s5_passon_sbret / completed / 終了コード 0 / 実時間 4.5 分
2026-10-28 16:00:59  始めました（22本目・同時 4）: fam_p3_s4_r0_a46 種7 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s7_passon_sbret（pid 89731）
2026-10-28 16:01:34  おわり: 20261103_night_cs36_fam_p3_r0_s6_passon_sbret / completed / 終了コード 0 / 実時間 5.0 分
2026-10-28 16:01:34  始めました（23本目・同時 4）: fam_p3_s4_r1_a46 種7 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s7_passon_sbret（pid 89755）
2026-10-28 16:03:19  おわり: 20261103_night_cs36_fam_p3_r1_s6_passon_sbret / completed / 終了コード 0 / 実時間 5.0 分
2026-10-28 16:03:19  始めました（24本目・同時 4）: fam_p3_s4_r2_a46 種7 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s7_passon_sbret（pid 89812）
2026-10-28 16:05:04  おわり: 20261103_night_cs36_fam_p3_r0_s7_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 16:05:04  始めました（25本目・同時 4）: fam_p3_s4_r0_a46 種8 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s8_passon_sbret（pid 89921）
2026-10-28 16:05:54  おわり: 20261103_night_cs36_fam_p3_r2_s6_passon_sbret / completed / 終了コード 0 / 実時間 5.9 分
2026-10-28 16:05:54  おわり: 20261103_night_cs36_fam_p3_r1_s7_passon_sbret / completed / 終了コード 0 / 実時間 4.3 分
2026-10-28 16:05:54  始めました（26本目・同時 3）: fam_p3_s4_r1_a46 種8 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s8_passon_sbret（pid 89974）
2026-10-28 16:05:59  始めました（27本目・同時 4）: fam_p3_s4_r2_a46 種8 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s8_passon_sbret（pid 89982）
2026-10-28 16:08:09  おわり: 20261103_night_cs36_fam_p3_r2_s7_passon_sbret / completed / 終了コード 0 / 実時間 4.8 分
2026-10-28 16:08:09  始めました（28本目・同時 4）: fam_p3_s4_r0_a46 種9 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r0_s9_passon_sbret（pid 90089）
2026-10-28 16:09:09  おわり: 20261103_night_cs36_fam_p3_r0_s8_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 16:09:09  始めました（29本目・同時 4）: fam_p3_s4_r1_a46 種9 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r1_s9_passon_sbret（pid 90153）
2026-10-28 16:10:19  おわり: 20261103_night_cs36_fam_p3_r1_s8_passon_sbret / completed / 終了コード 0 / 実時間 4.4 分
2026-10-28 16:10:19  始めました（30本目・同時 4）: fam_p3_s4_r2_a46 種9 すれ違い入 決まり案B切 待機場所へ戻る入 → 20261103_night_cs36_fam_p3_r2_s9_passon_sbret（pid 90189）
2026-10-28 16:10:54  おわり: 20261103_night_cs36_fam_p3_r2_s8_passon_sbret / completed / 終了コード 0 / 実時間 4.9 分
2026-10-28 16:12:24  おわり: 20261103_night_cs36_fam_p3_r0_s9_passon_sbret / completed / 終了コード 0 / 実時間 4.3 分
2026-10-28 16:13:14  おわり: 20261103_night_cs36_fam_p3_r1_s9_passon_sbret / completed / 終了コード 0 / 実時間 4.1 分
2026-10-28 16:14:09  おわり: 20261103_night_cs36_fam_p3_r2_s9_passon_sbret / completed / 終了コード 0 / 実時間 3.8 分
2026-10-28 16:14:09  --- まとめ ---
2026-10-28 16:14:09    completed: 30 回
2026-10-28 16:14:09    completed の実時間: 平均 4.5 分 / 最長 6.2 分
2026-10-28 16:14:09  判定を呼びます（/Volumes/KIOXIA/r2r2r-data/service_sim/unity で）: /opt/homebrew/Caskroom/miniforge/base/bin/python3 /Users/shimazueiichi/Robotics_UX/ServiceSim/tools/judge_night.py --runs 20261103_night_* --out night/20261103_p3 --label-prefix 20261103_night
2026-10-28 16:14:10  判定を書きました: /Volumes/KIOXIA/r2r2r-data/service_sim/unity/night/20261103_p3/judge.md
2026-10-28 16:14:10  スリープの設定を戻しました
2026-10-28 16:14:10  === 夜の実行係を終わります（終了コード 0）===
```

### 判定 judge.md

```markdown
# 夜の結果の振り分け（20261103_night_*）

基準データ: 20261102_night_cs34_*（60回）／振り分けた回: 30回

切り替えの入切（条件の一部。同じ入切の基準の回とだけ比べる）: 今回 すれ違い入・待機場所へ戻る入・案B切／基準 すれ違い入・待機場所へ戻る入・案B切

| 振り分け | 回数 |
|---|---|
| 正常 | 0 |
| 試算を見直す候補 | 0 |
| Unity の作り | 0 |
| 回の失敗 | 0 |
| 基準なし | 30 |

## 回の失敗

- なし

## 基準なし（基準データに同じ条件・同じ入切の回がないので判定していない）

- fam_p3 スタッフ4 ロボット0台・すれ違い入・待機場所へ戻る入・案B切
- fam_p3 スタッフ4 ロボット1台・すれ違い入・待機場所へ戻る入・案B切
- fam_p3 スタッフ4 ロボット2台・すれ違い入・待機場所へ戻る入・案B切

## Unity の作り（種の中央値が、基準の同じ条件の最大を超えた）

- なし

## 試算を見直す候補

### ロボットを増やしたときの向きが、種の過半数で試算と逆

- なし

### Unity÷試算 の大きさが、基準の同じ条件の範囲から外れた

- なし

## 記録（印にしない）：試算との差の大きさ（条件ごとの種の中央値・Unity÷試算）

| 条件 | 種の数 | 入店待ち | 料理の待ち | 席は空いているのに待った |
|---|---|---|---|---|
| fam_p3 スタッフ4 ロボット0台・すれ違い入・待機場所へ戻る入・案B切 | 10 | 1.31 | 1.96 | 4.35 |
| fam_p3 スタッフ4 ロボット1台・すれ違い入・待機場所へ戻る入・案B切 | 10 | 1.93 | 1.21 | 5.94 |
| fam_p3 スタッフ4 ロボット2台・すれ違い入・待機場所へ戻る入・案B切 | 10 | 1.49 | 1.77 | 4.95 |

## すれ違い 入 と 切 の比べ（同じ夜・同じ条件・種の中央値。印にしない）

| 条件 | 入店待ち | 料理の待ち | 席は空いているのに待った | 動けなくなった | あきらめた | ロボットが運んだ割合 |
|---|---|---|---|---|---|---|
| fam_p3 スタッフ4 ロボット0台・すれ違い切・待機場所へ戻る入・案B切（0回） | - | - | - | - | - | - |
| fam_p3 スタッフ4 ロボット0台・すれ違い入・待機場所へ戻る入・案B切（10回） | 8.14 | 1.12 | 6.50 | 0.00 | 2.00 | 0.00 |
| fam_p3 スタッフ4 ロボット1台・すれ違い切・待機場所へ戻る入・案B切（0回） | - | - | - | - | - | - |
| fam_p3 スタッフ4 ロボット1台・すれ違い入・待機場所へ戻る入・案B切（10回） | 6.60 | 2.59 | 4.56 | 1.00 | 32.50 | 0.67 |
| fam_p3 スタッフ4 ロボット2台・すれ違い切・待機場所へ戻る入・案B切（0回） | - | - | - | - | - | - |
| fam_p3 スタッフ4 ロボット2台・すれ違い入・待機場所へ戻る入・案B切（10回） | 5.46 | 2.19 | 3.41 | 11.50 | 79.50 | 0.82 |

線: 立ち往生 30秒以上の止まり／向きは 5%・0.2分より小さい変化を数えない／外れは基準の同じ条件の最小〜最大
```

### まとめたスクリプト night_p3_summary.py

```python
"""⑤の夜（20261103_night_cs36・30回）を台帳と回の記録からまとめる（2026-10-28。Claude Code の報告が書かれなかったため Claude が書いた）
使い方: cd /Volumes/KIOXIA/r2r2r-data/service_sim/unity && python3 night_p3_summary.py"""
import csv, statistics as S, os, collections
r = [x for x in csv.DictReader(open('unity_ledger_v1.csv')) if x['run_folder'].startswith('20261103_night_cs36')]
print(len(r), collections.Counter(x['status'] for x in r), 'everyone_left', collections.Counter(x['everyone_left'] for x in r))
def f(v): return float(v) if v not in ('', None) else None
def m(xs):
    xs = [a for a in xs if a is not None]
    return f"{S.median(xs):.2f}({min(xs):.2f}〜{max(xs):.2f})" if xs else '-'
cols = [('entry_wait_mean', '入店待ち', 'site_entry_wait_mean'), ('staff_wait_mean', '席空き待ち', 'site_staff_wait_mean'),
        ('dish_wait_mean', '料理の待ち', 'site_dish_wait_mean'), ('pay_wait_mean', '会計待ち', 'site_pay_wait_mean'),
        ('robot_share', '運んだ割合', 'site_robot_share'), ('trips', '往復', None), ('stuck_count', '60秒', None),
        ('warped', '瞬間移動', None), ('timeouts', '打切', None), ('table_freed', '卓空け', None), ('cold_share', '冷めた', None)]
for x in r:
    x['groups'] = sum(1 for _ in open(os.path.join(x['run_folder'], 'groups.csv'))) - 1
for rb in '012':
    xs = [x for x in r if x['robots'] == rb]
    print(f'## {rb}台 n={len(xs)}')
    for c, l, s in cols:
        print(f"  {l}: {m([f(x[c]) for x in xs])}" + (f"  試算 {f(xs[0][s]):.2f}" if s and xs[0][s] else ''))
    print('  組:', m([x['groups'] for x in xs]))
print('種ごとの組:', {x['seed']: x['groups'] for x in r if x['robots'] == '0'})
cnt = collections.Counter(); causes = collections.Counter(); grid = collections.Counter(); gc = collections.Counter()
for x in r:
    if x['robots'] != '2':
        continue
    for s in csv.DictReader(open(os.path.join(x['run_folder'], 'stops.csv'))):
        if float(s['duration_s']) < 30:
            continue
        X, Y = float(s['x']), float(s['z'])
        if 14.2 <= X <= 16.6 and 8.55 <= Y <= 9.35: w = '待機場所'
        elif ((X - 12.5) ** 2 + (Y - 8.85) ** 2) ** .5 <= 2.5: w = '受け渡し口2.5m'
        elif Y < 3.4 and 9.3 <= X <= 16.4: w = '入口・レジ前'
        elif min(((X - 7.25) ** 2 + (Y - 10) ** 2) ** .5, ((X - 17.75) ** 2 + (Y - 10) ** 2) ** .5) <= 1.0: w = 'スタッフ待つ点'
        else: w = 'そのほか'
        cnt[w] += 1; causes[s['cause']] += 1
        k = (int(X // 2) * 2, int(Y // 2) * 2); grid[k] += 1; gc[(k, s['cause'])] += 1
print('2台30秒以上:', dict(cnt), dict(causes))
for k, v in grid.most_common(10):
    print(' ', k, v, [(c, n) for (kk, c), n in gc.items() if kk == k])
```

### night_p3_summary.py の出力

```text
30 Counter({'completed': 30}) everyone_left Counter({'1': 30})
## 0台 n=10
  入店待ち: 8.14(1.79〜20.07)  試算 6.22
  席空き待ち: 6.50(0.63〜11.73)  試算 1.50
  料理の待ち: 1.12(0.98〜1.23)  試算 0.57
  会計待ち: 5.72(2.37〜7.44)  試算 18.81
  運んだ割合: 0.00(0.00〜0.00)  試算 0.00
  往復: 0.00(0.00〜0.00)
  60秒: 0.00(0.00〜0.00)
  瞬間移動: 10.00(6.00〜19.00)
  打切: 0.00(0.00〜0.00)
  卓空け: 0.00(0.00〜0.00)
  冷めた: 0.00(0.00〜0.02)
  組: 91.50(71.00〜110.00)
## 1台 n=10
  入店待ち: 6.60(1.59〜16.59)  試算 3.42
  席空き待ち: 4.56(0.38〜7.45)  試算 0.77
  料理の待ち: 2.59(2.40〜2.78)  試算 2.14
  会計待ち: 7.17(2.98〜8.63)  試算 12.95
  運んだ割合: 0.67(0.62〜0.75)  試算 0.69
  往復: 68.00(59.00〜80.00)
  60秒: 1.00(0.00〜6.00)
  瞬間移動: 48.00(34.00〜56.00)
  打切: 0.00(0.00〜0.00)
  卓空け: 0.50(0.00〜6.00)
  冷めた: 0.35(0.32〜0.43)
  組: 91.50(71.00〜110.00)
## 2台 n=10
  入店待ち: 5.46(1.81〜20.45)  試算 3.67
  席空き待ち: 3.41(0.53〜11.50)  試算 0.69
  料理の待ち: 2.19(1.95〜3.46)  試算 1.24
  会計待ち: 6.98(3.87〜12.27)  試算 13.00
  運んだ割合: 0.82(0.71〜0.90)  試算 0.98
  往復: 132.50(97.00〜160.00)
  60秒: 11.50(2.00〜30.00)
  瞬間移動: 62.00(45.00〜81.00)
  打切: 4.00(1.00〜13.00)
  卓空け: 3.00(1.00〜6.00)
  冷めた: 0.25(0.18〜0.33)
  組: 91.50(71.00〜110.00)
種ごとの組: {'0': 71, '1': 94, '2': 110, '3': 85, '4': 101, '5': 83, '6': 107, '7': 89, '8': 89, '9': 98}
2台30秒以上: {'受け渡し口2.5m': 5, 'そのほか': 117, 'スタッフ待つ点': 8, '待機場所': 51, '入口・レジ前': 3} {'もう1台のロボット': 94, 'スタッフとすれ違った': 39, 'お客さんとすれ違った': 14, '人が立ち止まっていた': 33, '分からない': 4}
  (14, 8) 53 [('スタッフとすれ違った', 4), ('もう1台のロボット', 37), ('人が立ち止まっていた', 9), ('分からない', 2), ('お客さんとすれ違った', 1)]
  (4, 2) 21 [('もう1台のロボット', 21)]
  (8, 2) 17 [('もう1台のロボット', 12), ('お客さんとすれ違った', 1), ('分からない', 1), ('人が立ち止まっていた', 2), ('スタッフとすれ違った', 1)]
  (20, 2) 16 [('人が立ち止まっていた', 5), ('スタッフとすれ違った', 5), ('もう1台のロボット', 5), ('お客さんとすれ違った', 1)]
  (6, 2) 11 [('もう1台のロボット', 8), ('スタッフとすれ違った', 2), ('お客さんとすれ違った', 1)]
  (6, 8) 10 [('スタッフとすれ違った', 5), ('お客さんとすれ違った', 2), ('人が立ち止まっていた', 3)]
  (4, 12) 8 [('お客さんとすれ違った', 3), ('スタッフとすれ違った', 5)]
  (2, 12) 6 [('スタッフとすれ違った', 4), ('分からない', 1), ('人が立ち止まっていた', 1)]
  (12, 8) 5 [('もう1台のロボット', 2), ('スタッフとすれ違った', 2), ('人が立ち止まっていた', 1)]
  (2, 6) 5 [('スタッフとすれ違った', 2), ('人が立ち止まっていた', 3)]
```

### まとめ：20261103_night_p3.txt

```text
⑤の夜（20261103_p3・30回）のまとめ — Claude が台帳と回の記録から書いた（2026-10-28 16:20）

Claude Code の報告がない理由：回している途中（16:04）に見張り係を入れ替えたため、依頼 20 は「失敗」扱いになり、
Claude Code の報告は書かれなかった。night_runner は止まらず最後まで回った（30回とも completed・終了コード 0・全員帰った）。
台帳 568 → 598 行。判定 judge.md は night/20261103_p3/ にある（⑤は基準なし）。
版：cs36_20261028_1435・店の形 d7bb919590d4・試算 v2.8・すれ違い入・待機場所へ戻る 入・案B 切・スタッフ4人・46組/時・レジ1つ

種10個の中央値（最小〜最大）／試算
              0台                      1台                      2台
入店待ち      8.14(1.79〜20.07)/6.22    6.60(1.59〜16.59)/3.42    5.46(1.81〜20.45)/3.67
席空き待ち    6.50(0.63〜11.73)/1.50    4.56(0.38〜7.45)/0.77     3.41(0.53〜11.50)/0.69
料理の待ち    1.12(0.98〜1.23)/0.57     2.59(2.40〜2.78)/2.14     2.19(1.95〜3.46)/1.24
会計待ち      5.72(2.37〜7.44)/18.81    7.17(2.98〜8.63)/12.95    6.98(3.87〜12.27)/13.00
運んだ割合    0/0                      0.67(0.62〜0.75)/0.69     0.82(0.71〜0.90)/0.98
往復          0                        68(59〜80)               132.5(97〜160)
動けなくなった(60秒) 0                  1(0〜6)                  11.5(2〜30)
瞬間移動      10(6〜19)                48(34〜56)               62(45〜81)
打ち切り      0                        0                        4(1〜13)
卓を空けた    0                        0.5(0〜6)                3(1〜6)
冷めた皿      0.00                     0.35                     0.25

入れた組の数（種0〜9。台数で同じ）：71, 94, 110, 85, 101, 83, 107, 89, 89, 98（中央値 91.5。試算 約93）
→ 依頼 19 で71組と少なかったのは種0だけのこと

2台の30秒以上の止まり（種10個の合計 184）
  場所：待機場所 51／受け渡し口の点から2.5m以内 5／入口・レジの前 3／スタッフが待つ点の近く 8／そのほか 117
  理由：もう1台のロボット 94／スタッフとすれ違った 39／人が立ち止まっていた 33／お客さんとすれ違った 14／分からない 4
  2m四方のマスで多い所：x14〜16・y8〜10（待機場所のまわり）53（うちロボットどうし37）／
    左下の6人席の前の通路 x4〜10・y2〜4 で計49（うちロボットどうし41）／右下の6人席の前 x20〜22・y2〜4 16
```

### 来る客の数は試算と同じで、71組は種0だけだった

入れた組の数は、種0〜9で71〜110組、中央値91.5組でした。試算は約93組です。1回目の確かめで少なく見えたのは、種0がたまたま少ない種だったためです。

### ロボットを足すと待ちが縮む向きは、試算と同じだった

入店待ちは、ロボット0台8.1分→1台6.6分→2台5.5分と縮みました。試算は6.2→3.4→3.7分です。料理の待ちは、0台1.1分→1台2.6分→2台2.2分で、1台のときに延びて2台で戻る形が試算（0.6→2.1→1.2分）と同じでした。④では「ロボットを足すと入店待ちが延びる」逆の向きが出ましたが、⑤では出ませんでした。

### 試算はレジで詰まり、3Dの店は片付けと案内で詰まる

試算では会計待ちが13〜19分で、店が詰まる所はレジです。3Dの店の会計待ちは6〜7分で、レジは詰まっていません。代わりに、席は空いているのに案内を待った時間が、0台6.5分（試算1.5分）・1台4.6分（0.8分）・2台3.4分（0.7分）と長くなりました。

これは③⑦（42卓）で見たずれと同じ形です。③⑦では、3Dの店のスタッフは1組あたりの仕事が試算より1割ほど長く、ピークでスタッフ4人の手がすべてふさがり、いちばん後回しの片付けがたまっていました。試算はピークでスタッフの手が95%ふさがっているので、1割長いだけで手が足りなくなります。46卓の⑤でも、同じことが起きていると見ています。試算の歩く距離は「受け渡し口から卓まで」で、案内（入口から卓）と片付け（卓から洗い場）の道のりを数えていないことが、ずれの元の1つです。このずれは、③⑦のときに決めたとおり、試算には入れず記録して調べる対象にしています。

### 2台のときに残った詰まりは、待機場所のまわりと左下の通路

2台の回の30秒以上の止まりは、種10個の合計で184回でした。入口・レジの前は3回で、直した所では詰まっていません。残った詰まりは2か所です。

| 場所 | 30秒以上の止まり | そのうちロボットどうし |
|---|---|---|
| 待機場所のまわり（受け渡し口の右） | 53回 | 37回 |
| 左下の6人席の前の通路 | 49回 | 41回 |
| 右下の6人席の前 | 16回 | 5回 |

待機場所のまわりは、③⑦でも見た形です。左下の6人席の前の通路は、6人席の天板（y=1.8m）と島の下の端（y=3.4m）の間の1.6mの通路で、ここでロボット2台が正面から出会っています。2台の回では打ち切りが中央値4回（1〜13回）あり、ロボットが運んだ皿の割合は0.82で、試算の0.98に届いていません。


## 作業ログ ― ⑤はここで区切り、⑥へ進む

④と同じく、⑤もここで区切りにしました。残った2か所の詰まりは直し続けず、記録して調べる対象にします。直すなら、店の形（サイト）を先に直します。次は⑥（ゆったり型・入口が左の壁）に広げます。

⑤で決めたことと、残したことは次のとおりです。

| 決めたこと・残したこと | 中身 |
|---|---|
| 基準データ v5 | 夜 20261102（③⑦・すれ違い入・待機場所へ戻る入・案B切・60回）。判定の既定を v5 にした |
| ⑤の店の形 | 島を2段に、右の壁ぞいを8卓に、キッチン側を左へ1.5m。版 d7bb919590d4 |
| 細い通路の入口の点 | 両端とも行けないときだけ、通路の中へ戻して置く（サイトの作り方の決まり） |
| スタッフが待つ点 | ⑤は2つ（4人で2つを分ける）のまま |
| 記録だけにしたもの | 試算＝レジ・3Dの店＝片付けと案内、という詰まる所のずれ。⑤の待機場所のまわりと左下の通路の詰まり。建てたときの2つの表示 |
