\CAPTION\ |
\CAPTION\ |
\CAPTION\ |
OpenHRPの本来の開発目的である、ヒューマノイドとはかなり毛色が違う対象で、ちゃんとシミュレーションできるのかは不安ですが、「ちゃんとシミュレートできている」かどうかの判断は「実機の性質」を知らなければ、できません。
ヒューマノイドロボットは複雑で、かつ、静特性はともかく動特性はぱっと見ででは妥当性がわかりません。
一方、玉乗りロボットは基本的な特性は十分に把握、制御ゲインで問題があったときにも、挙動から何が起きているかを検討付けやすいので、「知っている対象だから」という理由で選定しました。
それがいろいろと難儀を起こすことになったのですが...。
ただし、このロボットから持ってきたのは
のみです。大きく異なるところは
です。それは全く違うものになりそうですが、本体と球のパラメータが挙動としては重要なので、あまり気にしませんでした。
逆に、動特性を決める、慣性パラメータを「現実離れしない値」にするために、BallIPをネタにしました。
OpenHRPは、可動部分をトルク(力)操作型(torque、トルク)と、角度(変位)操作型(highgain、ハイゲイン)で指定できます。
ところが、ハイゲインモードはロボット全体の構造の一部で角度がかわるようなところでは問題なさそうな感じなのですが、接触駆動部のようなところで、角度(および角速度、各加速度)を指定すると、接触状況にかかわらず、ただ回って摩擦力の伝動がうまくいかない、という現象にあたりました。球にローラを押しつけて、ローラの角度を回しても、ローラの角度が変わるだけで、球の角度には影響が出ませんでした。
そのため、加速度操作型ではなく、トルク操作型にしました。
当初は標準プリミティブの球を使っていたが、ポリゴンのメッシュが緯度経度型で、赤道付近と極付近で接触特性が大きく異なること(面の大きさおよび頂点の構造)、メッシュ切りの細かさを指定できないことから、自前でVRML形状モデル(_icosa.wrl)を作成した。
自前で作った形状モデルは、ロボットモデルの該当箇所で"Inline"で記述され、読み込み時に一緒に取り込まれるようであるため、同一ディレクトリに置いておくのがよさそう。逆に、読み込み時取り込みなので、形状モデルのwrlファイルのみを差し替えることが可能(形状は動特性には影響せず。接触判定と画面表示にのみ影響する印象)。
技術的に細かい補足:
ロボットボディは
名前 | translation | rotation | jointAxis |
SX1 | (0,0,0.13) | (0,0,1,0) | (0,0,1) |
SX2 | (0,0,-0.13) | (0,1,0,π) | (0,0,1) |
SY1 | (0.13,0,0) | (0,1,0,π/2) | (0,0,1) |
SY2 | (-0.13,0,0) | (0,1,0,-π/2) | (0,0,1) |
そのため、OpenHRPで制御系を作る場合は、
すべてのポートは、TimedDoubleSeq型のデータ形式で、「時刻+各値(double)の配列」という形です。
ジャイロと加速度センサは各1個で各々3軸なので、各々3要素の配列、ロボットは8関節(4ローラ+4スライダ)あるのでacjointとcmforceは8要素の配列になります。値の順番は標準で関節に設定した番号順になります。
一方、cmjoint,cmspeed,cmaccelは中間に「:SX1,SX2,SY1,SY2:」と記載してあるので、4つのスライダの値に限定したもので、ローラは無関係になります。
スライダはIDが4~7でふってありますが、関節を限定すると、ここに記載した順番の配列になります。つまり、要素0がSX1、要素3がSY2の値になる4要素の配列です。
最後の--connectionによって、ブリッジが起動したときに、すでに動いているコンポーネントのポートと接続します。 なお、「--connection acaccel:BBcont0:acaccel」は「[ブリッジのacaccel]:[BBcont0:(の)acaccel]」という解釈です。 入出力の方向は関係なく、ブリッジ側:制御側、の順です。
ブリッジの起動は、GrxUIの「コントローラ」で設定します。バッチファイルを置いたところを実行ディレクトリにして、実行コマンドとしてバッチファイル名を指定します。コントローラ名は--server-nameで指定した名前です。 なお、このディレクトリにはブリッジの(かなり巨大な)ログが気づくと大量にたまります。 また、このディレクトリは、「プロジェクトのxmlファイルに対するの相対パス」で扱われるようです。 遠いディレクトリにおくと「../」が大量に続いたり、異なるドライブに分散させたりするとおかしくなるようです。 同一ディレクトリにシミュレーションモデルとコントローラのソースを置くのもどうかと思いますので、隣のディレクトリくらいにしておくといいかもしれません。もしくは、ブリッジのバッチファイルをモデルと同一ディレクトリにしておくか。
なお、このバッチファイルにエラーがあると、理由も分からずにシミュレーションの起動に失敗します。 おかしいと思ったら、コマンドプロンプトでそのままこのバッチファイルを実行して、エラーが出ないことを確認したほうがいいでしょう。
あとは、この中に、制御のプログラムを書き込みます。最低限、実装すべき関数は
OnExecute関数の冒頭に while(1)で囲まれた、値の取得部分があります。 本来は、単にisNewしてreadすればよさそうなのですが、書き方によっては、前回のシミュレーションの最後の状態が読めたり、不思議な現象が再現性良く現れたので、その対策として、時刻0が読めるまではから読みするようにしています。
姿勢角度の計算は、加速度出力とレートジャイロの出力から計算しています。
加速度は重力加速度方向をある程度検出できる一方で、ロボットの振動の影響を受けます。特に、OpenHRPの加速度センサは帯域に制限がないようで、かなり過激な波形がでます(実際の加速度センサは、センサの帯域や取り付け方法などによってほどほどになまっている)。そのまま使えません(本来は、水平成分と垂直成分をatan2にいれれば何とかなりそうですが垂直成分も変動が大きいので、9.8決め打ちにしています)。
ジャイロはそのまま積分すると、動き方によっては角度にずれが出ます。実在のレートジャイロに比べると、ドリフトしないのは理想的ですが。
そこで、この二つを、実在のBallIP同様に合成ジャイロの手法で、合成して、傾斜角度を求めています。
具体的には、加速度センサから計算した傾斜角から低域(ほぼ直流分)を取り出し、ジャイロの積分値から広域を取り出し、合算しています。
球の転動量はローラの回転角度で代用しています。ローラと球の間にはすべりが明らかにあり、同方向に回転する2本のローラは期待では同一回転をするはずですが、明らかに異なる角度で回っています。 ので、ここでは、単純に、同方向の2本のローラの回転の平均値を使いました。
制御、
なお、ゲインは、実験的?に決めたので、根拠はありません。
また、制御に味をだす?ため、目標値を時間とともに振るようなデモコードが入れてあります。
この現象に対処するために、いくつか試して現状で採用した方法は、「推力を設定しつつ、位置を強制する」です。 現行のシミュレータ(コントローラブリッジ)では、ハイゲインではない、トルク(力)モードであっても、位置、速度、加速度を設定できるようです。 具体的には、ブリッジのin-portで、TORQUEだけではなく、VALUE、VELOCITY、ACCELERATION を設定し、そこに制御側から値を書き込みます。 onExecuteの後半に実装してあり、
1:モデルの変更
2:制御コンポーネントの修正
BBcont.cpp の