-
Notifications
You must be signed in to change notification settings - Fork 4
Robot Model Specifications v1.0 の和訳
このドキュメントは、バーチャル・ヒューマノイド・サッカー大会に出場するためのロボットモデルを作成する際の制約事項を示しています。今後、このドキュメントは、重大な問題が発生した場合にのみ更新されます。 もしあなたが、このプロセスを容易にするツールを開発したり、使用したりしているのであれば、遠慮なくTCと共有してください。本書に記載されていない要素(例:ロボットの足と地面の間の特定の接触特性)をチームが必要と感じた場合は,できるだけ早くTCに連絡して,その要求を検討する。
このドキュメントは,ロボットモデルに何が許されるかについての明確な仕様をチームに提供することを目的としていますが,同時に,モデルの書き方や他のチームから提供されたモデルのレビューについてもアドバイスしています。 大会で使用するロボットモデルは、プロトフォーマットで作成されなければなりません。このフォーマットでは、ヒューマノイドリーグで使用できるものよりも多様なセンサーを使用することができるため、このドキュメントでは追加の制約を提示します。 これらのルールの主な関心事と、これらの制約の理由は以下の通りです。
- 研究の観点から、本大会では、シミュレーション2リアルな実験による伝達学習のための環境を提供することを目的としています。
- リアルさを追求するために、ロボットの特性やデザインは、通常の競技会で使用されているロボットに類似している必要があります。
- 公平な競争のために、ノイズモデルやハードウェアの欠陥を考慮してロボットを正確にモデル化しようとするチームが、他のチームに対してペナルティを受けないようにします。
- 自動審判を使うと、ロボットのモデルにいくつかの制約が加わります。 - シミュレーションに使用できるリソースが限られているため,ロボットのアーキテクチャやメッシュの精度に制限が必要になる場合があります.
チームは、複数のロボットモデルをアップロードして、異なるロボットでプレイすることができます。KidSizeでは、最大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)を使用してセンサーの応答を指定します。この情報は、各センサーの制限(最小および最大)とノイズプロファイルを指定するためにも使用されます。このテーブルは、モデル化するセンサーのハードウェア仕様に従って常に設定する必要があります。次のセンサーのリストは、ここに記載されている制限付きで許可されています。
- 位置センサー – センサーの解像度はハードウェアの仕様と一致している必要があります。たとえば、12ビットのロータリーエンコーダー(Dynamixelなど)の分解能は2π212≈0.0015です。
- 加速度計 – LUTを指定する必要があります
- ジャイロ – LUTを指定する必要があります
- タッチセンサー – 許可されている3つの異なるオプションは、バンパー、フォース、フォース-3dです。 –シミュレーションでの力の計算は本質的にノイズが多いため、これらのセンサー用に余分なノイズをモデル化する必要はありません。
- カメラ – チームがカメラを介して作成できる生データの最大量は100MB/秒(メガバイト/秒)チームごと(生のRGB画像に基づく)に設定されています。この要件により、画像のレンダリングによってシミュレーションが遅くならないことが保証されます。 4台のロボットを使用した有効な構成の例は、27FPSで640 * 480の画像を使用することです。
∗注:この制限は、グローバルネットワークの制限を超えています。したがって、この帯域幅をすべて使用するには、WebotsAPIにまだ実装されていないネットワークで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 = stallTorque
maxVelocity = maxVelocity
残りの2つのパラメータを生成するために、モーターのNTカーブを使用します。簡単にするために直線的であると仮定します。ダンピング定数は、NT-カーブの傾きの負の値です。これを計算するには、曲線の端点を読み取って、その傾きを計算します。
静的摩擦は、NT曲線とX軸との交点で計算され、有効トルクが得られます。すると
staticFriction = stallTorque - effectiveTorque
複数の動作電圧があるが、そのうちの1つにしかNTカーブがない場合(Dynamixelモータの場合)、値はそれに応じてスケールアップされます。
ここでは、MX28のデータシートを見ながら、全体の流れを説明します。
At 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を求めるために、負の傾きを計算します。
dampingConstant = -((Point2.y - Point1.y) / (Point2.x - Point1.x)) = -((1.26 - 5.13)/ (1.288 - 0.112)) = 3.29
静摩擦を求めるために、effectiveTorqueは以下のように計算されます。
effectiveTorque = -(Point1.y / (-dampingConstant)) - Point1.x = -(5.13 / -3.29) - 0.112 = 1.67
staticFriction = stallTorque - e˙ectiveTorque = 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]" )。
また、一部の関節(モーター)には、以下の接尾語を付けてください。
- [shoulder]:腕の第一関節の軸(例:名前 "right shoulder pitch [shoulder]")
- [hip]:足の第一関節の軸が接地面と平行になっているもの(例:名前 "left hip roll [hip]")
プロトの書き方に関する一般的なガイドラインは、サイバーボティクスのドキュメントを参照してください。
DEF/USEメカニズムの使用や、プロトを複数のサブファイルに分割することが推奨されます(特にビジュアルモデルや複雑なコリジョンモデルはそれぞれのファイルに)。
既にロボットの URDF をお持ちの場合は、urdf2webots を使用すると良いスタートラインに立てると思いますが、手動での調整が必要になるでしょう。
シミュレーションは合理的なリアルタイムファクターで実行されなければならないため、衝突モデル(例:boundingObject)は幾何学的なプリミティブ(ボックス、カプセル、シリンダー、スフィア)から構築されなければなりません。
これらの衝突モデルを手動で作成するには、onshape-to-robots の純粋な形状近似に基づいたツールをお勧めします。
すでにロボットのURDFモデルを使用している場合は、simplify_urdf_collisionツールを使用して、回転したバウンディングボックスを生成することができます。
ビジュアルモデルの複雑さ(三角形の数)は、コリジョンモデルの複雑さに比べてそれほど問題ではありませんが、それでも適度に低く設定する必要があります(例:総頂点数が50,000以下)。
CADソフトウェアからモデルをエクスポートする際には、通常、メッシュ近似の解像度を設定することができます。メッシュモデルしかない場合は、MeshlabのQuadratic Edge Collapse Decimationのようなソフトウェアを使用することができます。
実物のロボットに合わせて、アピアランスやPBRAppearanceを適用することをお勧めします。ここでは、サイバーボティクス社が提供するいくつかのアピアランスを紹介します。
モデルの検査は、以下の要素に基づいて行われます。
- PROTOモデルの内容と関連ファイル。
- アクチュエーターとセンサーの異なる特性をどのようにして得たかを説明した文書。
- postures.jsonファイル。
検査は、3つのディバイスに基づいて行われます。
- 半自動検証:幾何学的なプロポーションを自動的にチェックし、各ロボットの主な特徴をまとめたものを提供する。
- 査読付き検証:提供されたプロトファイルが、自動的にチェックできない一部の要素について、ルールを尊重しているかどうかを手動でチェックする。
- TC検証:チームから提起された問題点を手動で検証し、提出資料の追加チェックを行います。
ロボットの以下のプロパティが自動的に抽出されます。
- Htopです。直立姿勢時、z成分に沿った振幅。
- Hleg 直立姿勢時,[hip]とロボットのz軸方向の最小値との間のz成分。
- Hhead 直立姿勢において,[shoulder]から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
- 幾何学的なプリミティブのみをコリジョンモデルとして使用
- ビジュアルモデルの複雑さ
ロボットモデルから以下の情報を含むドキュメントが生成されます。
- 自動的に抽出されたロボットモデルのプロパティのリスト
- 各セクションで指定されたすべてのパラメータを持つすべてのジョイントのリスト
- センサーのリストとそのパラメータ
- ロボットの運動学的構造
レビューの過程で検証すべき点は以下の通りです。
- カスタムアクチュエーターの仕様は有効ですか?
- センサーの仕様は妥当か?
- ソリッド([足]、[腕])やリンク([肩]、[腰])のアノテーションはルールに合致していますか?
- 衝突モデルはロボットの構造に適合していますか?
- カラーマーカーの大きさ、色、位置は適切ですか?
- 直立姿勢は有効ですか?
- 伸展姿勢は有効ですか?
- その他、このモデルを採用すべきでない理由はありますか?
注:以下の資料は、5月23日に提出する2回目の提出物にのみ必要です。
シミュレーションの妥当な性能を確保するために,チームは歩行動作を行う単純なDockerイメージをアップロードする必要があります.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に使用できるパラメータのリストを以下に示します。
MX28-torque-12V 2.50
MX28-vel-12V 5.76
MX28-damping-12V 3.29
MX28-friction-12V 0.83
MX28-torque-14.8V 3.10
MX28-vel-14.8V 7.02
MX28-damping-14.8V 3.24
MX28-friction-14.8V 1.03
MX64-torque-12V 6.00
MX64-vel-12V 6.60
MX64-damping-12V 1.51
MX64-friction-12V 1.42
MX64-torque-14.8V 7.30
MX64-vel-14.8V 8.17
MX64-damping-14.8V 1.54
MX64-friction-14.8V 1.73
MX106-torque-12V 8.40
MX106-vel-12V 4.71
MX106-damping-12V 0.79
MX106-friction-12V 2.14
MX106-torque-14.8V 10.00
MX106-vel-14.8V 5.76
MX106-damping-14.8V 0.81
MX106-friction-14.8V 2.55
XH540W270-torque-12V 10.60
XH540W270-vel-12V 3.14
XH540W270-damping-12V 0.34
XH540W270-friction-12V 1.23
XH540W270-torque-14.8V 12.90
XH540W270-vel-14.8V 3.87
XH540W270-damping-14.8V 0.34
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
a = (point_2.y - point_1.y) / (point_2.x - point_1.x)
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
self.print_value("torque", stall_torque, use_14_8V)
self.print_value("vel", vel, use_14_8V)
self.print_value("damping", -a, 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()