レスキュー
情報共有 †
このページの趣旨 †
レスキューのエージェントを開発を通して、疑問に思うことや情報が不足していると感じることが多々ありました。
ここでは他のページで扱っていないこと(ルールに関するもの、ホストプログラムに関するもの、アルゴリズムに関するもの、その他ドキュメントに乗っていないような情報)を載せていきます。質問やその解答、便利なツール情報等どんなことでも書き込んで情報共有していきましょう。
Kernelとサブシミュレータを別々に起動する(ver 1.0) †
レスキューサーバ1.0(nightly)を対象に,カーネルとサブシミュレータを別々に起動する方法.これにより,カーネルとサブシミュレータを別マシンで稼働させることができます.
対象:
OS: Mac OS X(10.6.2)
※基本的にはrescue1.0とシェルスクリプト及びxtermが動作する環境なら問題はないと思います.
サーバ: 2010年3月18日付のrescue-nightly-build
方法:
(1) 以下のシェルスクリプト2つ(添付ファイル参照)をboot/ディレクトリに保存する
startKernel.sh
startSims.sh
(シェルスクリプトの中身について)
詳しくは各シェルスクリプトを読んでください.
両者ともに,boot/functions.shの一部を改造したものです.
クラスパスとオプションを指定して,kernel.StartKernel?を起動します.
クラスパスは,とりあえずjars/ディレクトリとlib/ディレクトリ以下全てのjarファイルを指定します.オプションはfunctions.sh内の関数startKernelにあるKERNEL_OPTIONSとほぼ同様です.
SampleViewer?, TrafficSimulator?, FireSimulatorWrapper?, IgnitionSimulator?, CollapseSimulator?, ClearSimulator?, SampleCivilian?を,各々LaunchComponents?を介して起動します.
クラスパスにはlib/ディレクトリ以下のjarファイルを指定します.また,シェルスクリプト内のHOST変数にカーネルのIPアドレス,PORT変数にカーネルのポートを指定します.
(2) まずstartKernel.shを実行し,「Setup kernel options」の画面が立ち上がったら,"Simulators"に何もチェックが入っていないことを確認してOKを押す.するとKernelGUIの画面が立ち上がる.
(3) 次にstartSims.shを実行し,KernelGUIの画面右にある"Simulators"に,接続したシミュレータ群が表示されれば成功.Runを押してシミュレーションを開始できます.
シェルスクリプトの中でxtermを使っています.もし
bashなどからのxtermの起動がコケる場合,xtermを起動してから,xterm内からこれらのシェルスクリプトを実行すればおそらく大丈夫です.
20100318 勉強会資料 †
複数PCによる起動に関して(var.1.0) †
ここではsample agentを複数のPCで起動する方法を記述します.
- サーバ側
%ant start-kernel
を行い、各エージェントの起動数をすべて0にしてから「OK」
- エージェント側(sample agentについてはこれで起動を確認)
以下のコマンドを実行
%java -cp jars/sample.jar:jars/rescuecore2.jar:jars/standard.jar:lib/uncommons-maths-1.2.jar:
・・・:<lib内のすべてのjarファイル>・・・
sample.LaunchSampleAgents -p 7000 -h <ホスト名 ex:127.0.0.1>
以上で複数(2台)のPCによる起動を行うことができます.
※Windowsの場合はクラスパスを指定する際に:(コロン)ではなく;(セミコロン)を用いてください.
カーネルやサーバー側プログラムに関して †
- FireSimulator?@0.49.10
- シミュレーションの途中で突然高温が発生して、マップのすべての建物が燃え尽きることが度々発生する。バグか。
- Kernel@0.49.10(リビジョン281?)
- 通信が出来ない。バグか。
→リビジョン281のkernel.ccの以下の箇所を修正すると通信が出来るようになる気がします。
- 最新版では修正された模様
- 再出火する仕組み
- 一度消火したつもりの建物が再出火する、周辺に火災が無いのに突如出火する。
- FireSimulator?では出火するかどうかは温度と建物の素材によって決定する。
- 温度の変化には、1.建物間の熱交換、2.空気による熱交換の2種類がある。
- 建物間の熱交換
- 建物と建物の距離、周囲にある建物の数などのパラメータから熱交換比率が計算され、温度の高いところから低いところへ比率に従って熱が移動する
- 空気による熱交換
- 設定ファイルで定義した値(cell_size)でマップを分割し、セル単位で温度を保持する。セルは隣接する8方位のセルと一定の比率で熱交換をする。温度の高いところから低いところへ熱は移動する。
- この機構により、一度鎮火した建物や、出火したことのない建物でも周辺に温度の高い場所(火災や、燃え尽きてあまり冷えていない建物)があると、熱が移動して出火することになる。
- 鎮火した後の追加放水などが必要となるが、追加放水は火災に直接行うときよりも温度を下げる効果が若干であるが低くなる。上手くバランスを取る必要がある。
- 巨大なマップなどで、シミュレータが一つだけ接続されずシミュレーションが開始されない場合がある
- 犯人はfiresimulator
- 初期化処理で時間がかかってしまって、接続の制限時間に間に合っていない様子。
- .raysファイルが作ってあれば問題無し
- .raysファイルは無ければ自動で作られるが、ファイルをprograms/firesimulator/resq_firesimulator/ ディレクトリにコピーしなければいけない。
- 火災の情報の伝わり方について
- 他の情報は代表点が半径10m以内にあることで更新されるが、火災の情報は定義された速度で徐々に広がっていく(火災について認知できる距離がだんだんと広がるイメージ)。遠い建物の火災情報が遅れながらも必ず伝わるのはこのため。
- FireSimulator?で使用される.raysファイルについて
- このファイルには建物間の接続関係が定義されている。これを読み込めば便利だ!が、ルール上どうなのか。本来は使わずに計算するのが正しいのだろう。(その計算方法自体はFireSimulator?のソースコードに記載されている。)
- コマンド送信について
- 1ステップ中に同じエージェントから複数回コマンドが送信された場合、制限時間以内にカーネルに届いたコマンドのうち最も新しいものが採用される。(古いコマンドは破棄される)
- コミュニケーションレスについて
- 2008年度からのルールコミュニケーションレスを手元で再現するにはconfig.txtを書き換える。
- 以下の項目をどちらも0にすればよい
- channel_radio_max_agent
- channel_radio_max_centre
ルールについて †
- 給水タンク・放水について
- 消防隊の給水タンクの初期値&最大容量は15000
- 給水タンクの補給は避難所でrestコマンド
- 一度のExtinguishで使用する量は1000、避難所でrestすることによる補給量も1ステップで1000。
給水タンクの残量はカーネルから送信されてこないので知ることができない。自分で計算しておく必要がある(時間切れなどでコマンドを送信したにも関わらず、受理されていない場合は誤差が出るがこれはどうしようもない)。
同様の理由で、他の消防隊の給水タンク残量も知ることはできない。
- 自分の給水タンクの残量は毎ステップカーネルから送信されてくる(yabAPIでは受信部分がコメントアウトされている)。
- 例え視界内にいても他の消防隊の給水タンク残量はカーネルから送られてこない。
- 放水の効果は距離に依存しない。0mからでも、30mからでも同じ放水効果である。
- 最初の3ステップ
- 最初の3ステップはエージェントが凍結されている。コマンドを送信してもカーネルでRejectされる。しかし、周囲の情報は毎ステップ取得できる。
- 救急隊の色々
- 救急隊が現在運搬中かどうか、また誰を運搬しているかはカーネルからの情報ではわからない。(位置情報を使えばほぼ確定できる程度に推定はできる。)
- 時間切れなどでUnLoad?やLoadが失敗していてもそれを直接知ることができない。処理に時間がかかる巨大なマップでは特に失敗しやすいので注意。
- 0.49.10現在、他人の行動を視覚的に知る方法はない。例えば近くの消防隊が現在どの建物に放水しているか、などは通信で知らせあうほか知るすべはない。(わかるようにルール改定する動きもあった(2005)?)
- 救急隊の埋没度が1以上のとき(埋没しているとき)、rescueコマンドを送信することはできるが、無効とされる。(この状況、Viewer上では活動しているように見えるが、埋没度は減じない。)別の救急隊に救出してもらうまで自分自身や、同じ場所に埋没しているほかのエージェントを救出することはできない。
- 救急隊がLoadコマンドを送信したステップに対象が移動している場合、Loadコマンドは失敗する。
- 救急隊が他の救助エージェント(PF,FB,AT)をLoadすることはできる。ただし、エージェントをLoad中のATはLoadできない。
- 救急隊がLoadできるのは同時に1体のみ。
- 建物のentrance
- entranceは一つの建物につき一つであるという暗黙の了解があるようだが、実際にはFolignoマップなど、複数の入り口を持つ建物が平気で存在し、公式にも使われている。
- 1度のMoveコマンドで建物を経由した道筋を指定した場合、移動距離に関わらず、建物に到達した時点で移動を終了する。(次のステップで別のエントランスに移動することはもちろん可能)
- YabAPIのように、いくつかのノードから一つの建物に移動するが、建物からは一つのノードにしか移動できないようなデータ保持形式&ルート探索方法を持っていると、建物に対して一方通行な状況が発生し、結果的に閉塞などに閉じ込められて身動きが取れなくなることがある。
- 建物の「壁」
- 建物の輪郭はApexesという項目に定義されている。
- 建物の熱交換など、一部の情報は「壁」のステータスに依存している。例えば、壁の面積が大きい場合(入り組んだ形をしているときなど)熱交換しやすい。
- 壁と壁が交差するように建物が設定されている場所も多く存在する。建物同士のほとんどが重なっている場合もある。
- 道路
- 道路の中には一見つながっているようで実はつながっていないというものが存在する。
- ほとんどのマップにあり、つながっているかに見えるがエージェントにとっては行き止まりという状態なので、そこを避けるときにエージェントが遠回りしているように見える。
- 他エージェントのステータス
- 自分以外のエージェントのステータスは、必ずしも正確な値を把握できるわけではない。視認したときに、ある程度丸められて得る。
- 例えば、HPは100の位が四捨五入されて1000代の数値になる。1335→1000、2891→3000
- この状況で死亡時刻を推定するにはいくつか方法があるが次の二つが主に使われる。
- 最近傍決定即など、統計情報と推移を比較して予測する手法
- 次のステップのHPを計算する関数を作成し、予測する手法
- 10mルールの追記事項
- エージェントの可視範囲は10mである。
- 可視範囲10mのルールでは少々直感とは乖離した情報取得を行うことがある。
- 例1:建物Aの中に居ても、他の建物Bが10m以内なら建物B内の市民の情報を得ることが出来る。
- 例2:道路C上に立っていても、道路Cの代表点が10m以上離れている場合は閉塞の情報などは得られない(PFでは、閉塞撤去作業はできるのに閉塞は見えていない、ということが起り得る→処理が完了したかどうか判定できない)。
- なお、センターエージェントもエージェントであるため、10m以内の情報を取得できる。(可聴30m情報も同様)
- 30m消火ルールの追記事項
- 消防隊は建物に対して30m以内なら放水することが出来る。
- 火災発生中の建物の中からはもちろん、周囲の建物「内」からも30m以内なら消火可能。
- ただし、消防隊「のみ」一つの建物には1部隊しか入ることはできない(その建物がセンター、避難所である場合を除く、さらに建物内で埋没しているなど初期設定で複数存在することは可能)。これは2005年より追加されたルール。
- 放水作業中の消防隊は道をふさぎやすいので、できるだけ建物に入って消火するのが良いかもしれない。
- 市民の声(ver 0.49.10)
- 声の種類は2種類
- Ouch!→ダメージを負っている
- Help!→埋没している
- 声を出す確率はそれぞれ10%
- ダメージを負っており、かつ埋没している場合は1-0.9*0.9=0.19 19%
- 可聴範囲が30mなので、上手く使えば市民のいる建物を効率的に割り出せる
- 声の主が初めて知るエージェントの場合(=未知の市民)、そのパラメータは一切不明なので死にそうなのかそうでないのか。どこに居るのかは当然わからない。
- 市民のrest
- 救急隊に運搬された市民が避難所でrestするタイミングは、UnLoad?の次のステップ。
- UnLoad?された瞬間に生きていても、次のステップでrestする前に死亡していれば当然死亡扱いになる。運搬ではその余裕を見ておく必要がある。
- 移動
- 道路の移動では、端からXmmまで移動、というような指定は出来ない。
- 移動先や、同じ道路上の前方に道路のキャパシティを超えた数のエージェントが居る場合は約8mの間隔をあけて静止する。消防隊を道路に並べたいときなどは考慮する必要がある。
- 移動は車線の状況を使って計算される。例えば、双方向1車線ずつの道路があり、片方の車線がエージェントによって混雑している場合、同じ道路でも移動方向によって通行可能かどうかが変わる。
- 埋没したエージェント
- 埋没している救助エージェントは移動や行動が出来なくなるが、通信はできる。
- 市民エージェントの場合、埋没度が0であってもダメージを負っている場合、自分で歩くことができない(→避難所に運ぶ必要がある)。
- 救助エージェントの場合、埋没度が0ならダメージを負っていても動くことができる(→避難所に運ぶ必要はない)。
- 死亡したエージェント
- 死亡したエージェントが車線の占有をすることがある。こういうエージェントは救急隊が移動させないと道路の閉塞を招くことになる。
- 避難所
- 「ルール上」は避難所が0というマップも有りとされている。しかし、給水ができない、ダメージを回復できない、市民がどこにも移動できないなどの理由からそれが大会で使用されたことはない(はず)。IranOpen2008では用意されていたが、動作できないチームが続出したためか、競技での使用は取りやめている。
- 通信
- TELLやSAYなどで送信するメッセージは256byteまでとされている。
- メッセージは必ずしも文字列である必要は無い。バイト単位、ビット単位で設計しても良い。
256byteのうち、20byte(メッセージタイプ、メッセージサイズ、チャンネル、送信者ID、終端を示す0、いずれもint型)はメッセージとして置き換えられないヘッダである。よって、メッセージの実質的な上限は236byteである。
- メッセージはデータ部分で256byte使うことが出来る。上記は誤り。
- HEARする際には、20byte(メッセージタイプ、メッセージサイズ、チャンネル、送信者ID、終端を示す0、いずれもint型)の情報がヘッダとしてメッセージ(上限256byte)に付加される。
- なお、センターエージェントもSAYをすることができる。
- スコアについて
- 0.49.xではシミュレーション終了時に生存していればスコア計算時に生きているとされる。
- 0.50.0ではシミュレーション終了時にダメージがあるエージェントは死亡扱いになる。
ビュワーについて †
- 距離計算のオーバーフロー
- rescuecoreに含まれるviewerのMovingObject?.x()、MovingObject?.y()にはバグがある。ソースコード中のe.head().x()*m_positionExtra/e.length()では、乗算でオーバーバッファフローをおこし、値が不正になる。ビュワーで、エージェントの表示位置がありえない場所(BuildingやNodeの存在しない場所)に表示されることがあるのはこのため。(ちなみにYabAPIにも同じバグがある。)