章13: 実機で入札と交通調停(bidding / traffic)
← 前章: 実機で1台を動かす | 目次 | 次章: 実機でバッテリと自動充電 →
狙い
- A4では入札コストが「距離」でなく「通るレーン数」で決まることを見る
- 狭いA4で2台を動かすと、mutex group
ring(同時に1台しか入れない排他区間)によってタスクが直列化されることをログで確かめる - 実機で2台同時に投げるときの安全な間隔を身につける
simとの違い
| sim(章5・6、A3) | 実機(この章、A4) | |
|---|---|---|
| 入札で効くもの | 直線距離に近い | レーン数(一方通行で回り込むため) |
| 章5の実験1(先に寄せて勝者を作る) | 成立する | 成立しない(寄せた直後に帰還する) |
| 2台のすれ違い | 格子で局所回避しながら交差 | ループ上は常に1台(mutexで待つ) |
| 2台同時投入 | 余裕がある | 物理限界に近い(頂点付近で角が接触しうる) |
動かす・観察する
実験1: 目的地を変えて勝者を入れ替える(章5の読み替え)
A4は一方通行ループなので、charger_1 → patrol_A は1レーン、 charger_2 → patrol_A は3レーン(ループを回り込む)。指名なしで投げると:
ros2 run rmf_demos_tasks dispatch_go_to_place -p patrol_A # → toio1 が落札
# 帰還を待ってから
ros2 run rmf_demos_tasks dispatch_go_to_place -p patrol_B # → toio2 が落札
端末2の rmf_task_dispatcher ログで、BidResponseの見積(到達時刻)がtoio1/toio2で逆転しているのを読む。章5の「距離で勝者を作る」は、A4では目的地で勝者を作るに読み替える。
章5の実験1(toio1を先に寄せてから近い方に落札させる)は、A4実機では寄せた直後に
finishing_requestでチャージャーへ帰ってしまい成立しない。上の読み替えがその代わり。
実験2: 指名して入札を飛ばす(章5と同じ)
ros2 run rmf_demos_tasks dispatch_patrol -p patrol_A patrol_B -n 1 -F toio -R toio2
入札が省かれてtoio2に直接割り当たる。ログの違いは章5の実験2と同じ。
実験3: 2台に続けて投げ、mutexの待ちを見る
ループ全体はmutex group ring になっている(toio_rmf_maps#16)。1本目の直後に2本目を投げると:
ros2 run rmf_demos_tasks dispatch_go_to_place -p patrol_A -F toio -R toio1
# 数秒後
ros2 run rmf_demos_tasks dispatch_go_to_place -p patrol_B -F toio -R toio2
端末2にこう出る:
[toio/toio2] is waiting to lock mutex group [ring] but that mutex is currently held by [toio/toio1]
toio2はチャージャーで待ち、toio1がチャージャーへ戻った瞬間に出発する。つまりA4では2台同時のタスクは直列化される。章6で見た「大域スケジュールで待つ」が、ここではmutexという形で現れている。
mutexの調停にはRMFの
mutex_group_supervisorが要り、toio_rmf_bringup#60以降のtoio_rmf.launch.pyに含まれている。無いとWaiting to lock mutex groupsのまま動かない(TROUBLESHOOTING)。
2台同時に投げるときの安全な間隔
mutexで直列化されるとはいえ、A4(0.30×0.20m)は狭い。mutexを入れる前の実測では、1本目の8秒後に同じ頂点へ2本目を投げると2台が接触した(最接近27 mm、toio_rmf_bringup#56)。mutex導入後は同じ条件でも最接近52 mmで、交渉で経路を放棄する事態(forfeit)も起きなかった。それでも待ち時間を短くするため、次の2点を守る:
- 2本目は1本目から30秒以上空ける
- 1台目が向かっていない頂点を2本目に指定する
確実な非接触が要る検証はA3(sim)、という判断は章6のとおり。
理解する
- 入札コストはnavグラフの形で決まる。同じ「近い方が勝つ」でも、A3では距離、A4ではレーン数。運用者が「なぜこの1台が選ばれたか」を説明するには、グラフの形を知っている必要がある。
- 交通調停の手段は一つではない。章6の大域スケジュール(予約)と局所回避に、ここでmutex group(排他区間)が加わった。狭くて逃げ道が無い場所は、調停で頑張るより「同時に入れない」と決めてしまう方が安全で、地図側でそう書ける。
- 直列化は遅いが壊れない。フリートの効率は落ちるが、実機の接触リスクを地図で消している。このパッケージでは、効率と安全のトレードオフを地図設計で安全側に倒した。
確認課題
patrol_Aとpatrol_Bを指名なしで交互に投げ、勝者がtoio1/toio2で入れ替わることをBidResponseのログで確認する。- 実験3でtoio2が待っている間に
/fleet_statesをechoし、toio2の状態(位置は動かず、タスクは割り当て済み)を読む。 - 2本目を30秒空けて投げた場合と数秒後に投げた場合で、toio2の待ち時間がどう変わるか比べる。mutexが無かったらどうなるか、章6の知識で説明できるか。
2台の振る舞いが見えたら、次は実機編の山場 ── 本当に減るバッテリでChargeBatteryを発火させる。
← 前章: 実機で1台を動かす | 目次 | 次章: 実機でバッテリと自動充電 →