====================================================================
依頼90：下げ膳にも使う（mode bus）を Unity に入れ、120回で確かめ、比較動画の素材を撮る
2026-11-04 07:00〜08:45　作業場所 cs:76 → cs:77　build_id cs77_20261104_0746（画面なし・保留 0）
====================================================================

結論
  ・下げ膳を入れた（cs:77）。serve の回は base73 と記録が一致、bus の同じ種の2回も一致、120回で瞬間移動 0・1コマの跳び 0
  ・しかし 120 回のうち 4 回（③2台 種2・④2台 種4・④2台 種9・⑥2台 種4）で店が止まり、全員が帰らなかった
    （回の上限 720 分まで回った）。解けずに残った詰まり 53 件（serve の同じ 120 回は 1 件）
  ・止まった元は、下げ膳で卓に着いたロボットがスタッフの来るのを時間の上限なく待つこと。助けの決まりは
    「卓で受け渡し中の台は動かさない」なので、その台がもう1台のロボットやスタッフの道をふさぐと解けない
  ・直すには決まりを足す必要があり、それはエイイチが決めることなので、ここで止めた。比較動画の素材（4）は撮っていない
    （録画の用意だけした。下の 6 章）

--------------------------------------------------------------------
0. 始める前の確かめ（どれも依頼どおり）
--------------------------------------------------------------------
  Unity エディタ・night_runner・rec_runner：動いていない（Unity Hub だけ）／KIOXIA：マウント済み／unity_ledger_v1.lock：無し／
  保留 0／作業場所 cs:76 - head
  サイトの params：手元に p2m-site の clone が無かったので、git pull のかわりに gh api で GitHub の main（31f3d3c。params を変えたコミットは
    41e9364「Unity の条件に下げ膳にも使う（mode bus）を12条件足す（120〜131番）」）から取った。132 条件・meta.bus あり。
    https://pixelstomotors.com/sim/serving-robot-params.json と md5 が同じ（c07e6c256afc1659a733d3562fa28f7c）
    前の写し（cs:76）との違いは meta.bus と 120〜131 番だけ（0〜119 番・common・unity_rules・stores は同じ）。店の形の md5 も同じ
  台帳を archive/unity_ledger_v1_pre_bus90_20261104/ に退避（2681 行・md5 c25f3f880430ef92cb70dc2d141aa803）

--------------------------------------------------------------------
1. 入れたこと（cs:77）
--------------------------------------------------------------------
  サイトの決まり（meta.bus・試算 v2.4 の bus()）と同じにした。条件の mode が bus の回だけ働く
  ・スタッフが片付けを仕事板から取ったとき、空いているロボットがいれば一緒に卓へ向かわせる。
    空いている＝往復していない（待機・往復おわり）・押されていない・下げ膳中でない・受け渡し口に積める料理が無い
    （料理はロボット最優先。試算でも料理を待つロボットの頼みがあればロボットは空いていない）。いなければ今までどおり人だけ
  ・スタッフ：卓で clear_s → ロボットが着くのを待つ → load_s で載せる → wipe_s。待つ・載せる・拭くは歩かずその場で、あきらめ・交代はしない
  ・ロボット：待機場所からそのまま卓へ（積む料理が無いので受け渡し口には寄らない）→ 卓で載せ終えるまで待つ（Dwell）→
    洗い場へ → load_s で下ろす（Dwell）→ 待機場所へ戻る（待機場所へ戻るが入の回。道が引けなければそこで往復を終え、今までどおり下がる）
  ・値は params から：clear_s 40・wipe_s 40・load_s 15（common）。下ろす時間は load_s を使った
    （試算のコードでは「15」と数字で書いてある。値は同じ）
  ・見張り（10秒で0.5m）・助け・瞬間移動なしは料理の往復と同じ作りのまま。卓で待つ・洗い場で下ろすは Dwell なので見張らない。
    待ったあと走り出すときは見張りを始め直す
  ・仕事の優先順（救出0 → 配膳・案内・会計・呼び出し1 → 片付け2）・料理は2分でスタッフ、は変えていない

  試しの回（/tmp。台帳に書いていない）で動けなくなったので、次の3つを足した（どれも bus の回だけ働く。決めてほしいこと 2）
   a. 卓で待っている下げ膳の台は、人の「細い通路にロボットがいたら入口で待つ」の相手にしない
      （待つと、台はスタッフを待ち、スタッフは台を待つ。試し ④2台 種1 で回の上限まで止まった）
   b. 片付けのスタッフがもう卓にいれば、台はそのスタッフから 1.2 m 以内で卓に着いたとみる
      （1.2 m＝台の半径 0.25＋前のセンサー 0.6＋人の半径 0.2＋余裕 0.15。スタッフは卓の止まる点に立っているので、台はセンサーで
       0.6 m 手前に止まり、スタッフは止まっている台には譲らない。試し ②2台 種8 で卓を強引に空ける 600 秒まで待った）。
      同じように、スタッフも卓で待つ自分の台の 0.85 m 以内まで来たら着いたとみる
   c. 卓で止まって待っている自分の台だけは、片付けのスタッフがよけない（台が動いているあいだは今までどおり譲る）
  記録（bus の回だけ。serve の回は今までと同じファイル・同じ列）
   ・timeline.csv のいちばん後ろに robots_bussing（下げ膳をしている台数。卓へ向かう〜待機場所に戻るまで）。staff_clear は今のまま
   ・bus_runs.csv（下げ膳1回ずつ：向かった・卓に着いた・載せ終えた・洗い場に着いた・下ろした・終わった時刻、スタッフのそばで着いたか）
   ・bus_summary.json（片付けの数・ロボットが運んだ数・人だけ・ロボットが下げ膳を運んだ割合＝試算の robot_bus_share と同じ式）
   ・trips.csv には下げ膳の往復も皿 0 の行で入る（台帳の trips の数にも入る）
  名前：bus の条件は fam_p1_s4_r2_a42_bus のように _bus を付けた（serve と名前がぶつかるため）。出力フォルダも最後に _bus。
    tools/night_runner.py・make_queue.py も同じに直し、make_queue に --mode serve|bus（既定 serve）を足した。
    serve の並べ方は前と同じ（base73 の 180 回の queue と、作り直した queue が1字も違わないことを確かめた）

  洗い場の止まる点の決め方
   店の形（public/sim/layouts/unity/*.json）の places に DishReturn がある（6店とも）。その点はロボット用の点として読まれていて、
   店の形の決まり（meta.rules）に「下げ膳の返却口は受け渡し口と同じ点（試算の dish_extra_m=0 と同じ前提）」とある。
   店の形に点があるので、新しくは置かず、その点（＝受け渡し口の点。③ (15.3, 5.95) など）を使った。店の形の JSON は変えていない

--------------------------------------------------------------------
2. 変えたファイル・版
--------------------------------------------------------------------
  cs:77：Service/ServiceOps.cs・Service/ServiceSpec.cs・Robot/ServingRobotController.cs・People/StaffAgent.cs・People/PersonRobotYield.cs・
         Experiment/ExperimentRunner.cs・Experiment/HeadlessRun.cs・Experiment/SimParams.cs・Experiment/SiteValues.cs・
         Experiment/TimelineLogger.cs・Experiment/serving-robot-params.json（サイトの写しに替えた）・tools/night_runner.py・tools/make_queue.py
  実行ファイル：Builds/headless　build_id cs77_20261104_0746・unity_cs ServiceSim/cs:77・pending_changes 空・error CS 0
  録画用：Builds/rec19_bus90（Builds/headless の写し。md5 291677dfbc64f53edd3e59476d1cc7a8）
  params の控え：unity/site_copy_9b8dae7ebf8c_bus90/（params・README.txt）
  （check-in の前に /tmp/req90/try1〜try5 に試しのビルドを作り、書き先を /tmp に向けて回した。その一時の直しと調べ用の記録は
   check-in の前に外した）

--------------------------------------------------------------------
3. 2つの一致の確かめ（cs:77）
--------------------------------------------------------------------
  ・serve が変わっていない：⑦ fam_p5・2台・種7（det90s）と base73（cs:76）の同じ回
    contacts・dishes・give_ups・groups・nowarp_jams・passes・people_jams・requeues・rescues・robot_track・stops・timeline・yields は1行も違わない。
    trips.csv は plan_ms_max の列だけ、summary.json・conditions.json は written_at だけ、run_info.json は版・回の名前・時刻・実時間の欄と
    plan_ms_max_per_trip（道を引くのにかかった実時間）だけ違う。→ 一致（依頼86 と同じ扱い）
  ・bus の同じ種で同じ結果：③ fam_p1・2台・bus・種7 を2回（det90a・det90b）。上の13ファイル・bus_runs.csv・bus_summary.json・
    summary.json・conditions.json が一致。違うのは run_info.json の回の名前・時刻・実時間・plan_ms_max_per_trip と trips.csv の plan_ms_max だけ → 一致

--------------------------------------------------------------------
4. 120回（label bus74・同時4本・条件 120〜131 × 種0〜9）
--------------------------------------------------------------------
  120 回とも completed（やり直し 0）。実時間 1〜数分。07:49〜08:34。瞬間移動の止める線には当たっていない
  記録：night/20261104_bus74_cs77/（queue・runner_log・judge.md・agg90.py・agg90_out.txt・cmp.py・watch90.py・watch_log.txt）

全体（同じ店・台数・種どうし）	serve（base73・cs:76）	bus（bus74・cs:77）
回の数	120	120
瞬間移動	0	0
1コマの跳び	0	0
解けずに残った詰まり（件）	1	53
同（回）	1	4
全員が帰ったあとに始まった詰まり（件）	0	0
全員が帰らなかった回	[]	[('③', 2, 2), ('④', 2, 4), ('④', 2, 9), ('⑥', 2, 4)]
詰まり（回）	2215	2565
詰まり（秒）	133086	1567741
卓を強引に空けた	32	30
助け	2243	2674

  下げ膳の中身（120 回の合計）：片付け 8316・ロボットが運んだ 2496・人だけ 5820・ロボットが向かった 2514・載せる前に取りやめ 10・
    スタッフのそばで卓に着いたとみた 1485

店・台数ごと（種 0〜9 の中央値。分・km・割合。向き＝serve→bus の増減、＋は増える）
店 台数	項目	Unity serve→bus（向き）	試算 serve→bus（向き）	合う？
③1台	入店待ち	3.47→3.47（＝）	1.68→1.72（＋）	逆
③1台	料理の待ち	2.45→2.50（＋）	1.97→2.03（＋）	合う
③1台	卓が使えるまで(turn)	4.97→5.11（＋）	2.27→2.27（－）	逆
③1台	スタッフ1人の歩いた距離km	2.72→2.63（－）	1.88→1.86（－）	合う
③1台	ロボットが下げ膳を運んだ割合	0.150	試算 0.165	（記録）
③2台	入店待ち	2.72→3.61（＋）	1.13→2.22（＋）	合う
③2台	料理の待ち	1.71→1.82（＋）	0.96→1.08（＋）	合う
③2台	卓が使えるまで(turn)	4.05→5.58（＋）	2.14→2.00（－）	逆
③2台	スタッフ1人の歩いた距離km	2.54→2.35（－）	1.61→1.45（－）	合う
③2台	ロボットが下げ膳を運んだ割合	0.354	試算 0.442	（記録）
⑦1台	入店待ち	3.87→3.87（＝）	1.58→1.53（－）	逆
⑦1台	料理の待ち	2.51→2.51（＋）	2.01→2.04（＋）	合う
⑦1台	卓が使えるまで(turn)	6.47→6.59（＋）	2.31→2.27（－）	逆
⑦1台	スタッフ1人の歩いた距離km	2.74→2.63（－）	1.97→1.90（－）	合う
⑦1台	ロボットが下げ膳を運んだ割合	0.145	試算 0.166	（記録）
⑦2台	入店待ち	3.87→5.07（＋）	1.60→1.70（＋）	合う
⑦2台	料理の待ち	1.52→1.83（＋）	1.01→1.10（＋）	合う
⑦2台	卓が使えるまで(turn)	4.49→6.79（＋）	2.19→2.04（－）	逆
⑦2台	スタッフ1人の歩いた距離km	2.55→2.37（－）	1.69→1.47（－）	合う
⑦2台	ロボットが下げ膳を運んだ割合	0.386	試算 0.443	（記録）
④1台	入店待ち	11.02→11.38（＋）	4.81→4.85（＋）	合う
④1台	料理の待ち	1.79→1.95（＋）	1.29→1.38（＋）	合う
④1台	卓が使えるまで(turn)	19.72→19.41（－）	9.51→9.43（－）	合う
④1台	スタッフ1人の歩いた距離km	2.37→2.17（－）	1.75→1.64（－）	合う
④1台	ロボットが下げ膳を運んだ割合	0.298	試算 0.274	（記録）
④2台	入店待ち	18.66→16.70（－）	5.57→3.86（－）	合う
④2台	料理の待ち	1.98→3.03（＋）	0.47→0.57（＋）	合う
④2台	卓が使えるまで(turn)	28.61→31.51（＋）	9.88→8.57（－）	逆
④2台	スタッフ1人の歩いた距離km	2.66→2.20（－）	1.75→1.37（－）	合う
④2台	ロボットが下げ膳を運んだ割合	0.550	試算 0.710	（記録）
⑤1台	入店待ち	6.99→6.98（－）	3.16→3.38（＋）	逆
⑤1台	料理の待ち	2.63→2.69（＋）	2.28→2.32（＋）	合う
⑤1台	卓が使えるまで(turn)	10.21→10.83（＋）	3.39→3.40（＋）	合う
⑤1台	スタッフ1人の歩いた距離km	3.22→3.10（－）	2.59→2.52（－）	合う
⑤1台	ロボットが下げ膳を運んだ割合	0.121	試算 0.145	（記録）
⑤2台	入店待ち	6.12→5.83（－）	2.37→2.78（＋）	逆
⑤2台	料理の待ち	1.71→2.06（＋）	1.27→1.34（＋）	合う
⑤2台	卓が使えるまで(turn)	10.45→9.86（－）	2.41→2.25（－）	合う
⑤2台	スタッフ1人の歩いた距離km	2.87→2.62（－）	2.12→1.91（－）	合う
⑤2台	ロボットが下げ膳を運んだ割合	0.353	試算 0.392	（記録）
⑥1台	入店待ち	5.19→4.92（－）	3.68→4.01（＋）	逆
⑥1台	料理の待ち	2.03→2.09（＋）	2.01→2.03（＋）	合う
⑥1台	卓が使えるまで(turn)	11.73→11.40（－）	6.61→6.57（－）	合う
⑥1台	スタッフ1人の歩いた距離km	2.58→2.47（－）	2.18→2.09（－）	合う
⑥1台	ロボットが下げ膳を運んだ割合	0.172	試算 0.164	（記録）
⑥2台	入店待ち	4.54→4.54（－）	2.11→1.77（－）	合う
⑥2台	料理の待ち	1.05→1.32（＋）	0.82→0.92（＋）	合う
⑥2台	卓が使えるまで(turn)	12.05→10.42（－）	5.27→4.74（－）	合う
⑥2台	スタッフ1人の歩いた距離km	2.37→2.14（－）	1.91→1.64（－）	合う
⑥2台	ロボットが下げ膳を運んだ割合	0.400	試算 0.482	（記録）
②1台	入店待ち	1.60→1.62（＋）	1.79→2.47（＋）	合う
②1台	料理の待ち	1.02→1.13（＋）	0.91→1.04（＋）	合う
②1台	卓が使えるまで(turn)	3.49→3.01（－）	3.06→3.02（－）	合う
②1台	スタッフ1人の歩いた距離km	1.53→1.33（－）	1.16→1.09（－）	合う
②1台	ロボットが下げ膳を運んだ割合	0.403	試算 0.399	（記録）
②2台	入店待ち	1.65→1.66（＋）	1.30→2.12（＋）	合う
②2台	料理の待ち	0.61→0.94（＋）	0.40→0.48（＋）	合う
②2台	卓が使えるまで(turn)	4.03→3.80（－）	2.80→2.66（－）	合う
②2台	スタッフ1人の歩いた距離km	1.55→1.21（－）	1.11→0.91（－）	合う
②2台	ロボットが下げ膳を運んだ割合	0.690	試算 0.818	（記録）
向き：合う 38・逆 10（入店待ち・料理の待ち・turn・歩いた距離 × 12）
  （逆の 10 本のうち 6 本は turn：試算では bus で減るか横ばいだが、Unity は ③⑦ の 1・2台と ④2台で増えた。4 本は入店待ちで、
   Unity は ③⑦1台・⑤⑥1台でほぼ横ばいか減り、試算はわずかに増える。差の小さいものが多い）
  ロボットが下げ膳を運んだ割合は 12 本とも試算より低め〜同じ（例 ③2台 0.354／試算 0.442、②2台 0.690／0.818）

  夜の判定（judge.md）の「回の失敗」7 件：全員が帰っていない 4 件（下の 5 章）と、「ロボットが1コマで 0.05 m 超え」3 件
   （②2台 種3・④1台 種6・④2台 種7。どれも連れて戻した回で、瞬間移動 0・1コマの跳び 0。base73b で書いたのと同じ、連れて戻す速さ
    1.0 m/秒 × 0.05 秒がちょうど 0.05 m になるため）

--------------------------------------------------------------------
5. 残った詰まりの中身と場所（止まった 4 回）
--------------------------------------------------------------------
  ・③2台 種2：2号機が下げ膳で卓8 (1.91, 10.73)（細い通路 A01）に着いて待っているところへ、1号機が同じ通路の卓4 へ向かって (1.95, 9.64) で
    向かい合って止まった。1号機は 4745 秒ごろに卓22・6・4 を回る往復で出ていて、2号機の下げ膳（4784 秒）はそのあと同じ通路へ出した
    （料理の往復には「同じ通路に2台を集めない」があるが、下げ膳を出すときには見ていない）。片付けのスタッフは2台のあいだ (1.89, 10.24) で
    譲ったまま卓に着けず、交代をくり返した。その後スタッフの料理・案内・呼び出し・会計が受け渡し口 (15.3, 6.0) などで止まり、詰まり 33 件
  ・⑥2台 種4：2号機が下げ膳で卓5 (2.17, 5.22) で待っているところへ、皿を載せた1号機が洗い場へ戻る途中 (2.27, 5.88) で止まった（0.67 m）。
    助けは卓で待つ台を動かさないので解けず、詰まり 12 件
  ・④2台 種9：1号機が下げ膳で卓21 (9.80, 4.40) で待ち、2号機が受け渡し口へ戻る途中 (9.29, 4.99) で止まった。受け渡し口の前の料理 (10.1, 4.75) の
    詰まり 5 件
  ・④2台 種4：2台が (3.51, 2.39) と (4.42, 2.34) で向かい合って止まった（どちらも料理の往復で、下げ膳の台ではない）。呼び出し・料理の詰まりと合わせて 4 件。
    serve（base73）の同じ回は全員が帰っている
  serve の同じ 120 回で残った詰まりは 1 件（⑤2台 種7・スタッフ片付け (5.68, 13.13)。base73b で書いたもの）

--------------------------------------------------------------------
6. 比較動画の素材
--------------------------------------------------------------------
  3 が合格でないので撮っていない。用意だけした：
   ・録画用の実行ファイル Builds/rec19_bus90（cs:77。-ssRecord・-ssRecCam・-ssRecHidePaths・-ssMaxWallMin が入っていることを確かめた）
   ・night/20261104_rec90/rec_runner.py（依頼87 の写しに説明を足しただけ）と queue_src.json（③2台 種7 の serve と bus の2回）
  撮るときは依頼87 と同じ --oblique --hide-paths --max-wall-min 80 --parallel 2 --no-retry --limit-min 120 で回し、
  rec_compare_20261104/{serve|bus}/ に写して make_panel_video.py で通しのパネル付きを作る

--------------------------------------------------------------------
7. 台帳
--------------------------------------------------------------------
  2681 行 → 2804 行（追記 123 行だけ：確かめ 3・120 回。どれも completed・unity_cs ServiceSim/cs:77・mode は serve 1／bus 122）
  先頭 2681 行の md5 は c25f3f880430ef92cb70dc2d141aa803（退避と同じ）。終わったあとの md5 8beaf91f429e049ce10152bd5ebf6946。鍵ファイルは残っていない

--------------------------------------------------------------------
決めてほしいこと
--------------------------------------------------------------------
  1. 下げ膳で卓に着いたロボットがふさぎ続けるのをどう解くか（どれも決まりを足すことになる）。たとえば
     (ア) 下げ膳を出すときも「同じ通路に2台を集めない」を使う（ほかの台が向かっている・いる細い通路の卓なら、ロボットは出さず人だけで下げる）。
         ③2台 種2 はこれで起きなかったはず
     (イ) 卓で待つ下げ膳の台は、助けで動かしてよい（今は「卓で受け渡し中の台は動かさない」。受け渡しは 25 秒で終わるが、下げ膳の待ちは上限がない）
     (ウ) 下げ膳の台が卓で待つ時間に上限を置く（過ぎたら皿を載せずに戻り、人だけで下げる）。サイトの試算には上限がない
     ⑥2台 種4・④2台 種9 は (イ) か (ウ) が要る。④2台 種4 は下げ膳の台ではない向かい合いで、元は調べきれていない
  2. 試しで足した a〜c（1 章）でよいか。どれも bus の回だけで、serve は変わらないことを確かめてある
  3. 比較動画の素材は、1 を決めて直し、120 回で全員が帰ることを確かめてから撮るのでよいか（用意は 6 章）
  4. 動画の題は依頼87 と同じ「③ 標準ファミレス・ロボット2台」のままでよいか（serve と bus で同じ題になる）

判定：止めた（決めてほしいことあり）
