サービスロボット導入シミュレーション Log#31 | 配膳ロボットのにらみ合い、解くのは店員だった
この記事の素材(コード・ログ・データ 4ファイル・まとめてダウンロードあり)arrow_downwardAIで読む ChatGPT・Claude などで、この記事に質問できます expand_more
配膳ロボット2台が狭い通路で正面から向かい合うと、実際の店でもロボットどうしでは解けず、店員が来て手で片方をどかしている。PUDU・KEENON・Bear Robotics などのメーカーは、どちらのロボットが譲るかの決まりを公開しておらず、これまでに集めた実物の動画4本はどれも、店員が来るまで18〜53秒以上かかり、手で直す作業は5秒前後だった。Unity(ゲームや3Dの映像を作るソフト)で再現したファミレスでは、同じ向かい合いでロボットが9分にらみ合い、最後は料理の取り消しでやっと動いていたので、30秒動けなければ店員が助けに来る作りに変えた。
この回で、配膳ロボットの導入を考える人に見せられるものが2つ増えました。
- 試算のページ(/series8)で店の形を選ぶと、その店を Unity で動かした動画を見られるようになった。 引きで店全体を見たあと、ロボットが長く止まった場所に寄って何が起きたかを映す。図面のある6店ぶんで、動画は押したときだけ読み込むので試算のページは重くならない
- シミュレーションの詰まり方が、実物の店の運用に近づく。 これまでは2台がにらみ合うと、10分の打ち切りまでだれも助けなかった。30秒で店員が助けに来るようにしたので、ロボットが詰まったときに店員がどれだけ手を取られるかも数字で出るようになる(数字は2026-11-03 の夜の取り直しで出る。いまは見込み)
- 動画の書き出しが速くなった。 字幕付きの動画を1店作るのに約1分36秒かかっていたのが、約27秒になった(同じ店・同じ回で測った値)
きっかけは、試算のページに動画を載せる作業の途中で見た1本の動画でした。2台のロボットが受け渡し口の近くで向かい合い、どちらも道は引けているのに動かない。記録を開くと、1号機が「よける場所」に入って待っているのに、その場所が2号機の進む道をふさいでいて、2台とも相手がどくのを待ち続けていました。では実物の配膳ロボットは、ロボットどうしの譲り合いをどう決めているのか。メーカーの資料・特許・規格と、これまでに集めた実物の動画を調べ直しました。
| やったこと | なぜ | 結果 |
|---|---|---|
試算のページに「平面図/Unity で動かすと」の切り替えを足した | 数字だけでは店で何が起きるか伝わらないため | 図面のある6店で、選んだ店の動画が流れる。字幕はスマホでも読める大きさ(1.5倍)に |
動画の書き出しを、4K の録画の使う場面へ飛んでから切る形にした | 1店に1分半かかり、Mac 連携の1回の作業時間(3分)に収まらなかったため | 1店 約96秒 → 約27秒。切り出した場面は前と同じ |
ロボット2台のにらみ合いに、30秒で店員が助けに来る作りを足した | Unity では9分止まり、実物の店は店員が手で解いているため | 2026-11-03 の夜の基準データの取り直し(6店・180回)に最初から入る |
実物の配膳ロボットの「ロボットどうしの決まり」を調べた | 将来、ロボット側の作りで詰まりを無くせると言えるようにするため | 取扱説明書で分かるのは2つだけ。譲る側の決め方は特許と、日本の管制の仕組み・規格にあった |
配膳ロボットを自分の店に入れたらどうなるかは、このシリーズの試算をもとにした別のページで試せます。
作業ログ ― 試算のページに、店ごとの Unity の動画を入れた
この記事のコード・ログ・データは、1ファイルずつ下に置いています。全文はリンク先にあります。
ファイルの一覧(4本)
01_serving-robot.html_script.js.txt ― serving-robot.html に足したコード(動画の行・切り替え・読み込み) / serving-robot.html の script(UNITY の行・unityPane・bigPlan・buildLayouts の全文)・4,502字
02_4K_1_96_27_focus_clips.py.txt ― 4K の録画を頭から読まない形にした(1店 96秒 → 27秒) / focus_clips.py(字幕の倍率と、場面へ飛んでから切る形を足した版の全文)・8,702字
03_1_2_9_give_ups.csv ― ⑦の店で、1号機と2号機が約9分止まっていた記録 / give_ups.csv(⑦・種7の全行)・6,425字
04_sec03.md ― 調査報告(research_serving_robot_fleet_rules_20261103.md の全文)・25,254字
数字の効果は、測ったものは測った値として、まだ測っていないものは見込みとして書きます。
Unity の動画を、平面図の枠の中の切り替えにした理由
動画の置き場所は2つ考えました。平面図の下に縦に並べる形と、平面図の枠の中で「平面図/Unity で動かすと」を切り替える形です。縦に並べると、試算の操作(人数・台数・使い方を選ぶ所)が約550px下に押し出されるので、切り替えにしました。動画は図面のある店にだけあり、図面のない「標準ファミレス」を選んだときは切り替えが出ません。
- ねらい:試算の数字(入店待ち・料理が届くまで)と、その店で実際に何が起きるかを、同じ画面で見比べられるようにする
- 変わったこと:店の形を選ぶと、平面図の右上に切り替えが出る。押すと同じ枠の中で動画に替わり、そのまま再生が始まる。動画は押すまで読み込まない
- 見込める効果:試算のページを開いただけでは動画を読み込まないので、ページの重さは変わらない。動画が見られたかは、サイトの記録(押したもの)で確かめる



動画の下には、動画の条件(ふつうの混み具合・その回のスタッフ人数・ロボット2台)が、上で選んでいる試算の条件とは別であることと、Unity の中で起きたことで、実際のロボットや人が同じ動きをするとは限らないことを一言添えました。
serving-robot.html に足したコード(動画の行・切り替え・読み込み)
動画と表紙の画像は、Cloudflare の R2(画像や動画を置いて配るための入れ物)に置き、サイトの /media/ から配っています。R2 は同じ名前で上書きできないので、作り直したら名前の版(v1 → v2)を上げて、下の const UNITY の行を書き換えます。
serving-robot.html の script(UNITY の行・unityPane・bigPlan・buildLayouts の全文)
// Unity で動かした様子(2026-11-03)。図面のある店ごとに、引き→問題の場所→寄りの動画を1本。
// 条件は Unity の録画の回のもの(試算で選んでいる人数・台数とは別)。動画と表紙の画像は R2(/media/)
const UNITY = {
fam_p0: { video: "/media/series8_unity_fam_p0_v1.mp4", poster: "/media/series8_unity_fam_p0_v1.jpg", staff: 2, note: "引きで店全体を見たあと、ロボットが長く止まった場所に3か所寄ります(約70秒)" },
fam_p1: { video: "/media/series8_unity_fam_p1_v1.mp4", poster: "/media/series8_unity_fam_p1_v1.jpg", staff: 4, note: "引きで店全体を見たあと、ロボットが長く止まった場所に3か所寄ります(約70秒)" },
fam_p2: { video: "/media/series8_unity_fam_p2_v1.mp4", poster: "/media/series8_unity_fam_p2_v1.jpg", staff: 2, note: "引きで店全体を見たあと、ロボットが長く止まった場所に3か所寄ります(約70秒)" },
fam_p3: { video: "/media/series8_unity_fam_p3_v1.mp4", poster: "/media/series8_unity_fam_p3_v1.jpg", staff: 4, note: "引きで店全体を見たあと、ロボットが長く止まった場所に3か所寄ります(約55秒)" },
fam_p4: { video: "/media/series8_unity_fam_p4_v1.mp4", poster: "/media/series8_unity_fam_p4_v1.jpg", staff: 3, note: "ロボットが30秒以上止まった場所がなかったので、引きだけです(8秒)" },serving-robot.html の style(足した部分の全文)
.plan-big .ph .pv-sw { margin-left: auto; display: inline-grid; grid-auto-flow: column; gap: 2px; padding: 3px; border-radius: 8px; background: #e3e3df; }
.pv-sw button { border: 0; border-radius: 6px; padding: 6px 12px; background: transparent; font: inherit; font-size: 13px; font-weight: 600; color: #555; cursor: pointer; white-space: nowrap; }
.pv-sw button[aria-selected="true"] { background: #111; color: #fff; }
.pv-sw button:focus-visible { outline: 2px solid #111; outline-offset: 2px; }
.pv-unity video { display: block; width: 100%; aspect-ratio: 16 / 9; background: #3a3a3a; border-radius: 4px; }
.pv-plan[hidden], .pv-unity[hidden] { display: none; }
@media (max-width: 599px) { .plan-big .ph .pv-sw { margin-left: 0; width: 100%; grid-auto-columns: 1fr; } }
p2m-site の README.md に足した節
## 試算の「Unity で動かすと」の動画(/series8・2026-11-03)
配膳ロボットの試算(`public/sim/serving-robot.html`)で図面のある店を選ぶと、平面図の右上に「平面図/Unity で動かすと」の切り替えが出る。押すとその店を Unity で動かした動画(引き→長く止まった場所→寄り)に替わり、そのとき初めて動画を読み込んで再生する。
- 動画と表紙の画像:R2 の `series8_unity_{店}_{版}.mp4`・`.jpg`(店は fam_p0〜fam_p5・large_p6・large_p7)。R2 は同じ名前で上書きできないので、作り直したら版(v1→v2)を上げる
- 作り方:KIOXIA の `r2r2r-data/service_sim/unity/series8_web_{日付}/make_web.sh`(iCloud の `サービスロボット導入シミュレーション/unity/focus_clips/focus_clips.py` を字幕1.5倍で回す)。できた `upload_{版}/` を `tools/upload_media.py` で R2 に入れる
- 差し替え:`serving-robot.html` の `const UNITY` の行(動画・表紙・その回のスタッフ人数・説明の一文)を直す。行がない店には切り替えが出ない
字幕を1.5倍にした(スマホの幅で読めなかったため)
最初の試作をスマホの幅(390px)で見ると、動画の中の字幕(「寄り:ロボットどうしが道をふさぎ合って止まる」など)が小さすぎて読めませんでした。動画を作るスクリプト(focus_clips.py)に字幕の倍率を足し、サイト用は1.5倍で書き出しています。倍率を指定しなければ今までと同じ大きさなので、Claude Code が動かしている撮り直しの処理(依頼75)の出力は変わりません。問題の場所に付ける輪の大きさには倍率をかけていません。

4K の録画を頭から読まない形にした(1店 96秒 → 27秒)
最初に6店をまとめて書き出したとき、1店に約1分36秒かかりました。動画は、4K(3840×2160)で撮った引きの録画から場面を切り出して作ります。ffmpeg(動画を変換・切り出しする道具)の切り出しの指定が「頭から全部読んで、使う場面だけ残す」形になっていて、店の時刻で2時間を超える録画を毎回頭から読んでいました。
- ねらい:Mac 連携の1回の作業(最長3分)の中で、何店かをまとめて書き出せるようにする
- 変わったこと:使う場面の手前まで飛んでから読み始める形(
-ssを入力の前に置く)にした。録画は1秒30コマなので、コマ番号を30で割った秒へ飛ぶ。書き出し直すので、コマ単位でずれない - 見込める効果ではなく測った値:③の店で 約96秒 → 約27秒。直す前と後で同じ場面が切り出されることを、映像のずれの大きさ(PSNR)で確かめた
PSNR は、2つの映像がどれだけ同じかを表す数字で、大きいほど同じ、inf(無限大)なら1コマ残らず同じです。寄りの2本は完全に同じで、引きの1本(p00_open)は 42.9 でした。40 を超えると目で見て違いは分かりません。
直す前と後の書き出しの比べ(③・fam_p1)
(直す前)
== fam_p1 22:00:14
1 ('ロボットどうしが道をふさぎ合って止まる', '店の時刻 23:59〜33:38・止まった合計 600秒(10回)') (20.6, 3.8)
2 ('スタッフとすれ違えず、ロボットが止まる', '店の時刻 100:47〜109:08・止まった合計 334秒(6回)') (5.8, 4.3)
3 ('ロボットどうしが道をふさぎ合って止まる', '店の時刻 43:40〜47:24・止まった合計 176秒(3回)') (16.5, 5.9)
OK fam_p1/focus_v1/focus_trial.mp4
OK fam_p1 22:01:50
(直した後)
OK fam_p1/focus_v1/focus_trial.mp4
real 0m26.857s
user 0m56.834s
sys 0m9.082s
(同じ場面か:直した後と直す前の PSNR)
== p00_open
[Parsed_psnr_0 @ 0xbe9ca599d2b0] PSNR y:41.377981 u:49.483028 v:56.007633 average:42.938245 min:37.412721 max:63.142575
== p01b_focus
[Parsed_psnr_0 @ 0xca35816bde20] PSNR y:inf u:inf v:inf average:inf min:inf max:inf
== p03b_focus
[Parsed_psnr_0 @ 0xb71877932e20] PSNR y:inf u:inf v:inf average:inf min:inf max:inf
focus_clips.py(字幕の倍率と、場面へ飛んでから切る形を足した版の全文)
"""問題に寄る動画を作る(サービスロボット導入シミュレーション・2026-11-02)
カメラの目的を分ける(エイイチと決めた)
- 引き:全体の流れを見る(60°見下ろし・左30°/右30°の店全体)
- 寄り:問題が起きている所を見る(ロボットが動けなくなった・長く止まった所と時刻)
問題がどこでいつ起きるかは回してみないと分からないので、1回の回で引きを高解像度(3840×2160)で撮り、
その回の stops.csv から問題を拾って、引きの映像から切り出して寄りを作る(寄りのカメラを別に置かない)。make_web.sh で6店を書き出して R2 に入れた
6店の動画は、サイト用の名前(series8_unity_{店}_v1.mp4 と表紙の .jpg)で書き出しました。最初は2つの理由で失敗しています。1つは、外付けの SSD(KIOXIA。exFAT という形式)の上で書いた画像を、すぐあとに ffmpeg が「見つからない」と言ったこと。作業は Mac 連携の作業場所の中の一時フォルダで行い、最後に KIOXIA へ写す形に変えました。もう1つは、裏で動かした書き出しが、Mac 連携の1回の作業が終わると一緒に止まったこと。こちらは上の速くした版で、1回の作業の中で数店ずつ回して済ませました。
make_web.sh(全文)
#!/bin/bash
# /series8 に載せる「Unity で動かすと」の動画を作る(2026-11-03)。字幕 1.5 倍で focus_clips.py を回し、
# サイト用の名前(series8_unity_{店}_{版}.mp4・.jpg)に書き出す。使い方: make_web.sh <版> <店 録画のフォルダ 回のフォルダ>...
D=${OUTD:?}; S="$(cd "$(dirname "$0")" && pwd)"; V=$1; shift
# KIOXIA(exFAT)の上で書いてすぐ ffmpeg に読ませると見つからないことがあるので、作業は手元の一時フォルダで行い、最後に写す
T=$HOME/s8work; mkdir -p $T; cd $T
export FOCUS_TEXT_SCALE=1.5 FOCUS_FONT=/usr/share/fonts/opentype/noto/NotoSansCJK-Bold.ttc
mkdir -p upload_$V
while [ $# -ge 3 ]; do
k=$1 rec=$2 run=$3; shift 3
echo "== $k $(date +%T)"
python3 "$S/focus_clips.py" "$rec" "$run" "$k/focus_$V" || { echo "NG $k"; continue; }
ffmpeg -v error -y -i "$k/focus_$V/focus_trial.mp4" -c copy -movflags +faststart "upload_$V/series8_unity_${k}_$V.mp4"
ffmpeg -v error -y -ss 1.5 -i "upload_$V/series8_unity_${k}_$V.mp4" -frames:v 1 -q:v 3 "upload_$V/series8_unity_${k}_$V.jpg"
mkdir -p "$D/$k" "$D/upload_$V"; cp -r "$k/focus_$V" "$D/$k/"; cp upload_$V/series8_unity_${k}_$V.* "$D/upload_$V/"
echo "OK $k $(date +%T)"
done
echo DONE
最初の書き出しのログ(⑦の途中で、裏の処理が止まった)
== fam_p1 22:00:14
1 ('ロボットどうしが道をふさぎ合って止まる', '店の時刻 23:59〜33:38・止まった合計 600秒(10回)') (20.6, 3.8)
2 ('スタッフとすれ違えず、ロボットが止まる', '店の時刻 100:47〜109:08・止まった合計 334秒(6回)') (5.8, 4.3)
3 ('ロボットどうしが道をふさぎ合って止まる', '店の時刻 43:40〜47:24・止まった合計 176秒(3回)') (16.5, 5.9)
OK fam_p1/focus_v1/focus_trial.mp4
OK fam_p1 22:01:50
== fam_p5 22:01:50
速くした版で残りの4店を書き出したログ
== fam_p2 22:12:31
OK fam_p2/focus_v1/focus_trial.mp4
OK fam_p2 22:12:57
== fam_p3 22:12:57
OK fam_p3/focus_v1/focus_trial.mp4
OK fam_p3 22:13:20
== fam_p4 22:13:20
OK fam_p4/focus_v1/focus_trial.mp4
OK fam_p4 22:13:24
== fam_p0 22:13:24
OK fam_p0/focus_v1/focus_trial.mp4
OK fam_p0 22:13:49
DONE
書き出した動画の長さと大きさ・R2 に入れたときのログ
upload_v1/series8_unity_fam_p0_v1.mp4 1315020 68.669000
upload_v1/series8_unity_fam_p1_v1.mp4 1429350 68.669000
upload_v1/series8_unity_fam_p2_v1.mp4 1478114 68.669000
upload_v1/series8_unity_fam_p3_v1.mp4 1284319 53.536000
upload_v1/series8_unity_fam_p4_v1.mp4 55098 7.967000
upload_v1/series8_unity_fam_p5_v1.mp4 1630210 68.669000
total 12800
drwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 524288 Nov 2 22:13 .
drwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 524288 Nov 2 22:14 ..
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 58370 Nov 2 22:14 series8_unity_fam_p0_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 1315020 Nov 2 22:14 series8_unity_fam_p0_v1.mp4
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 62443 Nov 2 22:14 series8_unity_fam_p1_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 1429350 Nov 2 22:14 series8_unity_fam_p1_v1.mp4
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 60083 Nov 2 22:14 series8_unity_fam_p2_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 1478114 Nov 2 22:14 series8_unity_fam_p2_v1.mp4
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 65819 Nov 2 22:14 series8_unity_fam_p3_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 1284319 Nov 2 22:14 series8_unity_fam_p3_v1.mp4
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 57747 Nov 2 22:14 series8_unity_fam_p4_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 55098 Nov 2 22:14 series8_unity_fam_p4_v1.mp4
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 62563 Nov 2 22:14 series8_unity_fam_p5_v1.jpg
-rwx------ 1 rcw-01levexvdomwvaskecpngafe rcw-01levexvdomwvaskecpngafe 1630210 Nov 2 22:14 series8_unity_fam_p5_v1.mp4
入れる 12・入っている 0・名前の重なり 0・合計 7.6MB
12/12
おわり
200 58370
200 62563
⑥(fam_p4)は、30秒以上止まった場所も動けなくなった所もなかったので、引きだけの8秒の動画です。動画に寄った3か所は、店ごとに次のとおりでした(x・y は店の中の位置 m、t0〜t1 は店の時刻の秒)。
店ごとに寄った上位3か所(episodes.json から)
== fam_p0
12.3 5.5 4812 4949 120 2 2 {'もう1台のロボット': 120.0988}
11.3 5.4 6085 6294 120 2 2 {'もう1台のロボット': 120.0988}
12.3 5.5 4316 4490 88 2 0 {'もう1台のロボット': 87.89920000000001}
== fam_p1
20.6 3.8 1440 2019 600 10 10 {'もう1台のロボット': 600.494}
5.8 4.3 6048 6548 334 6 5 {'スタッフとすれ違った': 334.09680000000003}
16.5 5.9 2621 2844 176 3 2 {'もう1台のロボット': 176.0982}
== fam_p2
3.6 2.3 1258 1788 600 10 10 {'もう1台のロボット': 240.1976, '人が立ち止まっていた': 120.0988, 'スタッフとすれ違った': 240.1976}
8.9 2.4 3996 4498 600 10 10 {'もう1台のロボット': 180.1482, '人が立ち止まっていた': 240.1976, '椅子・荷物・ベビーカー': 120.0988, 'お客さんとすれ違った': 60.0494}
7.1 2.3 5256 5764 540 9 9 {'もう1台のロボット': 420.3458, 'お客さんとすれ違った': 120.0988}
== fam_p3
13.4 8.9 2746 2857 120 2 2 {'スタッフとすれ違った': 60.0494, '人が立ち止まっていた': 60.0494}
14.3 8.8 4872 4932 60 1 1 {'もう1台のロボット': 60.0494}
15.1 8.8 2420 2477 57 1 0 {'スタッフとすれ違った': 56.9994}
== fam_p4
== fam_p5
20.6 4.0 1473 2021 762 13 11 {'もう1台のロボット': 761.5424}
1.8 6.4 2126 2383 180 3 3 {'スタッフとすれ違った': 120.0988, '人が立ち止まっていた': 60.0494}
1.8 8.4 4257 4477 164 3 2 {'お客さんとすれ違った': 164.3484}
公開後に、PC とスマホの幅で動画が流れることを確かめた
Playwright(ブラウザを自動で動かす道具)で公開したページを開き、⑦(PC の幅)と②(スマホの幅)で切り替えを押して、3秒あまりで再生が進んでいることを確かめました。
1280 {
src: 'https://pixelstomotors.com/media/series8_unity_fam_p5_v1.mp4',
t: '3.3',
paused: false,
w: 1280
}
390 {
src: 'https://pixelstomotors.com/media/series8_unity_fam_p0_v1.mp4',
t: '3.2',
paused: false,
w: 1280
}
動画を見たまま店を切り替えると流れなかった不具合
公開して約30分後、「Unity で動かすと」を押したまま店の形を切り替えると、動画が流れないと分かりました。下の画面は、③で動画を見たあと④に切り替えたところで、表紙の絵は出ているのに 0:00 のまま止まっています。

店を切り替えると平面図の枠を作り直します。動画を読み込む処理が「切り替えを押したとき」にしか動かない作りだったので、作り直した枠の動画は表紙だけになっていました。動画を見ている状態で店を替えたときにも読み込むようにしました(上の buildLayouts の全文に入っています)。
直した所(git の差分)
diff --git a/public/sim/serving-robot.html b/public/sim/serving-robot.html
index ee449da..ae6c684 100644
--- a/public/sim/serving-robot.html
+++ b/public/sim/serving-robot.html
@@ -540,6 +540,9 @@ function buildLayouts() {
+ `<div class="lay-grid" role="radiogroup" aria-label="店の形">`
+ items.map(([k, name, sub, pic], i) => `<input type="radio" name="layout" id="layout-${i}" value="${k}"${state.store === k ? " checked" : ""}><label for="layout-${i}">${pic}<b>${name}</b><span>${sub}</span></label>`).join("")
+ `</div>` + (isLayout(state.store) ? bigPlan(state.store) : "");
+ // 動画を見ている状態で店を替えたら、替えた先の店の動画をそのまま読み込んで流す(2026-11-03)
+ const vid = planView === "unity" && el.querySelector(".pv-unity:not([hidden]) video");
+ if (vid) { vid.src = vid.dataset.src; vid.play().catch(() => {}); }
el.onchange = e => { state.store = e.target.value; state.staff = S().staff[1]; state.cbase = S().staff[1]; state.reg = S().registers; buildStores(); buildLayouts(); buildControls(); render(); };
// 平面図と動画の切り替え。動画は押したときに初めて読み込み、そのまま再生する
el.onclick = e => {
直したあとの確かめ(公開したページで③ → ④・⑥・② と切り替え)
fam_p2 { src: 'series8_unity_fam_p2_v1.mp4', t: '2.5', paused: false }
fam_p4 { src: 'series8_unity_fam_p4_v1.mp4', t: '2.3', paused: false }
fam_p0 { src: 'series8_unity_fam_p0_v1.mp4', t: '2.6', paused: false }
いま載っている動画は、客が急に席に現れる不具合(瞬間移動)を直す前の回のものです。直した版の撮り直し(依頼75)がそろった店から入れ替えます。入れ替えた結果は、この記事に追記します。
作業ログ ― 配膳ロボット2台のにらみ合いを、30秒で店員が助ける形にした
⑦の店で、1号機と2号機が約9分止まっていた記録
⑦の店(42卓・通路を95cmにした店)の夜の回で、ロボットが受け渡し口の右下(店の中の位置 x 20.4〜20.6m・y 4.0〜5.1m)で、店の時刻 1472秒から 2022秒まで、約9分10秒止まっていました。記録(stops.csv)を見ると、2台とも道は引けている(solve_status が「引けた」)のに、動けなくなった印が60秒ごとに並ぶだけで、だれも助けに来ていません。1号機は「よける場所で待った」と書かれていますが、その場所が2号機の進む道の上でした。
詰まりが解けたのは、2号機が運んでいた料理が600秒待って打ち切られ(requeues.csv)、2号機の行き先が変わったときです。そのあいだ、同じ卓へ料理を運ぼうとしたスタッフが5回あきらめていました(give_ups.csv)。
stops.csv(⑦・種7の、もう1台のロボットが原因で30秒以上止まった行の全部)
condition_id,seed,robot_id,trip_id,t_s,x,z,aisle,in_narrow,cause,cause_detail,path_blocked,duration_s,resolved,clearance_left_cm,clearance_right_cm,min_gap_cm,blocked_s,no_path_s,yield_s,clear_wait_s,replans,solve_from,solve_to,solve_status,solve_corners,off_mesh_m
fam_p5_s4_r2_a42,7,1,7,1133.65,16.587,5.9491,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,33.3371,181.3968,33.3371,60.0494,0,0,0,19,16.587;5.949,16.9;6.05,引けた(狭い道),2,0.0116
fam_p5_s4_r2_a42,7,2,10,1475.4,20.349,5.0467,,0,もう1台のロボット,ServingRobot01,0,60.0494,動けなくなった,60.7642,275,60.7642,60.0494,0,0,0,19,20.349;5.047,21.362;2.188,引けた,19,0.0147
fam_p5_s4_r2_a42,7,2,10,1573.8,20.349,5.0467,,0,もう1台のロボット,ServingRobot01,0,44.1496,自分で動き出した,60.7642,275,60.7642,43.1996,0,0,0.95,14,20.349;5.047,21.362;2.188,引けた,19,0.0147
fam_p5_s4_r2_a42,7,2,10,1618,20.3454,5.0587,,0,もう1台のロボット,,0,60.0494,動けなくなった,64.0912,275,64.0912,60.0494,0,0,0,19,20.345;5.059,21.362;2.188,引けた,20,0.0088
fam_p5_s4_r2_a42,7,2,10,1700.7,20.3454,5.0587,,0,もう1台のロボット,,0,60.0494,動けなくなった,64.0912,275,64.0912,60.0494,0,0,0,20,20.345;5.059,21.362;2.188,引けた,20,0.0088
fam_p5_s4_r2_a42,7,2,10,1792.7,20.3454,5.0587,,0,もう1台のロボット,ServingRobot01,0,60.0494,動けなくなった,64.318,275,64.318,60.0494,0,0,0,20,20.345;5.059,21.362;2.188,引けた,20,0.0088
fam_p5_s4_r2_a42,7,2,10,1873.75,20.3454,5.0587,,0,もう1台のロボット,ServingRobot01,0,60.0494,動けなくなった,64.318,275,64.318,60.0494,0,0,0,19,20.345;5.059,21.362;2.188,引けた,20,0.0088
fam_p5_s4_r2_a42,7,2,10,1964.6,20.3454,5.0587,,0,もう1台のロボット,ServingRobot01,0,56.8494,自分で動き出した,64.318,275,64.318,56.8494,0,0,0,19,20.345;5.059,21.362;2.188,引けた,20,0.0088
fam_p5_s4_r2_a42,7,1,11,1472.6,20.5578,3.9894,,0,もう1台のロボット,よける場所で待った:ServingRobot02,0,60.0494,動けなくなった,275,65.5595,65.5595,60.0494,0,0,0,31,20.556;3.975,19.813;4.388,引けた(狭い道),7,0.0138
fam_p5_s4_r2_a42,7,1,11,1553.95,20.5558,3.9746,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,30.6132,64.9799,30.6132,60.0494,0,0,0,28,20.556;3.975,19.913;4.388,引けた(狭い道),7,0.0138
fam_p5_s4_r2_a42,7,1,11,1635.95,20.5558,3.9746,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,30.6132,64.9799,30.6132,60.0494,0,0,0,314,20.556;3.975,16.9;6.05,引けた(狭い道),6,0.0138
fam_p5_s4_r2_a42,7,1,11,1731.75,20.5558,3.9746,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,30.6132,64.9799,30.6132,56.6494,0,0,3.4,318,20.556;3.975,16.9;6.05,引けた(狭い道),3,0.0138
fam_p5_s4_r2_a42,7,1,11,1828.35,20.5558,3.9746,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,30.5928,64.9468,30.5928,49.6995,0,0,10.35,331,20.556;3.975,16.9;6.05,引けた(狭い道),3,0.0138
fam_p5_s4_r2_a42,7,1,11,1935.05,20.5558,3.9746,,0,もう1台のロボット,ServingRobot02,0,60.0494,動けなくなった,30.5928,64.9468,30.5928,48.9995,0,0,11.05,331,20.556;3.975,16.9;6.05,引けた(狭い道),3,0.0138
requeues.csv(⑦・種7)
condition_id,seed,t_s,dish_id,table_id,robot_id,fragile,ready_s,waited_s,requeued_so_far,why,to_staff
fam_p5_s4_r2_a42,7,2022.267,11,40,2,0,1421.581,600.686,1,打ち切り,0
give_ups.csv(⑦・種7の全行)
condition_id,seed,t_s,who,job,table_id,to_x,to_z,x,z,aisle,waited_s,action
fam_p5_s4_r2_a42,7,1831.431,スタッフ,料理を運ぶ,41,22.463,2.188,19.9815,4.4102,,60.0494,あきらめた
fam_p5_s4_r2_a42,7,1920.668,スタッフ,料理を運ぶ,41,22.463,2.188,19.9802,4.411,,60.0494,あきらめた
fam_p5_s4_r2_a42,7,1941.238,スタッフ,料理を運ぶ,41,15.3,5.95,20.25,3.3142,,60.0494,あきらめた
fam_p5_s4_r2_a42,7,1981.828,スタッフ,料理を運ぶ,41,22.463,2.188,19.9763,4.4244,,60.0494,あきらめた
fam_p5_s4_r2_a42,7,2001.397,スタッフ,料理を運ぶ,40,15.3,5.95,20.25,3.3119,,60.0494,あきらめた
fam_p5_s4_r2_a42,7,2187.178,スタッフ,料理を運ぶ,4,15.3,5.95,1.8388,8.244,A01,60.0494,あきらめた
fam_p5_s4_r2_a42,7,2262.001,スタッフ,料理を運ぶ,8,15.3,5.95,1.824,8.3095,A01,60.0494,あきらめた詰まる理由は、どちらが譲るか決まらないことと、よけた先が相手の道の上だったこと
いまの Unity の決まりは、料理を載せているロボットが先に行き、空で戻るロボットがよける、です。この決まりは、2台とも料理を載せているときや2台とも空のときに、どちらが譲るかを決めません。2台とも相手を待ちます。さらに、よける側が入った「よける場所」が、相手の進む道をふさいでいることがありました。
解き方の案は3つ出しました。
- 下がる1台を必ず決める。同じ優先なら、よけられる場所に近い方が、相手の道から外れた所までバックで戻る
- 狭い通路の入口で待つ。向こうからロボットが来ている細い通路には入らず、手前で待つ
- 30秒動けなければ、店員が来て片方を動かす。試算の「立ち往生」(スタッフが動かしに行く)と同じ扱い
2 は LOG423 で④の店に「1本道は1台ずつ」として試していて、ロボットの世話は3〜4割減ったものの、1台のときには届きませんでした。選んだのは3です。
30秒動けなければスタッフが来て片方を動かす。試算の立ち往生(スタッフが動かしに行く)と同じ扱いです。今はこれでいいよ。実際の店舗もそんな運用だし。
ただし、将来的にロボットにこういう動きの設計を組み込めばこういった詰まりが無くせますと言えるように最新の配膳ロボットの仕様を追いかけたいね
- ねらい:Unity の詰まり方を、実物の店の運用(詰まったら店員が手で解く)と、サイトの試算の決まり(立ち往生はスタッフが動かしに行く・作業15秒)にそろえる
- 変わったこと:ロボットが30秒以上動けなかったら、いちばん優先の仕事として、手の空いた近いスタッフが歩いて行き、着いてから15秒で片方を動かす。ロボットどうしなら空の方、同じなら行き先まで遠い方を動かす。入を標準にした切り替えで入れる
- 見込める効果:⑦のような9分のにらみ合いが、30秒+スタッフが着くまで+15秒で解ける見込み。店員が助けに使った回数と時間(rescues・rescue_staff_s)が店ごとに出るので、試算の立ち往生の割合(1往復の1%)と比べられる。結果は2026-11-03 の夜の取り直しで出る
依頼76 の最初に、店員の助けを足した
この作りは、2026-11-03 の夜の基準データの取り直し(依頼76。瞬間移動を直した版で6店を180回回す)の最初に入れました。助けを入れないまま取り直すと、すぐにもう一度取り直すことになるためです。依頼箱は依頼をファイル名の順に1件ずつ回すので、別の依頼に分けると、取り直しのあとに回ってしまいます。そこで依頼76 のファイルの頭に「0. 回す前に入れること」を足し、入れたあと⑦で向かい合いが解けることを確かめてから180回を回すようにしました。
依頼76 のファイル(足した後の全文)
---
作業フォルダ: /Users/shimazueiichi/Robotics_UX/ServiceSim
上限時間: 720
---
# 依頼76:瞬間移動を直した版で、6店の基準データを取り直す(依頼75 の後・夜)
エイイチと決めたこと(2026-11-03):瞬間移動の直し(依頼74)で客の動きが変わったので、6店の基準データを取り直す。
**エイイチは寝ている。人に聞かないと進めない所に当たったら、その回は止めて報告に書き、ほかの回は続ける。時刻で止めず、並べた回が全部終わるまで回す。**
## 0. 回す前に入れること:立ち往生をスタッフが解く(2026-11-03 エイイチと決めた・Claude が後から足した)
基準データを取り直す前に、これを今の標準に入れる。入れてから下の 180 回を回す(入れないまま取り直すと、すぐ取り直しになるため)。
**いま起きていること**:2台のロボットが向かい合うと、どちらも相手を待ち、誰も解かない。20261102 の夜の⑦(fam_p5・種7)では、店の時刻 1472〜2022 秒のあいだ (20.4, 5.0) 付近で1号機と2号機が約9分止まり、最後は料理の打ち切り(requeues.csv・600 秒)でやっと動いた。そのあいだ料理を運ぼうとしたスタッフも3回あきらめた(give_ups.csv)。stops.csv では 60 秒ごとに「動けなくなった」が並ぶだけで、助けが来ていない。
**入れる決まり**(試算の立ち往生と同じ扱い。サイトの tools/serving_sim/haizen_sim.py の maybe_stop・assumptions.json の rescue_s):
- ロボットが **30 秒以上** 動けなかったら(今の立ち往生の判定の線と同じ)、スタッフ1人が助けに行く。人と向かい合った場合も、ロボットどうしの場合も同じ
- 助けは **いちばん優先の高い仕事**(試算の staff_job の priority 0 と同じ)。いま手が空いているスタッフのうち近い人が行く。全員ふさがっていれば、今の仕事が終わった人から行く(待った時間も記録する)
- スタッフは歩いて行き、着いてから **15 秒**(試算の rescue_s・決まりの値。変えない)でロボットを動かす。動かすのは片方だけ
- ロボットどうしなら、動かすのは **空の方**(料理を載せていない方)。どちらも同じなら、行き先までまだ遠い方。人とロボットならロボットを動かす
- 動かした先は、相手の道(いま引いている道)から外れた、いちばん近くの空いた所。動かされたロボットはそこで道を引き直して仕事を続ける
- 作りは切り替えで入れ、**入を標準**にする(切にすると今までどおり)。ラベルなどへの載せ方は今までの切り替えと同じでよい
**記録**:回のフォルダに rescues.csv(いつ・どこで・どのロボット・相手は何か・行ったスタッフ・手が空くまで待った秒・歩いた m・解けるまでの秒)。summary.json に rescues(回数)と rescue_staff_s(スタッフが助けに使った秒の合計)。試算の meta.metrics.rescues と同じ意味にする。モニターに「助けに行く」を出す。
**確かめ**:⑦(fam_p5・種7・ロボット2台)を1回回し、30 秒以上の向かい合いが 30 秒+スタッフが着くまで+15 秒で解けることを(瞬間移動の直しで同じ時刻に起きるとは限らない。起きなければ向かい合いの出る種を探して確かめる) rescues.csv と stops.csv で確かめる。ほかに変な動き(助けに行ったスタッフが詰まる・同じ所で何度も助けが要る)が出たら、下の 180 回は回さずに報告して止める。
## 始める前に確かめること(違えば回さずに報告して終わる)
1. 上の 0 が入り、⑦の確かめで解けている
2. 依頼74 が合格している(依頼75 は終わっていればよい。不合格でも回してよい)
3. Unity エディタ・night_runner/rec_runner が動いていない。KIOXIA がマウントされ、unity_ledger_v1.lock がない。台帳を退避
4. ServiceSim の保留が 0
## 回すもの(画面なし・今の標準・直した版の実行ファイル)
- 基準データ v5 と同じ並び:③⑦ × 0・1・2台 × 種10個(60回)
- ④⑤⑥② の今までの夜と同じ並び:店ごとに 0・1・2台 × 種10個(各30回・計120回)
- 夜の名前は 20261103、ラベルは `tpfix_base`(立ち往生の助け 入)。同時に回す本数は今のまま
- 判定(judge_night.py)は今までどおり自動で出してよい(基準は v5 のまま。差が出るのは当たり前なので、印が付いても止めない)
## 報告
依頼箱の結果に加えて、claude_code_reports に 20261103_tpfix_base.txt として。
- 180回の completed の数・失敗・止まった回・最長の実時間
- 店ごと・台数ごとに、瞬間移動・入店待ち・料理の待ち・会計待ち・30秒以上の止まり(1往復あたり)・動けなくなった の種10個の中央値を、v5(③⑦)と今までの夜(④⑤⑥②)と並べた表
- 店ごと・台数ごとの rescues(1往復あたり)と rescue_staff_s の中央値。試算の stuck_rate 0.01 と並べる
- 0 の作りの変更点(ファイル・切り替えの名前)と⑦の確かめの結果
- 台帳の行数の変化と md5
作業ログ ― 実物の配膳ロボットは、ロボットどうしの譲り合いをどう決めているか
1台ごとの仕様ではなく、何台かまとめた動かし方(群制御)として見る
最初は、最新の配膳ロボットの仕様(センサー・通れる幅)を追うつもりでした。調べはじめると、詰まりを決めているのは1台ごとの性能ではなく、何台かをまとめてどう動かすかだと分かりました。この、何台かのロボットの通り方・待ち方・譲り方をまとめて決めることを、この記事では群制御と呼びます。
ロボットの仕様というより群制御のやり方を見直すって感じだね
ロボットの制御では難しいのかな?もっと学習が必要なんだろうか?
ロボットどうしの向かい合いだけなら、学習はほとんど要らず、決まりで解けます。倉庫では何百台もの搬送ロボットが、まとめ役の予約と順番の決まりで止まらずに回っています。学習が効くのは、客がどちらへ動くか・混む前にどの通路を避けるかのように、人の動きが入る所です。そこで Unity の進め方は、ロボットどうしは決まりで詰まりを消し、残った人との詰まりを学習で減らす二段構えにしました。道の選び方を差し替えられる部品にしておく考え(別のチャットで話した、人混みの中を進むロボットの研究室の動画から出た考え)とも合っています。
調べて分かったこと:取扱説明書に書いてある決まりは2つだけ
メーカーの公式資料・取扱説明書・特許・規格・日本の導入事例を、PUDU・KEENON・Bear Robotics と LG とソフトバンク・日本の管制の仕組みと規格、の4つに分けて調べました。全文は下の報告書です。
- 2台がすれ違えない幅の通路は、1台ずつ交互に通す。すれ違いに要る幅は、PUDU が 1.6m 超、KEENON T8 が 1.5m 超
- 塞がれたら待って道を組み直す。秒数まで公開しているのは PUDU BellaBot Pro だけで、初期値は「30秒待って組み直し、ふさがれた区間を180秒避ける」
どちらが譲るかの決まりは、どのメーカーも公式には公開していませんでした。 手がかりは特許だけで、KEENON は優先の低い方が壁ぎわか分かれ道の退避エリアで待つ形、PUDU は交差点で遅れて着く方が待つ形です。特許は、その方法が製品に入っている証拠にはなりません。いちばん Unity に写しやすいのは、三菱電機のロボット管制と、日本の規格 RFA B 0004 でした。狭い区間を予約制にして入口で順番を待たせ、一度に一方向だけ通し、失敗したら区間を閉じて担当者に知らせます。
これまでに集めた実物の動画4本と突き合わせた
research フォルダの観察台帳に、これまで共有された実物の配膳ロボットの動画を15本まとめてあります。調べはじめた時点ではこれを使っておらず、あとから突き合わせました。ロボットどうしが関わる場面は4本で、どれも PUDU の機体です。
| 見た日 | 店 | 起きたこと | 止まってから店員が来るまで | 店員の作業 |
|---|---|---|---|---|
| 2026-10-26 | ガスト | BellaBot 2台が1台分の通路で正面から向き合う | 41秒以上 | 約5秒(画面操作と手で押してよける) |
| 2026-10-27 | ファミレス(ドリンクバー横の待機場所) | 並んだ隣の機体に出口をふさがれ、声かけを繰り返す。同じ日に何度も起きた(投稿者談) | 45秒以上 | 1〜2秒(画面で一時停止) |
| 2026-10-27 | ガスト(ドリンクバーの前) | もう1台のそばでぶつかって止まり、向きを変えようとしたが抜けられない | 約18秒 | 約10秒(手で向きを変える・画面操作・2台目の位置直し) |
| 2026-10-28 | 和食系の店 | KettyBot 2台(料理あり・空)が待機場所の横で向かい合い、2台ともその場で向きを変え続けて進めない | 53秒以上 | 約4〜5秒(空の機体を手で横へ寄せる) |
4本とも、ロボットだけでは解けず、店員が手で解いています。2台とも同じ動き(その場で向きを変える・声をかける)を繰り返していて、どちらが譲るかが決まっていないように見えます。店員が来るまでは18〜53秒以上と長く、手で直す作業は5秒前後と短い。試算の決まりの値(助けの作業15秒)より短く、時間の大半は人が来るまでの待ちでした。店員が動かしたのは、分かる範囲では空の機体で、Unity で「空の方を動かす」とした決まりと同じです。
この突き合わせから、Unity の記録では「スタッフが着くまでの時間」と「手で直す時間」を分けて見ることにしました。動画は4本だけで、どれも PUDU なので、ほかのメーカーにそのまま当てはまるかは分かりません。
Unity の人は、ロボットのそばでだけ遠慮しすぎている
別のチャットで Unity のプロジェクトを読んで分かったことも、数字を読むときの注意として書いておきます。Unity の人は半径0.2m(幅40cm)の円柱で、人どうしで細い通路に詰まって1秒たつと、横を向いて幅24cmに細くなります。ところがロボットのそばでは横を向かず、ロボットとの間を0.3m空けてよけます。実際の店は、人がギリギリまで寄れて横向きにもなれる前提で作られているので、ロボットのそばのすり抜けは実物より詰まりやすく出ているかもしれません。2026-11-03 の夜の取り直しで出る店員の助けの回数も、このぶん多めに出る可能性があります。
調査報告(research_serving_robot_fleet_rules_20261103.md の全文)
# 配膳ロボットは狭い通路を「順番待ち」で解いている
実際の配膳ロボットが複数台で同じ店を走るとき、公式の取扱説明書に書かれている決まりは驚くほど単純で、**「2台がすれ違える幅(PUDU は 1.6m 超、KEENON T8 は 1.5m 超)より狭い通路は、1台ずつ交互に通す」**と**「動けなくなったら一定時間待ってから経路を組み直す(PUDU BellaBot Pro の初期値は 30 秒待ち、その区間を 180 秒避ける)」**の2つにほぼ尽きる。どちらが道を譲るかを決める規則(荷物を運んでいる方が優先、など)は、PUDU・KEENON・Bear Robotics/ソフトバンク・LG のどのメーカーも公式文書で公開していない。手がかりになるのは特許で、KEENON は「優先度の低い方が壁ぎわや分かれ道の退避エリアに入って待つ」「用事のないロボットが仕事中のロボットに道を譲る」、PUDU は「交差点では遅れて着く方が手前で待つ」という方法を特許にしている。ただし特許は「その方法を製品に載せている」証拠にはならない。動かせる台数は、公式の数字では PUDU と LG が「最大20台」、ソフトバンクの Servi アイリスエディションが「最大5台」で、日本の大手チェーンの実際は1店あたり1〜3台が中心だった。そして決まりで解けない向かい合いは現場で実際に起きていて、ガストでは2台が狭い通路で向き合ったまま動けなくなり、店員が1台の電源を切って解いた。日本の建物側の仕組み(三菱電機 Ville-feuille、RFA の規格)は、この問題を「狭い区間を予約制にし、一度に一方向だけ通し、失敗したら区間を閉じて人を呼ぶ」という形ではっきり決めていて、Unity のシミュレーションの部品にいちばん写しやすいのはこちらである。
この報告で使う言葉を先に決めておく。**群制御**は、複数のロボットが互いにぶつからず、詰まらずに動くための決まりと仕組みのこと。**向かい合いの詰まり(デッドロック)**は、狭い所で2台が互いを障害物と見なし、両方とも止まって動けなくなる状態のこと。情報の確かさは次の5つに分けて書く。**【公式】**は取扱説明書・仕様表・規格・企業の技術論文で確かめたもの、**【特許】**は特許公報に書かれた方法(製品に入っている保証はない)、**【宣伝】**はメーカーの宣伝文で仕組みの説明が付かないもの、**【報道】**は報道・販売店・第三者の記事、**【未確認】**は資料が見つからないか推測のもの。
## 公式の上限は「20台」が目安、日本の店の実際は1〜3台
このあと追記すること
この記事は、待っている2つの作業が終わったら追記します。
- 撮り直した動画(依頼75)への入れ替え。そろった店から試算のページの動画を v2 に替え、⑧⑨の大型店も直っていれば足す
- 依頼76 の結果。店員の助けを入れた版で、6店の基準データを取り直した結果(助けの回数・使った時間・入店待ちなど)を、前の基準データと並べる
追記 ― 店員の助けを入れた⑦の確かめと、動画の入れ替えを見送った理由(2026-11-03 夕方)
9分のにらみ合いは、助け2回・約105秒で解けた
依頼76 で、Claude Code が店員の助けを切り替え(-ssStuckRescue on|off、既定は入)として入れ、⑦(fam_p5・種7・ロボット2台)を1回回しました。前に約9分止まっていた向かい合い(店の時刻 1472秒〜)は、助け2回・約105秒で解けました。1回目の助けは、30秒+手が空くまで0.05秒+歩き5.9秒+作業15秒=51.3秒で、1号機を1.16m動かしています。この回で助けが入った35回の、解けるまでの秒の中央値は51.0秒でした。
| 止まってから店員が着くまで | 手で直す作業 | 解けるまで | |
|---|---|---|---|
Unity(助けなし・2026-11-02) | 来ない | なし | 約9分10秒(料理の取り消しで解けた) |
| 実物の動画4本(PUDU) | 18〜53秒以上 | 1〜10秒(多くは5秒前後) | 来てから数秒 |
Unity(助けあり・依頼76) | 30秒+手が空くまで+歩き(1回目は約36秒) | 15秒(試算の決まりの値) | 1回目51.3秒・35回の中央値51.0秒 |
店員が着くまでの時間は実物の幅の中に入りました。手で直す作業は、Unity の15秒が実物(5秒前後)より長いままです。ここは試算の決まりの値(rescue_s)に合わせているので、変えるかは試算の側で考えます。
新しく見えた詰まり:止まっている台に、何度も助けが要る
一方で、依頼に書いておいた「180回は回さずに止める」変な動きが2つとも出たので、基準データの180回は回していません。
- 同じ所で何度も助けが要った。往復を終えて止まっている2号機に、1号機が阻まれ続け、待機場所の手前と受け渡し口の近くでそれぞれ8回、助けが入った。2号機には行き先がないので、1号機の方が動かされ、35回中25回は0.05m未満しか動いていない
- 助けに行ったスタッフが細い通路で着けず、2回あきらめたあと、3回目で瞬間移動になった
実物の動画でも、待機場所で隣の機体に出口をふさがれて声かけを繰り返す場面(2026-10-27 のファミレス)がありました。止まっている台をどう扱うかは、群制御で決めておく必要がある所だと分かりました。このあとの依頼(77〜85)で、止まっている台を動かす先の直し・同じ種で同じ結果にする直し・瞬間移動を0にする直しが進み、6店180回のベースのデータ(依頼83)も取り終えています。その結果は別の記事で扱います。
依頼76 の Claude Code の報告(止められた操作の一覧を除く全文)
# 結果:20261103_76_直した版で基準データを取り直す
- 状態:完了
- 始めた時刻:2026-11-03 10:56
- 終わった時刻:2026-11-03 11:21(25分)
- 作業フォルダ:/Users/shimazueiichi/Robotics_UX/ServiceSim
- この続きを Claude Code で話すとき:作業フォルダで `claude --resume 9b93b5af-88af-4683-aa03-1c46052c18ed`
- 止められた操作:1件(いちばん下に一覧)
## Claude Code の報告
やったこと
- 始める前の確かめ:依頼74 は「済み」で、合格とみました。依頼75 は見張り係が止まったため「失敗」に回り、終わっています。Unity エディタと night_runner/rec_runner は動いておらず、KIOXIA はマウント済み、鍵ファイルはなし、保留は 0 でした。台帳は先に退避しました。
- 依頼の 0「立ち往生をスタッフが解く」を、切り替え(実行ファイルの引数 `-ssStuckRescue on|off`、queue の `stuck_rescue`)として入れました。
- 既定は入です。入の回は、出力フォルダ名の末尾に `_rescue` が付きます。
- 切の回の動きは今までと同じです。
- params には項目が無いので、params は変えずに、既定はコードの側に置きました。
- 入の回の動き:
- ロボットが 30 秒続けて動けなかったら、助けを優先 0 で呼びます。
- 手が空いている人のうち、道の長さで近い人が行きます。全員ふさがっていれば、仕事を終えた人が行きます。
- 着いてから 15 秒で片方を、相手の道から外れた一番近い空いた所へ動かし、そこで道を引き直させます。
- ロボットどうしなら空の方を、同じなら行き先まで遠い方を動かします。人とならロボットを動かします。
- スタッフが着く前に自分で動き出したら、取り消します。
- 記録:rescues.csv を書き、summary.json に `rescues`・`rescue_staff_s` を出し、モニターに「助けに行く」を出すようにしました。判定(judge_night.py)の条件にもこの入切を足しました。
- cs:63 で check-in し、画面なしの実行ファイルを作り直しました(build_id cs63_20261103_1114・保留 0)。
- ⑦(fam_p5・種7・2台)を 1 回回して確かめました。
結果
- 前に約 9 分止まっていた向かい合い(1472 秒〜)は、助け 2 回、約 105 秒で解けました。
- 1 回目は 30 秒+手が空くまで 0.05 秒+歩き 5.9 秒+15 秒=51.3 秒で、1号機を 1.16 m 動かしました。
- 解けるまでの秒は、35 回の中央値で 51.0 秒です。どの行も「30 秒+待ち+歩き+15 秒」と合っていました。
- ただし、依頼が「180 回は回さずに止める」と決めている変な動きが 2 つとも出ました。
- **同じ所で何度も助けが要る**:往復を終えて止まっている2号機に、1号機が阻まれ続けました。
- 待機場所の手前 (16.5, 5.9) で 8 回、受け渡し口の近く (15.7, 5.0) で 8 回、助けが入りました。
- 2号機は止まっていて道が無いので、1号機はほとんど動かされず(35 回中 25 回が 0.05 m 未満)、同じ所でまた止まりました。
- この詰まりは、助けを入れる前の cs:62 の同じ回でも起きていました(同じあたりで 30 秒以上の止まりが 12 回)。
- **助けに行ったスタッフが詰まる**:4028 秒、通路 A01 で、助けに行ったスタッフが 2 回あきらめ、3 回目に「移した」になりました。
- このため、基準データの 180 回は回していません。店ごと・台数ごとの表と、試算の stuck_rate 0.01 との並べは作れていません。
- 確かめの 1 回の数:呼んだ 41 回、動かした 35 回、取り消し 6 回、`rescue_staff_s` 943.7 秒、往復 127 回でした。
- 台帳は 1658 → 1659 行で、追記 1 行だけです。
- 始める前の md5:7896338a6483643ca5f88f1950795d27(退避と同じ)
- 終わったあとの md5:69510edef7fe2a792ba5e27a62421310
- 先頭 1658 行の md5 は始める前と同じで、前の行は変わっていません。
変えたファイル
- Assets/ServiceSim/Service/ServiceOps.cs
- Assets/ServiceSim/Robot/ServingRobotController.cs
- Assets/ServiceSim/People/StaffAgent.cs、PersonRobotYield.cs
- Assets/ServiceSim/Experiment/ExperimentRunner.cs、HeadlessRun.cs、TripLogger.cs
- Assets/ServiceSim/Store/KitchenMonitor.cs
- tools/make_queue.py、night_runner.py、judge_night.py
- 以上 11 ファイルを cs:63 で check-in しました。
- Builds/headless を作り直しました。
- 報告は claude_code_reports/20261103_tpfix_base.txt に書きました。
決めてほしいこと
1. 相手が往復を終えて止まっている台(待機場所や受け渡し口の点にいる台)のときの決まり。今の決まりのままでは、同じ所で何度も助けが入ります。案は次の 3 つです。
- 止まっている台の方を動かす
- 相手の体から離れた所へ、呼んだ台を動かす
- 店の形の側で、待機場所どうしの間を広げる(今は中心どうし約 0.76 m)
2. 助けに行くスタッフが細い通路で着けないとき、今は 60 秒であきらめ、3 回目で「移した」(瞬間移動)になります。このままにするか、助けのときだけ別の決まりにするか。
3. 1・2 を決めたあと、⑦の確かめをやり直して 180 回を回すか。並べ方と比べる相手は用意できています。
4. 画面なしの実行ファイルの既定を「助け 入」のままにしておくか。次の依頼77 は入を前提にしているので、入のまま残しています。
試算のページの動画は、入れ替えを見送った
撮り直し(依頼75)は Mac の見張り係が止まって一度失敗し、その後 6店の録画(夜の名前 20261103_rec_focus2・実行ファイル cs:62)が別に回っていました。ただ、この録画を作った cs:62 は、店員の助けが入る前(助けは cs:63 から)で、瞬間移動もまだ残っていた版です(瞬間移動が0になったのは依頼81 の cs:69。依頼80 の⑦の同じ回では22回)。さらに④と⑤は時間の上限で止まり(stopped)、大型店⑧⑨の録画はありません。入れ替えても「瞬間移動を直した版」にならないので、試算のページは v1 の動画のままにしています。
20261103_rec_focus2 の runs.csv と実行係のまとめ
folder,condition,seed,pass_by,tryno,launch_running,parallel,started_iso,ended_iso,started_unix,ended_unix,started_mono,ended_mono,wall_s,status,exit_code
20261103_rec_focus2_cs62_fam_p1_r2_s7_passon_sbret_ek_post,fam_p1_s4_r2_a42,7,on,1,1,2,2026-11-03T07:01:08,2026-11-03T08:09:52,1793656868.884,1793660992.788,337481.761,341605.665,4123.904,completed,0
20261103_rec_focus2_cs62_fam_p5_r2_s7_passon_sbret_ek_post,fam_p5_s4_r2_a42,7,on,1,2,2,2026-11-03T07:01:13,2026-11-03T08:14:03,1793656873.891,1793661243.360,337486.769,341856.237,4369.469,completed,0
20261103_rec_focus2_cs62_fam_p2_r2_s1_passon_sbret_ek_post,fam_p2_s2_r2_a28,1,on,1,2,2,2026-11-03T08:09:52,2026-11-03T09:18:39,1793660992.658,1793665119.539,341605.704,345732.585,4126.881,stopped,2
20261103_rec_focus2_cs62_fam_p3_r2_s1_passon_sbret_ek_post,fam_p3_s4_r2_a46,1,on,1,2,2,2026-11-03T08:14:03,2026-11-03T09:22:50,1793661243.238,1793665370.437,341856.259,345983.458,4127.200,stopped,2
20261103_rec_focus2_cs62_fam_p0_r2_s8_passon_sbret_ek_post,fam_p0_s2_r2_a19,8,on,1,2,2,2026-11-03T09:34:13,2026-11-03T10:35:18,1793666053.954,1793669718.025,345983.555,349647.627,3664.072,completed,0
20261103_rec_focus2_cs62_fam_p4_r2_s1_passon_sbret_ek_post,fam_p4_s3_r2_a38,1,on,1,2,2,2026-11-03T09:30:03,2026-11-03T10:36:08,1793665803.152,1793669768.117,345732.739,349697.704,3964.965,completed,0
2026-11-03 10:36:08 --- まとめ ---
2026-11-03 10:36:08 completed: 4 回
2026-11-03 10:36:08 stopped: 2 回
2026-11-03 10:36:08 completed の実時間: 平均 67.2 分 / 最長 72.8 分
試算のページの動画は、瞬間移動が0で店員の助けも入った今の標準(cs:69 以降)で撮り直してから入れ替えます。