概要
ロボットシミュレータのWebotsで,みんな大好きTrack(履帯,いわゆるキャタピラ)を使うロボットを作ろうとしたところ,
参考文献がほぼ英語の公式ドキュメントしかなく,わからん過ぎて苦労しました.ので,備忘録を兼ねて記事にまとめます.
※公式ドキュメント等
Track - Webots Reference Manual
TrackWheel - Webots Reference Manual
track.wbt - cyberbotics/webots github
この記事では,以下のような簡単な仕様のTrack付きロボットを作ることをゴールとします.
- 直方体の本体と,二つのTrack(履帯)からなるロボットを作る
- ロボットの持つTrackは,同じ大きさのTrackWheelを二つと,LinearMotorを持つ
- Geometries Animationを使って履帯の動きを表現する
なお,本記事作成で用いた環境は以下のものです.
- Windows 10
- Webots R2021a
- Controllerの実装: C++
- ノートPC(ThinkPad X13 Gen1, AMD RYZEN Pro 7, 16GB RAM)
作業手順
ワールドの作成
今回は履帯付きのロボットを走らせることが目的なので,ワールドはウィザードを使ってサクッと作ってしまいます.
Webots上部メニューのWizards
> New Project Directory...
から,ある程度の環境がそろったワールドを手軽に作成できます.
名称以外基本デフォルトで大丈夫ですが,途中チェック項目が並ぶところで Add a rectangle arena
にチェックを入れると最初から床面が生成されてさらに楽です.
プロジェクトを作成すると,図のように床面のある環境が表示されます.
筐体の作成
本体の作成
履帯の動きを見たいので,本体は適当に作ります.
- Webots左側のメニュー(Scene Tree)内の適当な項目をクリックしてScene Treeを選択する.
- 右クリック >
Add new...
でBase Nodes
>Robot
を選択し,ロボットノードを追加. - ちょっと持ち上げていたいので,Robotの
transition
を(0, 0.05, 0)
に指定 - 作成したRobotのchildreをダブルクリックし,Shapeを指定して追加
- 当たり判定のboundingObjectをShapeと同じにしたいので,Shapeをクリックして表示される
DEF
入力欄に任意の名前を入れ,Shapeに名前を付ける.
(本記事ではDEF
を"BOX
"に指定します) - ShapeのgeometryをダブルクリックしてBox型を指定する.本記事では大きさを
(0.2, 0.05, 0.1)
とした. - (オプショナル)さすがにさみしいので見た目をマシにするために立体表面の描画情報を追加する.
ShapeのappearanceをダブルクリックしてAppearance
を指定 →Appearance
のmaterial
をダブルクリックしてMaterial
を指定 - Robotの
boundingObject
をダブルクリックしUSE
> Shapeにつけた名前(ここではBOX
)を指定し,当たり判定を付加する - Robotのphysicsをダブルクリックし,Physicsを指定する
ここまで同じ手順を行うと,下図のように少しだけ宙に浮いたボックスが表示されます.
また,この状態を保存したうえでシミュレーションを実行すると,箱が落下して床の上に落ちる様子が見られます.
履帯の作成
履帯をくっつける本体ができたので,次は履帯を作ります.
Robotのchildrenを右クリックしてAdd new
を押し, Base nodes
> Track
を追加します.
これだけでは何も表示されないので,適切なパーツを追加していきます.
TrackWheel
の追加
TrackWheel
は履帯の内外に設置され,ベルトを動かしたり形作ったりする車輪です.
実際の履帯ではその役割によって駆動輪や転輪など複数種類があるのですが,Webotsではこれらの区別はなくすべてTrackWheel
として扱われます.
今回は先述のとおり,二つのTrackWheel
を一つの履帯の中で使用します.
- Trackのchildrenをダブルクリックし,
BaseNode
>TrackWheel
を追加します. -
TrackWheel
のposition
を(0.1, 0)
に(Track
の制約上TrackWheel
は二方向にしか位置調整できません),radius
を0.03
に指定します. - このままだと
TrackWheel
は何も描画されないので,その位置や回転がわかるようにします.
TrackWheel
は見た目によらず円柱の車輪系になるため,見た目は回転していることがわかりやすいようbox
を指定します.
TankWheel
のchildren
にShape
を追加し,geometry
を(0.035, 0.035, 0.03)
サイズのBox
にしますappearance
も同様にApparance
>Material
まで指定します. -
TrackWheel
を複製します.コピーし,Track
のchildren
にペーストします. - 二つある
TrackWheel
のうちどちらかのTransition
を(-0.1, 0)
に指定し,筐体後部に移します.
ここまでできると,下図のようによくわからない状態になっているはずです.
ベルトの追加
Webotsに用意されるGeometry Animationを使えば,配置したTrackWheel
間をつなぐように設置され,回転するベルトを簡単に作ることができます.
-
Track
のanimatedGeometry
に,ベルトとしてTrackWheel
を取り囲む図形を指定します.ここでは,geometry
に(0.02, 0.003, 0.03)
サイズのbox
を,appearance
にdiffuseColor
が(0.1, 0.1, 0.1)
のMaterial
を持つAppearance
を指定します. -
Track
のgeometriesCount
には,1.で指定した図形がいくつ用いられるかの数を思惟します.ここでは20
に指定します.
ここまで操作すると,下図のようになります.ベルトらしきものが描画され,それっぽくなってきました.
なお,このベルトの立体は見た目だけのものであり,実際の履帯の振る舞い・物理シミュレーション結果には関係ないことにご注意ください.
履帯の当たり判定を設定
地面に動力を伝える,当たり判定の部分を`boundingObjectとして追加し設定します.
履帯の形に合わせる必要はないのですが,今回はCylinder2つとBox1つを使い,履帯と同じ形のboundingObjectを作ります.
-
View
>Optional Rendering
>Show All Bounding Objects
を押し,boundingObjectsが見えるようにします. - Trackの
boundingObject
に,Group
を指定します. -
Group
のchildren
に,(0.2, 0.06, 0.03)
サイズのbox
を追加します. -
Group
のchildren
に,Transform
を追加し,transition
を(0.1, 0, 0)
に,rotation
を(1, 0, 0, -1.5708)
にします. -
Transform
のchildren
に,height
が0.03,radius
が0.03のCylinder
を追加します. -
Transform
を複製して,transition
を(-0.1, 0, 0)
にします.なお複製の際にCylinder
が消えてしまうので,これもコピペなどで追加します -
Track
のphysics
にPhysics
を指定します.
1.Track
を複製します.片方のtransition
を(0, 0, -0.05)
に,もう片方を(0, 0, 0.05)
にし,車体の両側に設置してやります.
ここまでやると,下図のようになるはずです.また保存してからシミュレーションを実行すると,履帯で接地する様子が見られます.
もう完成は目前です.
###挙動の設定
モータの回転を設定
あとは履帯が回転するようにしてやればおkです.
本当はもう1ステップありますが,とりあえずこれをやってやると本体が動くようになります.
- モータを追加します.
Track
のdevice
にLinearMotor
を指定し,name
に適当な名前を入れます.
これをもう片方の履帯にもやってやります.なお,name
はController作成時に使うので左右のモータで違う名前になる様にしてやってください.
本記事では,leftMotor
およびrightMotor
としました. - コントローラを作成します.
Wizards
>New Robot Controller...
から,お好みの言語と名前を指定します.
本記事ではC++を用い,trackController.cpp
という名前のファイルを作成します.
作成したコントローラは,Robot
のcontroller
で指定して本体と紐づけてやります. - コントローラを実装します.大体以下のようにしてやるとよいです.
//L10
#include <webots/Robot.hpp>
#include <webots/Motor.hpp> //追加
//L25付近
Robot *robot = new Robot();
//以下を追加
Motor *leftMotor, *rightMotor;
leftMotor = robot->getMotor("leftMotor");
rightMotor = robot->getMotor("rightMotor");
leftMotor->setPosition(INFINITY);
rightMotor->setPosition(INFINITY);
leftMotor->setVelocity(0.1);
rightMotor->setVelocity(0.1);
//以上を追加
あとはワールドを保存して,ビルド,実行します.
(Webotsの動画書き出し機能で出力したので,実際よりだいぶなめらかな映像になってます)
いいですね,僕は履帯が好きなのでめっちゃテンション上がります
摩擦の設定
一見ここまでで完成したように思えますが,この段階では履帯の摩擦の設定ができておらず,両モータの出力値の値が同じ場合のみ正しく動くようになっています.
試しに,片方のモータ値にマイナスをつけ,その場で旋回(超信地旋回)させようとするとうまく動かないことがわかると思います.
ですので,正しく旋回ができるよう,最後に履帯ー地面間の摩擦を設定してやります.
webotsでは,摩擦の設定は
- 摩擦の設定をしたい物体に素材名をつける
-
WorldInfo
から素材名を二つ指定し,その素材名を持つ物体間の摩擦係数を設定する
という手順で行います.ですので,ここで行う作業は以下のようになります.
-
Track
のcontactMaterial
に適当な素材名を指定します.ここでは"trackMaterial"とします.これを両方の履帯について行います. -
WorldInfo
のcontactProperties
に,ContactProperties
を追加します. - 追加した
ContactProperties
の`material2に先ほど指定した素材名(ここでは"trackMaterial")を指定します. -
ContactProperties
のcoulombFriction
を500に,forceDependentSlip
を1に指定します.
ここまで完了したら,左右モータに正負逆の値を入れてやると超信地旋回をするようになります.
お疲れさまでした!
おわりに
車輪とかと同様にサクッとつけられるかなと思っていたんですが,結構いろいろやることがあって大変でした.
忘れんうちに記事にまとめられてよかったなという感じがします.
なお,最後に指定したパラメータの値ですが,動いたのでオッケーって感じで正直最適な値をいくらにすればいいのかわかってません.
特にforceDependentSlip
に関しては,ほかのworldだと0のまんまでも超信地旋回できたりするので・・・・謎です
できたやつもそもそも履帯の回転量に対して旋回量少ない気がするし・・・・
もう少し調べてみて,わかったら追記などしていこうと思います.
※本記事で作成したコードをgithubに公開しました
https://github.com/ken551/webots_track_test/tree/main