-
Notifications
You must be signed in to change notification settings - Fork 4
v hsc_simulator_api_v1.0
バーチャルサッカー大会用API仕様書
このドキュメントでは、各チームのソースコードと競技用シミュレータのインターフェースについて説明します。より正確には、以下に焦点を当てています。
- チームがシミュレータに指示を与えるために用意する設定ファイルの定義
- ロボットを制御するプログラムとシミュレータの間の通信を可能にするためのプロトコル
今後、この文書は重大な問題が発生した場合にのみ更新されます。以下では、用語を使用しています。
- シミュレートされた環境の中で行動し、感知する仮想のロボットを指す「ロボット」または「ロボットモデル」と
- ロボット制御ソフトウェアとは、チームによって実装され、シミュレータ環境の外で動作するロボットの動作ソフトウェアのことです。
一般的な側面
ゲーム中のロボットの制御は,シミュレータとロボット制御ソフトウェアの間のカスタムTCPプロトコルに基づく非同期通信によって行われる.
このプロトコルはproto3メッセージに基づいています。現在のprotobufファイルはWebotsのgithubで見ることができます。
物理シミュレーションの各ステップの後、シミュレータはセンサーから得られるすべての新しいデータを含むメッセージを送信します。
2つのセンサーが更新されるまでの最小ステップは以下のように選択されます。
- カメラデータ:2つの連続したフレーム間の最小時間をminFrameStepとし、16msとする。
- その他のセンサー:2つの更新の間の最小時間はminControlStepと呼ばれ、8msとなっています。
8msのシミュレーションステップのリアルタイム期間は、8msより長いかもしれませんが、少なくとも8msであることが保証されています。
ROSとROS2のブリッジ
TCPプロトコルとROSまたはROS2トピックとの間のブリッジを可能にするシンプルなパッケージを開発中です。大会前に準備ができれば、ロボット制御ソフトウェアの一部として実行されます。そのため、これらのブリッジを使用すると、処理に若干の遅れが生じます。
設定ファイル
シミュレータは、JSON形式で書かれたチームごとの設定ファイルを必要とします。そのような設定ファイルの例は、付録で提供されています。設定ファイルには、2つのエントリを持つ辞書が含まれています。
- name: string 12文字以内のチームタグ
- players: Playersの辞書 プレーヤーのリストとそのプロパティ
playersは、ロボットのIDをキーとし、以下のプロパティを値として持つ。
- robotModelName: string このロボットに使用されるモデルの名前。これはヒューマノイドリーグのサブミッションシステムで提出されたファイル名と一致する必要があります。
- dockerTag: string このロボットの制御ソフトウェアを含むDockerイメージタグ。これはオプションで、デフォルトでは "latest "になっています。
- dockerCmd: string チームのDockerイメージを実行するためのコマンドです。次のように実行されます: docker run : . このプロパティのアイデアは、チームがどのロボットを使用するかに基づいて、異なるコマンドを渡せるようにすることです。このプロパティはオプションで、このプロパティが設定されていない場合、Dockerイメージは次のように実行されます: docker run :.
- halfTimeStartingPose。Pose ハーフタイム開始時にロボットのポーズをとる。
- reentryStartingPose: 取り外しのペナルティを受けた後のPose Robotのポーズ。
- shootoutStartingPose: PK戦でのPose Robotポーズ。
チームは、選手辞書への登録数を少なくすることで、所属リーグで認められている最大数よりも少ないロボットでゲームを開始することができる。ただし、これはゲーム中に変更することはできません。例えば、チームが1台のロボットでプレイすることを決定し、そのロボットがレッドカードを受けた場合、そのチームはフィールド上にロボットがいない状態でゲームを終了しなければなりません。n台のロボットでプレイするチームは、1~n番のロボットを使用しなければなりません。
Poseオブジェクトは、ロボットを配置するためのトランスフォームを定義します。
- translation: float[3] ロボットがスポーンされるべき[x,y,z]座標です。
- rotation: float[4] [rx,ry,rz,angle] [rx,ry,rz]は正規化されたベクトルで、angleはラジアン単位の回転角である。
- 注:定義では任意の回転軸を使用することができますが、AutoRefereeではz軸に沿った回転のみがサポートされています(例:0 0 1 3.14)。
Poseは以下のレファレンシャルで定義されています。
- 原点はグラウンドレベルでのフィールドの中心
- X軸は、相手ゴールの中心を指す
- Z軸は、グラウンドと直交する空の方向を指す
reentryStartingPoseは、yに負の値を指定し、ロボットがペナルティマークに向かってフィールドの外に完全に出るようにする。代替ポーズは、XZ平面に沿った鏡面対称性またはX軸に沿ったオフセットを用いて自動的に調整される。
チームは、初期位置がルールに適合していることを確認してください。そうでない場合は、次のような違反を繰り返す危険性があります。
手順
シミュレータへの接続を開始する
シミュレータとの通信を開始するために、ロボット制御ソフトは環境変数ROBOCUP_SIMULATOR_ADDRで定義されたアドレスに接続する必要があります(例:192.168.1.100:10001)。ポートのデフォルトは
- 10000 + ROBOT_ID (赤チーム)
- 10020 + 青チームのROBOT_ID
シミュレータには、各ロボットのIPアドレスが通知されます。そのため、他のロボットへの接続試行はすべて拒否されます。さらに、すべての接続試行はゲーム中に記録されます。万が一、他のチームのロボットへのシステム的な接続試行が記録された場合は、不正な接続を行ったチームに制裁が与えられます。
シミュレータへの接続時には、ロボット制御ソフトウェアは以下の文字列を含むサイズ8のメッセージを受け取る。
- Welcome: シミュレータが接続を受け入れた場合。
- Refused:接続が拒否された場合。
いずれの場合も、メッセージの最後には NULL 文字が入ります。
ゲーム中にロボットが切断された場合、同じポートに再接続することができる。
通信の終了
クライアントが応答しなくなったり、メッセージの処理が遅かったりして、シミュレータの通信キューがいっぱいになった場合、シミュレータは他のクライアントへのサービスの質を維持し、シミュレーションを適度な速度で維持するために、クライアントとの接続を中断します。このような中断は、シミュレータのログに記録されます。
接続はゲーム終了時に自動的に閉じられ、ロボット制御ソフトはGameControllerメッセージによってゲームの現在の状態を知ることができます。
センサーメッセージ
ロボットは以下の情報を含むSensorMeasurementsメッセージを定期的に受信する。
- time : 計測が行われたダブルタイムスタンプ(単位:[s])
- message : メッセージ[].
- message_type: MessageType Error or Warning
- text: 文字列の説明文
- accelerometer : 加速度センサー測定値[].
- name : 文字列
- value : double[3] [m/sˆ2], x軸, y軸, z軸
- bumper : バンパー計測値[] (BumperMeasurement[])
- name : 文字列
- value : boolean
- camera : CameraMeasurement[] (カメラ計測)
- name : 文字列
- width : int
- 高さ : int
- quality : int UNUSED:今年はRAW画像のみ対応しています。-1=生の画像、100=圧縮なし、0=高圧縮。
- image : char[] quality<0の場合はRGBの生データ、それ以外はJPEGエンコードされたデータ
- force : ForceMeasurement[] (強制計測
- name : 文字列
- value : double [N].
- force3d : Force3DMeasurement[].
- name : 文字列
- value : double[3] [N], X軸, Y軸, Z軸
- gyro : ジャイロ計測値[].
- name : 文字列
- 値 : double[3] [rad/s], X軸, Y軸, Z軸
- position_sensor : 位置センサー計測値[] : string
- name : 文字列
- value : double [rad] or [m]
シミュレータから送信されるすべてのメッセージの前には、それに続くメッセージのサイズが表示されます。このサイズは4バイト上に格納されており、ntohl(uint32_t)で読み取ることができます。
各チームの通信速度は350MB/sに制限されています。このバンドウィズは,チームの設定ファイルで定義されたN台のロボットに均等に分配される.したがって,各ロボット制御ソフトは,350/N MB/sの帯域を個別に持つことになる.ロボットがその予算を超えた場合(1秒単位の履歴)、パケットは破棄されます。
メッセージの送信
各ロボットは、各シミュレーション・ステップにおいて、以下のタイプのコマンド・リストを含む1つのメッセージを送信することができる。
-
motor_positions : MotorPosition[] (モーターポジション)
-
name : 文字列
-
position : double [m] or [rad].
-
motor_velocity : MotorVelocity[] (モーターベロシティ)
-
name : 文字列
-
速度:2倍[m/s]または[rad/s]
-
motor_force : MotorForce[] (モーターフォース
-
name : 文字列
-
force : double [N] (力)
-
motor_torque : MotorTorque[] (モータートルク)
-
name : 文字列
-
トルク : 2倍 [N.m]
-
motor_pid : MotorPID[] ドキュメント参照
-
name : 文字列
-
PID : double[3] [P,I,D] コントローラの値
-
sensor_time_step : SensorTimeStep[] 参照
-
name : 文字列
-
timeStep : int 2つの測定値の間の時間[ms]、0の場合はセンサーを無効にする
-
要求がセンサーの最小タイムステップより低い場合(0ではない)、最小タイムステップが使用されます。
-
要求された timeStep は、常に minControlStep の倍数でなければならない。
-
注:カメラセンサーの場合。
- カメラの解像度を動的に変更することはできませんが、ゲーム中に同じ位置にあるカメラを有効にしたり無効にしたりして、固定の解像度間で変更することは可能です。同じ位置、同じ向きで同じ視野に配置されたカメラは、ゲームの法則上、別のカメラとしては扱われません。
- camera_quality : CameraQuality[] UNUSED:今年はRAW画像のみ対応しています。
- name : 文字列
- quality : int -1 = 生画像, 100 = 圧縮なし, 0 = 高圧縮.
- camera_exposure : CameraExposure[] (カメラエクスポージャー
- name : string
- exposure : float unit: J/mˆ2].
ロボット制御ソフトウェアが送信する全てのメッセージは、ネットワークのバイトオーダーで4バイトに格納された次のメッセージのサイズを前置する必要があります。これは htonl(uint32_t)で取得できます。
センサーの有効化と無効化
初期状態では、すべてのセンサーが無効になっています。センサーからのデータを受信するためには、ロボット制御ソフトウェアが、データを更新するためのタイムステップを明示的に設定する必要がある(sensor_time_step参照)。新しいデータを受信するために、センサーのtimeStepを繰り返し設定する必要はない。一旦設定されたデータは、要求された更新頻度で自動的にロボット制御ソフトウェアに送信される。起動したセンサーを無効にするには、timeStepを0にするように要求することで実現できる。
付録
jsonの設定例
{
"name": "teamA",
"players": {
"1": {
"robotModelName": "robotA",
"dockerTag": "robotA",
"dockerCmd": "launchRobot.sh --goalkeeper",
"halfTimeStartingPose": {
"translation": [-3.5, -3.06, 0.24],
"rotation": [0, 0, 1, 1.57]
},
"reentryStartingPose": {
"translation": [-3, -3.11, 0.24],
"rotation": [0.0, 0, 1, 1.57]
},
"shootoutStartingPose": {
"translation": [2.6, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
"goalKeeperStartingPose": {
"translation": [-4.47, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
},
"2": {
"robotModelName": "robotA",
"dockerTag": "robotA",
"dockerCmd": "launchRobot.sh --fieldPlayer",
"halfTimeStartingPose": {
"translation": [-3.5, 3.06, 0.24],
"rotation": [0, 0, 1, -1.57]
},
"reentryStartingPose": {
"translation": [-3, -3.11, 0.24],
"rotation": [0.0, 0, 1, 1.57]
},
"shootoutStartingPose": {
"translation": [2.6, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
"goalKeeperStartingPose": {
"translation": [-4.47, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
},
"3": {
"robotModelName": "robotB",
"dockerTag": "robotB",
"dockerCmd": "launchRobot.sh --fieldPlayer",
"halfTimeStartingPose": {
"translation": [-0.75, -3.06, 0.24],
"rotation": [0, 0, 1, 1.57]
},
"reentryStartingPose": {
"translation": [-3, -3.11, 0.24],
"rotation": [0.0, 0, 1, 1.57]
},
"shootoutStartingPose": {
"translation": [2.6, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
"goalKeeperStartingPose": {
"translation": [-4.47, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
},
"4": {
"robotModelName": "robotB",
"dockerTag": "robotB",
"dockerCmd": "launchRobot.sh --fieldPlayer",
"halfTimeStartingPose": {
"translation": [-0.75, 3.06, 0.24],
"rotation": [0, 0, 1, -1.57]
},
"reentryStartingPose": {
"translation": [-3, -3.11, 0.24],
"rotation": [0.0, 0, 1, 1.57]
},
"shootoutStartingPose": {
"translation": [2.6, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
"goalKeeperStartingPose": {
"translation": [-4.47, 0, 0.24],
"rotation": [0, 0, 1, 0]
}
}
}
}