3D

RoboCup Soccer Server 3D Manual

ここは,RoboCup Soccer Server 3D Manualの日本語訳に関するページです.
このページのpdfファイルは fileこちら

システムの概要

はじめるにあたって,システムの構成要素についてある程度精通しておくべきである.サッカーシミュレーションは3つの重要な部分(サーバ,モニタとエージェント)から構成される.

サーバ

サーバを動かすために,SPADESシミュレーションミドルウエアについて精通しておくべきである.知っておくべきいくつかの重要な概念として以下がある.サーバはエージェントのプロセスを開始する責任がある.すなわち,2Dシミュレーションではエージェントの接続を待機するが,3Dシミュレーションでは待機しない.SPADESライブラリは,様々なエージェントタイプの開始方法に関する情報を含むデータベースを用いる.それはagentdb.xmlと呼ばれており,ディレクトリ ./app/simulator/にある.
 エージェントはUNIXのパイプを通してSPADES Commserverに接続する.エージェントはメッセージを交換するために,長さのあらかじめ固定されたフォーマットを用いる.その後,Commserverはサーバと交信する.サッカーサーバの初期設定では,統合Commserverが開始される.
 複数のシステムにエージェントプロセスを分配するために,複数のCommserverを実行させることが可能である.リモートCommserverを開始・設定する方法の更なる詳細については,SPADESのマニュアルを参照すること.この設定では,シミュレーションを開始する前に全てのCommserverを接続するまで待機するように,3Dサーバが設定されなければならない.これに関連する設定は,サーバスタートアップスクリプトrcssserver3D.rbにある.  `Spades.RunIntegratedCommserver?`と`Spades.CommServersWanted?`で上記の設定が行われる.1つ目の設定では,統合Commserverが開始するかどうかを設定する.デフォルト値は`true`である.2つ目の設定では,シミュレーションが初めに開始する前にサーバが待機するCommserverの数を設定する.統合Commserverは1つとして数える.したがって,デフォルト値は1である.

モニタ

初期モニタはrcssmonitor3D-liteと呼ばれており,ディレクトリ ./app/rcssmonitor3d/liteにある.それはサーバが自動的に生成するログファイルを再生するためにも用いられる(--logfile<filename>オプションを使う).自動的に生成されるログファイルは`monitor.log`と呼ばれている.サーバを開始したディレクトリ下のディレクトリ Logfiles/にある.2004 RoboCupのログファイルのセットが[?]*1で見つけられる.
 実装されたモニタプロトコルは,トレーナを実装するための(すなわち,フィールド上のテスト状況を自動的に再生成し,エージェント動作の評価をするための)コマンドセットをサポートする.`モニタライブラリ`はカスタマイズされたモニタとトレーナの実装を補助するために提供されている.ディレクトリ ./app/rcssmonitor3d/libを参照すること.サーバとモニタ間のプロトコルは,このテキストファイルの後の方で詳しく述べられている.
 エージェントを実装するための良い出発点は,ディレクトリ ./app/agenttestのプログラム agenttestである.このエージェントは,単純なキック-ラン動作を実装している.

サッカシミュレーション

サッカチーム

チームは複数の等しい能力を持つロボットで構成される.チームを生成するために書いたプログラムは,ロボットに与えられている(仮想の)低レベルコントロールシステムとデータを交換する.ロボットのパーセプタとエフェクタの両方がS式と共に動作する.この文法は,2Dサッカーシミュレータからすでに知っているでしょうし,そうでなければ,お気に入りのプログラミング言語からご存知でしょう.

環境

環境とあなたの新しいロボットの技術的データは以下のようになっている:
 フィールドは,FIFAの標準サッカーフィールドサイズ(長さ100〜110メートル,幅64〜75メートル)の平面である.ゴールボックスとボールもまたFIFAのサイズであり,ゴールは幅7.32メートル,ボールは直径0.222メートル,重さ0.41〜0.45kgである.我々のエージェントは小さくてジャンプできないので,ゴールはたった0.5メートルの高さしかない.FIFA公式の高さは2.44メートルである.
 FIFAは重力加速度についてはほとんど何も言わない(おそらく重力をどうやっても変えることができないから).しかし,我々のシミュレーションでは9.81m/s^2*2に固定されている.
 シミュレーションステップは0.01秒である.接続されたモニタは毎15シミュレーションステップに更新を受け取る.
 このテキストに含まれている値の多くは,変更される可能性があり,このテキストはいつも現在の状態を反映しているわけではない.サーバがスタートアップ時に実行するセットアップスクリプトの中に,現在の定数セットがある../app/simulator/rcssserver3D.rbを参照すること.サーバの初めての実行の後,このファイルはホームディレクトリ下のディレクトリ/.rcssserver3dにコピーされる.次の実行ではそこから読み出される.どんな実験の変更も,そこで行われる.

プレーヤ

シミュレータの現在のバージョンでは,ロボットは(来年に,さらに洗練された表現にいきつくまでは)球体として表現される.全てのロボットの直径は0.44メートルであり,重さは75kgである.
 ロボットは全方位駆動装置のようなものを保有し,それはロボットの体に物理的な力を加える.全方位駆動装置を用いることにより,任意の方向に加速することが可能であり,また,ほんの少しジャンプすることも可能である.加速を止めても,ロボットはしばらく動くでしょう.そして,また,フルスピードで動いているとき,突然止まることは出来ないでしょう(しかし,ブレーキとして使用することができる).最高スピードとジャンプの最高点はいまだに見つかっていない*3
 プレーヤが初めにサーバに接続するとき,開始するために2つのことを行わなければならない.初めに,ゲーム中に使用したいロボットタイプを生成しなければならない.現在は,上記で述べられたような球体のロボットに限られている.後のバージョンでは,より洗練されたロボットモデルが利用可能になるかもしれない.起動時にひとつのロボットタイプを選択することは,Createエフェクタの仕事である.さらに,プレーヤはユニフォームナンバを受け取り,チームに参加しなければならない.これはInitエフェクタの仕事である.

Createエフェクタ

初めにシミュレータに接続するとき,あなたのエージェントはなんの物理的表現もない.エージェントが持っている唯一のものは“Createエフェクタ”である.Createエフェクタの概念は,様々なエフェクタとパーセプタとロボットタイプを要求することである.現在,たった1つの用意されたロボットタイプがあるだけであり,Createエフェクタは全てのパラメータを無視する.当面は,初めに“( create )”を実行し,デフォルトのロボットタイプを得る.

コマンドの例:
 ( create )

Initエフェクタ

チームの名前とユニフォームナンバを設定するために,Initエフェクタを用いなければならない.初期化しなければ,エフェクタとパーセプタは適切に動かない.

文法:
 ( init (unum <number> ) ( teamname <string> ) )
例:
 ( init (unum 7 ) ( teamname RoboLog ) )

Beamエフェクタ

kickエフェクタと同様に,初期の計画には,2Dサッカーサーバの“move”コマンドのような,ある場所から別の場所へエージェントを“beaming”するといった人為的行動の導入はなかった.未だに,計画では,beamingがエフェクタセットから消滅するように,サッカーシミュレーションを開発することになっている.
 しかしながら,問題は,限られた時間のために,kick offモードの前にエージェントを陣地に動かす何かをしなければならないことである.beamingを取り除くために,レフェリは,適切に動作しないエージェントに対してイエローもしくはレッドカードを送るように拡張されなければならない.我々は,近い将来にこの機能に取り組む・・・あなたの協力で.それまで,エージェントのbeamingはbeforekickoffモードで許される.
 Beamエフェクタは3つの座標を必要とするが,現在は3つ目の要素をゼロにしている.つまり,エージェントは地面に沿ってグラウンドを動くことのみ許されている.

文法:
 ( beam <x> <y> <z> )
例:
 ( beam -6.6 0 0 )

Driveエフェクタ

エージェントの全方位駆動装置を動かすために,いわゆるDriveエフェクタを用いなければならない.それは,最大の長さ100ユニットのデカルト座標上のベクトル* (x, y ,z) を持つ*4.x軸はフィールドの敵側を指し,z軸は上を指す.Driveエフェクタを使ってモータの力を設定する.すなわち,もし,しばらくフルスピードで動かしたいなら,Driveエフェクタを“一度だけ”使えば十分である.設定した力は再び変更するまで各シミュレータステップで適用される.Driveエフェクタは確実に働き,それぞれの軸毎に,力に対する誤差がある(各軸の適用された力の2%以内).誤差は0.0を中心とする正規分布である.
 全方位駆動装置を使うことはバッテリを消費する.AgentState?パーセプタを読むことにより,バッテリの状態を得られる.もしバッテリが空なら,全方位駆動装置は機能しなくなる.他のロボットを押しのけることも可能である.敵を押しのけるためにこの特性を用いることは推奨されない.

文法:
 ( drive <x> <y> <z> )
例:
 ( drive 20.0 50.0 0.0 )

Kickエフェクタ

ボールを動かすために,ボールを望ましい方向に押すようにロボットを使う単純なオプションがある.または,ボールをキックするためにkickエフェクタを用いることが出来る.元々は,人為的kickエフェクタを生成するつもりはなかった.しかしながら,3番目の次元を使用するために,これは最も容易な方法である.本年度のコンペティションではない,将来のバージョンにおいてこの種のkickエフェクタを取り除き,実際の物理デバイスを支持するつもりである.
 kickエフェクタは,ロボットの体から放射状にボールを加速させることができる.kickEffectorは第1引数として角度を持つ.これはボールを加速させるための上向き角度である.角度は0〜50(単位は度)の間の数に限られている.2つ目の引数はキックする力を示し,これは0〜100の間の数である.それは利用可能な最大の力の百分率として解釈される.kickエフェクタはボールに対する力とトルクを加える.これは(決められた)シミュレーションステップで発生する.現在は10サイクルが用いられている.これは10分の1秒のシミュレーション時間に対応している.ボールをキックするために,ボールはロボットにとても近くなければならない.つまり,いわゆるプレーヤのキッカブルマージンの間に存在しなければならない.現在は0.04メートルに設定されている.
 横平面のキック角度は変更不可能である.これは,望ましい方向にボールをキックできるようにロボットを動かなさなければならないことを意味する.現在,kickエフェクタはそれほど強くない.なぜなら,オフサイドルールのようなものがないからである.他のロボットに向かってボールをキックすることにより,他のロボットを動かすことは不可能である(動いたとしても,それほどではない).Driveエフェクタと同様に,kickエフェクタはロボットがサッカーフィールドに接触しているときのみ動作する.
 kickエフェクタのノイズは以下のパラメータを持つ:

  • x-y平面の角度誤差はとても低く,σ= 0.02で0.0を中心とした正規分布である.
  • 上向き角度誤差は0.0を中心とした正規分布である.この角度誤差は極端な位置,つまり,0と50度で低く,範囲の中央に向かうほど,角度誤差はσ= 4.5まで高くなる.
  • キックパワー誤差はσ= 0.4で0.0を中心とした正規分布である.
文法:
 ( kick <angle> <power> )
例:
 ( kick 20.0 80.0 )

Visionパーセプタ

ロボットは賢い画像処理ソフトウエアが備えられた特別な全方位カメラを保持する.ロボットは360度の視界がある*5.Visionパーセプタは見えたオブジェクトのリストを供給する.ここで,オブジェクトと,ロボット,ボールまたはフィールド上のマーカである.現在フィールド上に8つのマーカがあり,フィールドの各コーナに1つ,各ゴールポストに1つある.
 オブジェクトから,以下の情報が得られる:

  • プレーヤとオブジェクトの距離
  • 横平面の角度.0度はいつも敵のゴールを指す.
  • 上向き角度.ここで,0度は水平を意味する.

 2Dサッカーシミュレーションと違って,視覚システムはオブジェクトの速度を提供しない.オブジェクトは他のオブジェクトにより見えなくなるかもしれない(これはまだ完全に実装されていない).すべての距離と角度はカメラの位置と相対的に与えられる.カメラは現在ロボット球体の中心に位置している.
 視覚システムのノイズパラメータは以下のとおりである:

  • 小さな目盛り調整誤差が,カメラ位置に付加される.それぞれの軸に対して,誤差は−0.005〜0.005メートルの間で一様に分布している.誤差はいったん計算されると,試合の間は不変である.
  • 動的ノイズは0.0を中心とした正規分布である.
    • 距離誤差:σ= 0.0965
    • 角度誤差( x-y 平面):σ= 0.1225
    • 角度誤差(上向き角度):σ= 0.1480
文法:
 ( vision
  ( <Type>
   ( team <teamname> )
   ( id <id> )~
   ( pol <distance> <horizontal angle> <latitudal angle> )
  )
 )

 とりうる値は以下である:

  • ‘Flag’と<id>.<id>は‘1_l’, ‘2_l’ , ‘1_r’ , ‘2_r’の中の1つ.
  • ‘Goal’と<id>.<id>は‘1_l’ , ‘2_l’ , ‘2_l’ , ‘2_r’の中の1つ*6
  • ‘Player’と<id>.<id>はプレーヤのユニフォームナンバである.
視覚出力の例:
 (Vision (Flag (id 1_l) (pol 54.3137 -148.083 -0.152227)) (Flag (id2_l)
 (pol   59.4273 141.046 -0.131907)) (Flag (id 1_r) (pol 61.9718-27.4136 -0.123048))
 (Flag (id 2_r) (pol 66.4986 34.3644 -0.108964))(Goal (id 1_l)
 (pol 46.1688 179.18 -0.193898)) (Goal (id 2_l) (pol46.8624 170.182 -0.189786))
 (Goal (id 1_r) (pol 54.9749 0.874504-0.149385)) (Goal (id 2_r)
 (pol 55.5585 8.45381 -0.146933)) (Ball (pol6.2928 45.0858 -0.94987))
 (Player (team robolog) (id 1) (pol 7.3364337.5782 5.86774)))

Sayエフェクタ

他のプレーヤにメッセージを送信するために,Sayエフェクタを用いなければならない.メッセージはsayMsgSize?文字の長さ(当面は512)である.ここで,sayメッセージに対して有効な文字はスペースと()を除いた表示文字*7である.プレーヤが言うメッセージは両方のチームのメンバからaudioCutDist?(当面は50)の範囲内で聞くことが出来る
Sayエフェクタは,メッセージを聞くプレーヤの限定的能力によりのみ制限される.これらの能力に影響するサーバの変数のリストについては,Hearパーセプタの章を参照すること.

文法:
 ( say <message> )
例:
 ( say player10_pass )

Hearパーセプタ

プレーヤがSayエフェクタを用いてメッセージを送るとき,パーセプタから知覚を得る.サーバ*8からの実際のセンサメッセージのフォーマットは以下になる:

( hear <time> <direction in degree> <message> )
  • <time>は現在の時間を示す.
  • <direction in degree>は,もし他のプレーヤが送信者であれば送信者への相対方向である(ノイズ無し).そうでなければ(引用符無しの)”self”である.
  • <message>はメッセージである.最大の長さはsayMsgSize?バイトである.

Hearパーセプタに影響を与えるサーバのパラメータは以下である:

  • audioCutDist?, default 50.0
  • hearMax, default 2
  • hearInc, default 1
  • hearDecay, default 2
  • sayMsgSize?, default 512

聴力が少なくともhearDecayであるならば,プレーヤはメッセージを聞くことが出来る.というのは,メッセージが聞こえたとき,hearDecayだけ聴力は減少するからである.毎サイクルにおいて,聴力はhearIncだけ増加する.最大聴力はhearMaxである.チャンネルに負担を掛けて他のチームのコミュニケーションを使用不可にすることからチームを避けるために,プレーヤは各チームに対して別々の聴力を持っている.現在の値では,1知覚更新おきに,各チームからせいぜい1つのメッセージしか聞けないということを意味する.
 もしプレーヤが聞くことの出来るメッセージよりも多くのメッセージが同時にやってきたら,実際に聞こえるメッセージは不定である(現在の実装では,到着順に従ってメッセージを選択する).この規則には,自分自身からのメッセージはあてはまらない.言い換えると,プレーヤは自分自身のメッセージを聞くことが出来て,同じPerceptor出力内で他のプレーヤのメッセージを聞くことが出来る.
 プレーヤにより発せられたメッセージは,そのプレーヤからaudioCutDist?メートル以内のプレーヤにのみ送信される.例えば,自分自身のゴールに近いディフェンダはゴールキーパからのメッセージを聞くことができるが,敵のゴールに近いストライカは,そのメッセージを聞くことが出来ない.

Hear出力の例:
 (hear 0.8 -179.99 Test_1)
 (hear 0.4 self Test_2)

GameState?パーセプタ

GameState?パーセプタはゲームの現在の状態について教えてくれる.このパーセプタから得られる最初の知覚は,ボールの重さやフィールドのサイズなどのようなものがくる.ゲームの変数についてである.

文法:
 (GameState (<Name> <Value>) ...)

Name>に対して可能な値は以下である:

  • timeは現在の経過ミュレーション秒(float型の値).
  • playmodeは文字列として現在のプレイモードを与える.

利用可能なプレイモードは,

BeforeKickOff, KickOff Left, KickOff Right, PlayOn, KickIn Left, 
KickIn Right, corner kick left, corner kick right, goal kick left,
goal kick right, offside left, offside right, GameOver, Goal Left,
Goal Right, free kick left, free kick right, unknown.

全てのプレイモードの最新のリストについては,./plugin/soccer/soccertypes.hを参照すること.

GameState出力の例:
 (GameState (time 0) (playmode BeforeKickOff))

AgentState?パーセプタ

AgentState?パーセプタはエージェントの現在の状態を教えてくれる.今現在はバッテリレベルと温度である.

文法:
 (AgentState
  (battery <battery level in percent>)
  (temp <temperature in degree>)
 )
AgentState出力の例:
 (AgentState (battery 100) (temp 23))

モニタとトレーナプロトコル

サッカーシミュレーションに対するデフォルトのモニタポートは12001である.サーバは定期的にS式を含むテキストをあなたに送信する.モニタに送られた全ての式の記録されたシークエンスを含むモニタログファイルは,ログファイルフォーマットとして後で用いられる.サーバディレクトリを起点として,Logfiles/monitor.logに自動的に生成される.

Init式

初めに1つのInit 式が送られる.init 式の例が下記で与えられている.サーバからは1行のS式が送られる事に注意しなさい.それらは,読みやすさのために,ここでは再フォーマットされている.

(Init
 (FieldLength 104) (FieldWidth 68) (FieldHeight 40)(GoalWidth 32)(GoalDepth 2)
 (GoalHeight 0.5) (BorderSize 10) (FreeKickDistance 9.15) (WaitBeforeKickOff 2)
 (AgentMass 75) (AgentRadius 0.22) (AgentMaxSpeed 10) (BallRadius 0.111)
 (BallMass 0.425878) (RuleGoalPauseTime 3) (RuleKickInPauseTime 1)(RuleHalfTime 300)
 (play_modes BeforeKickOff KickOff_Left KickOff_Right PlayOn KickIn_Left KickIn Right corner_kick_left
 corner_kick_right goal_kick_left goal_kick_right offside_left
 offside_right GameOver Goal_Left Goal_Right free_kick_left free_kick_right)
)

init 式のそれぞれの部分式は,シミュレーションの現在のインスタンスが用いるある1つのパラメータを与える名前−値の組である.様々なパラメータの意味は以下の通りである:

  • FieldLength?, FieldWidth?, FieldHeight?: メートル単位のサッカーフィールドの寸法.
  • GoalWidth?, GoalDepth?, GoalHeight?: メートル単位のゴールの寸法.
  • BorderSize?: シミュレートされるサッカフィールドは,場外エリアで囲まれている.BorderSize?は通常のフィールドの寸法と相対的に,メートル単位の余白の空間を与える.
  • FreeKickDistance?: プレーヤがフリーキックを実行するとき,敵のエージェントが離れなければならないメートル単位の距離を与える.
  • WaitBeforeKickOff?: 自動的にゲームを開始する前に,サーバが待機する秒単位の時間を与える.
  • AgentMass?: キログラム単位の各エージェントの質量.
  • AgentRadius?: メートル単位の各エージェントの半径.
  • AgentMaxSpeed?: m/s単位の各エージェントの最大スピード.
  • BallRadius?: メートル単位のボールの半径.
  • BallMass?: キログラム単位のボールの質量.
  • RuleGoalPauseTime?|jakjsdfkj: 得点が入った後でプレイモードkick offへ変わる前に,ゴールがされた後でサーバが待機する時間.
  • RuleKickInPauseTime?:ボールがフィールドを離れた後でプレイモードkick inへ変わる前に,サーバが待機する時間.
  • RuleHalfTime?:秒単位のハーフタイムの長さ.
  • play_modes:サッカシミュレーションの異なるplay_modesをリストアップする.後で,play_modesはゼロから始まるインデックスによりこのリストへ参照される.

Info式

初期initメッセージが送信された後はInfo 式のみが送信される.これらの式は現在のシミュレーションの全ての状態を含んでいる.Info式の例が以下で与えられている:

(Info (time 0)(half 1)(score_left 0)(score_right 0)(play_mode 0) (P(pos 0 0 0))
(P (pos 0 0 0))(P (pos 0 0 0))(P (pos 0 0 0)) (P (pos 0 0 0))(P (pos 0 0 0))(P 
(pos 0 0 0))(P (pos 0 0 0)) (P (pos 0 0 0))(P (pos 0 0 0))(F (id 1_l)(pos -52 -34 0))
(F (id 2_l)(pos -52 34 0))(F (id 1_r)(pos 52 -34 0))(F (id 2_r)(pos 52 34 0))
(G (id 1_l)(pos -52 -3.66 0))(G (id 2_l)(pos -52 3.66 0)) (G (id 1_r)
(pos 52 -3.66 0))(G (id 2_r)(pos 52 3.66 0)) (B (pos 0 0 10)) )

Info 式の各部分式は,現在のシミュレーションの状態のある側面についての情報を含んでいる名前−値の組である.すべての部分式が繰り返し送られるわけではない.これはフィールドのフラグの位置と2つのチームの名前に関係している.この情報は一度だけ送信される.スコアカウントのような更にゲーム状態の情報と現在のゲームの状態は,それらが変化したときのみに送信される.様々な式の意味は以下の通りである:

  • Die:サッカーシミュレーションが終わろうとしていることを,モニタに通知する.
  • time:秒単位の現在のシミュレーション時間.
  • half:現在のゲームハーフ,0は前半,1は後半を意味する.
  • score_left,score_rihgt:それぞれ,左と右のチームのスコアカウント.
  • play_mode:Init 式で与えられているplay_modesに対する0から始まる数字で指定される現在のプレイモード.
  • P:プレーヤについての情報を与える.この式はさらなる部分式を含んでいるかもしれない.
    • s:0は左,1は右に属しているプレーヤをチームに与える.
    • id:プレーヤのユニフォームナンバを与える.
    • pos:3つの要素ベクトルとしてプレーヤの位置を与える.
    • last:もし部分式が存在しているなら,プレーヤはボールに最後に触れたことを示す.
    • say:この式は,オプションのSayEffector?を用いて送信した文字列を与える.
  • F:フィールド上のフラグについての情報を与える.フラグの情報は動かないものなので,情報は一度だけ送信される.
    • pos:3要素ベクトルとしてフラグの位置を与える.
    • id:フラグの名前を与える.
  • B:ボールについての情報を与える.
    • pos:3要素ベクトルとしてボールの位置を与える.
  • ack:サーバにより実行されるコマンドを確認する:パラメータとしてユーザ定義のcooky stringを運ぶ.さらなる説明は以下を参照すること.

モニタコマンドパーサ

接続されたモニタは,更にモニタ接続を用いてサーバへS式としてコマンドを送信することが出来る.これらのコマンドにより,接続されたモニタは現在のプレイモードを設定することができ,またフィールド上の任意の位置へプレーヤとボールを動かすことが出来る.これはトレーナクライアントの実装を許可する.
 サポートされている式は以下の通りである:

  • (kickOff):サッカゲームを開始する.初めにキックオフするチームを選択するためにコインを投げる.
  • (playMode <play mode>):現在のプレイモードを設定する.可能なプレイモードは,モニタが接続したときに,モニタが受け取るInit式のplay_modes式内に文字列として与えられている.例:(playMode corner_kick_left).
  • (agent(team [R,L])(unum <uniform number>(pos <x, y, z>) (vel <vx, vy, vz)):この式はフィールドで与えられたプレーヤの位置と速度を設定する.例:(agent (team L)(unum 1)(pos -52.0 0.0 0.3)(vel 0.0 0.0 0.0)).
  • (ball (pos <x,y,z>)):フィールドのボールの位置を設定する.例:(ball(pos 10,20,1)).
  • (dropBall):現在の位置にボールを落とし,フリーキックの半径から全てのプレーヤをどける.
  • (getAck <cooky string>):実験的な特徴であり,現在利用不可である.サーバからの(ack <cooky>)返信を要求する.サーバは,コマンドが実行されたらすぐ返事を送信する.これは,トレーナの実装をサーバと同期させるために用いられる*9.getAck式は上記のコマンドの後に付け加えられる.
例:
 ((kickOff)(getAck kicked_off))

シーン記述言語

Sparkは管理されたシーングラフを利用する方法をいくつか与える.内部のC++インターフェースとRubyスクリプト言語による外部アクセスに加えて,シーン記述言語に対する拡張性のある機構が実装されている.これは,シーンの手続的なセットアップと記述ベースのセットアップの両方を可能とする.
シーンは任意の数の登録されているシーンインポータプラグインの中のひとつを利用してインポートされる.そして,各シーンインポータプラグインは異なるシーン記述言語をサポートしている.

RubySceneGraph? language

現在,一つのS式に基づくインポータが実装されている.この参照言語はRubySceneGraph? と呼ばれている.これは,シーングラフ構造をLispに似たS式の入れ子へと変換する.
S式は要素のリストである.各要素はアトムもしくはそれ自身がアトムのリストである.アトムはあらかじめ定義されたキーワード,もしくはさらなる文法構造を持たず,空でない文字列リテラルのいずれかである.EBNFを用いて表記されるS式の文法はListing 1に与えられる*10

character	->  ”A”  |  …  |  ”Z”  |  ”1”  |  …  |  ”9”,
atom 	     ->  character+
list		->  ”(” s_expression* ”)”
s_expression	->  atom  |  list 
Listing 1: EBNF notation of s-expression

意味に関して,RubySceneGraph?インタプリタは特別なアトムの集合を認識する.各部分式における最初のアトムは,そのタイプを決定する.キーワードの集合は,インタプリタが5つの異なる式タイプを区別することを可能とする4つのアトムから構成される.

  • RubySceneGraph?は,全てのシーングラフファイルのヘッダ式である
  • 式nodeは,新しいシーングラフノードを宣言する.
  • 式importSceneは,他のシーングラフファイルの内容と置き換えられる.
  • 式templateは,シーンの部品に対するパラメータ集合を宣言する.これは,マクロのように後から再利用される.
  • 残りすべての式のタイプは,メソッドコールとして解釈される.

上記で記載された様々な式タイプに加えて,置換機構が実装されている.ドル記号で始まるすべてのアトムリテラルはテンプレートパラメータとして解釈され,実際の値で置き換えられる.
我々は以下で,様々な式のタイプの意味をいくつかの使用例と利用可能なノードタイプとメソッドの部分的な参考資料と共に述べる.

ファイル構造

Rubyシーンファイルのトップレベルは,二つのS式から構成される.最初の式はヘッダ式でなければならない.ヘッダ式はパーサがファイルタイプを確認し,用いられている言語のバージョンに関する情報を得ることを可能にする.
ヘッダ式の文法は(RubySceneGraph? <major Version> <minor Version>)である.現在,唯一の有効なヘッダはmajor Versionに対して0,minor Versionに対しては1である.
ヘッダの次にシーングラフボディを含む単一のS式が続く.任意のそれ以降の式は無視される.ボディ式は任意に使用できる一つのテンプレート式とノード式の集合から構成される.この構造の例が,listing 2に概説されている.セミコロンで始まる行はコメント行であることに注意しなさい.

; the header expression 
(RubySceneGraph 0 1)
(
 ; the body of the file starts here

 ; declare this file as a template
 (template $lenX $lenY $lenZ $density $material)

 ; declare the top level scene graph node
 (node Box
       ; children of the top level node go here
       (node DragController
       )
 )
)
Listing 2: File Structure

ノード式

シーングラフはオブジェクトインスタンスノードの木から構成される.シーングラフにおける各ノードは式 (node <ClassName?>)を用いて宣言される.引数ClassName?はZeitgeistクラスファクトリに登録されたクラスの名前を与える.
 ノード式の役割は与えられたクラスタイプの新しいシーングラフオブジェクトを実体化することである.よって,インポータは要求されたオブジェクトを生成する際にZeitgeistクラスファクトリに頼る.それからオブジェクトは,最も内側で囲んでいるノード式の子として組み込まれる.もし囲んでいるノード式が無ければ,そのノードは表現されているシーングラフのトップレベルのノードである.
 トップレベルのノードの集合は,現在のグラフがインポートされているノードの子として組み込まれる.これは,システムのグローバルルートノード,もしくは他のシーングラフファイル内でimportScene式を用いて定義された挿入点である.よって,ノード式を入れ子にすることにより,結果としてのシーングラフの構造がとても小さい構文的な処理の負荷で定義される.

シーングラフテンプレート

シーン記述言語はさらに,マクロのような方法でシーングラフの部品の再利用を可能とする.これは,あらかじめ定義された一部のシーンもしくは完全なエージェントの記述のレポジトリを生成することを可能とする.マクロの概念は 式(importScene <filename> <parameter>*)を用いて利用可能である.この式は,システムのインポータ機能を再帰的に呼び出す.その式は,最も内側で囲んでいるノード式を相対的なルートノードとみなし,与えられたファイル内で記述されたシーングラフを組み込む.
 与えられたファイルは必ずしも他のRubySceneGraph?ファイルである必要はなく,インポータフレームワークに登録されている任意のファイルタイプでもよい.これは,異なるグラフ記述言語において表現されたシーングラフの部品の入れ子を可能とする.この特徴の応用例は,3Dモデル生成により適したアプリケーションプログラムによる結果としてのシーンの部品の生成である.今のところ,私たちはこの特徴をまだ有効に活用していない.
 importScene式に与えられるパラメータのリストは担当のインポータプラグインに伝えられる.もし,テンプレートを宣言している他のRubyシーングラフファイルがインポートされるなら,それらは正式なパラメータを用いて置き換えられる.
 インポートされたファイル内のテンプレート宣言は以下の構文を満たさなさなければならない: (template <parameterName>*). パラメータの名前はドル記号が前に付けられている文字列リテラルであり,宣言例に関してはlisting 2を見なさい.ファイルのボディ内で表れている全てのパラメータ名はそれらの実際の内容で置き換えられる.
 以下のlisting 3における使用例は,box.rsgファイルを仮定している.例では,Listing 2で与えられているテンプレート表現にしたがって異なるサイズと色を有する箱を生成するためにテンプレートを用いる.

(RubySceneGraph 0 1)
(
 (node Transform
      (importScene box.rsg 1 3 0.8 10 matRed)
 )
 (node Transform
     (importScene box.rsg 2 4 0.4 8 matBlue)
 )
)
Listing 3: importScene example

メソッドコール

上述のノード式を用いて生成されたノードは,デフォルトの性質を修正するためにメソッドコールを用いてさらにパラメータ化される.上で記述された式タイプに一致しない全ての式は,メソッドコールとして解釈される.それは,関数の名前で始まり,任意のパラメータリストが続くS式として解釈される (<method name> <parameter>*). 各メソッドコールは最も内側で囲まれたノード式の文脈で評価される.メソッドコールの意味は,対応するC++クラスのRuby記述インターフェース,つまりこの言語の名前を呼び出す.
このデザインの決定は,シミュレータの開発中に我々が完全なシーン記述言語を速やかに実装することを可能とした.つまり,シミュレータは我々の主要な記述言語であるRubyへとエクスポートされる新しいメソッドとして自動的に拡張される.  独自のメソッドとプロパティの名前を用いて完全に新しいシーン記述言語を実装しようとすることは,機能の再実装が必要であっただろう.しかし,それらは我々のスクリプトインターフェースからすぐに利用可能である.
 使用例は変換ノードのセットアップである.これらのノードタイプは,対応する親ノードと相対的にシーングラフ内のパスに沿ってノードの位置と方向を決めるために用いられる.よって,変換ノードは親ノードに対する補正値を設定するためにメソッドSetLocalPos?を与える.同様に,ボックスノードは,表現される箱の大きさを設定するノードを与える.

(RubySceneGraph 0 1)
(
 (node Transform
      (setLocalPos 10 20 5)
      (node Box
           (setExtents 1 1 1)
      )
 )
)
Listing 4: Method call example

言語リファレンス

このセクションで,私たちは最も代表的なノードタイプとそれらのもっとも重要なメソッドを記載する.ただし,完全なリファレンスはとても大規模なものとなるだろうし,シミュレータは常に拡張されているので,完成することはないだろう.

BaseNode?

BaseNode?タイプは全てのシーングラフノードに対する親クラスである.以下のメソッドが利用可能である:

  • (importScene <string fileName>) はセクション4.4で記述されているように,与えられたシーンをインポートする.
  • (setName <string filename>) はノードのユーザ定義名を設定する.これはパス式内でノードを参照するために用いられる.

Transform

Transformノードタイプは,対応する最も近い親変換ノードに対する子ノードの位置と方向を決定する.

  • (setLocalPos? <float x> <float y> <float z>) は相対的な位置を定義する.
  • (setLocalRotation? <float x> <float y> <float z>))は度で相対的な回転を定義する.
  • (setLocalTransform? <float m00> … <float m33>) はローカル4×4回転行列を定義する.

SingleMatNode?

SingleMatNode?は一つの物体の特性を用いたオブジェクト(例えば,軸,箱,球,capped cylinder)を表示する全てのノードに対する抽象親クラスである.以下のメソッドが利用可能である:

  • (setMaterial <string name>) はノードを描くために与えられた物体を用いる.

Axis

Axisノードは色つきの直行線を用いて座標軸を表示するSingleMatNode?である.デフォルトで,単位長さの線を描く.以下のメソッドが利用可能である:

  • (setSize <float size>) は描かれる各軸線の長さを設定する.

Box

Boxノードは与えられた大きさを持つ立方体を表示するSingleMatNode?である.デフォルトで単位長さの箱を描く.以下のメソッドが利用可能である:

  • (setExtents <float x> <float y> <float z>)は対応する軸に沿って箱の大きさを設定する*11

Sphere

Sphereノードは与えられた半径を持つ球を表示するSingleMatNode?である.デフォルトで,単位球を描く.以下のメソッドが利用可能である:

  • (setExtents <float radius>) は球の半径を設定する.

CCylinder

CCylinderノードは与えられた半径と長さを持つcapped cylinderを表示するSingleMatNode?である.デフォルトで,単位長さと半径を持つcylinderを描く.以下のメソッドが利用可能である:

  • (setParams <float radius> <float length>) はcapped cylinderの長さと半径を設定する.

Body

Bodyノードはシミュレートされるオブジェクトの物理的な側面を表現する.以下のメソッドが利用可能である:

  • (enable) はボディが物理シミュレーションに加わることを可能とする.
  • (disable) はボディが物理シミュレーションに加わらないようにする.
  • useGravity <bool f>) はボディが重力に影響されるかどうかを指定する*12
  • setSphere <float density> <float radius> )は球に対する質量分布を設定する.
  • setSphereTotal? <float mass> <float radius>) は球に対する質量分布を設定する.
  • setBox <float density> <float size>)はボックスに対する質量分布を設定する.
  • setBoxTotal? <float mass> <float size>)はボックスに対する質量分布を設定する.
  • setCylinder <float density> <float radius> <float length>) はcylinderに対する質量分布を設定する.
  • setCylindertTotal? <float mass> <float radius> <float length>) はcylinderに対する質量分布を設定する.
  • setCappedCylinder? <float density> <float radius> <float length>) はcapped cylinder に対する質量分布を設定する.
  • setMass <float mass>) はボディの合計質量を設定する.
  • setVelocity <float x> <float y> <float z>) はボディの初期速度を設定する.
  • setAngularVelocity? <float x> <float y> <float z>) は度で初期角速度を設定する.

Collider(粒子(衝突型)加速器)

Colliderは全てのサポートされる衝突プリミティブに対する抽象基底クラスである.それはさらに,Colliderインスタンスにより検出される衝突イベントに反応するCollisionHandler?の子ノードセットを管理する.利用可能なメソッドは以下の通りである:

  • (addCollisionHandler? <string ClassName?>)はColliderの下の衝突ハンドラノードを組み込む.これは,ノード式を用いて衝突を組み込むときと同じような効果を持つ便利な関数である*13.もし衝突ハンドラが組み込まれていないなら,デフォルトのContactJointHandler?が実行時間中に組み込まれる.

BoxCollider?

BoxCollider?BoxCollider?プリミティブを実装するColliderノードである.デフォルトでは,単位サイズのボックスColliderを生成する.利用可能なメソッドは以下の通りである:

  • (setBoxLengths? <float x> <float y> <float z>)は衝突プリミティブの大きさを設定する.

SphereCollider?

SphereCollider?は球体衝突プリミティブを実装するColliderノードである.デフォルトでは,単位サイズの球体 Colliderを生成する.

  • (setRadius <float radius >)は衝突プリミティブの半径を設定する.

CCylinderCollider?

CCylinderCollider?はcapped cylinder衝突プリミティブを実装するColliderノードである.初期では,単位長さと半径のcapped Colliderを生成する.利用可能なメソッドは以下の通りである:

  • (setParams <float radius> <float length>)は衝突プリミティブの半径と長さを設定する.
  • (setRadius <float radius>)は衝突プリミティブの半径を設定する.
  • (setLength <float length>)は衝突プリミティブの長さを設定する.

CollisionHandler?

CollisionHandler?*14は,衝突に対して行動を起こすハンドラの抽象基底クラスである.それぞれのColliderインスタンスに対して,1つ以上のCollisionHandler?が登録される.この基底クラスにおける利用可能なメソッドは無い.

ContactJointHandler?

ContactJointHandler?は,2つの影響する衝突プリミティブと関連する2つのボディの間でODEジョイントを生成するCollisionHandler?である.ジョイントは衝突を分析するために用いられる.すなわち,2つのボディが互いに貫通することができないような適切な力を生成することである.利用可能なメソッドは以下の通りである:

  • (setContactBounceMode? <bool set>)
  • (setContactBounceValue? <float value>)
  • (setMinBounceVel? <float velocity>)
  • (setContactSoftERPMode <bool set>)
  • (setContactSoftERP <float erp>)
  • (setContactSoftCFMMode <bool set>)
  • (setContactSoftCFM <float cfm>)
  • (setContactSlipMode? <bool set>)
  • (setContactSlip? <float slip>)
  • (setContactMu? <float mu>) 上記のメソッドはすべて,ODE接触構造の対応する値を利用可能にし,設定する.詳細については,ODEユーザガイド[?]*15を参照すること.

RecorderHandler?

RecorderHandler?は,それが所属するColliderの衝突情報を集めるCollisionHandler?である.それは例えば,バンパーセンサの実装やゲームルールの実装を支援する.そこで,それは,エージェントがフィールド上の特定のエリアに存在するかどうかを発見するために用いられる.これらのエリアは例えば,BoxCollider?として表現される.スクリプトインタフェイスを通してこれ以上利用可能なメソッドはない.

Joint

JointノードはすべてのJointに対する抽象基底クラスである.2つのボディがお互いに相対的なポジションと方向が特定の物になるように,2つのボディの間で強制される関係(制約)を定義する. Jointの図形パラメータを設定する関数は,Jointがボディに接続され,それらのボディが正しく配置された後にだけ呼び出される.そうでなければ,Jointは正しく初期化されないかもしれない,ということに注意しなさない.もしJointがまだ接続されていないなら,これらの関数は何もしないであろう. Jointノードは,親変換ノードにしたがって配置され,また方向付けられることに注意しなさい.利用可能なメソッドは以下の通りである:

  • attach(<string path1> <string path2>)は複数の新しいボディへジョイントを接合する.もしジョイントがすでに接合されていたら,はじめに古いボディから取り外される.このジョイントを1つのボディのみへ接合するために,2つ目のpathパラメータを除外する.これは,事実上ボディを静的環境へと接合させる. path式は相対的にJointノードからの共通のUnix文法にしたがう.オブジェクトインスタンスは,Setname関数を用いて名前セットにより参照される.pathの区切りとして"/",親ノードを参照するために".."を用いる.
    • (setAnchor <float x> <float y> <float z>)は,ジョイントノードからの相対座標でアンカーポイントを設定する.
  • (setHighStopDeg?)
  • (setLowStopDeg?)
  • (setHighStopPos?)
  • (setLowStopPos?)
  • (setBounce)
  • (setCFM)
  • (setStopCFM)
  • (setStopERP)
  • (setSuspensionERP)
  • (setSuspensionCFM)
  • (setLinearMotorVelocity?)
  • (setAngularMotorVelocity?)
  • (setMaxMotorForce?) 上記のメソッドの最後のブロックは,ODE Joint構造の対応する値を設定する.詳細については,ODEユーザガイド[?]*16を参照すること.

FixedJoint?

FixedJoint?ノードは2つのボディ,または1つのボディと静的環境間の固定された相対位置と方向を維持するジョイントを表す.

BallJoint?

BallJoint?ノードは,2つのボディをアンカーポイントで接続するball and socket jointを表す.それは,このアンカーに対する2つのボディの不変的な距離を強要する.その上,それはアンカーポイントに対してそれぞれのボディが一定の向きを保つことを強要する.2つのボディは,アンカーポイントのまわりを自由にぐるぐる回る.

HingeJoint?

HingeJoint?ノードはヒンジジョイントを表す.このJointタイプは,定義されたアンカーポイントを通る1つの軸に沿って,2つの剛体ボディを接続する.軸は,ノードの局所的座標系におけるz軸と固定されている.これは,親変換ノードを用いて調整可能である.ball and socket jointのように,それはアンカーポイントに対して,一定の距離や向きを強制する.しかしながら,回転する自由は,定められた軸に制約される.

Hinge2Joint

Hinge2Jointは,ヒンジが2つあるジョイントを表す.それは,連続して接続された2つのヒンジジョイントのように振る舞う.それぞれのヒンジジョイントは,異なるHingeJoint?を定義するが,同じアンカーポイントを共有する.2つの軸は,ノードの局所的座標系におけるxとz軸へと固定される.これは,親トランスフォームノードを用いて調整可能である.このジョイントタイプは一般的に,車のハンドルの操作をシミュレートするために用いられる.この場合では,1つ目の軸により車輪の操作,2つ目の軸により車輪の回転が可能となる.

UniversalJoint?

UniversalJoint?ノードは,いわゆるユニバーサルジョイントを表す.それは,追加的な回転自由度を制約するソケットジョイントである.UniversalJoint?は,2つの垂直軸で動作する(それぞれのボディで1つ定められている).ジョイントの局所的座標系におけるxとz軸へと固定されているこれらの軸は,垂直のままでいるように強制される.これは,2つの他の軸に垂直な軸について,2つのボディの回転が等しいということを意味する.したがって,2つのボディのいずれかが軸の周りを回っている時は,他方も同様に回転している.

おわりに

この日本語訳の翻訳者,連絡先は下記の通りである.

翻訳者

横田泰之(担当:1〜3章,4.6.9〜4.6.21節)
並川直樹(担当:4章〜4.6.8節)
中島智晴(監修)

連絡先

大阪府立大学 大学院工学研究科 電気・情報系専攻 計算知能工学研究室
助教授 中島智晴
nakashi at cs.osakafu-u.ac.jp


*1 [?]は原本のコンパイルミスかと思われる
*2 本文中では,m/sであるが,m/s^2であると思われる
*3 itはisであると思われる
*4 Cartesian vectorという言葉は辞書には見つからない
*5 バージョン0.5.2以降は視界が限定されているが,マニュアルには反映されていない
*6 '2_l'が2つあるのは,原本のミスかと思われる
*7 7ビットのASCII文字セットでは,表示文字は0x20〜0x7Eである
*8 from theの後にserverが抜けていると思われる
*9 witはwithだと思われる
*10 EBNFはExtended BNFの略.コンピュータが扱う言語の文法を定義する際に用いられるメタ言語の一つでBNFを拡張したもの
*11 本文では“)”が<float x>の後にあるが,上記の式が正しいと思われる
*12 本文では,“(”が欠如していると思われる.以後の式も同様である.
*13 iはisであると考えられる
*14 CClyinderCollider?CollionHandler?だと思われる
*15 [?]はコンパイルミスであると思われる
*16 [?]はコンパイルミスかと思われる

添付ファイル: filercssserver3d_0.52_manual_20060725.pdf 949件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2016-09-05 (月) 14:29:30 (2164d)