====================================================================
基準データ v3・皿の打ち切り上限・原因の調べ
2026-10-27 08:04　check-in：cs:22・cs:23・cs:24（保留 0）
====================================================================

結論

  1. 基準データ v3 に替えました（**cs:22**）。基準どうしの確かめで
     誤った印が1つも出ません。
  2. v3 の60回で「同じ皿が2回以上 打ち切り」は **0 回・0 枚**でした。
     なので直し（2回でスタッフに渡す）を入れました（**cs:23・cs:24**）。
     **基準データ v3 の数字は1つも変わりません**（実測でも確かめた）。
  3. 原因の調べ：**同じ種では再現しませんでした**（全員帰って 172 分で終了）。
     ただし同じ回の中で **ロボットが 551.9 秒（9.2 分）完全に静止**している
     場面を捕まえ、その中身が分かりました（3 章）。
     ★ 私が前に「いちばん疑っている」と書いた**後ずさりの分かれ道は、
       今回の証拠では支持されません**。取り下げます。
  4. 切り替え（det_check）は全部 切 に戻し、ExperimentPlan.asset が
     cs:22 と差分なしであることを確かめました。保留 0。


====================================================================
1. 基準データ v3（cs:22）
====================================================================

  judge_night.py
    BASELINE_DEFAULT  '20261025_stageB_cs7_*' → **'20261027_night_cs21_*'**
    BASELINE_EXCLUDE  **'*_passon*'**（新しく足した。--baseline-exclude で変更可）

  v3 ＝ 最初の夜（night 20261027・ServiceSim/cs:21）の
       **すれ違い「切」の60回**（③⑦ × ロボット 0/1/2 台 × 種0〜9）

  幅の取り方は **1条件10回の最小〜最大**。
  これは前からそうだったので（min(bv)〜max(bv)）、コードは変えていません。
  変わったのは「1条件が3回→10回になった」ことです。

  すれ違い「入」を外す理由
    標準は「切」。しかも種0 は 720 分終わらず数字が使えない。
    glob では名前を除けないので、BASELINE_EXCLUDE で外す形にしました。

  基準どうしの確かめ（いちばん大事な確かめ）
    python3 judge_night.py --runs '20261027_night_cs21_*' --out …
      基準データ: 20261027_night_cs21_*（*_passon* を除く）（**60回**）
      振り分けた回: 70回
        正常               **60**
        Unity の作り        **0**  ← 基準そのものに誤った印が出ない
        試算を見直す候補      0
        回の失敗             1（s0_passon）
        基準なし             9（すれ違い入）

    前の基準（cs:7）では ③1台・⑦1台・⑦2台 の3条件に
    「Unity の作り」の印が付いていました。あれは基準が3種しかなく
    幅が偶然狭かったせい（⑦1台の「動けなくなった」の幅は 3〜3）で、
    v3 では消えました。


====================================================================
2. 皿の打ち切り上限（cs:23・cs:24）
====================================================================

  2-1. 数え上げ（直す前に数えた・エイイチの条件）

    v3 の60回（すれ違い切）で「同じ皿が2回以上 打ち切りで戻された」
      **0 回 / 60 回**・**0 枚**

    参考
      1回だけ打ち切り           12 回で 25 枚
      入 s0_passon             2 枚（皿153:58 回・皿157:57 回）
      入 s1_passon             3 枚（皿126:4 回・皿146:3 回・皿145:3 回）

    → 0 回なので、相談なしで入れました（エイイチの条件どおり）。
      そしてこれは **「基準データ v3 の数字が1つも変わらない」証明**
      にもなります。上限 2 に1枚も届かないので、決まりが当たりません。

  2-2. なぜ「戻す」だけでは助からなかったか（調べて分かったこと）

    RequeueDish は、ちゃんと皿を戻して板にも出していました。

      _pass.Remove(d); _pass.Insert(0, d);          // 受け渡し口の **先頭** へ
      RemoveServeJob(d);
      if (slot != null && d.staffEligibleS >= 0f)
          PostJobFront(StaffJobKind.Serve, …);       // 板にも出す

    ところが受け渡し口のすぐ横にロボットが居るので、
    **歩いてくるスタッフより先にロボットが取り直し**、
    PickBatch → RemoveServeJob で板から消えます。
    だから 60 秒ごとの timeline では板はいつも空に見え、
    スタッフ4人は「頼まれていない」まま手空きでした。

  2-3. 入れた直し

    ServiceSpec   ＋ maxRobotTripTimeoutsPerDish = **2**（0 で無制限＝前と同じ）
    DishOrder     ＋ robotTimeouts（打ち切りで戻された回数）
                  ＋ staffOnly（ロボットには渡さない皿）
    RequeueDish   why が「打ち切り」のとき数え、上限に届いたら
                  staffOnly を立て、staffEligibleS を入れ、警告を1行出す
    PickBatch     ＋ if (d.staffOnly) continue;
                  （「人だけが運ぶ料理」の前例と同じ形）
    記録          summary.json の sim_like に dishes_to_staff_after_timeout
                  requeues.csv に to_staff 列（末尾に追加）

    ★ cs:23 で数えるところまで入れて summary.json に出し忘れ、
      cs:24 で足しました（commit メッセージでは「記録」と書いていたので）。

  2-4. 効き目の確かめ（実測）

    ① 発動するか … ③2台・種1・すれ違い入（名札 fixcheck2・cs:23）
       「皿 14（卓 4）は往復の打ち切りが 2 回になったので、
         ロボットには渡さずスタッフの仕事にします」… **8 枚**で発動
       requeues.csv に to_staff=1 が 8 行
       全員帰った True / 店の中 184.3 分

                        直す前（夜 cs:21）  直したあと（cs:23）
         時間切れ            6               8
         積み直し            11              18
         ロボが運んだ皿       171             140
         スタッフが運んだ皿    35              66
         ロボット分担         0.830           0.680

       ★ すれ違い「入」の回は、この直しで数字が変わります
         （皿がロボットからスタッフへ移るので当然）。
         「入」は標準ではなく基準も無いので問題にしませんが、
         入の回を直す前と比べるときは覚えておいてください。
         なお上の差には「同じ種でもずれる」ぶんも混ざっています。

    ② 「切」で発動しないか … ⑦2台・種2（切の中で時間切れが最多だった回。
       名札 fixcheck3・cs:24）
         **dishes_to_staff_after_timeout = 0**
         警告も 0 件（時間切れは 4 回あったが、同じ皿が2回には届かず）
       → 2-1 の数え上げ（0 枚）が、実測でも裏づけられました。
         ※ この回の入店待ちは 12.21 分で夜の 1.63 分と大きく違いますが、
           これは既知の「同じ種でもずれる」ぶんです。
           **直しが効いていないことは、数（0）で言えます**。


====================================================================
3. 原因の調べ（detCheckFrameFingerprint）
====================================================================

  3-1. まず分かったこと：det_frames は座標を持っていません

    det_frames.csv が記録しているのはロボット **位置の合計値**です。
      rSum = Σ(round(x*10000)*31 + round(z*10000)*17)
    2台ぶんが1つの数に混ざるので、
      取れる   … 動いているか・止まっているか
      取れない … 座標そのもの、「後ずさりの分かれ道に入ったか」
    後者を出すには det_frames に1台ずつの x,z を書き足す（コードを直す）
    必要があるので、今回は前者で進めました。

  3-2. 同じ種では再現しませんでした

    ③2台・種0・すれ違い入 を1回（名札 detcheck・cs:22）
      everyone_left  **True**（夜は False）
      店の中          **172.3 分**（夜は 720.0 分）
      時間切れ         **3**（夜は 59）
      積み直し         **4**（夜は 117）
      実時間           2.3 分（夜は 14.4 分）

    → **種では決まらない**不具合です。間合い（どのコマで何が重なるか）で
      起きます。10/25 に分かった「同じ種でもずれる」と、
      busycheck で分かった「忙しさで詰まりが変わる」と同じ筋です。
      夜の失敗した回は同時 4 本の中の1本（parallel_actual 4）、
      今回は 1 本で回したので、条件も違います。
    ★ 観測そのものが間合いを変えている可能性もあります
      （det_frames で 1 コマごとに 20 万行書くので、重さが変わる）。

  3-3. ただし同じ回の中で、同じ型の固まりを捕まえました

    この回には時間切れが3回あり、そのうち **往復116（ロボット2）** が
    決定的でした。

      det_frames … 位置の合計が **9150.4 秒 〜 9700.1 秒 の 551.9 秒間
                   まったく同じ**（＝ロボットは完全に静止）
      その間の止まり記録（stops.csv）

        9094.1 秒  x=15.11 z=5.82  原因=分からない    3.05 秒  自分で動き出した
        9167.4 秒  x=14.358 z=5.384 原因=**もう1台のロボット（ServingRobot01）**
                   60.05 秒  **動けなくなった**  blocked 60.05 秒 / no_path **52.9 秒**
        9243.2 秒  同じ場所・同じ内容（60.05 秒）
        9319.7 秒  同じ
        9396.2 秒  同じ
        9473.2 秒  同じ
        9550.8 秒  同じ
        9628.6 秒  同じ          ← ここまで **7 回**くり返し
        9705.8 秒  13.45 秒  **回り込んで動き出した**（やっと抜けた）

      ・場所の余裕は **275 cm**。狭くて挟まったのではありません
      ・60 秒のうち **53 秒は「道が引けない」**（no_path_s 52.9）
      ・原因欄に **もう1台のロボット（ServingRobot01）** と出ています
      ・直前（9077.95 秒）に すれ違いが1件あり、結果は「すれ違えた」

    つまり型はこうです。
      **2台が互いの前をふさぐ → 道が引けない → 60 秒待って「動けなくなった」
      → 引き直す → まだ引けない → … を 9.2 分くり返し、
      たまたま回り込めて抜けた。**
    夜の失敗した回は、これが **抜けられなかった**のだと見ています。

  3-4. 前に書いた疑いを取り下げます

    10/27 07:43 の報告で「いちばん疑っているのは cs:10 で入れた
    後ずさりの分かれ道（_passByBackingOff → BackOffStep → return）」
    と書きました。**今回の証拠では支持されません。**
    止まりはちゃんと記録されていて、原因欄も「もう1台のロボット」と
    出ています。記録に出ない分かれ道に入っていたのではなく、
    **記録される普通の道（道が引けない）で詰まっていました**。

    ただし完全に同じとは言えません。夜の失敗した回は
    600 秒の往復に対して止まりが **standby1 で 0.95 秒 1 件だけ**で、
    今回の「60 秒 × 7 回」とは形が違います。
    夜の回そのものの原因は、まだ特定できていません。

  3-5. 切り替えは戻しました

    ExperimentPlan.asset の detCheckSyncPeoplePaths / detCheckNoAvoidance /
    detCheckFrameFingerprint はすべて 0。
    cm cat で cs:22 と比べて **差分なし**を確認。保留 0。
    Assets のコードは、この調べでは1行も直していません。


====================================================================
4. 残っていること・相談
====================================================================

  ① 夜の失敗した回そのものの原因は未特定です
     再現しないので、やれることは2つです。
     (ア) 4本同時で s0_passon を何回か回して再現を狙う
          （1回 4 分弱。10 回で 40 分ほど。再現率は不明）
     (イ) det_frames に **1台ずつの x,z** を書き足して、
          次に起きたときに必ず分かるようにしておく（十数行の直し）
     私は **(イ)** を勧めます。再現待ちをするより、
     次に起きたときに1回で分かる形にしておくほうが確実です。

  ② 2台が互いをふさぐ件（3-3）は、直しの候補が別にあります
     ・60 秒で「動けなくなった」と判定したら、**回り込み**を
       もっと早く試す（今回は 9.2 分かかって最後に回り込めた）
     ・受け渡し口の点が1つしかない件（既知）を直す
     どちらも動きを変えるので、基準データ v3 を取り直すことになります。
     今は触らないほうがよいと思います。

  ③ Unity を次に開くと、ServiceSpec.asset に
     maxRobotTripTimeoutsPerDish: 2 の行が出て保留 1 件になります。
     その行はそのまま check-in して構いません（既定を .asset に残す形）。
     私がやってもよいので、開いたら声をかけてください。

  ④ 台帳に足した行（この作業ぶん）
     20261027_detcheck_cs22_fam_p1_r2_s0_passon    （調べ用）
     20261027_fixcheck2_cs23_fam_p1_r2_s1_passon   （発動の確かめ）
     20261027_fixcheck3_cs24_fam_p5_r2_s2          （切で発動しない確かめ）
     名札で分かれるので、基準 v3（20261027_night_*）には入りません。


====================================================================
5. check-in
====================================================================

  cs:22  judge_night.py … 基準データ v3（BASELINE_DEFAULT・BASELINE_EXCLUDE）
  cs:23  ServiceSpec / ServiceOps / TripLogger … 打ち切り2回でスタッフへ
  cs:24  TripLogger / ExperimentRunner … dishes_to_staff_after_timeout を
         summary.json に出す（cs:23 の書き忘れ）

  いまの保留 0。実行ファイルは cs24_20261027_0800（保留 0・ARM64）。
  台帳の列（59列・schema 2）は変えていません。
