# サービスロボット導入シミュレーション Log#40 | 病院の搬送ロボット、外来の廊下を避けて問題を4割減らす

- 記録: LOG477（サービスロボット導入シミュレーション）
- 公開: 2026/11/10
- 記事のページ: https://pixelstomotors.com/record/hospital-transport-robot-avoid-outpatient-hall
- サイト: Pixels to Motors（ADAPT DESIGN / 島津 栄一） https://pixelstomotors.com/
- 要約: 病院で検体を運ぶ搬送ロボットは、速さを上げるより外来の混む廊下を通らない道にする方が、廊下で起きる問題を約4割減らせた。仮の病院を Unity で再現した1日のシミュレーションで、代わりに検体が届くのは約2分遅くなった。

> AI が読むための記事の全文です（コード・実行ログを含む）。引用するときは上の「記事のページ」の住所を使ってください。

---

病院で検体を運ぶ搬送ロボットは、速さを上げるより、外来の混む廊下を通らない道にする方が、廊下で起きる問題を減らせました。仮の病院を Unity の3Dで再現し、7:30〜16:30 の1日を回したシミュレーションで、**内科外来から検査部への検体の道を「外来の大廊下」から「外来の奥の職員通路（裏口の道）」に変えると、ロボットが走っている間の問題（急に止まる・人とひやりとする・人によけさせる・立ち往生・車いすの前を横切る）は1日111回から68回に約4割減り、積む所で待っている間に人とひやりとする回数は約2,600回から約190回になりました。** 代わりに、検体が届くまでの平均は12.2分から14.0分へ約2分延びます（ロボット1台・0.6m/秒・乱数の種10個の中央値。実物の病院で測った数字ではありません）。

この回で分かったことと、次にできるようになったことです。

- 病院が搬送ロボットの速さを決めるときの材料が出た。止まるまでの距離が速さで延びる作りを入れると、0.6m/秒までは速いほど1往復あたりの問題は減るが、0.8m/秒では人に止まりきれない回数が増え始めた
- 「どこで待たせるか」「どの道を通すか」の方が速さより効くと分かった。外来の混む時間だけ裏口に切り替える案は、8時と11時に表と裏口の間を移る道で問題が増え、裏口だけの方が少なかった
- 配膳ロボットで作ったやり方（サイトの試算を正にし、Unity で廊下の出来事を数える）を、病院の搬送にそのまま持ち出せた。慈恵医大柏病院の公表値（運行の時間帯・1日の利用回数・削減時間）と答え合わせをしながら、仮置きの値を動かして結果がどう変わるかを見る形にした

病院を題材にしたのは、配膳の次にサービスロボットが入りそうな現場の中で、病院の院内搬送がいちばん数字がそろっているからです。東京慈恵会医科大学附属柏病院は、KEENON の搬送ロボット W3 1台で、採血管などの検体と当日分の抗がん剤を同じ階の3ルートで運び、ルートごとの時間帯と、1日あたりの利用回数（内科外来→中央検査室が4〜9回、薬剤部→外来化学療法室が5〜15回）と、1日66〜172分の削減時間を発表しています（[ロボスタ 2026-08-04](https://robotstart.info/article/2026/08/04/382233.html)、[DFA Robotics の導入事例](https://dfarobotics.com/case/jle82w5tc2n/)）。ただ、ロボットが廊下で何回止まり、人と何回ぶつかりそうになったかは、どこにも出ていません。病院が速さを上げてよいか、どこを走らせるかを決めるには、そこが要ります。

困ったのは、ファミレスのときと違って、病院には自分の働いた実感がないことでした。だから病院のフロアの形はコードで一から作り、公開値で埋まらない値（依頼の数・受け取る人が来るまでの時間・止まる割合）は仮置きにして、動かしたときに結果がどう変わるかを見る形にしました。廊下を歩く人の内訳（車いす1割・杖の人1割）も根拠のない仮置きで、実際の外来より多めに置いています。止まりきれなかった相手の多くが車いすだったので、この記事の回数は多めに出ていると見てください。内訳は次の回で調べて直します。

| やったこと | なぜ | 結果 |
|---|---|---|
| 仮の病院 h0（外来の階・120m×60m）をコードで作り、SimPy で1日の試算 h0〜h1 を回した | 慈恵柏の3ルートを、同じ階・ロボット1台で再現するため | h0 で人の搬送の時間は1日68分減（発表の幅の下の方）。青の依頼を1時間1.5件に下げた h1 で、便の数が発表の4〜9回に入った。1便あたりの減りは発表の半分以下で、道の長さか人の手間のどちらかが足りない |
| Unity で青のルートの廊下を建て、速さ4つ×混み具合2つで問題を数えた（依頼127） | 病院が知りたい「速くしたら何がどれくらい起きるか」は SimPy では数えられないため | 速いほど1往復あたりの問題は減った。ただしロボットは速さに関係なく同じ所で止まっていた |
| 速さで止まるまでの距離が変わる作りを入れ、積む所を部屋の中と比べた（依頼132） | 速さの悪い面を表すため | 0.8m/秒で止まりきれない回数が増え始めた。部屋の中に入れても問題は減らなかった |
| 外来の奥に職員通路を足した h0b を作り、裏口の道と比べた（依頼134） | 問題の97%が、積む所から縦廊下の角までの大廊下に集まっていたため | 混んでいる時間は問題がほぼ半分、止まりきれないのは5分の1。空いている時間は道が長い分だけ多い |
| 試算 h2 に道の決め方を足し、試算の便の時刻表で Unity の1日を回した（依頼136・138） | 時間帯で道を切り替える案を確かめるため | 切り替えは移る道で増えた。1日を通すと裏口だけが一番少なく、届くのは約2分遅い |

[図解: LOG477_hospital_route.html](https://pixelstomotors.com/embeds/LOG477_hospital_route.html)

配膳ロボットを自分の店に入れたらどうなるかは、このシリーズの試算をもとにした別のページで試せます。病院の搬送も、試算が固まったら同じ形にしていきます。

[配膳ロボットの導入前シミュレーション](https://pixelstomotors.com/serving-robot-one-less-staff)


## 作業ログ ― 仮の病院 h0 と、慈恵柏の公表値でそろえた前提の表

ここから下は作業ログです。数字は、特に断りがなければシミュレーションの値です。効果の欄は、測った値か見込みかを書いています。

### 搬送ロボット KEENON W3 と、病院の院内搬送

[KEENON の BUTLERBOT W3](https://www.keenon.com/jp/product/W3) は、鍵のかかる収納を持った屋内の搬送ロボットです。病院では、看護補助者（看護師の仕事を手伝うスタッフ）が歩いて運んでいた採血管・尿などの検体や薬剤を、決まった区間で運びます。このシリーズで使う値は次のとおりです。

| 言葉 | この記事での意味 | 値と出典 |
|---|---|---|
| 最高速度 | W3 が出せる速さの上限 | 0.8m/秒（公式） |
| 収納 | 別々に開けられる箱の数。1回の走行で最大4か所に届けられる | 4室（公式・慈恵柏の実証） |
| 通れる最小の幅 | ロボットが通れる通路の幅 | 0.7m（公式） |
| 電池 | 1時間に3便・1便5分の条件で動ける時間 | 12時間（公式）。充電は6.5時間 |
| 便・利用回数 | ロボットが積む所を出て届け先へ行く1回 | 慈恵柏の内科ルート1日4〜9回・薬剤ルート1日5〜15回 |

このプロジェクトでは、病院が速さや道を決めるときの材料を、公開値と仮置きの値を分けた前提の表から出します。

### SimPy は、時間・順番・数を数える道具

[SimPy](https://simpy.readthedocs.io/) は、Python で「何が、いつ、どの順番で起きるか」を回す道具です。依頼が出る・ロボットが待つ・走る・届く、を時刻つきで並べ、1日の待ち時間や便の数を数えます。廊下で人とぶつかりそうになる、のような空間の出来事は数えられないので、そこは Unity で数えます（配膳のときと同じ役割分担）。

### 仮の病院 h0 は、外来の階を120m×60m で起こした

部屋は通れない箱、廊下だけが床です。廊下の幅は医療法施行規則の一般の中廊下（内法2.1m以上）に合わせ、待合に面する外来の大廊下だけを4.0m（仮置き）にしました（[札幌市 病院の構造設備基準](https://www.city.sapporo.jp/hokenjo/f4imuyaku/documents/3r6kouzousetubikijyun.pdf)）。3ルートは慈恵柏と同じ組み合わせで、距離は廊下の中心線の上で測ります。緑（救急室→検査部）21m、青（内科外来→検査部）86m、赤（薬剤部→外来化学療法室）109m です。

![仮の病院 h0 の平面図。外来の大廊下・職員の中廊下と、緑・青・赤の3ルート](https://pixelstomotors.com/media/LOG477_01_hospital_h0.png)

慈恵柏の3ルートは運行の時間帯が重なっていません（緑 7:30〜8:00、青 8:00〜11:00・13:00〜14:00・15:00〜16:30、赤 11:00〜13:00・14:00〜15:00）。1台で3ルートを持てるように時間割が組まれていると読めます。

### 前提の表 assumptions.json

値ごとに、根拠の種類（公開事例・仮置き・図面から・決まり・設定）と出典を持たせています。決まりの行は、この回でエイイチと決めたものです。出発は満杯（4室）か、いちばん古い依頼が10分待ったら。至急はすぐ。届くまでの平均が15分以上、または至急が5分以上で「間に合わない」の印。山場は外来の8〜11時。

![検体1つが届くまでの流れと、どこにどの根拠の値が入るか](https://pixelstomotors.com/media/LOG477_02_flow.png)

#### tools/hospital_sim/assumptions.json（この記事を書いた時点の全文）

```json
{
 "about": "サービスロボット導入シミュレーション 病院の搬送ロボット（検体・薬剤、同じ階）の前提の表。試算 hospital_sim.py はこの表を読んで回す。値を直すときは、ここを直して git に残す",
 "model": "h2",
 "layout": "../hospital_layouts/hospital_h0.json",
 "basis_kinds": {
  "仮置き": "まだ根拠がない仮の値。幅（range）を動かして結果がどう変わるかを見る",
  "公開事例": "メーカーの仕様・導入事例など、公開されている値",
  "図面から": "仮の病院のフロアの形（hospital_layouts）から決まる値",
  "現場": "現場で測った値。n に測った回数を書く",
  "Unity": "Unity で測った値",
  "決まり": "エイイチと決めた、試算の回し方・判定の線・運用の決まり",
  "設定": "試算の回し方の設定"
 },
 "common": {
  "robot_speed_max": {
   "value": 0.8,
   "unit": "m/秒",
   "what": "ロボットの最高速度",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）",
   "n": null,
   "updated": "2026-11-09"
  },
  "robot_speed": {
   "value": 0.5,
   "unit": "m/秒",
   "what": "ロボットが廊下を走る速さ（平均）",
   "basis": "仮置き",
   "source": "配膳の robot_speed と同じ値から始める",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0.4,
    0.8
   ]
  },
  "staff_speed": {
   "value": 1.0,
   "unit": "m/秒",
   "what": "看護補助者が歩く速さ",
   "basis": "仮置き",
   "source": "配膳の staff_speed と同じ",
   "n": null,
   "updated": "2026-11-09"
  },
  "compartments": {
   "value": 4,
   "unit": "室",
   "what": "1台の収納の数（それぞれ別に開く）",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）・慈恵柏の実証（1回で最大4か所）",
   "n": null,
   "updated": "2026-11-09"
  },
  "payload_kg": {
   "value": 20,
   "unit": "kg",
   "what": "積める重さ",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）",
   "n": null,
   "updated": "2026-11-09",
   "note": "検体・薬剤では上限にならないので試算では使わない"
  },
  "min_passage_m": {
   "value": 0.7,
   "unit": "m",
   "what": "通れる最小の幅",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）",
   "n": null,
   "updated": "2026-11-09",
   "note": "フロアの形の決まりに使う"
  },
  "battery_h": {
   "value": 12,
   "unit": "時間",
   "what": "電池で動ける時間",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）（1時間に3便・1便5分の条件）",
   "n": null,
   "updated": "2026-11-09",
   "note": "試算では走った時間と便の数を出して、条件と比べるだけ"
  },
  "charge_h": {
   "value": 6.5,
   "unit": "時間",
   "what": "充電（15%→100%）",
   "basis": "公開事例",
   "source": "KEENON 公式 BUTLERBOT W3（https://www.keenon.com/jp/product/W3）",
   "n": null,
   "updated": "2026-11-09"
  },
  "load_s": {
   "value": 30,
   "unit": "秒",
   "what": "送る側がロボットに積んで暗証番号で閉める（1便あたり）",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    15,
    60
   ]
  },
  "pickup_wait_s": {
   "value": 60,
   "unit": "秒",
   "what": "着いてから受け取る人が来るまで",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0,
    300
   ],
   "note": "公開データがなく、結果に一番効きそうな値"
  },
  "unload_s": {
   "value": 20,
   "unit": "秒",
   "what": "受け取る人が開けて取り出す（1便あたり）",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    10,
    40
   ]
  },
  "staff_handoff_s": {
   "value": 20,
   "unit": "秒",
   "what": "人が歩いて運ぶとき、着いた先で渡す",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09"
  },
  "staff_hold_min": {
   "value": 10,
   "unit": "分",
   "what": "人が歩いて運ぶとき、まとめるために待つ長さ（至急はすぐ）",
   "basis": "仮置き",
   "source": "ロボットの出発の決まりとそろえた。人が1件ずつすぐ歩くのか、まとめて行くのかは公開データなし",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0,
    20
   ]
  },
  "pause_rate": {
   "value": 0.3,
   "unit": "確率（1便の片道あたり）",
   "what": "一時停止：人や車いすが前を横切って止まる",
   "basis": "仮置き",
   "source": "配膳の pause_rate と同じ値から始める",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0.1,
    0.6
   ]
  },
  "pause_s": {
   "value": [
    3,
    10
   ],
   "unit": "秒（最短, 最長）",
   "what": "一時停止の長さ",
   "basis": "仮置き",
   "source": "配膳と同じ",
   "n": null,
   "updated": "2026-11-09"
  },
  "stuck_rate": {
   "value": 0.01,
   "unit": "確率（1便の片道あたり）",
   "what": "立ち往生：人が動かしに行かないと解けない",
   "basis": "仮置き",
   "source": "配膳と同じ",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0.0,
    0.05
   ],
   "note": "公開データなし（調査メモ 2026-10-20）"
  },
  "stuck_resolve_s": {
   "value": 120,
   "unit": "秒",
   "what": "立ち往生が解けるまで（人が気づいて来て動かす）",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    60,
    300
   ]
  },
  "urgent_share": {
   "value": 0.1,
   "unit": "割合",
   "what": "至急の依頼の割合",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0.0,
    0.3
   ]
  },
  "layout_scale": {
   "value": 1.0,
   "unit": "倍",
   "what": "フロアの形の距離を何倍にして使うか（道の長さの影響を見るため）",
   "basis": "設定",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    1.0,
    2.5
   ],
   "note": "1.0＝仮の病院 h0 のまま。案2（仮の病院を大きくする）の当たりを付けるために動かす"
  },
  "staff_extra_s": {
   "value": 0,
   "unit": "秒（1回あたり）",
   "what": "人が歩いて運ぶとき、歩く・渡す以外にかかる時間（窓口で待つ・記録・呼び止められるなど）",
   "basis": "仮置き",
   "source": "",
   "n": null,
   "updated": "2026-11-09",
   "range": [
    0,
    300
   ],
   "note": "公開データなし。案3の当たりを付けるために動かす。標準は0（入れない）"
  }
 },
 "routes": {
  "green": {
   "name": "緑",
   "from": "救急室・病棟",
   "to": "検査部",
   "from_point": "救急室の処置室",
   "to_point": "検査部の検体受付",
   "carries": "検体",
   "windows": [
    [
     "07:30",
     "08:00"
    ]
   ],
   "windows_basis": "公開事例",
   "windows_source": "日刊工業 企業リリース（DFA Robotics・慈恵医大柏病院。https://www.nikkan.co.jp/releases/view/221980）",
   "requests_per_h": {
    "value": 6,
    "unit": "件/時",
    "what": "1時間あたりの依頼の数",
    "basis": "仮置き",
    "source": "",
    "n": null,
    "updated": "2026-11-09",
    "range": [
     2,
     12
    ],
    "note": "依頼1件＝ロボットに1回で預けるひとまとまり"
   }
  },
  "blue": {
   "name": "青",
   "from": "内科外来",
   "to": "検査部",
   "from_point": "内科外来の処置室",
   "to_point": "検査部の検体受付",
   "carries": "採血管・PCR/抗原の検体・尿",
   "windows": [
    [
     "08:00",
     "11:00"
    ],
    [
     "13:00",
     "14:00"
    ],
    [
     "15:00",
     "16:30"
    ]
   ],
   "windows_basis": "公開事例",
   "windows_source": "日刊工業 企業リリース（DFA Robotics・慈恵医大柏病院。https://www.nikkan.co.jp/releases/view/221980）",
   "requests_per_h": {
    "value": 1.5,
    "unit": "件/時",
    "what": "1時間あたりの依頼の数",
    "basis": "仮置き",
    "source": "慈恵柏の内科外来ルートの利用回数（1日4〜9回）に便の数が入るように合わせた（案1。h0 は8件で1日19便になっていた）",
    "n": null,
    "updated": "2026-11-09",
    "range": [
     0.7,
     2.5
    ],
    "note": "依頼1件＝送る側がロボットに1回で預けるひとまとまり（採血管の袋など）。1本ずつの数ではない"
   }
  },
  "red": {
   "name": "赤",
   "from": "薬剤部",
   "to": "外来化学療法室",
   "from_point": "薬剤部の払い出し口",
   "to_point": "外来化学療法室の受付",
   "carries": "当日分の抗がん剤・前投薬",
   "windows": [
    [
     "11:00",
     "13:00"
    ],
    [
     "14:00",
     "15:00"
    ]
   ],
   "windows_basis": "公開事例",
   "windows_source": "日刊工業 企業リリース（DFA Robotics・慈恵医大柏病院。https://www.nikkan.co.jp/releases/view/221980）",
   "requests_per_h": {
    "value": 5,
    "unit": "件/時",
    "what": "1時間あたりの依頼の数",
    "basis": "仮置き",
    "source": "",
    "n": null,
    "updated": "2026-11-09",
    "range": [
     2,
     10
    ],
    "note": "依頼1件＝ロボットに1回で預けるひとまとまり"
   }
  }
 },
 "rules": {
  "max_hold_min": {
   "value": 10,
   "what": "出発の決まり：満杯（収納の数）か、いちばん古い依頼がこの分だけ待ったら出発。至急はすぐ",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）"
  },
  "after_delivery": {
   "value": "届けたら、いま運行の時間帯にあるルートの出発地へ戻って待つ",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）"
  },
  "fallback": {
   "value": "至急の依頼が出たとき、その出発地に空いているロボットがいなければ、看護補助者が歩いて運ぶ",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）",
   "note": "2026-11-09 h0 の結果を見て確認：至急も空いているロボットがいればロボットが運ぶ（人に回すのは空いていないときだけ）。2台だと赤の至急が5分の線を超えるが、決まりはこのまま"
  },
  "day": {
   "value": [
    "07:30",
    "16:30"
   ],
   "what": "1日の運行",
   "basis": "決まり",
   "source": "慈恵柏の時間帯の最初と最後"
  },
  "peak": {
   "value": [
    "08:00",
    "11:00"
   ],
   "what": "山場（外来の混む時間・青のルート）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）"
  },
  "judge_mean_min": {
   "value": 15,
   "what": "依頼から届くまでの平均がこの分以上で『間に合わない』",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）"
  },
  "judge_urgent_min": {
   "value": 5,
   "what": "至急の依頼から届くまでの平均がこの分以上で『間に合わない』",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）"
  },
  "robots": {
   "value": [
    0,
    1,
    2
   ],
   "basis": "設定",
   "note": "0台＝看護補助者だけが歩いて運ぶ（比べるもと）"
  },
  "seeds": {
   "value": 10,
   "basis": "設定",
   "note": "1条件を乱数の種10個で回して平均する"
  },
  "route_plan": {
   "value": "廊下だけ",
   "what": "青のロボットの道の決め方：廊下だけ（h0 の道）／裏口だけ（h0b の道）／時間で切替（back_door_hours の間だけ裏口）",
   "basis": "設定",
   "source": "エイイチと決めた（2026-11-09 依頼134 の結果を見て）",
   "note": "標準は廊下だけ（今までと同じ）。3つを並べて比べる"
  },
  "back_door_hours": {
   "value": [
    [
     "08:00",
     "11:00"
    ]
   ],
   "what": "時間で切替のとき、ロボットが裏口から積む時間帯（外来の混む山場）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼134 の結果を見て）"
  }
 },
 "answer_check": {
  "note": "試算の入力には使わず、結果と比べる答え合わせの値（すべて企業発表）",
  "saved_min_per_day": {
   "value": "66分10秒〜172分（薬剤ルート 45分30秒〜107分30秒、内科ルート 20分40秒〜64分30秒）",
   "source": "日刊工業 企業リリース（DFA Robotics・慈恵医大柏病院。https://www.nikkan.co.jp/releases/view/221980）"
  },
  "staff_trips": {
   "value": "9.5回 → 4.8回（看護補助者1人あたり）",
   "source": "livedoor（実証の報道。https://news.livedoor.com/article/detail/28659609/）。2024年10月の2週間、2階、ビーコンで計測"
  },
  "staff_walk_time": {
   "value": "9分39秒 → 4分57秒",
   "source": "同上",
   "note": "事例ページでも「平均移動時間」とだけあり、1日あたりか1回あたりかは書かれていない。答え合わせに使わない"
  },
  "trips_per_day": {
   "value": "内科外来→中央検査室 1日あたり4〜9回利用・薬剤部→外来化学療法室 1日あたり5〜15回利用（救急室・病棟→中央検査室は記載なし）",
   "source": "ロボスタ 2026-08-04（https://robotstart.info/article/2026/08/04/382233.html）・チェンジホールディングス（https://www.changeholdings.co.jp/news/289/）。DFA Robotics の発表の表「利用回数」",
   "note": "2026-11-09 原文の表で確認。1日あたりの削減時間と同じ表にある"
  },
  "saved_per_use": {
   "value": "1回あたりにすると 内科 約5分10秒〜7分10秒・薬剤 約7分10秒〜9分6秒",
   "source": "上の削減時間 ÷ 利用回数（こちらで割った値。発表には1回あたりの記載なし）"
  },
  "robots": {
   "value": "1台",
   "source": "DFA Robotics 導入事例（https://dfarobotics.com/case/jle82w5tc2n/）"
  }
 },
 "unity": {
  "about": "Unity（ServiceSim の病院の場面）で、ロボットの速さを上げたときに廊下で何がどれくらい起きるかを数えるための条件。Unity はこれを hospital-unity-params.json（export_unity_params.py で書き出す）から読む",
  "route": {
   "value": "blue",
   "unit": "",
   "what": "建てる範囲：青のルートの道（内科外来の処置室 → 外来の大廊下 → 西の縦廊下 → 職員の中廊下 → 検査部の検体受付）と、外来の大廊下の人の多い区間（x0〜70）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09"
  },
  "speeds": {
   "value": [
    0.4,
    0.5,
    0.6,
    0.8
   ],
   "unit": "m/秒",
   "what": "ロボットの速さ（病院が設定する速さ）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09",
   "note": "上限は W3 の公表の最高速度0.8m/秒"
  },
  "crowd_people": {
   "value": {
    "空いている": 20,
    "混んでいる": 60
   },
   "unit": "人",
   "what": "外来の大廊下に同時にいる人の数",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09"
  },
  "people_mix": {
   "value": {
    "歩く患者・付き添い": 0.7,
    "杖の人": 0.1,
    "車いす": 0.1,
    "スタッフ": 0.1
   },
   "unit": "割合",
   "what": "人の内訳",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09"
  },
  "stretcher_per_h": {
   "value": 2,
   "unit": "回/時",
   "what": "ストレッチャーが通る回数",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09"
  },
  "seeds": {
   "value": 10,
   "unit": "個",
   "what": "1条件を回す乱数の種の数",
   "basis": "設定",
   "source": "エイイチと決めた（2026-11-09）",
   "n": null,
   "updated": "2026-11-09"
  },
  "count_rules": {
   "sudden_stop": {
    "value": 1.0,
    "unit": "秒",
    "what": "1 急に止まった：走っている状態からこの秒数以内に止まった",
    "basis": "決まり",
    "source": "エイイチと決めた（2026-11-09）",
    "n": null,
    "updated": "2026-11-09"
   },
   "near_miss_m": {
    "value": 0.3,
    "unit": "m",
    "what": "2 ひやり：人とロボットの外形どうしがこの距離未満まで近づいた",
    "basis": "決まり",
    "source": "エイイチと決めた（2026-11-09）",
    "n": null,
    "updated": "2026-11-09"
   },
   "yield_m": {
    "value": 2.0,
    "unit": "m",
    "what": "3 人がよけさせられた：ロボットからこの距離以内で、人が止まるか向きを変えた",
    "basis": "決まり",
    "source": "エイイチと決めた（2026-11-09）",
    "n": null,
    "updated": "2026-11-09"
   },
   "stuck_s": {
    "value": 30,
    "unit": "秒",
    "what": "4 立ち往生：この秒数以上動けず、人が動かしに行った（配膳と同じ）",
    "basis": "決まり",
    "source": "エイイチと決めた（2026-11-09）",
    "n": null,
    "updated": "2026-11-09"
   },
   "cross_front_m": {
    "value": 1.5,
    "unit": "m",
    "what": "5 車いす・杖の人・ストレッチャーの進む先この距離以内をロボットが横切った",
    "basis": "決まり",
    "source": "エイイチと決めた（2026-11-09）",
    "n": null,
    "updated": "2026-11-09"
   }
  },
  "output": "KIOXIA の r2r2r-data/service_sim/unity/hospital/（MASTER の保存先テーブルの Unity の出力の行）",
  "braking": {
   "decel_mps2": {
    "value": 0.5,
    "unit": "m/秒²",
    "what": "ロボットが止まるときの減速の強さ",
    "basis": "仮置き",
    "source": "公開データなし（W3 の公表値に止まるまでの距離はない）",
    "n": null,
    "updated": "2026-11-09",
    "range": [
     0.3,
     1.0
    ]
   },
   "react_s": {
    "value": 0.2,
    "unit": "秒",
    "what": "気づいてからブレーキがかかるまで",
    "basis": "仮置き",
    "source": "",
    "n": null,
    "updated": "2026-11-09"
   },
   "notice_margin_m": {
    "value": 0.3,
    "unit": "m",
    "what": "気づく距離＝止まるまでの距離＋この余裕（速いほど遠くで気づく作り）",
    "basis": "仮置き",
    "source": "",
    "n": null,
    "updated": "2026-11-09",
    "note": "横から急に出てきた人など、気づく距離より内側に入られたときは止まりきれないことがある"
   },
   "what": "止まるまでの距離＝速さ×react_s＋速さ²÷(2×decel_mps2)。0.4m/秒で約0.24m、0.8m/秒で約0.80m"
  },
  "loading_point": {
   "value": [
    "廊下",
    "部屋の中",
    "裏口"
   ],
   "unit": "",
   "what": "積む所：廊下＝扉から廊下へ0.5m（h0）／部屋の中＝扉から処置室の中へ1.0m（h0）／裏口＝処置室の裏口から外来の奥の職員通路へ0.5m（h0b。大廊下を通らない道）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09",
   "note": "裏口は hospital_h0b.json の形で建てる"
  },
  "count_shape": {
   "value": "丸（直径0.549m）",
   "unit": "",
   "what": "数えるときのロボットの形。動くときと同じ丸で見る（依頼127 は長方形で数えて距離がマイナスに出た）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼127 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "near_miss_speed_mps": {
   "value": 0.3,
   "unit": "m/秒",
   "what": "ひやりのうち、近づいたときのロボットの速さがこれ以上のものを『速いままのひやり』として分けて数える",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09 依頼127 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "near_miss_speed_basis": {
   "value": "1秒前からの最大",
   "unit": "",
   "what": "速いままのひやりを分けるときに見るロボットの速さ（一番近づいた瞬間ではなく、その1秒前からの最大）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "sensor_width_m": {
   "value": 0.65,
   "unit": "m",
   "what": "前のセンサーの幅（体の幅0.549m＋左右5cmずつ。依頼132 は共通の設定の0.5m で体より狭かった）",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "wheelchair_avoid_stopped_robot": {
   "value": true,
   "unit": "",
   "what": "車いす・ストレッチャー（押す人）も、止まっているロボットはよける（依頼132 はよけずに最大0.62m 入り込んでいた）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "near_miss_split_by_robot_moving": {
   "value": true,
   "unit": "",
   "what": "ひやりを、ロボットが動いていたもの（ロボットが近づいた）と止まっていたもの（人が近づいた）に分けて数える",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "east_hall_people_ratio": {
   "value": 0.25,
   "unit": "倍",
   "what": "大廊下の東の端（x70〜120。人の少ない区間）に置く人の密度。人の多い区間の何倍か",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09 依頼132 の結果を見て）",
   "n": null,
   "updated": "2026-11-09",
   "note": "裏口の道が大廊下を横切る所（x99）のため。どの積む所の回でも同じに置く"
  },
  "staff_corridor_interval_s": {
   "value": 60,
   "unit": "秒",
   "what": "外来の奥の職員通路・東の縦廊下（北）をスタッフが通る間隔（平均）",
   "basis": "仮置き",
   "source": "依頼134 で Unity が決めた値をサイトの条件に移した（エイイチと決めた（2026-11-09 依頼134 の結果を見て））",
   "n": null,
   "updated": "2026-11-09",
   "note": "空いている時間の裏口の問題の数は、ほぼこの値で決まる"
  },
  "stretcher_yield": {
   "value": {
    "who": "ロボットが譲る",
    "wait_s": 20
   },
   "unit": "",
   "what": "狭い職員の中廊下でストレッチャーと向き合ったら、ロボットが譲り、最大この秒数待つ",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼134 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "crowd_by_time": {
   "value": [
    [
     "07:30",
     "08:00",
     "空いている"
    ],
    [
     "08:00",
     "11:00",
     "混んでいる"
    ],
    [
     "11:00",
     "16:30",
     "空いている"
    ]
   ],
   "unit": "",
   "what": "1日を通して回すときの大廊下の混み具合（外来の山場だけ混んでいる）",
   "basis": "仮置き",
   "source": "エイイチと決めた（2026-11-09 依頼134 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "waiting_near_miss": {
   "value": "別に数える",
   "what": "積む所で止まって待っている間のひやり（止まったロボットの横を人が通る）は、問題1〜5に混ぜず『廊下に止まっている間のひやり』として別に並べる",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼136 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "day_end_rule": {
   "value": "最後の便が終わるまで",
   "what": "1日を通して回すとき、16:30 を過ぎた便も最後の便が積んだ所へ戻るまで回す（16:30 以降も人と混み具合は空いているのまま）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼136 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  },
  "switch_move": {
   "value": "8:00・11:00 に走って移る",
   "what": "時間で切替のとき、積んだ所へ戻ったあと、back_door_hours の始まりと終わりの時刻に表と裏口の間を走って移る（依頼136 の形）",
   "basis": "決まり",
   "source": "エイイチと決めた（2026-11-09 依頼136 の結果を見て）",
   "n": null,
   "updated": "2026-11-09"
  }
 }
}
```

#### tools/hospital_layouts/make_hospital.py（仮の病院 h0・h0b を作るコード）

```python
# -*- coding: utf-8 -*-
"""仮の病院のフロアの形（同じ階・案 h0）を作る。

サービスロボット導入シミュレーション 病院の搬送ロボット（検体・薬剤）用。
実在の病院ではなく、外来・検査部・薬剤部・外来化学療法室・救急室の
典型的な並びをコードで一から起こしたもの（2026-11-09 エイイチと決めた）。

決まり
- 廊下の幅は医療法施行規則 第16条1項11号の一般の廊下に合わせる：中廊下 2.1m 以上
- 外来の大廊下（待合に面する）は 4.0m（仮置き。人が多い所）
- ロボットが通れる最小の幅は W3 の公表値 0.7m。全部の廊下がこれを超える
- 距離は廊下の中心線の上で測る（扉の点 → 廊下 → 扉の点）。試算はこの距離を使う

使い方：python3 make_hospital.py 出力先 [h0|h0b]
出力：hospital_{h0,h0b}.json（形・3ルートの道と距離・点と点の距離 distances）・hospital_h0.png（平面図）
"""
import heapq
import json
import sys
from pathlib import Path

W, D = 120.0, 60.0          # 外寸 m（x 右、y 奥）
HALL_Y0, HALL_Y1 = 27.0, 31.0     # 外来の大廊下 4.0m
STAFF_Y0, STAFF_Y1 = 13.0, 15.1   # 職員の中廊下 2.1m
HALL_C = (HALL_Y0 + HALL_Y1) / 2
STAFF_C = (STAFF_Y0 + STAFF_Y1) / 2
CROWD_X0, CROWD_X1 = 0.0, 70.0   # 外来の大廊下のうち受付・会計・待合の前（人の多い区間）
CONNECT_X = {"西の縦廊下": 24.0, "玄関の通り": 48.0, "東の縦廊下": 99.0}
CONNECT_W = {"西の縦廊下": 2.1, "玄関の通り": 8.0, "東の縦廊下": 2.1}

ROOMS = [  # 名前, x0, y0, x1, y1, 種類
    ("内科外来", 0, 31, 42, 60, "外来"),
    ("ほかの外来", 42, 31, 96, 60, "外来"),
    ("外来化学療法室", 96, 31, 120, 60, "届け先"),
    ("薬剤部", 0, 0, 23, 13, "出発"),
    ("お薬の窓口", 0, 15.1, 23, 27, "その他"),
    ("総合受付・会計・待合", 25.1, 15.1, 70, 27, "混む所"),
    ("倉庫", 25.1, 0, 44, 13, "その他"),
    ("正面玄関", 44, 0, 52, 13, "混む所"),
    ("医事・事務", 52, 0, 70, 13, "その他"),
    ("中央検査室", 70, 0, 98, 13, "届け先"),
    ("生理検査", 70, 15.1, 98, 27, "その他"),
    ("救急室", 100.1, 0, 120, 27, "出発"),
]

POINTS = {  # 扉の前の点（ロボットが積む・受け取る所）。名前: (x, y, つながる廊下の中心の点)
    "内科外来の処置室": (12.0, HALL_Y1, (12.0, HALL_C)),
    "外来化学療法室の受付": (104.0, HALL_Y1, (104.0, HALL_C)),
    "薬剤部の払い出し口": (13.0, STAFF_Y0, (13.0, STAFF_C)),
    "検査部の検体受付": (80.0, STAFF_Y0, (80.0, STAFF_C)),
    "救急室の処置室": (108.0, STAFF_Y0 + 0.0, (108.0, STAFF_C)),
}
# 救急室は x100.1〜 にあり、中廊下の南ではなく東の端。扉は中廊下の東の突き当たりに出す
POINTS["救急室の処置室"] = (100.1, STAFF_C, (99.0, STAFF_C))

ROUTES = {
    "green": ("救急室の処置室", "検査部の検体受付", "検体（救急・病棟）"),
    "blue": ("内科外来の処置室", "検査部の検体受付", "採血管・PCR/抗原・尿"),
    "red": ("薬剤部の払い出し口", "外来化学療法室の受付", "抗がん剤・前投薬"),
}

# 案 h0b（2026-11-09 エイイチと決めた「大廊下を通らない道」）：
# 外来の奥（北の壁ぞい）に職員通路 2.1m を足し、内科外来の処置室の裏口から積む。
# 北の職員通路 → 東の縦廊下（x99）で大廊下の人の少ない東の端を横切る → 職員の中廊下 → 検査部。
# h0 の部屋・廊下・点はそのまま（内科外来・ほかの外来は奥行きが2.1m 縮み、外来化学療法室は縦廊下の分だけ右へ縮む）。
NORTH_Y0, NORTH_Y1 = D - 2.1, D
NORTH_C = (NORTH_Y0 + NORTH_Y1) / 2
NORTH_X1 = 100.05
NORTH_CONNECT_X = 99.0
VARIANTS = {
    "h0": {"name": "仮の病院 h0（外来の階）", "north": False},
    "h0b": {"name": "仮の病院 h0b（外来の階・外来の奥に職員通路）", "north": True},
}


def apply_variant(v):
    """h0b のときだけ、部屋・点・ルートを差し替える（h0 は何もしない）"""
    global ROOMS, POINTS, ROUTES
    if not VARIANTS[v]["north"]:
        return
    rooms = []
    for n, x0, y0, x1, y1, k in ROOMS:
        if n in ("内科外来", "ほかの外来"):
            y1 = NORTH_Y0
        if n == "ほかの外来":
            x1 = NORTH_CONNECT_X - 1.05
        if n == "外来化学療法室":
            x0 = NORTH_CONNECT_X + 1.05
        rooms.append((n, x0, y0, x1, y1, k))
    ROOMS = rooms
    POINTS = dict(POINTS)
    POINTS["内科外来の処置室（裏口）"] = (12.0, NORTH_Y0, (12.0, NORTH_C))
    ROUTES = dict(ROUTES)
    ROUTES["blue"] = ("内科外来の処置室（裏口）", "検査部の検体受付", "採血管・PCR/抗原・尿")


def build_graph(variant="h0"):
    nodes = set()
    edges = {}

    def add(a, b):
        d = abs(a[0] - b[0]) + abs(a[1] - b[1])  # 廊下は縦横だけ
        if abs(a[1] - HALL_C) < 1e-6 and abs(b[1] - HALL_C) < 1e-6:
            d += 0.01 * crowded_len(a[0], b[0])  # 同じ長さなら人の多い所を通らない方を選ぶ（距離には入れない）
        edges.setdefault(a, []).append((b, d))
        edges.setdefault(b, []).append((a, d))
        nodes.update([a, b])

    north = VARIANTS[variant]["north"]
    hall_xs = {0.0, W} | set(CONNECT_X.values())
    staff_xs = {0.0, 100.1} | {v for v in CONNECT_X.values() if v <= 100.1}
    north_xs = {0.0, NORTH_CONNECT_X}
    for name, (x, y, c) in POINTS.items():
        if abs(c[1] - HALL_C) < 1e-6:
            hall_xs.add(c[0])
        elif abs(c[1] - NORTH_C) < 1e-6:
            north_xs.add(c[0])
        else:
            staff_xs.add(c[0])
        add((x, y), c)
    if north:
        hall_xs.add(NORTH_CONNECT_X)
        xs = sorted(north_xs)
        for a, b in zip(xs, xs[1:]):
            add((a, NORTH_C), (b, NORTH_C))
        add((NORTH_CONNECT_X, NORTH_C), (NORTH_CONNECT_X, HALL_C))
    xs = sorted(hall_xs)
    for a, b in zip(xs, xs[1:]):
        add((a, HALL_C), (b, HALL_C))
    xs = sorted(staff_xs)
    for a, b in zip(xs, xs[1:]):
        add((a, STAFF_C), (b, STAFF_C))
    for x in CONNECT_X.values():
        add((x, STAFF_C), (x, HALL_C))
    return edges


def crowded_len(xa, xb):
    lo, hi = min(xa, xb), max(xa, xb)
    return max(0.0, min(hi, CROWD_X1) - max(lo, CROWD_X0))


def true_len(path):
    return sum(abs(p[0] - q[0]) + abs(p[1] - q[1]) for p, q in zip(path, path[1:]))


def shortest(edges, s, t):
    dist = {s: 0.0}
    prev = {}
    q = [(0.0, s)]
    while q:
        d, u = heapq.heappop(q)
        if u == t:
            break
        if d > dist[u]:
            continue
        for v, w in edges[u]:
            nd = d + w
            if nd < dist.get(v, 1e18) - 1e-9:
                dist[v] = nd
                prev[v] = u
                heapq.heappush(q, (nd, v))
    path = [t]
    while path[-1] != s:
        path.append(prev[path[-1]])
    return dist[t], path[::-1]


def on_hall(p, q):
    return abs(p[1] - HALL_C) < 1e-6 and abs(q[1] - HALL_C) < 1e-6


def main(out_dir, variant="h0"):
    apply_variant(variant)
    out = Path(out_dir)
    out.mkdir(parents=True, exist_ok=True)
    edges = build_graph(variant)
    routes = {}
    for key, (a, b, carries) in ROUTES.items():
        pa, pb = POINTS[a][:2], POINTS[b][:2]
        d, path = shortest(edges, pa, pb)
        d = true_len(path)
        hall_m = sum(crowded_len(p[0], q[0]) for p, q in zip(path, path[1:]) if on_hall(p, q))
        routes[key] = {"from": a, "to": b, "carries": carries, "distance_m": round(d, 2),
                       "crowded_hall_m": round(hall_m, 2), "path": [list(map(lambda v: round(v, 2), p)) for p in path]}
    names = list(POINTS)
    dist = {}
    for a in names:
        for b in names:
            if a != b:
                dist[f"{a}|{b}"] = round(true_len(shortest(edges, POINTS[a][:2], POINTS[b][:2])[1]), 2)
    data = {
        "meta": {
            "schema_version": "hospital-layout/0.1",
            "name": VARIANTS[variant]["name"],
            "units": "m",
            "coords": "原点は建物の外壁の内側の左下の角。x は右、y は奥（上）。配膳の店の形と同じ向き",
            "rules": {
                "staff_corridor_w": STAFF_Y1 - STAFF_Y0,
                "staff_corridor_w_source": "医療法施行規則 第16条1項11号（一般の中廊下 内法2.1m以上）",
                "hall_w": HALL_Y1 - HALL_Y0,
                "hall_w_basis": "仮置き",
                "robot_min_passage_m": 0.7,
                "distance": "廊下の中心線の上で、扉の点から扉の点まで（縦横の移動だけ）",
                "crowded": "外来の大廊下の x70 より西（受付・会計・待合の前）を、人の多い区間として数える",
            },
        },
        "layout": {
            "outer": {"w": W, "d": D},
            "rooms": [{"name": n, "rect": [x0, y0, x1, y1], "kind": k} for n, x0, y0, x1, y1, k in ROOMS],
            "corridors": [
                {"name": "外来の大廊下", "rect": [0, HALL_Y0, W, HALL_Y1], "w": HALL_Y1 - HALL_Y0},
                {"name": "職員の中廊下", "rect": [0, STAFF_Y0, 100.1, STAFF_Y1], "w": STAFF_Y1 - STAFF_Y0},
            ] + [{"name": n, "rect": [x - CONNECT_W[n] / 2, STAFF_Y1, x + CONNECT_W[n] / 2, HALL_Y0], "w": CONNECT_W[n]}
                 for n, x in CONNECT_X.items()]
              + ([{"name": "外来の奥の職員通路", "rect": [0, NORTH_Y0, NORTH_X1, NORTH_Y1], "w": 2.1},
                  {"name": "東の縦廊下（北）", "rect": [NORTH_CONNECT_X - 1.05, HALL_Y1, NORTH_CONNECT_X + 1.05, NORTH_Y0], "w": 2.1}]
                 if VARIANTS[variant]["north"] else []),
            "points": {n: [x, y] for n, (x, y, _) in POINTS.items()},
        },
        "routes": routes,
        "distances": dist,
    }
    if variant != "h0":  # h0 の JSON は中身を変えない（Unity の依頼が md5 で確かめているため）
        data["meta"]["variant"] = variant
    (out / f"hospital_{variant}.json").write_text(json.dumps(data, ensure_ascii=False, indent=1), encoding="utf-8")
    draw(data, out / f"hospital_{variant}.png")
    for k, r in routes.items():
        print(k, r["from"], "→", r["to"], r["distance_m"], "m（人の多い区間", r["crowded_hall_m"], "m）")


def draw(data, path):
    import matplotlib
    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    from matplotlib import font_manager
    from matplotlib.patches import Rectangle
    for f in font_manager.findSystemFonts():
        if "NotoSansCJK" in f or "NotoSansJP" in f:
            font_manager.fontManager.addfont(f)
            plt.rcParams["font.family"] = font_manager.FontProperties(fname=f).get_name()
            break
    col = {"外来": "#eef1f5", "届け先": "#dce9fb", "出発": "#e3f3e6", "混む所": "#fff1dc", "その他": "#f4f4f4"}
    rc = {"green": "#2e9d4f", "blue": "#2f6fd6", "red": "#d24b3e"}
    fig, ax = plt.subplots(figsize=(16, 8.6), dpi=150)
    for r in data["layout"]["rooms"]:
        x0, y0, x1, y1 = r["rect"]
        ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0, fc=col[r["kind"]], ec="#9aa3ad", lw=1))
        ax.text((x0 + x1) / 2, (y0 + y1) / 2, r["name"], ha="center", va="center", fontsize=11, color="#333")
    for c in data["layout"]["corridors"]:
        x0, y0, x1, y1 = c["rect"]
        ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0, fc="#ffffff", ec="none"))
    ax.add_patch(Rectangle((CROWD_X0, HALL_Y0), CROWD_X1 - CROWD_X0, HALL_Y1 - HALL_Y0, fc="#fff1dc", ec="none"))
    ax.text(45, HALL_C, "外来の大廊下 4.0m（受付・待合の前は人が多い）", va="center", ha="center", fontsize=9, color="#8a5a00")
    ax.text(0.6, STAFF_C, "職員の中廊下 2.1m", va="center", fontsize=8, color="#777")
    offs = {"green": 0.45, "blue": 0.0, "red": -0.45}
    for k, r in data["routes"].items():
        xs = [p[0] for p in r["path"]]
        ys = [p[1] + offs[k] for p in r["path"]]
        ax.plot(xs, ys, color=rc[k], lw=2.6, solid_capstyle="round")
        ax.plot(xs[0], ys[0], "o", color=rc[k], ms=9)
        ax.plot(xs[-1], ys[-1], "s", color=rc[k], ms=9)
    for n, (x, y) in data["layout"]["points"].items():
        dy = -1.6 if y > D - 3 else (1.6 if y > 20 else -1.6)
        ax.text(x, y + dy, n, ha="center", va="center", fontsize=9, color="#222",
                bbox=dict(fc="white", ec="#bbb", lw=0.6, pad=1.5))
    legend = [f"{ {'green':'緑','blue':'青','red':'赤'}[k]}  {r['from']} → {r['to']}  {r['distance_m']:.0f}m"
              for k, r in data["routes"].items()]
    for i, (k, t) in enumerate(zip(data["routes"], legend)):
        ax.text(1, -3 - i * 2.2, "●", color=rc[k], fontsize=12, va="center")
        ax.text(3, -3 - i * 2.2, t, fontsize=11, va="center")
    ax.text(60, -3, "● 出発（積む所）　■ 届け先　オレンジ＝人の多い所", fontsize=10, color="#555", va="center")
    ax.set_xlim(-1, W + 1)
    ax.set_ylim(-9.5, D + 1)
    ax.set_aspect("equal")
    ax.axis("off")
    ax.add_patch(Rectangle((0, 0), W, D, fc="none", ec="#555", lw=1.6))
    ax.set_title(f"{data['meta']['name']}（120m×60m）と搬送の3ルート", fontsize=15, loc="left")
    fig.savefig(path, bbox_inches="tight", facecolor="white")


if __name__ == "__main__":
    main(sys.argv[1] if len(sys.argv) > 1 else ".", sys.argv[2] if len(sys.argv) > 2 else "h0")
```



## 作業ログ ― SimPy の試算 h0〜h2 と、慈恵柏の発表とのずれ

### 試算 h0：ロボット1台で、人の搬送の時間は1日103分から35分に

青の依頼を1時間8件と仮置きした最初の版です。ロボット1台で人が搬送に使う時間は1日68分減り、慈恵柏の発表（66〜172分）の下の方に入りました。2台にしても76分減でほとんど変わりません。届くまでの時間は、人が歩くより少し延びます（青で8.1分→10.7分）。

![試算 h0。届くまでの平均・至急・人の時間の減り](https://pixelstomotors.com/media/LOG477_03_h0_result.png)

至急の決まりは、空いているロボットがいればロボットが運ぶ形のままにしました。2台だと赤の至急が5.5分になり5分の線を超えますが、赤の109mをロボットが走るためで、決まりは変えないことにしました。

### 慈恵柏の発表とのずれ：便の数と、1便あたりの減り

発表の表（2026年8月4日）で、1日の利用回数を原文で確かめました。青の便は試算で1日18.8回、発表は4〜9回。1便あたりの人の時間の減りは、試算で青2.2分・赤3.0分、発表を割ると5〜9分です。

![試算 h0 と慈恵柏の発表のずれ。便の数と1便あたりの減り](https://pixelstomotors.com/media/LOG477_04_gap_explain.png)

- ねらい：便の数を発表に合わせ、残るずれがどこから来るかを分ける
- 変わったこと：h1 で青の依頼を1時間8件から1.5件に下げ、便の数は1日6.4回になった（依頼1件＝送る側がロボットに1回で預けるひとまとまり）
- 見込める効果：1便あたりの減りのずれは残る。道を2倍にしても（案2）、人が運ぶときの歩く以外の手間を1回3〜4分足しても（案3）発表の幅に届く。違いは、案2だと検体が届くのも遅くなり（青12.7分→15.6分）、案3では変わらないこと。どちらが本当かは病院の現場でしか分からないので、両方を並べたままにした

![案2（道を長く）と案3（人の手間を足す）の比べ](https://pixelstomotors.com/media/LOG477_05_case2_vs_case3.png)

ロボットの速さは平均0.5m/秒の仮置きです。0.8m/秒（最高速度）なら、道が2倍でも青は13.3分で15分の内側に戻ります。速さは機械の数字であると同時に、病院がロボットをどれだけ信じて走らせるかの数字でもあります。だから病院が知りたいのは、速くしたときにどんな問題がどんな頻度で起きるかで、それを Unity で数えることにしました。

#### tools/hospital_sim/hospital_sim.py（試算 h0〜h2 の全文）

```python
# -*- coding: utf-8 -*-
"""サービスロボット導入シミュレーション 病院の搬送ロボット（検体・薬剤、同じ階）試算

版の記録
  h0（2026-11-09）：最初の版
  h2（2026-11-09）：青の道の決め方（route_plan：廊下だけ／裏口だけ／時間で切替）を足した。時間で切替は
     back_door_hours（外来の混む 8〜11時）の間だけロボットが裏口から積む（Unity 依頼134 で、混む時間は裏口で
     問題がほぼ半分、空いている時間は今の道の方が少なかったため）。人が歩くときはいつも表の短い道。
     ロボットの便の時刻表（trip_log）を残し、Unity に渡せるようにした
  h1（2026-11-09）：青の依頼の数を1時間8件 → 1.5件（慈恵柏の利用回数 1日4〜9回に合わせた。案1）。
     依頼1件は、ロボットに1回で預けるひとまとまり（採血管の袋など）と定義した。
     道の長さを何倍にするか（layout_scale）と、人が運ぶときの歩く以外の手間（staff_extra_s）を
     動かせるようにした（どちらも標準では効かない値：1.0倍・0秒）

前提の値はこのファイルの隣の assumptions.json（前提の表）から、フロアの形は
../hospital_layouts/hospital_h0.json から読む。コードの中に前提の値を書かない。

何を回すか
  1日（7:30〜16:30）、3ルート（緑・青・赤）に依頼が出る。依頼は各ルートの運行の時間帯の間だけ、
  1時間あたりの数（requests_per_h）でばらばらに出る（ポアソン到着）。至急の割合は urgent_share。
  ロボット0台：看護補助者が歩いて運ぶ（比べるもと）。まとめるために staff_hold_min 分まで待ち、至急ならすぐ出る。
  ロボット1台・2台：出発の決まり（rules）どおりに運ぶ。
    - いま運行の時間帯にあるルートの出発地で待つ（時間帯が切り替わったら、次のルートの出発地へ移る）
    - 満杯（収納の数）か、いちばん古い依頼が max_hold_min 分待ったら出発。至急はすぐ。時間帯が終わって残った依頼もすぐ
    - 積む（load_s）→ 走る（距離/速さ＋一時停止・立ち往生）→ 受け取る人を待つ（pickup_wait_s の平均の指数分布）
      → 取り出す（unload_s）→ 戻る
    - 至急の依頼が出たとき、その出発地に空いているロボットがいなければ、看護補助者が歩いて運ぶ
  依頼の出方は、乱数の種ごとに台数によらず同じ（台数の違いだけを比べるため）。

出すもの（ルートごと・1日）
  届くまでの時間（依頼が出てから受け取る人が取り出すまで）の平均・90%・最大、至急の平均、
  運んだ回数（ロボットの便・人が歩いた回数）、看護補助者などが搬送に使った時間
  （人が歩く往復と渡す時間・ロボットに積む時間・取り出す時間・立ち往生を解く時間）。
  ロボットが走った時間と距離、山場（8〜11時の青）の届くまでの時間。
  判定：届くまでの平均が judge_mean_min 分以上、または至急の平均が judge_urgent_min 分以上で「間に合わない」。

使い方
  python3 hospital_sim.py                 # 標準の条件（0/1/2台）と、仮置きの値を動かした条件を回す
  python3 hospital_sim.py --out 出力先     # results.json と summary.txt を書く
"""
import argparse
import json
import math
import random
import statistics
from pathlib import Path

import simpy

HERE = Path(__file__).resolve().parent


def hm(s):
    h, m = s.split(":")
    return int(h) * 3600 + int(m) * 60


def load_inputs(layout=None):
    A = json.loads((HERE / "assumptions.json").read_text(encoding="utf-8"))
    L = json.loads((HERE / (layout or A["layout"])).read_text(encoding="utf-8"))
    return A, L


def params(A, over=None):
    c = {k: v["value"] for k, v in A["common"].items()}
    r = {k: v["value"] for k, v in A["rules"].items()}
    p = {"c": c, "r": r, "req_mult": 1.0}
    if over:
        for k, v in over.items():
            if k == "req_mult":
                p["req_mult"] = v
            elif k.startswith("rph_"):
                p.setdefault("rph", {})[k[4:]] = v
            elif k in c:
                c[k] = v
            else:
                r[k] = v
    return p


def make_requests(A, p, seed):
    """依頼の出方。台数によらず同じになるよう、専用の乱数で作る"""
    rng = random.Random(f"req-{seed}")
    day0 = hm(A["rules"]["day"]["value"][0])
    out = []
    for key in sorted(A["routes"]):
        R = A["routes"][key]
        lam = p.get("rph", {}).get(key, R["requests_per_h"]["value"]) * p["req_mult"] / 3600.0
        for a, b in R["windows"]:
            t, end = hm(a) - day0, hm(b) - day0
            while True:
                t += rng.expovariate(lam)
                if t >= end:
                    break
                out.append({"route": key, "t": t, "urgent": rng.random() < p["c"]["urgent_share"]})
    out.sort(key=lambda q: q["t"])
    for i, q in enumerate(out):
        q["id"] = i
    return out


class Day:
    def __init__(self, A, L, p, n_robots, seed):
        self.A, self.L, self.p, self.n = A, L, p, n_robots
        self.c, self.r = p["c"], p["r"]
        self.env = simpy.Environment()
        self.rng = random.Random(f"run-{seed}-{n_robots}")
        self.day0 = hm(A["rules"]["day"]["value"][0])
        self.day_end = hm(A["rules"]["day"]["value"][1]) - self.day0
        # 積む所・届け先の点はフロアの形のルートに合わせる（h0b は青が裏口から出る）
        self.routes = {k: dict(R, from_point=L["routes"][k]["from"], to_point=L["routes"][k]["to"]) for k, R in A["routes"].items()}
        self.win = {k: [(hm(a) - self.day0, hm(b) - self.day0) for a, b in R["windows"]] for k, R in self.routes.items()}
        self.queue = {k: [] for k in self.routes}
        self.done = []
        self.staff_s = {k: 0.0 for k in self.routes}  # 人が搬送に使った秒
        self.staff_walks = {k: 0 for k in self.routes}
        self.robot_trips = {k: 0 for k in self.routes}
        self.robot_run_s = 0.0
        self.robot_m = 0.0
        self.stuck_n = 0
        self.idle_at = {}  # ロボット番号 → 待っている出発地のルート（走っているときは None）
        self.reqs = make_requests(A, p, seed)
        # 青の道の決め方（h2）：廊下だけ／裏口だけ／時間で切替（back_door_hours の間だけ裏口）
        self.plan = self.r.get("route_plan", "廊下だけ")
        if self.plan != "廊下だけ" and "内科外来の処置室（裏口）" not in str(self.L["distances"].keys()):
            self.L = json.loads((HERE / "../hospital_layouts/hospital_h0b.json").read_text(encoding="utf-8"))
        self.back_hours = [(hm(a) - self.day0, hm(b) - self.day0) for a, b in self.r.get("back_door_hours", [])]
        self.trip_log = []  # ロボットの便（Unity に渡す時刻表）

    def robot_from(self, k, t):
        """ロボットが積む所。青だけ、決め方により裏口になる。人が歩くときはいつも表（routes の from_point）"""
        if k == "blue" and (self.plan == "裏口だけ" or (self.plan == "時間で切替" and any(a <= t < b for a, b in self.back_hours))):
            return "内科外来の処置室（裏口）"
        return self.routes[k]["from_point"]

    # 距離
    def dist(self, a, b):
        if a == b:
            return 0.0
        return self.L["distances"][f"{a}|{b}"] * self.c["layout_scale"]

    def route_dist(self, k):
        R = self.routes[k]
        return self.dist(R["from_point"], R["to_point"])

    def active(self, t):
        return [k for k, ws in self.win.items() if any(a <= t < b for a, b in ws)]

    def next_route(self, t):
        best = None
        for k, ws in self.win.items():
            for a, b in ws:
                if a > t and (best is None or a < best[0]):
                    best = (a, k)
        return best[1] if best else None

    # 依頼が出る
    def arrivals(self):
        for q in self.reqs:
            yield self.env.timeout(max(0.0, q["t"] - self.env.now))
            k = q["route"]
            if self.n > 0 and q["urgent"] and k not in self.idle_at.values():
                self.env.process(self.staff_walk([q], k))  # 決まり：空いているロボットがいなければ人が運ぶ
            else:
                self.queue[k].append(q)

    # 人が歩いて運ぶ
    def staff_walk(self, items, k):
        d = self.route_dist(k)
        v = self.c["staff_speed"]
        extra = self.c["staff_extra_s"]
        yield self.env.timeout(d / v + extra + self.c["staff_handoff_s"])
        for q in items:
            self.finish(q, "staff")
        self.staff_s[k] += 2 * d / v + extra + self.c["staff_handoff_s"]
        self.staff_walks[k] += 1

    def staff_route(self, k):
        """0台のとき：まとめるために staff_hold_min 分まで待ち、至急ならすぐ。時間帯が終わって残ればすぐ"""
        hold = self.c["staff_hold_min"] * 60
        while True:
            yield self.env.timeout(5)
            Q = self.queue[k]
            if not Q:
                if self.env.now > self.day_end + 3600:
                    return
                continue
            now = self.env.now
            if any(q["urgent"] for q in Q) or now - Q[0]["t"] >= hold or k not in self.active(now):
                items, self.queue[k] = Q[:], []
                self.env.process(self.staff_walk(items, k))

    # ロボット
    def leg(self, d):
        """片道。距離・速さ・一時停止・立ち往生"""
        s = d / self.c["robot_speed"]
        if d > 0 and self.rng.random() < self.c["pause_rate"]:
            s += self.rng.uniform(*self.c["pause_s"])
        stuck = 0.0
        if d > 0 and self.rng.random() < self.c["stuck_rate"]:
            stuck = self.c["stuck_resolve_s"]
            self.stuck_n += 1
        self.robot_m += d
        self.robot_run_s += s + stuck
        return s + stuck, stuck

    def robot(self, i):
        cap = self.c["compartments"]
        hold = self.r["max_hold_min"] * 60
        loc = None  # 最初は1つ目のルートの出発地にいる
        first = self.next_route(-1) or sorted(self.routes)[0]
        loc = self.routes[first]["from_point"]
        while True:
            now = self.env.now
            act = self.active(now)
            waiting = [k for k in self.routes if self.queue[k]]
            if not act and not waiting and self.next_route(now) is None:
                self.idle_at[i] = None
                return
            # 行き先のルート：残った依頼（時間帯の外）→ いま運行中で古い依頼があるもの → いま運行中 → 次の時間帯
            leftover = [k for k in waiting if k not in act]
            if leftover:
                k = min(leftover, key=lambda x: self.queue[x][0]["t"])
            elif act:
                k = min(act, key=lambda x: self.queue[x][0]["t"] if self.queue[x] else math.inf)
            else:
                k = self.next_route(now)
            home = self.robot_from(k, now)
            if loc != home:
                self.idle_at[i] = None
                s, _ = self.leg(self.dist(loc, home))
                yield self.env.timeout(s)
                loc = home
                continue
            Q = self.queue[k]
            go = bool(Q) and (len(Q) >= cap or any(q["urgent"] for q in Q) or now - Q[0]["t"] >= hold or k not in act)
            if not go:
                self.idle_at[i] = k
                yield self.env.timeout(5)
                continue
            self.idle_at[i] = None
            Q.sort(key=lambda q: (not q["urgent"], q["t"]))
            items, self.queue[k] = Q[:cap], Q[cap:]
            yield self.env.timeout(self.c["load_s"])
            dest = self.routes[k]["to_point"]
            self.trip_log.append({"route": k, "depart_s": round(self.env.now, 1), "from": home, "to": dest, "items": len(items),
                                  "robot": i})
            s, stuck = self.leg(self.dist(home, dest))
            yield self.env.timeout(s)
            pw = self.rng.expovariate(1 / self.c["pickup_wait_s"]) if self.c["pickup_wait_s"] > 0 else 0.0
            yield self.env.timeout(pw + self.c["unload_s"])
            for q in items:
                self.finish(q, "robot")
            self.robot_trips[k] += 1
            self.staff_s[k] += self.c["load_s"] + self.c["unload_s"] + stuck
            loc = dest

    def finish(self, q, by):
        q2 = dict(q)
        q2["done"] = self.env.now
        q2["by"] = by
        self.done.append(q2)

    def run(self):
        self.env.process(self.arrivals())
        if self.n == 0:
            for k in self.routes:
                self.env.process(self.staff_route(k))
        else:
            for i in range(self.n):
                self.env.process(self.robot(i))
        self.env.run(until=self.day_end + 3 * 3600)
        return self.summary()

    def summary(self):
        pk0, pk1 = (hm(x) - self.day0 for x in self.r["peak"])
        out = {"routes": {}, "robot_run_min": self.robot_run_s / 60, "robot_km": self.robot_m / 1000,
               "stuck": self.stuck_n, "not_done": len(self.reqs) - len(self.done)}
        for k in self.routes:
            D = [(q["done"] - q["t"]) / 60 for q in self.done if q["route"] == k]
            U = [(q["done"] - q["t"]) / 60 for q in self.done if q["route"] == k and q["urgent"]]
            P = [(q["done"] - q["t"]) / 60 for q in self.done if q["route"] == k and pk0 <= q["t"] < pk1]
            out["routes"][k] = {
                "n": len(D),
                "mean_min": statistics.mean(D) if D else None,
                "p90_min": sorted(D)[int(0.9 * (len(D) - 1))] if D else None,
                "max_min": max(D) if D else None,
                "urgent_n": len(U),
                "urgent_mean_min": statistics.mean(U) if U else None,
                "peak_mean_min": statistics.mean(P) if P else None,
                "robot_trips": self.robot_trips[k],
                "staff_walks": self.staff_walks[k],
                "staff_min": self.staff_s[k] / 60,
            }
        return out


def run_condition(A, L, n, over=None, seeds=None):
    p = params(A, over)
    seeds = seeds or p["r"]["seeds"]
    runs = [Day(A, L, p, n, s).run() for s in range(seeds)]

    def avg(get):
        v = [get(x) for x in runs]
        v = [x for x in v if x is not None]
        return statistics.mean(v) if v else None

    res = {"robots": n, "over": over or {}, "seeds": seeds, "routes": {},
           "robot_run_min": avg(lambda x: x["robot_run_min"]), "robot_km": avg(lambda x: x["robot_km"]),
           "stuck": avg(lambda x: x["stuck"]), "not_done": avg(lambda x: x["not_done"])}
    for k in A["routes"]:
        res["routes"][k] = {f: avg(lambda x, f=f: x["routes"][k][f]) for f in runs[0]["routes"][k]}
    res["staff_min"] = sum(res["routes"][k]["staff_min"] for k in A["routes"])
    jm, ju = p["r"]["judge_mean_min"], p["r"]["judge_urgent_min"]
    res["late"] = {k: bool((r["mean_min"] or 0) >= jm or (r["urgent_mean_min"] or 0) >= ju) for k, r in res["routes"].items()}
    return res


SWEEPS = [  # 仮置きの値を動かす（ロボット1台・2台で）
    ("pickup_wait_s", [0, 60, 180, 300]),
    ("req_mult", [0.5, 1.0, 1.5, 2.0]),
    ("robot_speed", [0.4, 0.5, 0.8]),
    ("max_hold_min", [5, 10, 20]),
    ("stuck_rate", [0.0, 0.01, 0.05]),
    ("layout_scale", [1.0, 1.5, 2.0, 2.5]),     # 案2 の当たり：道を何倍にすると発表に届くか
    ("staff_extra_s", [0, 60, 120, 180, 240]),  # 案3 の当たり：人が運ぶときの歩く以外の手間
    ("route_plan", ["廊下だけ", "時間で切替", "裏口だけ"]),  # h2：青の道の決め方
]
ZERO_TOO = ("req_mult", "layout_scale", "staff_extra_s")  # 0台（比べるもと）も同じ値で回し直す


def main():
    ap = argparse.ArgumentParser()
    ap.add_argument("--out", default=None)
    ap.add_argument("--layout", default=None, help="フロアの形を差し替える（例 ../hospital_layouts/hospital_h0b.json）")
    args = ap.parse_args()
    A, L = load_inputs(args.layout)
    if args.layout:
        A["model"] = A["model"] + "_" + L["meta"].get("variant", "x")
    base = [run_condition(A, L, n) for n in A["rules"]["robots"]["value"]]
    zero = base[0]
    sweeps = []
    for key, vals in SWEEPS:
        for v in vals:
            o = {key: v}
            z = run_condition(A, L, 0, o) if key in ZERO_TOO else zero
            for n in (1, 2):
                r = run_condition(A, L, n, o)
                r["saved_staff_min"] = z["staff_min"] - r["staff_min"]
                r["saved_by_route"] = {k: z["routes"][k]["staff_min"] - r["routes"][k]["staff_min"] for k in A["routes"]}
                sweeps.append(r)
    for r in base:
        r["saved_staff_min"] = zero["staff_min"] - r["staff_min"]
        r["saved_by_route"] = {k: zero["routes"][k]["staff_min"] - r["routes"][k]["staff_min"] for k in A["routes"]}
    result = {"model": A["model"], "layout": L["meta"]["name"], "base": base, "sweeps": sweeps}
    text = report(A, result)
    print(text)
    if args.out:
        out = Path(args.out)
        out.mkdir(parents=True, exist_ok=True)
        (out / f"results_{A['model']}.json").write_text(json.dumps(result, ensure_ascii=False, indent=1), encoding="utf-8")
        (out / f"summary_{A['model']}.txt").write_text(text, encoding="utf-8")


def f(x, d=1):
    return "-" if x is None else f"{x:.{d}f}"


def report(A, R):
    names = {k: v["name"] for k, v in A["routes"].items()}
    L = [f"試算 {R['model']}（{R['layout']}）乱数の種 {R['base'][0]['seeds']} 個の平均", ""]
    L.append("■ 標準の条件")
    for r in R["base"]:
        L.append(f"ロボット{r['robots']}台  人が搬送に使った時間 {f(r['staff_min'])}分/日（0台より {f(r['saved_staff_min'])}分減）"
                 + (f"  ロボットが走った {f(r['robot_run_min'],0)}分・{f(r['robot_km'],2)}km" if r["robots"] else ""))
        for k in ["green", "blue", "red"]:
            x = r["routes"][k]
            L.append(f"  {names[k]} 依頼{f(x['n'],0)}件 届くまで 平均{f(x['mean_min'])}分 90%{f(x['p90_min'])}分 最大{f(x['max_min'])}分"
                     f" 至急{f(x['urgent_mean_min'])}分 山場{f(x['peak_mean_min'])}分"
                     f" 便{f(x['robot_trips'])} 人が歩いた{f(x['staff_walks'])}回 人の時間{f(x['staff_min'])}分"
                     + ("  ← 間に合わない" if r["late"][k] else ""))
    L.append("")
    L.append("■ 仮置きの値を動かす（青のルートの届くまでの平均・至急・人の時間の減り）")
    for r in R["sweeps"]:
        (k, v), = r["over"].items()
        b = r["routes"]["blue"]
        sb = r.get("saved_by_route", {})
        L.append(f"{k}={v} ロボット{r['robots']}台  減り 青{f(sb.get('blue'))}分 赤{f(sb.get('red'))}分（1便あたり 青{f(sb.get('blue',0)/max(r['routes']['blue']['robot_trips'] or 1,1e-9))}分 赤{f(sb.get('red',0)/max(r['routes']['red']['robot_trips'] or 1,1e-9))}分）  青 平均{f(b['mean_min'])}分 至急{f(b['urgent_mean_min'])}分 山場{f(b['peak_mean_min'])}分"
                 f"  人の時間 {f(r['saved_staff_min'])}分減" + ("  ← 間に合わない：" + "・".join(names[x] for x, y in r["late"].items() if y) if any(r["late"].values()) else ""))
    return "\n".join(L)


if __name__ == "__main__":
    main()
```

#### 試算 h2 の結果（summary_h2.txt の全文）

```text
試算 h2（仮の病院 h0（外来の階））乱数の種 10 個の平均

■ 標準の条件
ロボット0台  人が搬送に使った時間 52.8分/日（0台より 0.0分減）
  緑 依頼3件 届くまで 平均5.7分 90%4.7分 最大9.7分 至急0.7分 山場-分 便0.0 人が歩いた1.8回 人の時間1.9分
  青 依頼8件 届くまで 平均9.7分 90%11.8分 最大11.8分 至急1.8分 山場9.1分 便0.0 人が歩いた6.5回 人の時間20.8分
  赤 依頼13件 届くまで 平均9.0分 90%12.2分 最大12.2分 至急2.2分 山場-分 便0.0 人が歩いた7.6回 人の時間30.1分
ロボット1台  人が搬送に使った時間 14.5分/日（0台より 38.3分減）  ロボットが走った 100分・2.92km
  緑 依頼3件 届くまで 平均7.3分 90%6.2分 最大11.3分 至急2.2分 山場-分 便1.7 人が歩いた0.1回 人の時間1.5分
  青 依頼8件 届くまで 平均12.7分 90%15.3分 最大16.3分 至急4.7分 山場12.4分 便6.4 人が歩いた0.1回 人の時間5.7分
  赤 依頼13件 届くまで 平均12.4分 90%15.9分 最大17.3分 至急4.7分 山場-分 便7.4 人が歩いた0.3回 人の時間7.4分
ロボット2台  人が搬送に使った時間 13.6分/日（0台より 39.2分減）  ロボットが走った 111分・3.27km
  緑 依頼3件 届くまで 平均7.0分 90%6.0分 最大11.0分 至急2.5分 山場-分 便1.8 人が歩いた0.0回 人の時間1.5分
  青 依頼8件 届くまで 平均12.6分 90%15.1分 最大16.1分 至急5.4分 山場12.1分 便6.5 人が歩いた0.0回 人の時間5.8分  ← 間に合わない
  赤 依頼13件 届くまで 平均12.2分 90%15.6分 最大17.2分 至急5.2分 山場-分 便7.6 人が歩いた0.0回 人の時間6.3分  ← 間に合わない

■ 仮置きの値を動かす（青のルートの届くまでの平均・至急・人の時間の減り）
pickup_wait_s=0 ロボット1台  減り 青15.1分 赤22.6分（1便あたり 青2.4分 赤3.1分）  青 平均11.6分 至急3.3分 山場11.1分  人の時間 38.1分減
pickup_wait_s=0 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均11.6分 至急3.8分 山場11.1分  人の時間 39.2分減
pickup_wait_s=60 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
pickup_wait_s=60 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
pickup_wait_s=180 ロボット1台  減り 青14.9分 赤22.2分（1便あたり 青2.4分 赤3.1分）  青 平均14.8分 至急6.8分 山場15.0分  人の時間 37.5分減  ← 間に合わない：青
pickup_wait_s=180 ロボット2台  減り 青14.8分 赤23.6分（1便あたり 青2.3分 赤3.1分）  青 平均14.2分 至急8.4分 山場13.7分  人の時間 38.8分減  ← 間に合わない：青・赤
pickup_wait_s=300 ロボット1台  減り 青14.7分 赤22.2分（1便あたり 青2.4分 赤3.1分）  青 平均17.0分 至急7.9分 山場17.0分  人の時間 37.3分減  ← 間に合わない：青・赤
pickup_wait_s=300 ロボット2台  減り 青14.6分 赤23.1分（1便あたり 青2.2分 赤3.0分）  青 平均16.0分 至急11.7分 山場15.4分  人の時間 38.1分減  ← 間に合わない：緑・青・赤
req_mult=0.5 ロボット1台  減り 青8.8分 赤16.4分（1便あたり 青2.4分 赤3.2分）  青 平均13.5分 至急3.8分 山場13.6分  人の時間 25.4分減
req_mult=0.5 ロボット2台  減り 青9.0分 赤16.4分（1便あたり 青2.4分 赤3.1分）  青 平均13.6分 至急4.7分 山場13.5分  人の時間 25.7分減  ← 間に合わない：赤
req_mult=1.0 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
req_mult=1.0 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
req_mult=1.5 ロボット1台  減り 青21.1分 赤29.0分（1便あたり 青2.3分 赤2.9分）  青 平均12.5分 至急4.4分 山場12.4分  人の時間 50.5分減
req_mult=1.5 ロボット2台  減り 青21.4分 赤32.8分（1便あたり 青2.3分 赤3.0分）  青 平均12.6分 至急4.5分 山場12.3分  人の時間 54.6分減  ← 間に合わない：赤
req_mult=2.0 ロボット1台  減り 青25.1分 赤33.4分（1便あたり 青2.4分 赤3.0分）  青 平均12.0分 至急4.5分 山場12.0分  人の時間 58.9分減
req_mult=2.0 ロボット2台  減り 青25.7分 赤39.6分（1便あたり 青2.3分 赤3.1分）  青 平均12.0分 至急4.5分 山場12.1分  人の時間 65.7分減  ← 間に合わない：赤
robot_speed=0.4 ロボット1台  減り 青14.9分 赤22.2分（1便あたり 青2.4分 赤3.1分）  青 平均13.3分 至急4.9分 山場13.1分  人の時間 37.5分減
robot_speed=0.4 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均13.2分 至急5.9分 山場12.7分  人の時間 39.2分減  ← 間に合わない：青・赤
robot_speed=0.5 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
robot_speed=0.5 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
robot_speed=0.8 ロボット1台  減り 青15.1分 赤23.2分（1便あたり 青2.4分 赤3.1分）  青 平均11.6分 至急3.9分 山場11.3分  人の時間 38.7分減
robot_speed=0.8 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均11.6分 至急4.0分 山場11.0分  人の時間 39.2分減
max_hold_min=5 ロボット1台  減り 青14.1分 赤20.1分（1便あたり 青1.9分 赤2.2分）  青 平均9.3分 至急4.0分 山場9.0分  人の時間 34.1分減
max_hold_min=5 ロボット2台  減り 青13.9分 赤22.1分（1便あたり 青1.9分 赤2.4分）  青 平均9.3分 至急4.7分 山場9.0分  人の時間 36.0分減  ← 間に合わない：赤
max_hold_min=10 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
max_hold_min=10 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
max_hold_min=20 ロボット1台  減り 青15.2分 赤23.8分（1便あたり 青2.7分 赤4.2分）  青 平均18.9分 至急4.1分 山場18.7分  人の時間 39.7分減  ← 間に合わない：青・赤
max_hold_min=20 ロボット2台  減り 青15.9分 赤25.1分（1便あたり 青2.7分 赤4.2分）  青 平均18.8分 至急4.7分 山場18.3分  人の時間 41.7分減  ← 間に合わない：青・赤
stuck_rate=0.0 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
stuck_rate=0.0 ロボット2台  減り 青15.4分 赤23.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.6分 至急5.3分 山場12.0分  人の時間 39.6分減  ← 間に合わない：青・赤
stuck_rate=0.01 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
stuck_rate=0.01 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
stuck_rate=0.05 ロボット1台  減り 青14.9分 赤22.2分（1便あたり 青2.3分 赤3.0分）  青 平均12.7分 至急4.7分 山場12.5分  人の時間 37.5分減
stuck_rate=0.05 ロボット2台  減り 青14.8分 赤22.4分（1便あたり 青2.3分 赤2.9分）  青 平均12.7分 至急5.4分 山場12.2分  人の時間 37.6分減  ← 間に合わない：青・赤
layout_scale=1.0 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
layout_scale=1.0 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
layout_scale=1.5 ロボット1台  減り 青23.9分 赤35.1分（1便あたり 青3.8分 赤4.9分）  青 平均14.1分 至急5.6分 山場13.8分  人の時間 60.0分減  ← 間に合わない：青・赤
layout_scale=1.5 ロボット2台  減り 青24.3分 赤37.6分（1便あたり 青3.7分 赤5.0分）  青 平均13.9分 至急6.6分 山場13.5分  人の時間 62.9分減  ← 間に合わない：青・赤
layout_scale=2.0 ロボット1台  減り 青32.4分 赤47.1分（1便あたり 青5.2分 赤6.6分）  青 平均15.6分 至急6.5分 山場15.3分  人の時間 81.1分減  ← 間に合わない：青・赤
layout_scale=2.0 ロボット2台  減り 青33.6分 赤51.4分（1便あたり 青5.2分 赤6.8分）  青 平均15.4分 至急8.0分 山場14.9分  人の時間 86.7分減  ← 間に合わない：青・赤
layout_scale=2.5 ロボット1台  減り 青41.3分 赤59.3分（1便あたり 青6.7分 赤9.0分）  青 平均17.6分 至急7.7分 山場17.0分  人の時間 102.8分減  ← 間に合わない：青・赤
layout_scale=2.5 ロボット2台  減り 青42.3分 赤65.0分（1便あたり 青6.6分 赤8.6分）  青 平均16.7分 至急8.1分 山場16.3分  人の時間 109.6分減  ← 間に合わない：青・赤
staff_extra_s=0 ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
staff_extra_s=0 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
staff_extra_s=60 ロボット1台  減り 青21.5分 赤30.1分（1便あたり 青3.4分 赤4.1分）  青 平均12.7分 至急4.9分 山場12.4分  人の時間 53.7分減
staff_extra_s=60 ロボット2台  減り 青21.5分 赤31.4分（1便あたり 青3.3分 赤4.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 55.1分減  ← 間に合わない：青・赤
staff_extra_s=120 ロボット1台  減り 青27.9分 赤37.4分（1便あたり 青4.4分 赤5.1分）  青 平均12.7分 至急5.2分 山場12.4分  人の時間 69.1分減  ← 間に合わない：青・赤
staff_extra_s=120 ロボット2台  減り 青28.0分 赤39.0分（1便あたり 青4.3分 赤5.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 71.0分減  ← 間に合わない：青・赤
staff_extra_s=180 ロボット1台  減り 青34.3分 赤44.7分（1便あたり 青5.4分 赤6.0分）  青 平均12.7分 至急5.4分 山場12.4分  人の時間 84.5分減  ← 間に合わない：青・赤
staff_extra_s=180 ロボット2台  減り 青34.5分 赤46.6分（1便あたり 青5.3分 赤6.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 86.9分減  ← 間に合わない：青・赤
staff_extra_s=240 ロボット1台  減り 青40.7分 赤52.0分（1便あたり 青6.4分 赤7.0分）  青 平均12.7分 至急5.7分 山場12.4分  人の時間 99.9分減  ← 間に合わない：青・赤
staff_extra_s=240 ロボット2台  減り 青41.0分 赤54.2分（1便あたり 青6.3分 赤7.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 102.8分減  ← 間に合わない：青・赤
route_plan=廊下だけ ロボット1台  減り 青15.1分 赤22.8分（1便あたり 青2.4分 赤3.1分）  青 平均12.7分 至急4.7分 山場12.4分  人の時間 38.3分減
route_plan=廊下だけ ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均12.6分 至急5.4分 山場12.1分  人の時間 39.2分減  ← 間に合わない：青・赤
route_plan=時間で切替 ロボット1台  減り 青14.5分 赤23.0分（1便あたり 青2.3分 赤3.1分）  青 平均14.0分 至急5.6分 山場14.7分  人の時間 37.8分減  ← 間に合わない：青・赤
route_plan=時間で切替 ロボット2台  減り 青15.0分 赤23.8分（1便あたり 青2.3分 赤3.1分）  青 平均13.9分 至急7.0分 山場14.5分  人の時間 39.2分減  ← 間に合わない：青・赤
route_plan=裏口だけ ロボット1台  減り 青14.7分 赤22.9分（1便あたり 青2.4分 赤3.1分）  青 平均14.8分 至急5.6分 山場14.6分  人の時間 37.9分減  ← 間に合わない：青・赤
route_plan=裏口だけ ロボット2台  減り 青14.7分 赤23.5分（1便あたり 青2.3分 赤3.1分）  青 平均14.7分 至急6.0分 山場14.4分  人の時間 38.6分減  ← 間に合わない：青・赤
```



## 作業ログ ― Unity で病院の廊下を建て、速さごとの問題を数える

### 数える問題5つと、回す条件

数える問題はエイイチと決めました。1 急に止まった（走っていて1秒以内に止まった）、2 ひやり（人とロボットの外形が0.3m未満）、3 人がよけさせられた（2m以内で人が止まるか向きを変えた）、4 立ち往生（30秒以上動けず人が動かしに行った）、5 車いす・杖の人・ストレッチャーの進む先1.5m以内を横切った。速さは0.4・0.5・0.6・0.8m/秒、大廊下に同時にいる人は空いている20人・混んでいる60人（仮置き）です。Unity は値を自分で決めず、サイトから書き出した hospital-unity-params.json を読みます。

#### tools/hospital_sim/export_unity_params.py（Unity が読む条件を書き出すコード）

```python
# -*- coding: utf-8 -*-
"""病院の搬送ロボットの Unity が読む条件 hospital-unity-params.json を、前提の表（assumptions.json）とフロアの形から書き出す。

Unity は値を自分で決めず、このファイルを読む（配膳の serving-robot-params.json と同じ考え方。正はサイト側）。
使い方：python3 export_unity_params.py
"""
import hashlib
import json
from pathlib import Path

HERE = Path(__file__).resolve().parent


def day_schedule(A):
    """1日を通して回すときの、青のロボットの便の時刻表（試算 hospital_sim.py の1台から書き出す）。
    Unity はこの時刻に積む所を出る（依頼の出方・まとめ方・ほかのルートへ行っている間は試算が決める）"""
    import hospital_sim as H
    A2, L = H.load_inputs()
    day0 = H.hm(A2["rules"]["day"]["value"][0])
    out = {"what": "青のロボットの便の時刻表。plan × 速さ × 種。depart は 7:30 からの秒、from は積む所（表＝内科外来の処置室／裏口）",
           "model": A2["model"], "day_start": A2["rules"]["day"]["value"][0], "plans": {}}
    for plan in ("廊下だけ", "時間で切替", "裏口だけ"):
        out["plans"][plan] = {}
        for sp in (0.5, 0.6, 0.8):
            p = H.params(A2, {"route_plan": plan, "robot_speed": sp})
            out["plans"][plan][str(sp)] = []
            for seed in range(A2["rules"]["seeds"]["value"]):
                d = H.Day(A2, L, p, 1, seed)
                d.run()
                out["plans"][plan][str(sp)].append([{"depart": t["depart_s"], "from": t["from"]} for t in d.trip_log if t["route"] == "blue"])
    return out


def main():
    A = json.loads((HERE / "assumptions.json").read_text(encoding="utf-8"))
    lay_path = (HERE / A["layout"]).resolve()
    L = json.loads(lay_path.read_text(encoding="utf-8"))
    U = A["unity"]
    lb = (HERE / "../hospital_layouts/hospital_h0b.json").resolve()
    LB = json.loads(lb.read_text(encoding="utf-8"))
    c = {k: v["value"] for k, v in A["common"].items()}
    route = U["route"]["value"]
    out = {
        "about": "病院の搬送ロボットの Unity（ServiceSim の病院の場面）が読む条件。export_unity_params.py が assumptions.json から書き出す。直すときは assumptions.json を直して書き出し直す",
        "model": A["model"],
        "layout": {"file": "tools/hospital_layouts/hospital_h0.json",
                   "md5": hashlib.md5(lay_path.read_bytes()).hexdigest(),
                   "name": L["meta"]["name"]},
        "route": {"key": route, **{k: A["routes"][route][k] for k in ("from_point", "to_point")},
                  "path": L["routes"][route]["path"], "distance_m": L["routes"][route]["distance_m"],
                  "what": U["route"]["what"]},
        "robot": {"speeds_mps": U["speeds"]["value"], "speed_max_mps": c["robot_speed_max"],
                  "min_passage_m": c["min_passage_m"], "size_m": {"w": 0.459, "d": 0.549, "h": 1.081},
                  "size_source": "KEENON 公式 BUTLERBOT W3"},
        "people": {"crowd": U["crowd_people"]["value"], "mix": U["people_mix"]["value"],
                   "stretcher_per_h": U["stretcher_per_h"]["value"]},
        "count_rules": {k: {"value": v["value"], "unit": v["unit"], "what": v["what"]} for k, v in U["count_rules"].items()},
        "braking": {k: (v["value"] if isinstance(v, dict) else v) for k, v in U["braking"].items()},
        "loading_point": U["loading_point"]["value"],
        "loading_point_what": U["loading_point"]["what"],
        "count_shape": U["count_shape"]["value"],
        "near_miss_speed_mps": U["near_miss_speed_mps"]["value"],
        "near_miss_speed_basis": U["near_miss_speed_basis"]["value"],
        "sensor_width_m": U["sensor_width_m"]["value"],
        "wheelchair_avoid_stopped_robot": U["wheelchair_avoid_stopped_robot"]["value"],
        "near_miss_split_by_robot_moving": U["near_miss_split_by_robot_moving"]["value"],
        "east_hall_people_ratio": U["east_hall_people_ratio"]["value"],
        "layout_back_door": {"file": "tools/hospital_layouts/hospital_h0b.json",
                             "md5": hashlib.md5(lb.read_bytes()).hexdigest(),
                             "name": LB["meta"]["name"],
                             "blue_path": LB["routes"]["blue"]["path"], "blue_distance_m": LB["routes"]["blue"]["distance_m"]},
        "staff_corridor_interval_s": U["staff_corridor_interval_s"]["value"],
        "stretcher_yield": U["stretcher_yield"]["value"],
        "crowd_by_time": U["crowd_by_time"]["value"],
        "back_door_hours": A["rules"]["back_door_hours"]["value"],
        "day_schedule": day_schedule(A),
        "waiting_near_miss": U["waiting_near_miss"]["value"],
        "day_end_rule": U["day_end_rule"]["value"],
        "switch_move": U["switch_move"]["value"],
        "seeds": U["seeds"]["value"],
        "basis": {k: U[k]["basis"] for k in ("speeds", "crowd_people", "people_mix", "stretcher_per_h")},
    }
    (HERE / "hospital-unity-params.json").write_text(json.dumps(out, ensure_ascii=False, indent=1), encoding="utf-8")
    print("wrote hospital-unity-params.json")


if __name__ == "__main__":
    main()
```

### 依頼127：速いほど1往復あたりの問題は減った。ただし止まり方が速さで変わっていなかった

混んでいるとき、ひやりは0.4m/秒で1往復19.9回、0.8m/秒で10.9回。廊下にいる時間が短くなるからです。1日の便の数は依頼の数で決まって速さでは変わらないので、1日あたりも減ることになります。ただ、Unity のロボットは速さに関係なく同じ所で止まっていて、速い方が安全とはまだ言えませんでした。問題の97%は、積む所から縦廊下の角までの約12mに集まっていました。

![依頼127。速さごとの1往復あたりの問題](https://pixelstomotors.com/media/LOG477_06_u127_speed.png)
![依頼127。問題が起きた場所（積む所から縦廊下の角に集まる）](https://pixelstomotors.com/media/LOG477_07_hotspots127.png)

#### 依頼127 の依頼文（病院の廊下を建てて速さごとに問題を数える）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 600
---
# 依頼127：病院の廊下（青のルート）を建て、搬送ロボットの速さごとに廊下で起きる問題を数える

サービスロボット導入シミュレーションの病院編の最初の Unity の依頼。サイトの試算（SimPy）では答えられない「ロボットを速くしたら、どんな問題がどんな頻度で起きるか」を Unity で数える。病院はこの表を見て、自分で速さを決められるようにしたい（2026-11-09 エイイチと決めた）。

**配膳の場面・配膳の実行ファイル・配膳の台帳には触らない。** 病院は別の場面（例 Assets/ServiceSim/Hospital/）として作る。配膳と共通の部品（ロボットの道探し・よけ方・センサーで止まる・人のよけ方）は、中身を変えずに使ってよい。共通の部品を直さないと作れないときは、直さずに止めて報告する。
**エイイチは見ていない。人に聞かないと進めない所に当たったら、その項目は止めて報告に書き、ほかは続ける。夜の間も続けてよい。**

## 正（読むもの）
- 条件：p2m-site main の `tools/hospital_sim/hospital-unity-params.json`（md5 9887bf36e0384e0b3d044840c8d94f54）。値を Unity で決めない。違う md5 なら回さずに報告して終わる
- フロアの形：p2m-site main の `tools/hospital_layouts/hospital_h0.json`（params の layout.md5 と一致すること）。部屋は通れない箱、廊下（corridors の rect）が床。単位 m、x 右・y 奥 → Unity の X・Z
- 範囲：params の route（青のルート）の道の上と、外来の大廊下（x0〜70 の人の多い区間）。そのほかは建てなくてよい

## 始める前に確かめること（違えば回さずに報告して終わる）
1. 作業場所に保留がない（配膳の依頼126 の後の状態）。Unity・night_runner・rec_runner が動いていない。KIOXIA がマウント済み
2. 上の2つのファイルの md5

## 1. 病院の場面を作る
- 床と壁：hospital_h0.json から建てる。外来の大廊下 4.0m・職員の中廊下 2.1m・縦の廊下 2.1m（玄関の通りは 8.0m）
- ロボット：W3 の大きさ（params の robot.size_m）。積む所（内科外来の処置室）と届け先（検査部の検体受付）を往復し続ける。往復の間の止まり（積む・受け取りを待つ）は入れない（廊下で起きることだけを数えるため）。速さは params の speeds の1つを引数で選ぶ。センサーで止まる・よける・道探しは配膳の標準と同じ
- 人：外来の大廊下に params の people.crowd の人数を保つ（出入りしても数が一定になるように）。内訳は people.mix。歩く速さ・止まり方・よけ方は Unity だけの値として決めてよい（報告に一覧で書く）。目安：歩く患者・付き添い 1.0〜1.3m/秒、杖の人 0.6m/秒、車いす 0.8m/秒、スタッフ 1.3m/秒。患者の一部は待合の前で立ち止まる。スタッフはロボットをよける（配膳と同じ）。杖の人・車いすは自分からは大きくよけない
- ストレッチャー：params の stretcher_per_h の回数、職員の中廊下と縦の廊下を通す（押す人1人を含めた大きさ）
- 瞬間移動はさせない。同じ条件・同じ種なら同じ結果になるようにする

## 2. 数えるもの（params の count_rules が正。線の値を変えない）
1回の往復（片道ずつ）ごとに数える。
1. 急に止まった：走っている状態から sudden_stop 秒以内に止まった回数
2. ひやり：人（車いす・ストレッチャーを含む）とロボットの外形どうしが near_miss_m 未満になった回数（同じ相手と離れずに続いている間は1回）。一番近づいた距離も残す
3. 人がよけさせられた：ロボットから yield_m 以内で、人が止まるか向きを変えた回数
4. 立ち往生：stuck_s 秒以上動けなかった回数（解けるまでの秒も。人が動かしに行く作りは配膳と同じ）
5. 車いす・杖の人・ストレッチャーの進む先 cross_front_m 以内をロボットが横切った回数
あわせて、片道にかかった秒・平均の速さ（実際に出ていた速さ）を残す。

## 3. 回す
- 確かめ（違えば 4 は回さない）：0.5m/秒・混んでいる・種0 を2回回して一致すること、瞬間移動 0。0.8m/秒・空いている・種0 で往復が最後まで回ること
- 本番：速さ4つ × 混み具合2つ × 種0〜9 ＝ 80回。1回は店の時間で60分（画面なし・同時4本まで）
- 出力：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261109_speed127/（回ごとの往復の記録・数えた問題の一覧（いつ・どこ x,z・相手の種類）・条件ごとのまとめ）。配膳の台帳には書かない。この依頼の索引 CSV を同じフォルダに置く

## 4. 録画（3 の本番が通れば撮る）
- 混んでいる・種0 で、0.5m/秒 と 0.8m/秒 を2分ずつ、真上から外来の大廊下の人の多い区間を撮り、左右に並べた動画を1本。数えた問題が起きた所に印（色は問題の種類ごと）を出す。置き場所は 3 と同じフォルダ

## 止める線
瞬間移動が1回でも出たとき、または同じ種の2回が違ったとき。止めたら報告に書き、ほかの項目は続ける。

## 報告
claude_code_reports/20261109_hospital_127.txt に：始める前の確かめ、1 で作ったもの（ファイルと場所・Unity だけの値の一覧）、確かめの結果、
表（速さ×混み具合ごと、種10個の中央値と最小・最大）：往復の数・片道の秒・実際の平均の速さ・1〜5 の問題の数（1往復あたり）・ひやりの一番近い距離、
問題が多かった場所の上から3つ（どこで・何と・なぜ）と上から見た図の置き場所、4 の動画の名前と長さ、check-in の番号、決めてほしいこと（直し方の候補は作らない）。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

#### 依頼127 の報告（依頼箱の結果の全文）

```markdown
# 結果：20261109_127_病院の廊下を建てて搬送ロボットの速さごとに起きる問題を数える

- 状態：完了
- 始めた時刻：2026-11-09 11:32
- 終わった時刻：2026-11-09 12:48（76分）
- 作業フォルダ：/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき：作業フォルダで `claude --resume 1b38a38e-a86b-410b-93d7-4ac7c782ec37`
- 止められた操作：1件（いちばん下に一覧）

## Claude Code の報告

やったこと
- 始める前の確かめをしました。作業場所は cs:109 で保留はありませんでした。Unity・night_runner・rec_runner は動いておらず、KIOXIA はマウント済みでした。params の md5 は 9887bf36…、形の md5 は a29cd1d9… で、params の layout.md5 と一致しました。
- 病院の場面を `Assets/ServiceSim/Hospital/` に新しく作りました。建てたのは外来の大廊下 x0〜70・西の縦廊下・職員の中廊下です。
  - ロボットは W3 の大きさで1台、処置室と検体受付を止まりなしで往復し続けます。
  - 人は外来の大廊下に 20 人／60 人を保ち、内訳は params のとおりです。ストレッチャーは 2 回/時です。
  - 配膳と共通の部品は1行も変えていません。
  - 病院だけの実行ファイル（`Builds/hospital127/`）を作りました。配膳の場面・配膳の実行ファイル・配膳の台帳には触っていません。
- 立ち往生の助けに「60 秒着けなければ次のスタッフに交代する」が抜けていたのを見つけ、足しました（cs:111）。最初に回した 80 回（cs:110）は `old_cs110/` に退避し、全部を cs:111 で回し直しました。
- 確かめの回、本番 80 回、録画 2 回を回しました。まとめの表・上から見た図・左右に並べた動画を作り、報告を書きました。

結果
- 確かめ：0.5 m/秒・混んでいる・種0 を2回回し、記録4つが1バイトも違いませんでした。瞬間移動は 0 です。0.8 m/秒・空いている・種0 は 35 片道を最後まで回りました。
- 本番 80 回はすべて最後まで回りました。瞬間移動は 0 で、人数はいつも決めた人数のままでした。1回は約 45〜60 秒で回ります。
- 1往復あたりの数（混んでいる、種10個の中央値）：

| 速さ | 実際の平均の速さ | 急に止まった | ひやり | 人がよけさせられた | 立ち往生 | 横切り |
|---|---|---|---|---|---|---|
| 0.4 m/秒 | 0.37 m/秒 | 6.5 | 19.9 | 8.3 | 0.38 | 0.91 |
| 0.8 m/秒 | 0.72 m/秒 | 3.4 | 10.9 | 4.6 | 0.19 | 0.66 |

- 1往復あたりは速いほど少なくなります。1時間あたりの数は速さでほとんど変わらず、速いほど往復が多いためです。
- ひやりの一番近い距離は、どの条件でもマイナス（外形の重なり、中央値 −0.08〜−0.09 m）でした。主な理由は、ロボットを丸として動かしていることです（決めてほしいことの1）。
- 問題が多かった場所（80 回の合計 15,740 回のうち）：
  1. 大廊下の処置室から縦廊下の手前まで（x14〜22）：57%。ロボットが北の壁ぞいを走り、出入りする人とすれ違って止まります。
  2. 大廊下と西の縦廊下の角：24%。人の流れを斜めに横切るため、横切りの 55% がここです。
  3. 処置室の前：16%。積む所が人の流れの中にあり、立ち往生の 39% がここです。
- 上から見た図は `hotspots127.png` です（KIOXIA の出力フォルダと、報告の隣の `_files` フォルダに置きました）。
- 動画は `hospital127_0.5vs0.8_busy_s0.mp4`、長さ 120.0 秒です。
- check-in は cs:110 と cs:111 です。
- 報告の最後の行は「判定：止めた（決めてほしいことあり）」にしました。

変えたファイル
- `Assets/ServiceSim/Hospital/` の中だけ（すべて新しいファイル）：
  - `HospitalLayout.cs`、`HospitalRun.cs`、`HospitalWalker.cs`、`Editor/HospitalSetup.cs`
  - `Hospital.unity`、`Data/` のサイトの写し2つ、`Materials/` の7つ
- KIOXIA の `hospital/20261109_speed127/`：
  - 索引 `index127.csv`、回ごとの記録 `runs/`、まとめ（`summary127.csv`・`per_run127.csv`・`hotspots127.csv`・`hotspots127.png`）
  - 動画、`tools/`（回し係・まとめ・動画の3つ）
- 報告：`claude_code_reports/20261109_hospital_127.txt` と `20261109_hospital_127_files/`

決めてほしいこと
1. ロボットの形：配膳の部品は丸い体で動くので、丸の直径を W3 の長い辺 0.549 m にしました。数えるときは長方形で見ているため、人が角に重なり、ひやりの距離がマイナスになります。この表し方でよいか。
2. ロボットの地図はサイトに無いので、Unity で床の形から作りました（ふだんの幅 1.0 m は配膳と同じ、通れる幅 0.7 m は params）。これでよいか、サイトで作るか。
3. ロボットはサイトの青の線の上を走りません。大廊下では北の壁ぞい、職員の中廊下では南の壁ぞいを走ります（道探しは配膳と同じ）。このままでよいか。
4. 止まる点を、扉から廊下の中へ 0.5 m の所にしました。そのため積む所が人の流れの中になっています。部屋の中で止まる形にするか。
5. 数え方の細かい線をこちらで決めました（報告の 1-3 に一覧）。
   - 「走っている状態」は設定の速さの半分以上。
   - 「向きを変えた」は 30 度より開いたとき。
   - 横切りはロボットと相手の向きが 45〜135 度のとき。
   - 人がよけさせられたは、ロボットのせいか、ほかの人のせいかを分けていません。

   これでよいか。
6. 人・ストレッチャーの Unity だけの値、扉の置き方、ストレッチャーの通り道、録画の範囲（x0〜40）でよいか。

## 止められた操作

- {"tool_name": "Bash", "tool_use_id": "toolu_01Jq46V4hjeqV5b2vdCTsL5b", "tool_input": {"command": "cd /Users/shimazueiichi/Robotics_UX/ServiceSim; rm -rf /tmp/h127/rec; mkdir -p /tmp/h127/rec; E=Builds/hospital127/HospitalSim.app/Contents/MacOS/ServiceSim; time $E -batchmode -h127Speed 0.8 -h127Crowd busy -h127Seed 0 -h127Out /tmp/h127/rec -h127Rec on -logFile /tmp/h127/rec/log.txt 2>&1 | tail -1; grep -E \"\\[Hospital\\]|Exception\" /tmp/h127/rec/log.txt | head; ls /tmp/h127/rec/*/frames | wc -l
```

### 依頼132：止まるまでの距離を速さで変えると、0.8m/秒で止まりきれない回数が増え始めた

止まるまでの距離＝速さ×0.2秒＋速さ²÷(2×0.5m/秒²)（どちらも仮置き）。0.4m/秒で約0.24m、0.8m/秒で約0.80m です。止まりきれなかった回数（動いたまま人と重なった）は、廊下・混んでいるとき、1往復あたり0.6m/秒の0.92回が一番少なく、0.8m/秒で1.12回に増えました。積む所を部屋の中に入れても、問題は扉の口に移っただけで減りませんでした。

![依頼132。止まりきれなかった・速いままのひやり・急に止まった](https://pixelstomotors.com/media/LOG477_08_u132_brake.png)

#### 依頼132 の依頼文（速さで変わる止まり方を入れ、積む所を部屋の中と比べる）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 480
---
# 依頼132：病院の搬送ロボットに「速さで変わる止まり方」を入れ、積む所を廊下と部屋の中で比べる

依頼127 の報告（claude_code_reports/20261109_hospital_127.txt）を読んで、エイイチと決めたこと（2026-11-09）：
- 依頼127 では速いほど1往復あたりの問題が減ったが、ロボットが速さに関係なく同じ所で止まっていたので、速さの悪い面（止まりきれない・速いまま近づく）が表れていなかった。これを入れる
- 問題の97%が積む所から縦廊下の角までの約12mに集まっていた。積む所を部屋の中に入れた形と比べる
- 決めてほしいことへの答え：1 数えるときも動くときと同じ丸（直径0.549m）で見る／2 地図を Unity で床から作るのはこのままでよい／3 壁ぞいを走るのはこのままでよい／4 積む所は下の 1-2 のとおり両方を回す／5 数え方の細かい線（設定の速さの半分以上・30度・45〜135度・よけた理由を分けない）はこのままでよい／6 人・ストレッチャーの値、扉の置き方、ストレッチャーの通り道、録画の範囲はこのままでよい

**配膳の場面・配膳の実行ファイル・配膳の台帳、配膳と共通の部品には触らない。** 止まり方は病院の側（Assets/ServiceSim/Hospital/ の中）で、共通の部品の外から入れる。共通の部品を直さないと入れられないときは、直さずに止めて報告する。
**エイイチは見ていない。人に聞かないと進めない所に当たったら、その項目は止めて報告に書き、ほかは続ける。夜の間も続けてよい。**

## 正（読むもの）
- 条件：p2m-site main の `tools/hospital_sim/hospital-unity-params.json`（md5 0507fd8d5cdf2b3ff8bcb010a4f48493）。依頼127 の写し（9887bf36…）との違いは braking・loading_point・loading_point_what・count_shape・near_miss_speed_mps の5項目だけのはず。ほかにも違いがあれば回さずに報告して終わる
- フロアの形：依頼127 と同じ hospital_h0.json（md5 が params の layout.md5 と一致すること）

## 始める前に確かめること（違えば回さずに報告して終わる）
1. 作業場所に保留がない（cs:111 のあと）。Unity・回し係が動いていない。KIOXIA がマウント済み
2. 上の md5 と、違いが5項目だけであること

## 1. 作りの直し（病院の側だけ）
1. 速さで変わる止まり方（params の braking が正）
   - 止まるまでの距離＝速さ×react_s＋速さ²÷(2×decel_mps2)。ロボットは前方の「止まるまでの距離＋notice_margin_m」の中に人や物が入ったら、react_s のあと decel_mps2 で減速して止まる（速いほど遠くで気づく）
   - 気づく距離より内側に急に入られたとき（横から出てきた人など）は、止まりきれずに近づくことがある。そのまま起きるようにする（無理に止めない・瞬間移動しない）
   - 加速は今のままでよい（使った値を報告に書く）
2. 積む所（params の loading_point）：「廊下」＝依頼127 と同じ（扉から廊下へ0.5m）、「部屋の中」＝扉から処置室の中へ1.0m。引数で選べるようにする。届け先（検体受付）は今のまま
3. 数える形（params の count_shape）：ひやりの距離は、動くときと同じ丸（直径0.549m）と相手の外形で測る
4. ひやりのそれぞれに、近づいたときのロボットの速さ（一番近づいた瞬間と、その1秒前の最大）を残す。near_miss_speed_mps 以上を「速いままのひやり」として分けて数える
5. 止まりきれなかった：ロボットが 0.1m/秒以上で動いているあいだに、丸と相手の外形が重なった（距離0未満）回数も分けて数える
- 引数がないときは、1〜5 を入れた形を既定にする。依頼127 の形（止まり方なし・長方形で数える）にも引数で戻せるようにする
- check-in（保留0）して、病院の実行ファイル（Builds/hospital132/）を作る。依頼127 の実行ファイルは残す

## 2. 確かめ（違えば 3 は回さない）
- 0.5m/秒・混んでいる・廊下・種0 を2回回して一致すること、瞬間移動0
- 0.8m/秒・空いている・部屋の中・種0 で往復が最後まで回ること
- 依頼127 の形に戻す引数で 0.5m/秒・混んでいる・種0 を回し、依頼127 の同じ回と、名前・時刻・cs・計算時間以外が一致すること（違ったら、どこが違うかを書く。止めない）

## 3. 回す
- 速さ4つ × 混み具合2つ × 積む所2つ × 種0〜9 ＝ 160回。1回は店の時間で60分（画面なし・同時4本まで）
- 出力：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261109_brake132/（依頼127 と同じ形の記録とまとめ・索引 CSV）。依頼127 のフォルダは変えない

## 4. 録画（3 が通れば撮る）
- 混んでいる・種0 で、0.4m/秒・廊下 と 0.8m/秒・廊下 を2分ずつ左右に並べた動画を1本、0.8m/秒・廊下 と 0.8m/秒・部屋の中 を2分ずつ並べた動画を1本。撮り方・印は依頼127 と同じ。速いままのひやりと止まりきれなかったには、ほかと違う目立つ印を出す

## 止める線
瞬間移動が1回でも出たとき、または同じ種の2回が違ったとき。止めたら報告に書き、ほかの項目は続ける。

## 報告
claude_code_reports/20261109_hospital_132.txt に：始める前の確かめ、1 の直し（どのファイルのどこ・加速の値）、2 の確かめ、
表（速さ×混み具合×積む所ごと、種10個の中央値と最小・最大）：往復の数・片道の秒・実際の平均の速さ・1〜5 の問題の数（1往復あたり）・速いままのひやり（1往復あたり）・止まりきれなかった（1往復あたり）・ひやりのときのロボットの速さ（中央値と90%）・ひやりの一番近い距離、
依頼127 との並べ（廊下の形で、速さごとに 1〜5 の増え減り）、積む所を部屋の中にして問題がどこからどこへ移ったか（上から見た図）、4 の動画の名前と長さ、check-in の番号、決めてほしいこと（直し方の候補は作らない）。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

#### 依頼132 の報告（依頼箱の結果の全文）

```markdown
# 結果：20261109_132_病院の搬送ロボットに速さで変わる止まり方を入れ積む所を部屋の中と比べる

- 状態：完了
- 始めた時刻：2026-11-09 13:27
- 終わった時刻：2026-11-09 14:12（45分）
- 作業フォルダ：/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき：作業フォルダで `claude --resume 42316e13-c5df-4924-b11e-337209a59784`

## Claude Code の報告

**やったこと**
- **始める前の確かめ**：作業場所は cs:111 で保留なし。Unity も回し係も動いておらず、KIOXIA はマウント済み。params の md5（0507fd8d…）と形の md5（a29cd1d9…）は依頼の数と一致し、依頼127 の写しとの違いは足された5項目だけでした。
- **1 作りの直し**（病院の側だけ）：配膳と共通の部品は1行も変えていません。check-in は cs:112（保留0）で、実行ファイルは Builds/hospital132 に作りました。Builds/hospital127 は残してあります。
  - **止まり方**：病院が使っているロボットの設定の写しで、前のセンサーの長さを「止まるまでの距離＋0.3 m」に、減速を 0.5 m/秒² にしました。センサーの長さは 0.4 m/秒で 0.54 m、0.8 m/秒で 1.10 m です。
  - **気づいてから踏むまでの 0.2 秒**：新しい部品（HospitalBrake）で、そのあいだは減速しないようにしました。
  - **加速**：今のままの 1.0 m/秒² です。
  - **積む所**：引数で「廊下」と「部屋の中」（扉から処置室の中へ 1.0 m）を選べます。
  - **数え方**：丸で数えること、速いままのひやり、止まりきれなかった、の3つを入れました。
  - **依頼127 の形に戻す引数**も入れました。
- **2 確かめ**：止める線には当たっていません。
  - 0.5 m/秒・混んでいる・廊下・種0 の2回は、記録4つが1バイトも違いませんでした。瞬間移動は0です。
  - 0.8 m/秒・空いている・部屋の中・種0 は、60分で32片道を最後まで回りました。
  - 依頼127 の形の回は、依頼127 の同じ回と記録4つが同一でした。summary.json の違いは名前・cs・計算時間と、params の md5（写しを入れ替えたため）だけです。
- **3 本番**：160回すべて completed、瞬間移動は0です。
- **4 録画**：動画を2本作りました。

**結果**
- **1往復あたりの1〜5**：依頼127 とほぼ同じで、速いほど少ない向きも変わりませんでした。
  - 急に止まったは、0.8 m/秒で約3割減りました（混んでいる 3.37→2.53）。減速を 0.5 m/秒² にしたためです。
  - 2・3・5 は丸で数えるように変えたので、止まり方の違いと数え方の違いの両方が入っています。
- **速さの悪い面**は、新しく数えた2つに出ました。

  | 混んでいる・廊下 | 0.4 m/秒 | 0.8 m/秒 |
  |---|---|---|
  | 止まりきれなかった（1往復あたり） | 1.42 | 1.12 |
  | 止まりきれなかった（1時間あたり） | 11 回 | 16 回 |
  | 速いままのひやり（1往復あたり） | 8.44 | 4.76 |
  | 速いままのひやり（1時間あたり） | 68 回 | 76 回 |

- **160回の合計**：
  - ひやり 16,146回（うち速いまま 8,229回）。
  - 止まりきれなかった 1,527回。相手は車いす 564・スタッフ 474 が多いです。
- **積む所を部屋の中にしても、問題は減りませんでした**（合計 15,394→16,176、5%増）。
  - 処置室の前の数えは、扉の口と北の壁ぞいに寄っただけでした。
  - 急に止まったは 263→496、横切りは 13→83 に増えました。
  - 問題が集まる約12m（積む所から縦廊下の角まで）は変わりませんでした。
- **ひやりの一番近い距離**は −0.11〜−0.43 m（中央値）で、依頼127 の −0.09 m より深くなりました。丸で測るようにしたことと、止まったロボットにストレッチャー・車いすが最大 0.62 m 入り込む分が入るためです。
- **動画**：どちらも 120.1 秒です。
  - hospital132_0.4vs0.8_hall_busy_s0.mp4
  - hospital132_0.8_hall_vs_room_busy_s0.mp4
  - 速いままのひやりは赤の二重の四角と「速」、止まりきれなかったは黄色の縁の四角に黒の×で出しています。
  - 撮った区間の動きと数えは、本番の同じ回と同じでした。
- **報告**：claude_code_reports/20261109_hospital_132.txt に書きました。上から見た図は 20261109_hospital_132_files/ に写してあります。

**変えたファイル**
- Assets/ServiceSim/Hospital/HospitalBrake.cs（新しい・.meta とも）
- Assets/ServiceSim/Hospital/HospitalRun.cs
- Assets/ServiceSim/Hospital/Editor/HospitalSetup.cs
- Assets/ServiceSim/Hospital/Data/hospital-unity-params.json
- KIOXIA の 20261109_brake132/（記録・まとめ・図・動画・tools）
- 報告ファイル

**決めてほしいこと**
1. 速いままのひやりを「一番近づいた瞬間の速さが 0.3 m/秒以上」にしました。「1秒前からの最大」で分けると数が増えます（0.8 m/秒・混んでいる・廊下で 4.76→5.78）。どちらにするか。
2. センサーの長さを、いまの速さではなく設定の速さで決めました（回の中で変えない）。これでよいか。
3. センサーの幅は共通の設定のまま 0.5 m で、体の丸（0.549 m）より狭いです。これでよいか。
4. 丸で数えるのを、ひやりだけでなく、人がよけさせられたと横切りにも使いました。これでよいか。
5. ストレッチャー・車いすは止まったロボットをよけず、最大 0.62 m 入り込みます（48回）。このままでよいか。
6. 部屋の中の形は Unity だけで決めた値です（扉の幅 1.2 m・処置室の床 4.0×3.8 m・中には人を出さない）。これでよいか。
7. ひやり 16,146回のうち 5,809回は、一番近づいた瞬間にロボットが止まっていました（人がロボットのほうへ来たもの）。ひやりを「ロボットが動いていたもの」で分けるか。

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



## 作業ログ ― 外来の廊下を通らない裏口の道と、1日を通した比べ

### 仮の病院 h0b：外来の奥に職員通路を足した

内科外来・ほかの外来の奥（北の壁ぞい）に職員通路2.1m を足し、青のルートは処置室の裏口から出ます。大廊下は人の少ない東の端（x99）で横切るだけになり、道は86mから153mに延びます。h0 の形のファイルは中身を変えていません。

![仮の病院 h0b。外来の奥の職員通路と、裏口から出る青のルート](https://pixelstomotors.com/media/LOG477_09_hospital_h0b.png)

### 依頼134：混んでいる時間は、裏口の道で問題がほぼ半分

0.6m/秒のとき、1日あたりの問題は廊下の161回から裏口の81回、止まりきれなかったのは7.0回から1.4回です。空いている時間は、道が長い分と職員通路でスタッフとすれ違う分だけ、裏口の方が多くなりました（35回と52回）。

![依頼134。積む所（廊下・部屋の中・裏口）と速さごとの1日あたりの問題](https://pixelstomotors.com/media/LOG477_10_u134_backdoor.png)

#### 依頼134 の依頼文（裏口の道を建てて大廊下を通らない形と比べる）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 600
---
# 依頼134：病院に「外来の奥の職員通路（裏口の道）」を足し、大廊下を通らない形と比べる

依頼132 の報告（claude_code_reports/20261109_hospital_132.txt）を読んで、エイイチと決めたこと（2026-11-09）：
- 依頼132 の決めてほしいことへの答え：
  1 速いままのひやりは「1秒前からの最大の速さ」で分ける（params の near_miss_speed_basis）
  2 センサーの長さを設定の速さで決めるのはこのままでよい
  3 センサーの幅は体より広げる：0.65m（params の sensor_width_m。病院の側の写しで変える。共通の設定は変えない）
  4 よけさせられた・横切りも丸で数えるのはこのままでよい
  5 車いす・ストレッチャー（押す人）も、止まっているロボットはよける（params の wheelchair_avoid_stopped_robot）
  6 部屋の中の形（扉1.2m・床4.0×3.8m）はこのままでよい
  7 ひやりを、ロボットが動いていたもの・止まっていたものに分けて数える（params の near_miss_split_by_robot_moving）
- 問題の97%が、積む所から縦廊下の角までの大廊下（約12m）に集まり、積む所を部屋の中にしても減らなかった。**大廊下を通らない道**を試す：サイトで外来の奥に職員通路 2.1m を足した形 h0b を作った。青のルートは内科外来の処置室の裏口から出て、北の職員通路 → 東の縦廊下（x99）で大廊下の人の少ない東の端を横切る → 職員の中廊下 → 検体受付（153m。今の道は86m）

**配膳の場面・配膳の実行ファイル・配膳の台帳、配膳と共通の部品には触らない。** 変えるのは Assets/ServiceSim/Hospital/ の中だけ。共通の部品を直さないと入れられないときは、直さずに止めて報告する。
**エイイチは見ていない。人に聞かないと進めない所に当たったら、その項目は止めて報告に書き、ほかは続ける。夜の間も続けてよい。**

## 正（読むもの）
- 条件：p2m-site main の `tools/hospital_sim/hospital-unity-params.json`（md5 d1c177bd463d3a84f0578611b98853a0）。依頼132 の写し（0507fd8d…）との違いは loading_point（「裏口」が増えた）・near_miss_speed_basis・sensor_width_m・wheelchair_avoid_stopped_robot・near_miss_split_by_robot_moving・east_hall_people_ratio・layout_back_door の7項目だけのはず。ほかにも違いがあれば回さずに報告して終わる
- フロアの形：h0 は依頼127・132 と同じ `tools/hospital_layouts/hospital_h0.json`（md5 a29cd1d9…、変わっていない）。裏口の回は `tools/hospital_layouts/hospital_h0b.json`（md5 ddefbd8ca0db243f41601532e7b8dee8。params の layout_back_door.md5 と一致すること）
- h0b で h0 と違うのは：内科外来・ほかの外来の奥行きが2.1m 縮み、北の壁ぞいに「外来の奥の職員通路」、x99 に「東の縦廊下（北）」、外来化学療法室が縦廊下の分だけ右へ縮む、青のルートの積む所が「内科外来の処置室（裏口）」。ほかは同じ

## 始める前に確かめること（違えば回さずに報告して終わる）
1. 作業場所に保留がない（cs:112 のあと）。Unity・回し係が動いていない。KIOXIA がマウント済み
2. 上の md5 と、違いが7項目だけであること

## 1. 作りの直し（病院の側だけ）
1. 裏口：h0b の形で、外来の奥の職員通路・東の縦廊下（北）・大廊下の東の端（x70〜120）を建てる。積む所は裏口から職員通路へ0.5m。地図は依頼127 と同じやり方で床から作る
2. 大廊下の東の端（x70〜120）には、人の多い区間の east_hall_people_ratio 倍の密度で人を置く。**積む所がどれの回でも同じに置く**（比べられるように）。外来の奥の職員通路と東の縦廊下には、スタッフを時々通す（Unity だけの値でよい。報告に書く）
3. センサーの幅 0.65m、車いす・ストレッチャーも止まったロボットをよける、速いままのひやりは1秒前からの最大、ひやりをロボットが動いていた／止まっていたで分ける
- 引数がないときは、上を全部入れた形を既定にする。依頼132 の形にも引数で戻せるようにする
- check-in（保留0）して、病院の実行ファイル（Builds/hospital134/）を作る。前の実行ファイルは残す

## 2. 確かめ（違えば 3 は回さない）
- 0.6m/秒・混んでいる・裏口・種0 を2回回して一致すること、瞬間移動0、裏口の道を最後まで往復すること（大廊下を横切るのは x99 だけであること）
- 依頼132 の形に戻す引数で 0.5m/秒・混んでいる・廊下・種0 を回し、依頼132 の同じ回と一致すること（違ったら、どこが違うかを書く。止めない。東の端に人を置いたことで違うなら、そう書く）

## 3. 回す
- 速さ4つ（0.4・0.5・0.6・0.8）× 混み具合2つ × 積む所3つ（廊下・部屋の中・裏口）× 種0〜9 ＝ 240回。1回は店の時間で60分（画面なし・同時4本まで）
- 出力：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261109_backdoor134/（依頼132 と同じ形の記録・まとめ・索引 CSV）。前のフォルダは変えない

## 4. 録画（3 が通れば撮る）
- 混んでいる・種0・0.6m/秒で、廊下 と 裏口 を2分ずつ左右に並べた動画を1本。裏口の側は道が長いので、外来の奥の職員通路と大廊下を横切る所が入るように撮る範囲を決めてよい（どこを撮ったか報告に書く）。印は依頼132 と同じ

## 止める線
瞬間移動が1回でも出たとき、または同じ種の2回が違ったとき。止めたら報告に書き、ほかの項目は続ける。

## 報告
claude_code_reports/20261109_hospital_134.txt に：始める前の確かめ、1 の直し（どのファイルのどこ・Unity だけの値）、2 の確かめ、
表（速さ×混み具合×積む所ごと、種10個の中央値と最小・最大）：往復の数・片道の秒・実際の平均の速さ・1〜5 の問題の数（1往復あたり）・ひやり（ロボットが動いていた／止まっていた）・速いままのひやり・止まりきれなかった（どれも1往復あたり）・ひやりのときのロボットの速さ（中央値と90%）・ひやりの一番近い距離、
**1日あたりの数も出す**（青の1日の往復を 6.4 往復として、1往復あたり×6.4。病院にとって1日の便の数は速さや道で変わらないため）、
裏口にして問題がどこへ移ったか・どれだけ減ったか（上から見た図）、4 の動画の名前と長さ、check-in の番号、決めてほしいこと（直し方の候補は作らない）。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

#### 依頼134 の報告（依頼箱の結果の全文）

```markdown
# 結果：20261109_134_病院の裏口の道を建てて大廊下を通らない形と比べる

- 状態：完了
- 始めた時刻：2026-11-09 16:01
- 終わった時刻：2026-11-09 17:24（83分）
- 作業フォルダ：/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき：作業フォルダで `claude --resume d6e6e29e-a760-45db-826b-e8fee151bbb5`
- 止められた操作：1件（いちばん下に一覧）

## Claude Code の報告

**やったこと**
- 始める前の確かめ：作業場所は cs:112 で保留 0。Unity と回し係は動いておらず、KIOXIA もマウント済みでした。md5 は3つとも依頼の数と同じです。params の違いは7項目でしたが、ほかに説明の文（loading_point_what）だけが変わっていました。「裏口」を足したことの説明なので、loading_point の一部とみて回しました（決めてほしいことの5）。
- 1 の直し（Assets/ServiceSim/Hospital/ の中だけ。cs:113）：
  - 裏口の道（職員通路・東の縦廊下（北））を建てました。積む所は裏口から職員通路へ 0.5 m です。
  - 大廊下は x120 まで建て、東の端には人を混んでいる 11 人・空いている 4 人置きました。積む所のどの回でも同じに置いています。
  - 職員通路にはスタッフを平均 60 秒に1人通しました（Unity だけの値）。
  - センサーの幅 0.65 m、車いす・ストレッチャーのよけ方、速いままのひやり（1秒前からの最大）、ひやりをロボットが動いていた／止まっていたで分ける、の4つを入れました。
  - 引数 `-h134Mode 132` で依頼132 の形に戻せます。実行ファイルは Builds/hospital134 で、前の実行ファイルは残しました。
- 2 の確かめ：裏口・0.6 m/秒・混んでいる・種0 の2回は、記録4つが1バイトも違いませんでした。瞬間移動は 0、7往復を最後まで回し、大廊下を横切ったのは x98.56 の所だけでした。依頼132 の形に戻した回も、依頼132 の同じ回と記録4つが1バイトも違いません。
- 3：240回を回しました。4：動画を1本作りました。報告は claude_code_reports/20261109_hospital_134.txt に書きました。

**結果**
- 240回すべて最後まで回り、瞬間移動は 0 でした。
- 混んでいるときは、裏口でほぼ半分に減りました。

  | 0.6 m/秒・混んでいる（1日あたり） | 廊下 | 裏口 |
  |---|---|---|
  | 問題 1〜5 の合計 | 160.8 | 81.4 |
  | 止まりきれなかった | 7.0 | 1.4 |

  - 0.4・0.5・0.8 m/秒でも同じ向きです（227→108、184→93、115→65）。
- 空いているときは、裏口のほうが多くなりました（0.6 m/秒で 1日あたり 35.0→52.1）。道が長い（片道 80 m→148 m）分と、職員通路のスタッフに会う分です。
- 問題の場所：
  - 積む所から縦廊下の角まで（x10〜26）の 15,354 件は 0 になりました。
  - 代わりに増えた所（1往復あたり）は、x99 で大廊下を横切る所が 3.18、東の縦廊下（北）が 1.83、職員通路が全体で約 6.1 です。
  - 図は move134.png と hotspots134.png です。
- 動画は hospital134_0.6_hall_vs_back_busy_s0.mp4（120.0 秒）です。左が廊下、右が裏口で、右は x66〜106・z24〜60（職員通路の東の端・東の縦廊下（北）・大廊下を横切る所）を撮りました。
- 止まったロボットへの車いすの深い重なり（−0.3 m より深い）は 7 回から 0 回になりました。ストレッチャーは幅 2.1 m の職員の中廊下で残っています（廊下 11 回・部屋の中 16 回）。

**変えたファイル**
- HospitalRun.cs・HospitalWalker.cs・Editor/HospitalSetup.cs・Hospital.unity・Data/hospital-unity-params.json・Data/hospital_h0b.json（.meta を含む）。check-in は cs:113 です。
- KIOXIA の 20261109_backdoor134/ に、記録・まとめ・索引 CSV・図・動画・道具（run134.py・agg134.py・vid134.py）を置きました。前のフォルダは変えていません。

**決めてほしいこと**
1. 職員通路のスタッフの通り方（平均 60 秒に1人）は Unity だけで決めた値です。空いているときの裏口の数は、ほぼこの値で決まります。このままでよいか、サイトの条件に入れるか。
2. 狭い職員の中廊下で、ストレッチャーと止まったロボットのどちらが譲るか。待つ上限の 20 秒もこれでよいか。体を止めて重ならないようにする形も試しましたが、ロボットも相手を見て止まったままの待ち合いになり、助けが約3倍に増えたのでやめました。
3. 東の端の人数を四捨五入にしたこと（10.7→11 人、3.6→4 人）。
4. 東の端の扉の場所・待合で立ち止まらないこと・助けのスタッフに選ばれうることを、Unity で決めたこと。
5. 説明の文（loading_point_what）の変化を、7項目の外の違いとして扱って止めるべきだったか。
6. 空いているときは裏口のほうが問題が多いことを、病院の判断としてどう見るか。

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

## 止められた操作

- {"tool_name": "Bash", "tool_use_id": "toolu_01CzcjmNrUMEXCjTKSv1JS6V", "tool_input": {"command": "cd ~/Robotics_UX/ServiceSim; U=/Applications/Unity/Hub/Editor/2022.3.62f3/Unity.app/Contents/MacOS/Unity; $U -batchmode -nographics -projectPath . -executeMethod ServiceSim.Hospital.EditorTools.HospitalSetup.Build -logFile /tmp/h134/logs/build_test2.log; echo exit $?; grep \"error CS\" /tmp/h134/logs/build_test2.log | head; cd /tmp/h134; rm -rf trial2; mkdir trial2; APP=~/Robotics_UX/ServiceSim/Buil
```

### 依頼136・138：時間で切り替える案は、移る道で増えた

外来の混む8〜11時だけ裏口から積み、ほかの時間は表から積む案を、試算 h2 が決めた便の時刻表どおりに Unity で1日回しました。結果は、時間で切替が廊下だけより多くなりました。8時と11時に表と裏口の間を移る道（約200m のうち約90m が大廊下）で問題が起き、特に8時は人が増えていく最中の大廊下を通るためです。

- ねらい：混む時間だけ裏口を使い、届くまでの遅れを混む時間だけにする
- 変わったこと：1日あたりの走っている間の問題（0.6m/秒）は、廊下だけ111回・時間で切替129回（うち移る間66.5回）・裏口だけ68回。廊下に止まっている間のひやりは約2,600回・約1,100回・約190回（依頼138 の中央値）
- 見込める効果：裏口だけにすれば、廊下での問題は約4割減り、廊下に止まる時間はほぼなくなる。届くまでの平均は12.2分から14.0分に延びる（試算 h2）。どちらも15分の線の内側

![1日を通した比べ。走っている間の問題・待っている間のひやり・届くまでの平均](https://pixelstomotors.com/media/LOG477_11_u136_day.png)

依頼138 では、16:30 を過ぎる便も最後まで回し（時刻表の572便すべて）、積む所で待っている間のひやりを問題1〜5と別に数えました。16:30 までの数は依頼136 と同じでした。

#### 依頼136 の依頼文（病院の1日を回し、時間で切り替える形と比べる）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 600
---
# 依頼136：病院の1日（7:30〜16:30）を回し、青の道を時間で切り替える形を比べる

依頼134 の報告（claude_code_reports/20261109_hospital_134.txt）を読んで、エイイチと決めたこと（2026-11-09）：
- 外来の混む時間は裏口の道で廊下の問題がほぼ半分、空いている時間は今の道（廊下）の方が少なかった。そこで**時間で道を切り替える**（外来の混む 8〜11時だけ裏口から積み、ほかの時間は表から積む）形を、1日を通して回して比べる
- 決めてほしいことへの答え：
  1 職員通路のスタッフの通る間隔（平均60秒）はサイトの条件に入れた（params の staff_corridor_interval_s。値は同じ）
  2 狭い中廊下でストレッチャーと向き合ったら、ロボットが譲って最大20秒待つ、のままでよい（params の stretcher_yield。値は同じ）
  3 東の端の人数の四捨五入、4 東の端の扉の場所など Unity で決めた細部は、このままでよい
  5 説明の文の違いで止めなかったのは問題ない（依頼の書き漏れだった）

**配膳の場面・配膳の実行ファイル・配膳の台帳、配膳と共通の部品には触らない。** 変えるのは Assets/ServiceSim/Hospital/ の中だけ。
**エイイチは見ていない。人に聞かないと進めない所に当たったら、その項目は止めて報告に書き、ほかは続ける。夜の間も続けてよい。**

## 正（読むもの）
- 条件：p2m-site main の `tools/hospital_sim/hospital-unity-params.json`（md5 f25037c48d34b4c3e8d4ebac8558b347）。依頼134 の写し（d1c177bd…）との違いは staff_corridor_interval_s・stretcher_yield・crowd_by_time・back_door_hours・day_schedule の5項目だけのはず。ほかに違いがあれば回さずに報告して終わる
- フロアの形：依頼134 と同じ h0・h0b（md5 は params の layout.md5・layout_back_door.md5 と一致すること）
- **day_schedule**：サイトの試算（hospital_sim.py の h2・ロボット1台）が決めた、青のロボットの便の時刻表。plans（廊下だけ／時間で切替／裏口だけ）× 速さ（0.5・0.6・0.8）× 種0〜9。depart は 7:30 からの秒、from は積む所（「内科外来の処置室」＝表、「内科外来の処置室（裏口）」＝裏口）。**ロボットはこの時刻に from を出て検体受付へ行き、表の積む所（次の便が裏口なら裏口）へ戻って待つ。** 便の時刻・積む所は Unity で決めない。積む所が表と裏口で入れ替わるときは、その間を走って移る（瞬間移動しない）。前の便から戻りきる前に次の時刻が来たら、着いてすぐ出る（遅れた秒を残す）
- crowd_by_time：大廊下の混み具合を時刻で変える（8〜11時だけ混んでいる）。人数の変え方（いっぺんに増やす／数分かけて増やす）は Unity で決めてよい（報告に書く）

## 始める前に確かめること（違えば回さずに報告して終わる）
1. 作業場所に保留がない（cs:113 のあと）。Unity・回し係が動いていない。KIOXIA がマウント済み
2. 上の md5 と、違いが5項目だけであること

## 1. 作りの直し（病院の側だけ）
- 1日（9時間）を回せるようにする：時刻表どおりに便を出す、混み具合を時刻で変える、積む所を表と裏口で入れ替える
- ロボットの作り・数え方・人・ストレッチャー・職員通路のスタッフは依頼134 の既定のまま
- 依頼134 の形（60分・往復し続ける）にも引数で戻せるようにする
- check-in（保留0）して、病院の実行ファイル（Builds/hospital136/）を作る。前の実行ファイルは残す

## 2. 確かめ（違えば 3 は回さない）
- 時間で切替・0.6m/秒・種0 を2回回して一致すること、瞬間移動0、時刻表の便がすべて走ること（走れなかった便があれば数と理由）、11:00 の前後で積む所が裏口から表に移ること
- 依頼134 の形に戻す引数で 0.6m/秒・混んでいる・裏口・種0 を回し、依頼134 の同じ回と一致すること（違ったら、どこが違うかを書く。止めない）

## 3. 回す
- 道の決め方3つ（廊下だけ・時間で切替・裏口だけ）× 速さ3つ（0.5・0.6・0.8）× 種0〜9 ＝ 90回。1回は 7:30〜16:30（画面なし・同時4本まで）
- 出力：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261109_day136/（依頼134 と同じ形の記録・まとめ・索引 CSV）。前のフォルダは変えない

## 4. 録画（3 が通れば撮る）
- 時間で切替・0.6m/秒・種0 の、10:55〜11:10（裏口から表へ移る所を含む）を、移る道が入る範囲で撮る。印は依頼134 と同じ

## 止める線
瞬間移動が1回でも出たとき、または同じ種の2回が違ったとき。止めたら報告に書き、ほかの項目は続ける。

## 報告
claude_code_reports/20261109_hospital_136.txt に：始める前の確かめ、1 の直し（どのファイルのどこ・人数の変え方）、2 の確かめ、
表（道の決め方×速さごと、種10個の中央値と最小・最大）：**1日あたり**の 1〜5 の問題・ひやり（ロボットが動いていた／止まっていた）・速いままのひやり・止まりきれなかった、便の数・片道の秒（表と裏口で分けて）・時刻表からの遅れ（秒）、
時間帯ごと（7:30〜8:00・8:00〜11:00・11:00 以降）の問題の数、積む所を入れ替えるときに起きた問題、上から見た図、4 の動画の名前と長さ、check-in の番号、決めてほしいこと（直し方の候補は作らない）。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

#### 依頼136 の報告（依頼箱の結果の全文）

```markdown
# 結果：20261109_136_病院の1日を回して青の道を時間で切り替える形と比べる

- 状態：完了
- 始めた時刻：2026-11-09 17:59
- 終わった時刻：2026-11-09 20:34（155分）
- 作業フォルダ：/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき：作業フォルダで `claude --resume 08fb7262-46b8-496f-b38c-5fa32352bcd3`

## Claude Code の報告

**やったこと**
- 始める前の確かめ：保留は0で（cs:113）、Unity も回し係も動いていませんでした。KIOXIA はマウント済みです。params（f25037c4）、h0、h0b の md5 はすべて合っていました。違いは5項目のほかに、いちばん上の `model` が h1 → h2 に変わっていました。依頼文が「h2」と書いているので時刻表の版の名前とみて、止めずに回しました（決めてほしいことの5）。
- 1：病院の1日（7:30〜16:30）を回せるようにしました。直したのは Assets/ServiceSim/Hospital/ の中だけです。
  - 便は時刻表どおりに出し、「積む所 → 検体受付 → 積んだ所」と走ります。
  - 待つ所は 8:00〜11:00 だけ裏口、ほかは表です。8:00 と 11:00 に、表と裏口の間を走って移ります。
  - 人数は、増えるときは5分かけて1人ずつ増やします。減るときは出た人を入れ直さないだけで、約1分で減りきります。
  - 引数 `-h136Mode 134` で依頼134 の形に戻せます。
  - check-in は cs:114 で、実行ファイルは Builds/hospital136 に作りました。前の実行ファイルは残しています。
- 2：確かめ（同じ種の2回・瞬間移動・便・11:00 の入れ替え・依頼134 の形との一致）はすべて通りました。数は「結果」に書きました。
- 3：本番90回（3つの道の決め方 × 3つの速さ × 種0〜9、同時4本、約2時間10分）を回しました。
- 4：時間で切替・0.6m/秒・種0 の 10:55〜11:10 を撮りました。

**結果**
- 確かめ（2）：
  - 同じ種の2回は、記録7つが1バイトも違いませんでした。瞬間移動は0です。
  - 時刻表の5便はすべて走りました。11:00 より前の便は裏口から、後の便は表から出ました。11:00:00 に裏口を出て、11:05:47 に表に着きました。
  - 依頼134 の形に戻す引数の回は、依頼134 の同じ回と記録4つが1バイトも違いませんでした。
- 本番：90回すべて completed、瞬間移動0です。
- 便：時刻表の572便のうち552便が走りました。
  - 2便は 16:30 の時点で帰りの途中でした。
  - 18便は時刻が 16:30:30〜35 で、回の終わりより後なので走らせていません。
  - 遅れは1便だけで、11:00 に移る途中で時刻が来て68秒遅れて出ました。
- 片道の秒（0.6m/秒）：表から 140〜149、裏口から 249〜250 です。
- 1日あたり、走っている間の1〜5の問題（中央値。廊下だけ／時間で切替／裏口だけ）：

| 速さ | 廊下だけ | 時間で切替 | 裏口だけ |
|---|---|---|---|
| 0.5m/秒 | 132 | 159 | 86 |
| 0.6m/秒 | 111 | 125 | 68 |
| 0.8m/秒 | 73.5 | 93 | 43 |

- 時間で切替が廊下だけより多いのは、8:00 と 11:00 の移る道（約200m、そのうち大廊下を約90m）の分です。0.6m/秒では 125 のうち 66.5 が移る間でした。
  - 8〜11時だけを見ると、廊下だけ 91／時間で切替 85.5／裏口だけ 47 です。
  - 移る間の問題は、8:00 の表 → 裏口（1,373件）が 11:00 の裏口 → 表（643件）の倍ほどでした。8:00 は人が増えていく最中に大廊下を通るためです。
- 積む所で待っている間の数えは、別に出しました。1日あたり 廊下だけ 約2,600、時間で切替 約1,100、裏口だけ 約190 です。表の積む所は大廊下の中にあるので、止まったロボットの横を人が通るたびに「ひやり」になります。
- 表のすべて（ひやりの内訳・止まりきれなかった・時間帯ごとの数）、上から見た図、録画の中身は報告ファイルに書きました。
- 動画は hospital136_0.6_switch_s0_1055-1110.mp4（900秒）です。

**変えたファイル**
- Assets/ServiceSim/Hospital/HospitalRun.cs
- Assets/ServiceSim/Hospital/Editor/HospitalSetup.cs
- Assets/ServiceSim/Hospital/Data/hospital-unity-params.json
- 上の3つは cs:114 で check-in しました。
- 新しく作ったもの：Builds/hospital136
- KIOXIA の 20261109_day136/（回し係・まとめ・図・動画・記録・索引）
- 報告：claude_code_reports/20261109_hospital_136.txt と 20261109_hospital_136_files/

**決めてほしいこと**
1. 待つ所を入れ替える時刻：依頼文の「表（次の便が裏口なら裏口）へ戻って待つ」のとおりにすると、11:00 の前後に移る所がありません。そこで、依頼の「その間を走って移る」「10:55〜11:10 を撮る」とサイトの h2 に合わせ、「積んだ所へ戻り、8:00・11:00 に表と裏口の間を走って移る」にしました。この形でよいか。
2. 表の積む所（大廊下の中）で待っている間の数え（1日 約2,600）を、問題に入れるか。
3. 16:30 より後の18便と、16:30 で途中の2便：最後の便が終わるまで回すか。
4. 人数の変え方（増えるときは5分かけて1人ずつ、減るときは入れ直さず約1分で減りきる）でよいか。
5. params の `model`（h1 → h2）が5項目の外で変わっていたのを、止めずに回してよかったか。

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

#### 依頼138 の依頼文（1日を最後の便まで回し直し、待っている間のひやりを分けて出す）

```markdown
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 480
---
# 依頼138：病院の1日を最後の便まで回し直し、待っている間のひやりを分けて出す

依頼136 の報告（claude_code_reports/20261109_hospital_136.txt）を読んで、エイイチと決めたこと（2026-11-09）：
1 待つ所の移り方は依頼136 の形（積んだ所へ戻り、8:00・11:00 に表と裏口の間を走って移る）でよい（params の switch_move）
2 積む所で止まって待っている間のひやりは、問題1〜5に混ぜず「廊下に止まっている間のひやり」として別に並べる（params の waiting_near_miss）
3 16:30 を過ぎる便も、最後の便が積んだ所へ戻るまで回す。16:30 以降も人と混み具合は空いているのまま（params の day_end_rule）
4 人数の変え方（増えるときは5分かけて1人ずつ、減るときは入れ直さず約1分）はこのままでよい
5 params の model の違いで止めなかったのは問題ない（依頼の書き漏れだった）

**配膳の場面・配膳の実行ファイル・配膳の台帳、配膳と共通の部品には触らない。** 変えるのは Assets/ServiceSim/Hospital/ の中だけ。
**エイイチは見ていない。人に聞かないと進めない所に当たったら、その項目は止めて報告に書き、ほかは続ける。夜の間も続けてよい。**

## 正（読むもの）
- 条件：p2m-site main の `tools/hospital_sim/hospital-unity-params.json`（md5 f72d3810674b31dadd9dfa4ce0141178）。依頼136 の写し（f25037c4…）との違いは waiting_near_miss・day_end_rule・switch_move の3項目だけのはず（day_schedule は同じ）。ほかに違いがあれば回さずに報告して終わる
- フロアの形：h0・h0b（依頼136 と同じ md5）

## 始める前に確かめること（違えば回さずに報告して終わる）
1. 作業場所に保留がない（cs:114 のあと）。Unity・回し係が動いていない。KIOXIA がマウント済み
2. 上の md5 と、違いが3項目だけであること

## 1. 作りの直し（病院の側だけ）
- 回の終わりを「最後の便が積んだ所へ戻るまで」にする（day_end_rule）。依頼136 の形（16:30 で終わる）にも引数で戻せるようにする
- まとめで、積む所で止まって待っている間のひやりを「廊下に止まっている間のひやり」として問題1〜5と別の列にする（依頼136 で別に出した数え方のまま）
- check-in（保留0）して、病院の実行ファイル（Builds/hospital138/）を作る。前の実行ファイルは残す

## 2. 確かめ（違えば 3 は回さない）
- 時間で切替・0.6m/秒・種0 を2回回して一致すること、瞬間移動0、時刻表の便がすべて走り終わること
- 依頼136 の形に戻す引数で同じ回を回し、依頼136 の同じ回と一致すること（違ったら、どこが違うかを書く。止めない）

## 3. 回す
- 道の決め方3つ × 速さ3つ（0.5・0.6・0.8）× 種0〜9 ＝ 90回（依頼136 と同じ並び）
- 出力：/Volumes/KIOXIA/r2r2r-data/service_sim/unity/hospital/20261109_day138/。前のフォルダは変えない

## 止める線
瞬間移動が1回でも出たとき、または同じ種の2回が違ったとき。止めたら報告に書き、ほかの項目は続ける。

## 報告
claude_code_reports/20261109_hospital_138.txt に：始める前の確かめ、1 の直し、2 の確かめ、
表（道の決め方×速さごと、種10個の中央値と最小・最大）：**1日あたり**の 1〜5 の問題（走っている間）・そのうち表と裏口を移る間の数・廊下に止まっている間のひやり・ひやり（ロボットが動いていた／止まっていた）・速いままのひやり・止まりきれなかった、便の数（走った／時刻表）・片道の秒・時刻表からの遅れ、
時間帯ごと（7:30〜8:00・8:00〜11:00・11:00〜16:30・16:30 以降）の問題の数、依頼136 との違い（16:30 以降の便の分）、check-in の番号、決めてほしいこと（直し方の候補は作らない）。
**報告の最後の1行は必ず次のどれか**：「判定：合格」／「判定：止めた（決めてほしいことあり）」／「判定：失敗」
```

#### 依頼138 の報告（依頼箱の結果の全文）

```markdown
# 結果：20261109_138_病院の1日を最後の便まで回し直し待っている間のひやりを分けて出す

- 状態：完了
- 始めた時刻：2026-11-09 21:21
- 終わった時刻：2026-11-09 23:47（146分）
- 作業フォルダ：/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき：作業フォルダで `claude --resume d3864dfb-2c65-47f2-a360-d5b6c3cebb3b`

## Claude Code の報告

**やったこと**
- 始める前の確かめをしました。作業場所は cs:114 で保留0、Unity と回し係は止まっていて、KIOXIA もマウント済みでした。params の md5 は f72d3810 で依頼と同じです。依頼136 の写しとの違いは、足された3項目（waiting_near_miss・day_end_rule・switch_move）だけでした。h0・h0b の md5 も依頼136 と同じです。
- 作りを直しました（Assets/ServiceSim/Hospital/ の中だけ）。
  - 新しい引数 `-h138Mode 138` で、最後の便が積んだ所へ戻るまで回します（既定）。`-h138Mode 136` で依頼136 の形（16:30 で終える）に戻せます。
  - 16:30 以降も混み具合は空いているのままです。ストレッチャーは同じ間隔で続け、16:30 より後の分だけ別の乱数で決めます。こうすると 16:30 までの流れが依頼136 と同じになります。
  - 積む所で止まって待っている間の数えは、「廊下に止まっている間のひやり」として問題1〜5とは別の列にしました。
- check-in は cs:115（保留0）です。実行ファイルは Builds/hospital138 に作り、前の実行ファイルは残しました。
- 確かめ4つを回したあと、本番90回を回しました。

**結果**
- 確かめはすべて合いました。
  - 時間で切替・0.6m/秒・種0 の2回は、記録7つが1バイトも違いませんでした。瞬間移動0で、時刻表の5便すべて走り終えました。
  - 依頼136 の形に戻す引数で回した同じ回も、依頼136 の回と記録7つが1バイトも違いませんでした。
  - 16:30 を過ぎる回（裏口だけ・0.5m/秒・種3）も2回回し、1バイトも違いませんでした。
- 本番90回はすべて completed、瞬間移動0です。止める線には当たっていません。
- 時刻表の572便はすべて走り終えました（依頼136 は552便）。
- 16:30 を過ぎたのは20回で、過ぎた長さは78〜633秒です。上限（16:30＋60分）に当たった回は0でした。
- 90回すべてで、16:30 までの時間帯ごとの数が依頼136 の同じ回と同じでした。違いは 16:30 以降の分だけです。

1日あたりの中央値（廊下だけ／時間で切替／裏口だけ）:

| 速さ | 走っている間の1〜5 | 廊下に止まっている間のひやり |
|---|---|---|
| 0.5m/秒 | 136／167.5／86 | 2572／1078／188 |
| 0.6m/秒 | 111／129／68 | 2601／1103／185 |
| 0.8m/秒 | 78／93／47.5 | 2668.5／1096.5／192.5 |

- 時間で切替のうち、表と裏口を移る間の数は 87.5／66.5／42.5（0.5／0.6／0.8m/秒）です。
- 16:30 以降に増えた分（合計）:

| 道の決め方 | 16:30 を過ぎた回 | 便 | 1〜5 | 止まりきれなかった |
|---|---|---|---|---|
| 廊下だけ | 6回 | +6 | +62 | +3 |
| 時間で切替 | 6回 | +6 | +54 | +5 |
| 裏口だけ | 8回 | +8 | +52 | 0 |

- 報告は claude_code_reports/20261109_hospital_138.txt に書きました。最後の行は「判定：止めた（決めてほしいことあり）」です。決めてほしいことが3つあるためです。
- データは KIOXIA の 20261109_day138/ にあります。

**変えたファイル**
- Assets/ServiceSim/Hospital/HospitalRun.cs
- Assets/ServiceSim/Hospital/Editor/HospitalSetup.cs
- Assets/ServiceSim/Hospital/Data/hospital-unity-params.json（f72d3810 に入れ替え）
- 新しく作ったもの：Builds/hospital138/、KIOXIA 20261109_day138/（run138.py・agg138.py・集計の表と図）、報告ファイルとその付録フォルダ

**決めてほしいこと**
1. 「廊下に止まっている間のひやり」の列に入れる数をどちらにするか。いまは依頼136 と同じく、待っている間の1〜5の合計（ひやり＋人がよけさせられた）にしています。ひやりだけの数も横に並べました。
2. 最後の便が 16:30 より前に戻った回は、依頼136 と同じく 16:30 まで回しました（その間に止まっている分も数えています）。戻った時刻で終える形にはしていません。これでよいか。
3. params に決めが無かったので、次の2つは私が決めました。これでよいか。
   - 16:30 以降のストレッチャーは、同じ間隔（1時間2台）で続けました。
   - 最後の便を待つ上限を 16:30＋60分にしました（本番で当たった回は0）。

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

#### 試算 h2 が書き出した Unity の条件（hospital-unity-params.json の全文）

```json
{
 "about": "病院の搬送ロボットの Unity（ServiceSim の病院の場面）が読む条件。export_unity_params.py が assumptions.json から書き出す。直すときは assumptions.json を直して書き出し直す",
 "model": "h2",
 "layout": {
  "file": "tools/hospital_layouts/hospital_h0.json",
  "md5": "a29cd1d981e5b3086fb623fc647926d9",
  "name": "仮の病院 h0（外来の階）"
 },
 "route": {
  "key": "blue",
  "from_point": "内科外来の処置室",
  "to_point": "検査部の検体受付",
  "path": [
   [
    12.0,
    31.0
   ],
   [
    12.0,
    29.0
   ],
   [
    24.0,
    29.0
   ],
   [
    24.0,
    14.05
   ],
   [
    48.0,
    14.05
   ],
   [
    80.0,
    14.05
   ],
   [
    80.0,
    13.0
   ]
  ],
  "distance_m": 86.0,
  "what": "建てる範囲：青のルートの道（内科外来の処置室 → 外来の大廊下 → 西の縦廊下 → 職員の中廊下 → 検査部の検体受付）と、外来の大廊下の人の多い区間（x0〜70）"
 },
 "robot": {
  "speeds_mps": [
   0.4,
   0.5,
   0.6,
   0.8
  ],
  "speed_max_mps": 0.8,
  "min_passage_m": 0.7,
  "size_m": {
   "w": 0.459,
   "d": 0.549,
   "h": 1.081
  },
  "size_source": "KEENON 公式 BUTLERBOT W3"
 },
 "people": {
  "crowd": {
   "空いている": 20,
   "混んでいる": 60
  },
  "mix": {
   "歩く患者・付き添い": 0.7,
   "杖の人": 0.1,
   "車いす": 0.1,
   "スタッフ": 0.1
  },
  "stretcher_per_h": 2
 },
 "count_rules": {
  "sudden_stop": {
   "value": 1.0,
   "unit": "秒",
   "what": "1 急に止まった：走っている状態からこの秒数以内に止まった"
  },
  "near_miss_m": {
   "value": 0.3,
   "unit": "m",
   "what": "2 ひやり：人とロボットの外形どうしがこの距離未満まで近づいた"
  },
  "yield_m": {
   "value": 2.0,
   "unit": "m",
   "what": "3 人がよけさせられた：ロボットからこの距離以内で、人が止まるか向きを変えた"
  },
  "stuck_s": {
   "value": 30,
   "unit": "秒",
   "what": "4 立ち往生：この秒数以上動けず、人が動かしに行った（配膳と同じ）"
  },
  "cross_front_m": {
   "value": 1.5,
   "unit": "m",
   "what": "5 車いす・杖の人・ストレッチャーの進む先この距離以内をロボットが横切った"
  }
 },
 "braking": {
  "decel_mps2": 0.5,
  "react_s": 0.2,
  "notice_margin_m": 0.3,
  "what": "止まるまでの距離＝速さ×react_s＋速さ²÷(2×decel_mps2)。0.4m/秒で約0.24m、0.8m/秒で約0.80m"
 },
 "loading_point": [
  "廊下",
  "部屋の中",
  "裏口"
 ],
 "loading_point_what": "積む所：廊下＝扉から廊下へ0.5m（h0）／部屋の中＝扉から処置室の中へ1.0m（h0）／裏口＝処置室の裏口から外来の奥の職員通路へ0.5m（h0b。大廊下を通らない道）",
 "count_shape": "丸（直径0.549m）",
 "near_miss_speed_mps": 0.3,
 "near_miss_speed_basis": "1秒前からの最大",
 "sensor_width_m": 0.65,
 "wheelchair_avoid_stopped_robot": true,
 "near_miss_split_by_robot_moving": true,
 "east_hall_people_ratio": 0.25,
 "layout_back_door": {
  "file": "tools/hospital_layouts/hospital_h0b.json",
  "md5": "ddefbd8ca0db243f41601532e7b8dee8",
  "name": "仮の病院 h0b（外来の階・外来の奥に職員通路）",
  "blue_path": [
   [
    12.0,
    57.9
   ],
   [
    12.0,
    58.95
   ],
   [
    99.0,
    58.95
   ],
   [
    99.0,
    29.0
   ],
   [
    99.0,
    14.05
   ],
   [
    80.0,
    14.05
   ],
   [
    80.0,
    13.0
   ]
  ],
  "blue_distance_m": 153.0
 },
 "staff_corridor_interval_s": 60,
 "stretcher_yield": {
  "who": "ロボットが譲る",
  "wait_s": 20
 },
 "crowd_by_time": [
  [
   "07:30",
   "08:00",
   "空いている"
  ],
  [
   "08:00",
   "11:00",
   "混んでいる"
  ],
  [
   "11:00",
   "16:30",
   "空いている"
  ]
 ],
 "back_door_hours": [
  [
   "08:00",
   "11:00"
  ]
 ],
 "day_schedule": {
  "what": "青のロボットの便の時刻表。plan × 速さ × 種。depart は 7:30 からの秒、from は積む所（表＝内科外来の処置室／裏口）",
  "model": "h2",
  "day_start": "07:30",
  "plans": {
   "廊下だけ": {
    "0.5": [
     [
      {
       "depart": 8843.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21700.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22849.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28154.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31312.6,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3838.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6445.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8643.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10170.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12437.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23283.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27691.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30050.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30842.1,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2881.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 4869.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6242.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7666.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22603.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28969.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3784.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10549.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20867.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32434.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3131.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 5748.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8509.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9256.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20384.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21597.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23419.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29265.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30660.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31979.6,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6503.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7145.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8660.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10186.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12387.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31297.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8581.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9196.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12634.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29639.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3606.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9849.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11594.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20615.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31117.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32432.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4507.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6452.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7382.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10954.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11765.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22149.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23430.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30744.4,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5073.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7426.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9292.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30923.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31720.1,
       "from": "内科外来の処置室"
      }
     ]
    ],
    "0.6": [
     [
      {
       "depart": 8843.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21697.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22849.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28149.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31310.8,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3840.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6444.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8645.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10170.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12439.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23282.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27694.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30051.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30840.9,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2881.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 4866.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6238.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7669.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22601.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28967.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3784.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10547.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20867.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32431.8,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3131.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 5746.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8510.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9260.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20387.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21598.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23419.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29264.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30662.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31978.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6503.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7148.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8660.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10189.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12387.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31300.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8582.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9195.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12630.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29639.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3605.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9846.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11594.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20612.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31119.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32432.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4508.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6451.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7383.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10953.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11761.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22148.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30740.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5074.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7424.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9293.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30921.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31720.9,
       "from": "内科外来の処置室"
      }
     ]
    ],
    "0.8": [
     [
      {
       "depart": 8841.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21702.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22847.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28151.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31311.0,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3836.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6448.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8642.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10171.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12439.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23280.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27691.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30051.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30839.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2884.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 4867.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6242.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7667.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22604.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23433.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28966.6,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3787.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10548.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20868.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32431.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3130.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 5748.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8510.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9258.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20384.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21598.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23421.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29265.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30661.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31981.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6506.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7149.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 8660.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10186.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12388.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31297.4,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8582.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9198.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 12632.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29639.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3605.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9849.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11591.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 20614.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31120.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32431.8,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4506.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 6448.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7384.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 10951.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 11763.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22146.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23433.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30743.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5073.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 7426.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 9293.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30924.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31722.5,
       "from": "内科外来の処置室"
      }
     ]
    ]
   },
   "時間で切替": {
    "0.5": [
     [
      {
       "depart": 8842.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21700.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22849.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28154.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31312.6,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3836.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6446.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8642.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10172.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12437.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23282.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27695.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30049.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30841.1,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2880.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4866.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6242.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7669.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22602.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23430.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28968.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3783.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10546.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20870.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32432.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3129.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5749.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8508.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21599.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23420.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29267.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30661.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31981.9,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6507.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7197.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8660.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10189.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12388.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31297.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8585.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9283.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 13048.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29639.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3605.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11594.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20611.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31118.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32433.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4510.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6448.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7386.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10951.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11785.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22150.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30740.4,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5071.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7422.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9291.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30923.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31720.1,
       "from": "内科外来の処置室"
      }
     ]
    ],
    "0.6": [
     [
      {
       "depart": 8840.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21701.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22847.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28152.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31309.1,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3839.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6446.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8645.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10173.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12436.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23280.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27693.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30050.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30839.2,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2883.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4866.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6241.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7666.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22604.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23435.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28965.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3786.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10547.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20869.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32433.4,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3130.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5748.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8510.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9258.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20387.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21598.6,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23419.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29264.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30662.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31978.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6505.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7148.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8664.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10185.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12387.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31298.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8584.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9195.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12978.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29638.9,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3607.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11592.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20612.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31119.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32432.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4511.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6453.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7383.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10951.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11763.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22146.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23430.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30743.9,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5072.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7426.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9293.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30923.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31722.6,
       "from": "内科外来の処置室"
      }
     ]
    ],
    "0.8": [
     [
      {
       "depart": 8839.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21702.1,
       "from": "内科外来の処置室"
      },
      {
       "depart": 22847.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28151.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31311.0,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3837.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6447.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8644.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10169.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12440.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23280.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 27691.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30051.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30839.3,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 2883.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4869.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6241.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7668.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22602.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 28969.1,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3785.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10549.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20870.9,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32433.7,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3131.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5747.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8512.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9257.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20384.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 21598.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23421.8,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29265.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30661.5,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31981.5,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 6505.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7145.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8664.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10188.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12387.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31300.6,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 8586.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9195.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12889.7,
       "from": "内科外来の処置室"
      },
      {
       "depart": 29643.1,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 3604.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11595.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20614.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31120.3,
       "from": "内科外来の処置室"
      },
      {
       "depart": 32431.8,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 4507.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6452.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7385.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10955.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11765.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22149.4,
       "from": "内科外来の処置室"
      },
      {
       "depart": 23431.2,
       "from": "内科外来の処置室"
      },
      {
       "depart": 30740.8,
       "from": "内科外来の処置室"
      }
     ],
     [
      {
       "depart": 5074.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7425.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9295.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30922.0,
       "from": "内科外来の処置室"
      },
      {
       "depart": 31720.0,
       "from": "内科外来の処置室"
      }
     ]
    ]
   },
   "裏口だけ": {
    "0.5": [
     [
      {
       "depart": 8842.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21698.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22850.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28154.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31310.6,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3836.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6446.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8642.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10172.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12437.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23280.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 27695.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30047.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30907.1,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 2880.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4866.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6242.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7669.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22605.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23466.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28966.7,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3783.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10546.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20868.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32434.2,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3129.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5749.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8508.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21597.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23421.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29265.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30662.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31980.9,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 6507.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7197.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8660.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10189.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12388.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31301.2,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 8585.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9283.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12634.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29642.2,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3605.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11594.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20614.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31120.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32433.7,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 4510.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6448.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7386.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10951.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11785.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22148.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23432.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30743.4,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 5071.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7422.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9291.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30922.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31723.5,
       "from": "内科外来の処置室（裏口）"
      }
     ]
    ],
    "0.6": [
     [
      {
       "depart": 8840.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21699.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22849.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28149.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31309.1,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3839.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6446.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8645.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10173.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12436.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23284.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 27691.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30051.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30839.2,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 2883.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4866.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6241.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7666.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22602.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23431.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28967.2,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3786.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10547.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20867.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32431.8,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3130.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5748.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8510.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9258.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20386.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21600.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23419.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29264.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30660.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31980.4,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 6505.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7148.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8664.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10185.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12387.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31298.7,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 8584.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9195.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12633.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29639.3,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3607.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11592.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20615.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31117.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32434.0,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 4511.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6453.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7383.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10951.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11763.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22150.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23431.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30740.5,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 5072.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7426.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9293.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30925.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31720.0,
       "from": "内科外来の処置室（裏口）"
      }
     ]
    ],
    "0.8": [
     [
      {
       "depart": 8839.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21698.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22846.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28152.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31309.8,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3837.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6447.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8644.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10169.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12440.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23279.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 27695.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30047.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30843.0,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 2883.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 4869.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6241.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7668.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22601.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23432.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 28967.8,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3785.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10549.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20867.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32434.9,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3131.8,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 5747.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8512.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9257.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20385.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 21596.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23418.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29266.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30660.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31982.7,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 6505.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7145.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 8664.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10188.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12387.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31296.8,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 8586.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9195.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 12630.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 29643.1,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 3604.6,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9846.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11595.0,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 20612.7,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31116.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 32430.6,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 4507.9,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 6452.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7385.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 10955.4,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 11765.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 22148.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 23432.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30744.5,
       "from": "内科外来の処置室（裏口）"
      }
     ],
     [
      {
       "depart": 5074.3,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 7425.5,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 9295.1,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 30926.2,
       "from": "内科外来の処置室（裏口）"
      },
      {
       "depart": 31723.2,
       "from": "内科外来の処置室（裏口）"
      }
     ]
    ]
   }
  }
 },
 "waiting_near_miss": "別に数える",
 "day_end_rule": "最後の便が終わるまで",
 "switch_move": "8:00・11:00 に走って移る",
 "seeds": 10,
 "basis": {
  "speeds": "決まり",
  "crowd_people": "仮置き",
  "people_mix": "仮置き",
  "stretcher_per_h": "仮置き"
 }
}
```

### 残したずれと、次に見ること

- 1便あたりの人の時間の減りは、道の長さと人の手間のどちらで埋まるかを決めていない（現場で聞くまで両方を並べる）
- 速さの悪い面は、止まるまでの距離（減速0.5m/秒²・気づいてから0.2秒）が仮置きのままの結果。病院の設定やメーカーの値が分かれば置き換える
- 至急は1ルートで1日1件もなく、10日分の平均でもぶれが大きい
- Unity の Hospital の場面は ServiceSim の Assets/ServiceSim/Hospital/（cs:110〜115）。配膳の場面と共通の部品は1行も変えていない
- 結果は KIOXIA の service_sim/unity/hospital/ の 20261109_speed127・brake132・backdoor134・day136・day138
