STEP2: シミュレータを作ろう

Open Dynamics Engine

ODE本 Step2 扉図のカラー画像


ODE本「簡単!実践!ロボットシミュレーション - Open Dynamics Engineによるロボットプログラミング

」のStep2です.

ここでは,ロボットを動かす上で必要になる関節を動かす方法,シミュレーションの再実行法,高速化,キーボードからの操作を学びホッピングロボットのシミュレータを作ります.

以下にStep2のシミュレータの動画を掲載します.ソースコードはこのページの注意事項を読み,ダウンロード,ビルドやコンパイルし実行してください.


<p><em>There is embedded content here that you cannot see. Please <a href="http://demura.net/wordpress/?page_id=1307">open the post in a web browser</a> to see this.</em></p>

  • プログラム2.5: ホッピングロボット(P37)
  • 説明:スライダ(直動式)ジョイントの動かし方を学び,一本脚ロボットをちょっとジャンプさせます.

  • プログラム2.6: ドロースタッフの設定(P40)
  • プログラム2.7: comman関数(P41)
  • プログラム2.8: simLoop関数の変更(P42)

  • <p><em>There is embedded content here that you cannot see. Please <a href="http://demura.net/wordpress/?page_id=1307">open the post in a web browser</a> to see this.</em></p>

    • プログラム2.9: ホッピングロボット,再実行可能版 (P44)
    • 説明:シミュレーションは普通は1回では終わらず,何度も繰り返し実行しなければなりませんよね.ここでは,ミュレーションの再実行法を学びます.

    • プログラム2.10: ホッピングロボット,描画無版 (P50)
    • EX2.8: テクスチャファイル (P53)

    • プログラム2.1: ヒンジジョイントの制御(P32)
    • [cpp]
       void controlHinge(dReal target)
       {
        static const dReal kp    = 5.0;   // 比例定数
        static const dReal fmax = 200;  // 最大トルク [Nm]
        dReal tmp   =  dJointGetHingeAngle(joint);  // 現在の角度を取得
        dReal u     =  kp * (target - tmp);  // 操作量
        dJointSetHingeParam(joint,dParamVel,u);  // 角速度の設定
        dJointSetHingeParam(joint,dParamFMax,fmax); // 最大トルクの設定
       }
      [/cpp]
    • プログラム2.2: ヒンジジョイントの力制御(P33)
    • [cpp]
      void controlHinge2(dReal target)
      {
        static const dReal kp   = 5.0, kt = 2.0;   // 比例定数
        dReal tmp      =  dJointGetHingeAngle(joint);  // 現在の角度を取得
        dReal u          =  kp * (target - tmp);  // 操作量
        dReal omega = dJointGetHingeAngleRate(joint);   // 角速度
        dReal trq        =  kt  * omega;  // 摩擦トルク
        dJointAddHingeTorque(joint, u - trq);   // トルクを加える
      }
       [/cpp]
    • プログラム2.3: スライダージョイントの作り方(P34)
    • [cpp]
         s_joint = dJointCreateSlider(world, 0);  // ジョイントの生成
        dJointAttach(s_joint, leg[0].body,leg[1].body);  // ジョイントの取付
        dJointSetSliderAxis(s_joint, 0, 0, 1); // 軸ベクトルの設定
        dJointSetSliderParam(s_joint, dParamLoStop, -0.5); // 最大収縮長[m]
        dJointSetSliderParam(s_joint, dParamHiStop,  0.5);  // 最大伸展長[m]
      [/cpp]
    • プログラム2.4: スライダージョイントの動かし方(P35)
    • [cpp]
       static void controlSlider(dReal target)  {
        static dReal kp   = 25.0;   // 比例定数
        static dReal fmax = 400;  // 最大力[N]
        dReal tmp  = dJointGetSliderPosition(s_joint);   // スライダの現在位置
        dReal u    = kp * (target - tmp);   // 残差
        dJointSetSliderParam(s_joint, dParamVel,  u);
        dJointSetSliderParam(s_joint, dParamFMax, fmax);
       }
      [/cpp] 
    • プログラム2.6: ドロースタッフの設定(P40)
    • [cpp]
       void  setDrawStuff()
      {
         fn.version = DS_VERSION;  // drawStuffのバージョン
         fn.start   = &start;  // シミュレーションループの前に呼び出される関数
         fn.step    = &simLoop;   // ステップ毎に呼びだされる関数のアドレス
         fn.command = &command;   // キー入力により呼び出される関数のアドレス
         fn.path_to_textures = "../../drawstuff/textures"; // テクスチャのパス
       }
      [/cpp]
    • プログラム2.7: comman関数(P41)
    • [cpp]
       void command(int cmd)
       {
         float xyz[3],hpr[3];  // 視点,視線
         switch (cmd) {
         case 'a':funcA(); break;           // aキーを押すとfuncAを実行
         case '1':func1(); break;      // 1キーを押すとfunc1を実行
         case 's':                      // sキーを押すと視点,視線を表示
            dsGetViewpoint(xyz,hpr);     // 視点,視線を取得
            printf("xyz=%4.2f %4.2f %4.2f   ",xyz[0],xyz[1],xyz[2]);
            printf("hpr=%6.2f %6.2f %5.2f \n",hpr[0],hpr[1],hpr[2]);
            break;
          default:printf("Input a or 1\n");break;// 上記以外のキーを押すとき
        }
      }
      [/cpp]
    • プログラム2.8: simLoop関数の変更(P42)
    • [cpp]
       static void simLoop(int pause)
       {
         const dReal *pos1, *R1, *pos2, *R2;
         int s = 200;   // 跳躍する周期(ステップ)
         if (!pause) {   //  一時停止
            STEPS++;  //  ステップ数
            printf("STEPS:%4d\n",STEPS);
            if ((0 <= (STEPS % s)) && ((STEPS % s) <= 10)) controlSlider(0.5);
            else                               controlSlider(0.0);
      
            dSpaceCollide(space,0,&nearCallback);  // 衝突検出計算
            dWorldStep(world,0.01);   // 1ステップ進める
           dJointGroupEmpty(contactgroup);
         }
      
         dsSetColor(1.0,0.0,0.0);  // 赤色の設定
         dsDrawSphere(dBodyGetPosition(torso.body),   // 球の描画
                               dBodyGetRotation(torso.body), torso. r);
       }
      [/cpp]

    (最終更新日 2008-7-27)

    Leave a Reply

    カウンタ (since 2008-3-15)
    Copyright © 1998-2009    Kosei Demura