Skip to content
This repository has been archived by the owner on Aug 15, 2024. It is now read-only.

v hsc_model_specification_v1.02の翻訳

Yasuo Hayashibara edited this page May 18, 2021 · 5 revisions

ロボットモデル仕様書 v1.02

このドキュメントは、バーチャル・ヒューマノイド・サッカー大会に出場するためのロボットモデルを作成する際の制約事項を示したものです。今後、このドキュメントは、重大な問題が発生した場合にのみ更新されます。
もしあなたが、このプロセスを容易にするツールを開発したり、使用したりしているのであれば、遠慮なくTCと共有してください。もし、あなたのチームが、このドキュメントに記載されていない要素(例えば、ロボットの足と地面の間の特定の接触特性)を必要としていると感じた場合には、できるだけ早くTCに連絡してください。

はじめに

このドキュメントは,ロボットモデルに何が許されるかについての明確な仕様をチームに提供することを目的としているが,同時に,モデルの書き方や他のチームから提供されたモデルのレビュー方法についてもアドバイスしている。
大会で使用するロボットモデルは、プロトフォーマットで書かれています。このフォーマットでは、ヒューマノイドリーグで使用できるものよりも多様なセンサーを使用することができるため、このドキュメントでは追加の制約を提示します。
これらのルールの主な関心事と、これらの制約の理由は以下の通りです。

  • 研究の観点から、本大会では、シミュレーション2リアルな実験による伝達学習のための環境を提供することを目的としています。
  • リアルさを追求するために、ロボットの特性やデザインは、通常の競技会で使用されているロボットに類似している必要があります。
  • 公平な競争のために、ノイズモデルやハードウェアの欠陥を考慮してロボットを正確にモデル化しようとするチームが、他のチームに対してペナルティを受けないようにします。
  • 自動審判を使うと、ロボットのモデルにいくつかの制約が加わります。
  • シミュレーションに使えるリソースは限られているので,ロボットのアーキテクチャやメッシュの精度に制限が必要になることもあります.

チームは、複数のロボットモデルをアップロードして、異なるロボットでプレイすることができます。キッズサイズでは、最大4台の異なるロボットを使用することができます。大人サイズでは、最大で2台の異なるロボットが使用できます。
ロボットモデルの他に、例年のロボット仕様書に似た、より充実したドキュメントを提供する必要があります。このドキュメントには、ロボットに使用されているセンサー(モーター、加速度計、ジャイロスコープ、カメラなど)の関連データシートと、プロトのパラメータがどのようにデータシートから導き出されたかの説明が含まれていなければなりません。
カスタム開発されたハードウェアの場合は、どのようにして性能値を測定したのか、そのテスト手順を記述する必要があります。チームで実験を行った場合は、生データの共有が推奨されます。
Dynamixel Motor MX28, MX64, MX106, XH540-W270の値の例は付録に記載されていますが、チームは正当な理由としてハードウェアの適切なベンチマークを提供する場合、カスタム値を使用することができます。

モデルの制約

このセクションで明示的に言及されていないすべてのセンサーとアクチュエータのノードは、競技中に禁止されています。

エクスポートされたパラメータ

ロボットモデルは PROTO シンタックスでなければならないため,以下のフィールドを公開する必要がある.

• translation
• rotation
• name
• controllerArgs

公開されたフィールドはすべて,レフリーによって自動的に埋められます.他のパラメータを公開してもよいが、それらは無視される(例:デフォルト値に設定される)。 使用するモーターの種類ごとのパラメータなど、モデルの主要なパラメータを公開することが推奨されます。

PROTO MyRobot [
field SFVec3f translation 0 0 0
field SFRotation rotation 0 1 0 0
field SFString name ""
field MFString controllerArgs []
field SFFloat MX64-torque-12V 6.00
field SFFloat MX64-vel-12V 6.60
field SFFloat MX64-damping-12V 1.51
field SFFloat MX64-friction-12V 1.42
field SFFloat MX106-torque-12V 8.40
field SFFloat MX106-vel-12V 4.71
field SFFloat MX106-damping-12V 0.79
field SFFloat MX106-friction-12V 2.14
]{
Robot {
translation IS translation
rotation IS rotation
name IS name
controllerArgs IS controllerArgs
...
}
}

サイバーボティクス社が提供するREADMEに記載されているように、名前のフィールドを解析し、ロボットがそれに適応してチームカラーや選手番号を表示するようにしてください。

if fields.name.value ~= '' then
-- name is supposed to be something like "red player 2" or "blue player 1"
local words = {}
for word in fields.name.value:gmatch("%w+") do table.insert(words, word) end
local color = words[1]
local number = words[3]

そして、PROTOファイルが要求された色とプレーヤー番号を表示するために、色と番号の変数を使用する必要があります。これは、これらの変数からテクスチャ名を作成したり、マテリアルの色の割り当てや形状の作成などに直接使用することで実現できます。
最後に、すべてのモデルで selfCollision を有効にしてください。

センサー

いくつかのセンサーでは、ルックアップテーブル(LUT)を使ってセンサーの応答を指定します。この情報は、各センサーの限界値(最小値と最大値)とノイズプロファイルの指定にも使用されます。このテーブルは、モデリングするセンサーのハードウェア仕様に応じて常に設定する必要があります。
以下のセンサーのリストは、ここで述べた制限付きで許可されています。

  • ポジションセンサー

  • センサーの解像度は、ハードウェアの仕様に合わせる必要があります。例えば、Dynamixelのような12ビットのロータリーエンコーダは、2212ˇ0.0015の分解能を持っています。

  • 加速度センサ

  • LUTを指定する必要があります。

  • ジャイロ

  • LUTが指定されていること

  • タッチセンサー

  • Bumper、Force、Force-3dの3種類のオプションがあります。

  • シミュレーションでの力の計算は本質的にノイズが多いため、これらのセンサーについては余分なノイズをモデル化する必要はありません。

  • カメラ

  • チームがカメラで作成できる生データの最大量は、チームあたり100MB/s(メガバイト/秒)に設定されています(RGBの生画像を基準としています)。これは、画像のレンダリングによってシミュレーションの速度が低下しないようにするためです。4台のロボットを使用する場合、640*480の画像を27FPSで使用するのが有効な設定例です。

  • 注意:この制限はグローバルネットワークの制限を超えています。したがって、この帯域幅をすべて使用するためには、Webots APIにはまだ実装されていないJPEG圧縮をネットワーク上で使用する必要があります。

注意:加速度センサーとジャイロセンサーについては、シミュレーターの中でゆっくりとドリフトさせるオ˙セットが追加されます。これは、これらのセンサーが温度などのパラメータに非常に敏感であることをモデル化したものです。ただし、これらのパラメータはPROTOファイルではアクセスできません。

アクチュエータ

アクティブジョイントは、2つの異なる方法で実装することができます。

  • HingeJointWithBacklashは、次のような子機を用いて角度のあるアーティキュレーションを行います。
  • A RotationalMotor
  • バックラッシュは実際のハードウェアに合わせて設定します。
  • パラメータmaxTorqueとmaxVelocityは、以下の詳細な手順に従って設定されます。
  • jointParametersは、実際のハードウェアのパラメータに合わせて設定します。
  • springConstant:PEA(Parallel Elastic Actuator)を搭載している場合、PEAに合わせたバネ力を指定することができます。
  • dampingConstantとstaticFrictionのパラメータは、以下の詳細な手順に従って設定します。
  • Hinge2JointWithBacklashは、2軸の角度のあるアーティキュレーションのためのものです。Hinge2JointWithBacklashは、シミュレーションを高速化するため、可能であればこの方法が望ましいです。
  • パラメータはHingeJointと同じですが、各モーターに対して個別に設定する必要があります。
  • 直線的なアーティキュレーション用のSliderJointは、以下の子を持ちます。
  • リニアモーターで、フィールドのmaxForceをハードウェアの仕様に合わせた値に設定します。
  • JointParametersは、HingeJointのジョイントパラメータと同様に設定します。

どちらのタイプのジョイントも、以下の子を持つ必要があります。

前節の制約条件に合致する位置センサー

アクチュエーターとジョイントのパラメーター

以下のパラメータは、モーターの仕様から導き出す必要があります。- maxTorque - maxVelocity - dampingConstant - staticFriction
maxTorque - maxVelocity - dampingConstant - staticFriction データシートからこれらの値を求めるには、以下の手順を踏む必要があります。
maxTorque = stallTorque
maxTorque = stallTorque maxVelocity = maxVelocity
残りの2つのパラメータを生成するために、モーターのNTカーブを使用します。簡略化のため、直線的であると仮定しています。ダンピング定数は、NT-カーブの傾きの負の値です。これを計算するには、曲線の端点を読み取り、その傾きを算出します。
静的摩擦は、NT曲線とx軸の交点を介して計算され、e˙ectiveTorqueが得られます。静摩擦 = ストールトルク - 効果的トルク
複数の動作電圧が利用可能で、そのうちの1つにしかNTカーブがない場合(Dynamixelモータの場合)、値はそれに応じてスケールアップされます。
この手順を説明するために、MX28のデータシートを見てみましょう。
12Vの場合: - maxTorque = stallTorque = 2.5 Nm - maxVelocity = maxVelocity = 55 rev/min = 5.76 rad/s
NT曲線の2つの終点を、Point1 = (0.112 Nm, 49 rev/min = 5.13 rad/s)、Point2 = (1.288 Nm, 12 rev/min = 1.26 rad/s)と読み取る。dampingConstantを得るためには、負の傾きを計算します(軸を反転させた場合)。

vel_diff = (Point2.y - Point1.y) torque_diff = (Point2.x - Point1.x)
dampingConstant = -(torque_di˙ / vel_di˙) = -((1.288 - 0.112) / (1.26 - 5.13)) = 0.30
静的摩擦を求めるために、NT曲線とy軸の交点としてeffectiveTorqueを計算する:effectiveTorque = -(Point1.y / (vel_diff /torque_diff )) - Point1.x = 1.67
静摩擦 = 失速トルク - 有効トルク = 2.5 - 1.67 = 0.83
12V以外の電圧を使用した場合、グラフに表示されるポイントは、X軸方向にトルクスケーリングファクター、Y軸方向に速度スケーリングファクターでスケーリングされます。
velocityScalingFactor = maxVelocityAt14_8V / maxVelocityAt12V
torqueScalingFactor = maxTorqueAt14_8V / maxTorqueAt12V
PROTOファイルの作成を容易にするために、2つの要素が付録として用意されています。

  • 古典的なダイナミクセルモータのパラメータを計算したもの。
  • お手持ちのモータのデータシートからこれらの値を簡単に計算できるスクリプト。

ロボットの構造

チームは、postures.jsonという名前の専用ファイルに、使用する構成を記述します。

  • 直立姿勢(膝を伸ばしきった状態)の場合
  • 最長伸展姿勢

ファイルのフォーマットは以下の通りです(単位はrad)。

{
"robot_name" : "MyRobotName",
"upright" : {
"motor_1_name": 0.123,
"motor_2_name": 0.456,
...
},
"extension": {
"motor_1_name": 0.123,
"motor_2_name": 0.456,
...
}
}

各ロボットはSolid名に以下のアノテーションをつけてボディパーツを合成する必要があります。

  • [foot]: 歩行時に地面に接することができるすべてのボディ・パーツ (例: Solid.name "left foot [foot]")。
  • [arm]: 肩から手までのすべてのボディパーツ用。それらのパーツはボールに触れることはできません(例:Solid.name "left elbow [arm]")。
    [hand]: 各ロボットは、手として宣言された2つのソリッドを持たなければなりません。それらのソリッドの質量や体積は非常に小さいかもしれませんが、ソリッドの中心は腕の先端にあるべきです。これらのアノテーションは、ロボットの凸包を計算するために使用されます。

いくつかのジョイント(モーターなど)には、以下のような注釈をつける必要があります。

  • [shoulder]: 腕の第一関節の軸(例:名前 right shoulder pitch [shoulder]」)。
  • [hip]: 軸が接地面に平行な脚の第一関節の場合(例:名前 left hip roll [hip]」)。

関節のアノテーションは、以下のように、デバイスの名前フィールドで行う必要があります。

HingeJointWithBacklash{
jointParameters HingeJointParameters {
...
}
device [
RotationalMotor {
name "LeftHipRoll [hip]"
...
}
PositionSensor {
...
}
]
}

モデルの書き方のガイドライン

プロトの書き方に関する一般的なガイドラインは、サイバーボティクスのドキュメントを参照してください。
DEF/USEメカニズムの使用や、プロトを複数のサブファイルに分割することが推奨されます(特にビジュアルモデルや複雑なコリジョンモデルはそれぞれのファイルに)。
すでにロボットのURDFを持っている場合は,urdf2webotsを使うとよい出発点となるが,おそらく手動での調整が必要となる.
ロボットモデルを他のチームや一般の人が利用できるようにすることに同意する場合は、PROTOファイルの上にライセンスを追加することをお勧めします。

衝突モデルの複雑さ

シミュレーションは合理的なリアルタイムファクターで実行されなければならないため、衝突モデル(例:boundingObject)は幾何学的なプリミティブ(ボックス、カプセル、シリンダー、スフィア)から構築されるべきです。もしロボットが足の下にクリートを使用している場合は、シリンダーではなくカプセルや球を使ってモデル化する必要があります。これにより、芝生とクリートの接触を計算する際の複雑さが軽減されます。
これらの衝突モデルを手動で作成するには,onshape-to-robots の純粋な形状近似をベースにしたツールをお勧めします.
すでにロボットのURDFモデルを使用している場合は、simplify_urdf_collisionツールを使用して回転したバウンディングボックスを生成することができます。

ビジュアルモデル

ビジュアルモデルの複雑さ(三角形の数)は、コリジョンモデルの複雑さに比べてそれほど問題ではありませんが、それでも適度に低く設定する必要があります(例:総頂点数が50,000以下)。
CADソフトウェアからモデルをエクスポートする際には、通常、メッシュ近似の解像度を設定することができます。メッシュモデルしかない場合は、MeshlabのQuadratic Edge Collapse Decimationのようなソフトウェアを使用することができます。
実物のロボットに合わせて、アピアランスやPBRAppearanceを適用することをお勧めします。ここでは、サイバーボティクス社が提供するいくつかのアピアランスを紹介します。

モデルの検査

モデルの検査は、以下の要素に基づいて行われます。

  • PROTO モデルと関連ファイルの内容。
  • PROTOモデルの内容と関連ファイル アクチュエータとセンサーの異なる特性をどのようにして得たかを説明した文書。
  • postures.json ファイル。

検査は3つの異なる部分に基づいて行われます。

半自動検証: 幾何学的な比率を自動的にチェックし、各ロボットの主な特性の概要を提供します。

  • 査読付き検証:提供されたプロトファイルが、自動的にチェックできない一部の要素について、ルールを尊重しているかどうかを手動でチェックする。
  • TC検証:チームから提起された問題点を手動で検証し、提出資料を追加チェックします。

セミオートマチック・バリデーション

ロボットの以下の特性を自動的に抽出します。

  • Htop: Htop:直立姿勢時のz成分に沿った振動の振幅。
  • Hleg: 直立姿勢時、[hip]からロボットのz軸方向の最小値までのz成分。
  • Hhead 直立姿勢時、[肩]からz軸方向のロボットの最大値までのz成分。
  • M:ロボットの総質量。
  • Hcom 直立姿勢時、質量中心の高さ。
  • BMI = M/Htopˆ2
  • 幅:直立姿勢時、ロボットが収まる最小の円筒の直径。
  • 足幅、足長 片足のバウンディングボックスのy(レスペクトx)軸方向のサイズ
  • MaxLength: 最長伸展姿勢におけるロボットの2点間の最大距離。

以下の制約条件は自動的にチェックされます。

  • 5 <= bmi <= 30
  • (足幅足高さ)<= (2.2Hcom)ˆ2/32
  • 1.2 <= 最大(足幅,足高)/最小(足幅,足高)<= 3.5
  • 幅 <= 0.55 Htop
  • 0.35 Htop <= Hleg <= 0.7 Htop
  • 0.1 Htop <= Hhead <= 0.3 Htop
  • 許可されたセンサー/アクチュエーターのみが使用されている
  • すべての必須フィールドが設定されている(例:LUT
  • 衝突モデルには幾何学的なプリミティブのみを使用
  • ビジュアルモデルの複雑さ

ロボットモデルから以下の情報を含むドキュメントが生成されます.

  • 自動抽出されたロボットモデルのプロパティのリスト
  • 各セクションで指定されたすべてのパラメータを持つすべての関節のリスト
  • センサのリストとそのパラメータ
  • ロボットの運動学的構造

査読付き検証

レビューの過程で検証すべき点は以下の通りです。

  • カスタムアクチュエーターの仕様は妥当か?
  • センサーの仕様は正しいか?
  • ソリッド([足]と[腕])とリンク([肩]と[腰])のアノテーションはルールに合致しているか?
  • 衝突モデルはロボットの構造に適合していますか?
  • カラーマーカーの大きさ、色、位置は適切ですか?
  • 直立姿勢は有効ですか?
  • 伸展姿勢は有効ですか?
  • その他、このモデルを採用すべきでない理由はありますか?

TCの検証

シミュレーションの妥当な性能を確保するために、チームは歩行動作のあるシンプルなDockerイメージをアップロードすることが求められる。コントローラは、ロボットコントローラAPIを介して、フィールド上の仮想ロボットモデルに接続する必要があります。接続が確立されるとすぐに、コントローラはロボットにコマンドを送り、少なくとも1分間歩かせる必要があります。ロボットは、フィールド上の境界線の範囲内であれば、どの方向にでも歩くことができます。

歩くことができます。ロボットの挙動から歩行動作を行うための合理的な試みが想定される場合には、ロボットが倒れていても提供されたコントローラは有効とみなされます。 dockerイメージは、第2回目の審査締切日までに、技術委員会が用意したコンテナレジストリにアップロードする必要があります。チームリーダーには、第2回目の審査締切日の数日前に、レジストリへのアクセストークンと指示がメールで送られます。

ロボットのコントローラとそれに対応する動作は、ベンチマークの目的で使用されます。提供されたロボットモデルを使用して,競技に使用されるハードウェア上で,2つのフルチーム(KidSizeでは4台,AdultSizeでは2台のロボット)を,技術委員会が提供するリアルタイムファクターでシミュレーションできる必要があります.ロボットが複雑すぎる場合は、シミュレーションの複雑さを軽減するための適切な対策を講じるようチームに連絡します。

また、KidSize チームは、ロボットが正常に立ち上がる動作をしている様子を撮影した YouTube の動画へのリンクを提供するよう求められます。 2回目のレビューセッションの後、チームがモデルファイルの更新を要求した場合、技術委員会はケースバイケースでその修正を検討します。5月23日以降に行われる変更は、変更を要求するチームによって適切に正当化される必要があります。

アップロード形式

チームのすべてのロボットモデルは、.zip形式のアーカイブで提出する必要があります。 フォルダの構造は以下のようにしてください。

.
|-- documentation
| |-- documentation.pdf
| |-- datasheet1.pdf
| |-- ...
|-- RobotName1
| |-- RobotName1.proto
| |-- postures.json
| |-- ...
|-- RobotName2
| |-- RobotName2.proto
| |-- postures.json
| |-- ...

... は、オプションで追加されるデータシートやドキュメントを documentation フォルダに、ロボットモデルに要求されるその他のファイルを robot フォルダに入れます。提出物には,KidSizeでは最大4台,AdultSizeでは最大2台のロボットモデルを含めることができます。

付録

古典的なダイナミクロスモーターの値

TCではDynamixel motorに使用できるパラメータの一覧を以下に示します。

Appendix
Values for classical dynamixel motors
The TC provides the following list of parameters that can be used for Dynamixel motors:
MX28-torque-12V 2.50
MX28-vel-12V 5.76
MX28-damping-12V 0.30
MX28-friction-12V 0.83
MX28-torque-14.8V 3.10
MX28-vel-14.8V 7.02
MX28-damping-14.8V 0.31
MX28-friction-14.8V 1.03
MX64-torque-12V 6.00
MX64-vel-12V 6.60
MX64-damping-12V 0.66
MX64-friction-12V 1.42
MX64-torque-14.8V 7.30
MX64-vel-14.8V 8.17
MX64-damping-14.8V 0.65
MX64-friction-14.8V 1.73
MX106-torque-12V 8.40
MX106-vel-12V 4.71
MX106-damping-12V 1.26
MX106-friction-12V 2.14
MX106-torque-14.8V 10.00
MX106-vel-14.8V 5.76
MX106-damping-14.8V 1.23
MX106-friction-14.8V 2.55
XH540W270-torque-12V 10.60
XH540W270-vel-12V 3.14
XH540W270-damping-12V 2.95
XH540W270-friction-12V 1.23
XH540W270-torque-14.8V 12.90
XH540W270-vel-14.8V 3.87
XH540W270-damping-14.8V 2.92
XH540W270-friction-14.8V 1.49

モーターパラメータを近似するスクリプト

他のモーターのモーターパラメータを近似する必要がある場合、このスクリプトを再利用してその値を計算することができます。

import math
VAR_LENGTH = 30
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
class JointSpecs:
def __init__(self, name, max_tor_12V, max_tor_14_8V, max_vel_12V_rpm, max_vel_14_8V_rpm,
NT_curve_point_1, NT_curve_point_2):
self.name = name
self.max_tor_12V = max_tor_12V
self.max_tor_14_8V = max_tor_14_8V
self.max_vel_12V_rpm = max_vel_12V_rpm
self.max_vel_14_8V_rpm = max_vel_14_8V_rpm
self.NT_curve_point_1_12V = NT_curve_point_1
self.NT_curve_point_2_12V = NT_curve_point_2
# convert to rad/s
self.max_vel_12V = self.max_vel_12V_rpm * math.tau / 60
self.max_vel_14_8V = self.max_vel_14_8V_rpm * math.tau / 60
self.NT_curve_point_1_12V.y = self.NT_curve_point_1_12V.y * math.tau / 60
self.NT_curve_point_2_12V.y = self.NT_curve_point_2_12V.y * math.tau / 60
# scale N-T points from 12V to 14_8V
self.scale_factor_tor = self.max_tor_14_8V / self.max_tor_12V
self.scale_factor_vel = self.max_vel_14_8V / self.max_vel_12V
self.NT_curve_point_1_14_8V = Point(
self.NT_curve_point_1_12V.x * self.scale_factor_tor,
self.NT_curve_point_1_12V.y * self.scale_factor_vel)
self.NT_curve_point_2_14_8V = Point(
self.NT_curve_point_2_12V.x * self.scale_factor_tor,
self.NT_curve_point_2_12V.y * self.scale_factor_vel)
def get_values(self, use_14_8V):
# choose correct values based on voltage
if use_14_8V:
stall_torque = self.max_tor_14_8V
vel = self.max_vel_14_8V
point_1 = self.NT_curve_point_1_14_8V
point_2 = self.NT_curve_point_2_14_8V
else:
stall_torque = self.max_tor_12V
vel = self.max_vel_12V
point_1 = self.NT_curve_point_1_12V
point_2 = self.NT_curve_point_2_12V
vel_diff = (point_2.y - point_1.y)
torque_diff = (point_2.x - point_1.x)
a = vel_diff / torque_diff
b = point_1.y - (point_1.x * a)
# compute torque at vel=0
# 0 = a*x+b -> x = -b / a
torque_vel0 = -b / a
friction = stall_torque - torque_vel0
damping_constant = -torque_diff / vel_diff
self.print_value("torque", stall_torque, use_14_8V)
self.print_value("vel", vel, use_14_8V)
self.print_value("damping", damping_constant, use_14_8V)
self.print_value("friction", friction, use_14_8V)
print("")
def print_value(self, property_name, value, use_14_8V):
v_text = "14.8V" if use_14_8V else "12V"
var_name = (f"{self.name}-{property_name}-{v_text}").ljust(VAR_LENGTH)
print(f"{var_name}{value:5.2f}")
def print_all_values(self):
self.get_values(False)
self.get_values(True)
# max_tor_12V, max_tor_14_8V, max_vel_12V_rpm, max_vel_14_8V_rpm, NT_curve_point_1, NT_curve_point_2
JointSpecs("MX28", 2.5, 3.1, 55, 67, Point(0.112, 49),
Point(1.288, 12)).print_all_values()
JointSpecs("MX64", 6.0, 7.3, 63, 78, Point(0.15, 64),
Point(2.85, 25)).print_all_values()
JointSpecs("MX106", 8.4, 10, 45, 55, Point(0.7, 42),
Point(5.6, 5)).print_all_values()
JointSpecs("XH540W270", 10.6, 12.9, 30, 37, Point(0.4, 29),
Point(8.6, 2.5)).print_all_values()