diff --git a/tools/serving_sim/build_page_large.py b/tools/serving_sim/build_page_large.py index b50e2e9..79b6395 100644 --- a/tools/serving_sim/build_page_large.py +++ b/tools/serving_sim/build_page_large.py @@ -67,6 +67,8 @@ for k in KEYS: tables=[[t["x"], t["y"], round(t["x"] + t["w"], 3), round(t["y"] + t["h"], 3), t["seats"]] for t in L["tables"]], dish=[d["rect"] for d in L["dish_up"]], standby=L["robot_standby"]["rect"], ent=[L["entrance"]["side"], L["entrance"]["a0"], L["entrance"]["a1"]]) + if L["robot_standby"].get("slot_rects"): # 待機点を1列に並べない店は、1台ずつの区画を描く(2026-11-07 ⑧の2列) + D["plans"][k]["standby_slots"] = L["robot_standby"]["slot_rects"] assert len(gens) == 1, gens D["layout_generation_large"] = gens.pop() lines[idx[0]] = "const D = " + json.dumps(D, ensure_ascii=False, separators=(",", ":")) + ";" diff --git a/tools/sim_layouts/README.md b/tools/sim_layouts/README.md index 0db200b..3942ac1 100644 --- a/tools/sim_layouts/README.md +++ b/tools/sim_layouts/README.md @@ -59,6 +59,7 @@ - 版は `large-` で始まる(large_store.py と famires_v3 の版から決まる) - トイレが2つ・レジが2つの店のための Unity の細かい形の規則(2026-11-02。`unity_export.py`):トイレの入口の点は、そのトイレの部屋に接する入口から取る(前はどのトイレも1つ目の入口になっていた)。会計に立つ点と並ぶ点は1つ目のレジだけに置く(Unity はレジ1つの条件で回すため。2つ目のレジは部屋として建てるだけ)。トイレ・レジが1つの今の6店は結果が変わらないので、出力は作り直していない(版 9b8dae7ebf8c のまま)。大型店は作り直した(版 large-f4f8ad343efe → large-291ae2e65898。卓・距離・止まる位置は同じ) - 2026-11-06:⑨のレジのまわりが狭すぎたので、島と左の壁ぞいの席を上へ1.0m(レジの上の端から島まで 1.5m → 2.5m)、レジと下の壁ぞいの6人席を右へ1.0m(レジの左の待つ所 3.1m → 4.1m)動かした。70卓・312席のまま、受け渡し口から卓まで 4.0〜34.4m。版は large-99db3254b08b(⑧は卓・距離・止まる位置とも前と同じ)。試算は⑨の 3,066 条件だけ回し直して入れ替え、結果は iCloud の simulation/v2_9_large/results_large_p7_v3.json +- 2026-11-07:⑧のロボットの待機点を、1列(間0.8m)から2列の互い違い6点に変えた(エイイチ 案B・(2))。1列で間0.8mだと、ロボットの前のセンサー(中心から0.85m)が隣の待機点の台にかかり、待機場所のそばで止まり合っていたため。奥の列は今までと同じ y=11.35 に x 18.9・20.5・22.1、手前の列は y=9.5 に x 19.7・21.3・22.9(同じ列は1.6m、斜めの隣は約2.0m)。2列のあいだに、ロボットのふだんの道(1.0m)が通る1.05m をあけた(右上の卓への距離を変えないため)。待機点は `robot_standby.slot_rects` に1台ずつの区画で持つ(famires_v3.standby_slots が読む。障害物も区画ごと)。卓までの距離は 19卓が −0.6〜+0.4m 変わり、平均 15.6 → 15.5m。版は large-b13cd179e6bf(⑨は版の名前だけ変わり、中身は同じ)。⑧の試算は 3,066 条件を回し直した - サイトと同じ描き方の平面図の画像は `large_plan_images.py`(試算のページの planSvg・bigPlanSvg をそのまま使う) ``` diff --git a/tools/sim_layouts/famires_v3.py b/tools/sim_layouts/famires_v3.py index 13e86ba..ccfb00f 100644 --- a/tools/sim_layouts/famires_v3.py +++ b/tools/sim_layouts/famires_v3.py @@ -234,7 +234,10 @@ def table_sides(t): def standby_slots(sb): - """待機場所を1台ずつの区画に分ける(長い方の向きに slots 等分)""" + """待機場所を1台ずつの区画に分ける(長い方の向きに slots 等分)。 + slot_rects があるときはそれをそのまま使う(1列に並べない店。2026-11-07 ⑧の待機点を2列の互い違いにした)""" + if sb.get("slot_rects"): + return [list(r) for r in sb["slot_rects"]] x0, y0, x1, y1 = sb["rect"] n = sb["slots"] if (x1 - x0) >= (y1 - y0): @@ -248,7 +251,10 @@ def all_obstacles(L, skip=None, standby=None): obs += [(w["rect"], "壁:" + w["label"]) for w in L["walls"]] obs += [(fp(t), f"卓:{t['id']}") for i, t in enumerate(L["tables"]) if i != skip] if standby is None: - obs += [(L["robot_standby"]["rect"], "待機場所")] + if L["robot_standby"].get("slot_rects"): # 区画が離れて並ぶ店は、外接する矩形でなく区画ごとに障害物にする + obs += [(tuple(r), "待機場所") for r in L["robot_standby"]["slot_rects"]] + else: + obs += [(L["robot_standby"]["rect"], "待機場所")] else: obs += [(tuple(r), "待機場所") for r in standby] return obs @@ -958,8 +964,8 @@ def draw(ax, L, res_t, summ, conv): x0, y0, x1, y1 = sb["rect"] ax.add_patch(Rectangle((x0, y0), x1 - x0, y1 - y0, fc="#fff4e6", ec=ROBOT, lw=1.4, zorder=5)) body = (ROBOT_MODELS[SETTINGS["model"]]["body_width"] or 0.5) / 2 - for i in range(sb["slots"]): - ax.add_patch(Circle((x0 + (x1 - x0) * (i + 0.5) / sb["slots"], (y0 + y1) / 2), body, fc=ROBOT, ec="white", lw=0.8, zorder=6)) + for r in standby_slots(sb): + ax.add_patch(Circle(((r[0] + r[2]) / 2, (r[1] + r[3]) / 2), body, fc=ROBOT, ec="white", lw=0.8, zorder=6)) ax.add_patch(Circle(tuple(L["start"]), 0.12, fc="white", ec=ROBOT, lw=1.5, zorder=6)) for kx0, ky0, kx1, ky1 in checkout_keepout(L): # 会計の列(ロボットは通らない) ax.add_patch(Rectangle((kx0, ky0), kx1 - kx0, ky1 - ky0, fc="none", ec=ROBOT, lw=0.8, ls="--", hatch="///", alpha=0.5, zorder=4)) diff --git a/tools/sim_layouts/large_store.py b/tools/sim_layouts/large_store.py index ccf00c4..4610b27 100644 --- a/tools/sim_layouts/large_store.py +++ b/tools/sim_layouts/large_store.py @@ -54,6 +54,18 @@ def back_block(x0, pos="center"): # 6台分(1台 0.8m)を横一列。真ん中と左寄りは受け渡し口の右、右寄りは左 sx = c - 1.7 - 4.8 if pos == "right" else c + 1.7 standby = dict(label="ロボット待機・充電", rect=[sx, FY - 0.85, sx + 4.8, FY - 0.05], slots=6) + if pos == "center": + # ⑧(奥の真ん中):2列を互い違いに6点(2026-11-07 エイイチ 案B)。1列で間0.8mだと、ロボットの前のセンサー + # (中心から0.85m)が隣の待機点の台にかかって止まり合ったため。 + # 同じ列は1.6m・斜めの隣は約2.0m あける。奥の列は今までと同じ y(FY-0.45)、手前の列は1.85m手前で、2列のあいだに + # ロボットのふだんの道(1.0m)が通る1.05m をあける(エイイチ (2):右上の卓への距離を今と変えないため)。左端は受け渡し口の前(1.2m)にかからない所、右端は T56・T57 へ上がる1.2m の通路を残す所まで。 + # 1台分の区画は今までと同じ0.8m角 + cx = [c + 1.9, c + 3.5, c + 5.1] + cxf = [c + 2.7, c + 4.3, c + 5.9] + pts = [(x, FY - 0.45) for x in cx] + [(x, FY - 2.3) for x in cxf] + slots = [[round(x - 0.4, 3), round(y - 0.4, 3), round(x + 0.4, 3), round(y + 0.4, 3)] for x, y in pts] + standby = dict(label="ロボット待機・充電", slots=6, slot_rects=slots, + rect=[min(r[0] for r in slots), min(r[1] for r in slots), max(r[2] for r in slots), max(r[3] for r in slots)]) return rooms, dish, standby, [c, FY - 0.45]