Home > リソース > MBDynチュートリアル > 15.2重剛体振り子(2)〜参照座標系 Reference
MBDynチュートリアル

15.2重剛体振り子(2)〜参照座標系 Reference

前項で作成した2重剛体振り子のシミュレーションモデルは、一定の初期位置からのシミュレーションしか行えないため、汎用性に欠けます。そこで、様々な初期位置からのシミュレーションが行えるようにモデルを改良してみましょう。ここでは、複雑なモデルを構築する上で大変便利な、参照座標系“reference”を活用します。

例題4(2重剛体振り子)

前項の例題3と同様に、2つの細長いリンクからなる2重剛体振り子を考えます。リンク1が鉛直線となす角をθ1、リンク2がリンク1となす角をθ2とする時、初期のθ1とθ2を任意に変えてシミュレーションを行えるようなシミュレーションモデルの入力ファイルを作成します。

シミュレーションモデルの設計

例題4のシミュレーションモデルの設計図を図1に示します。初期のθ1とθ2を変数として、一般的な配置でモデルを作成します。各リンクのstructural node(「Node_Link1」、「Node_Link2」)は、各リンクの重心位置に長手方向をx方向とする向きで定義します。リンク1はグローバル座標系に対してrevolute pinで接続し、リンク1とリンク2はrevolute hingeで接続します。図のように2つの“reference”「Ref_Link1」と「Ref_Link2」を定義することで、モデル構築が比較的容易になります。

plan_double_rigid_pendulum_2

図1: 汎用的な2重剛体振り子シミュレーションモデルの設計図

Reference

referenceはモデルを構築する際に便宜的に定義することができる参照座標系です。referenceを定義するステートメントの型は次のようになります。

   reference: <label> ,
      <absolute position> ,
      <absolute orientation matrix> ,
      <absolute velocity> ,
      <absolute angular velocity> ;

referenceの定義は入力ファイルのどこでも(ブロック外でも)行うことができます。このように定義したreferenceは、nodeやジョイントを定義するステートメントの中で次の量を入力する際に参照することができます。

これらの量(value)を既存のreferenceを参照して入力する場合には、キーワード「reference」を用いて次のように記述します。

   reference, <reference label>, <value>

Referenceを利用したモデルの構築

referenceを利用して、本例題の2つのリンクのnodeを定義する手順を以下に示します。

まず、reference「Ref_Link1」を次のように定義します。(「Ref_Link1」はグローバル座標系をy軸周りにπ/2-θ1だけ回転して得られる座標系です。)

   set: integer Ref_Link1 = 1;
   
   reference: Ref_Link1,
      null,                        # absolute position
      euler, 0., pi/2.-theta1, 0., # absolute orientation
      null,                        # absolute velocity
      null;                        # absolute angular velocity

reference「Ref_Link1」を参照して、node「Node_Link1」を次のように定義することができます。(「Node_Link1」は「Ref_Link1」をそのx方向にL/2だけ平行移動して得られます。)

   set: integer Node_Link1 = 1;
   
   structural: Node_Link1, dynamic,
      reference, Ref_Link1, 1./2.*L, 0., 0., # absolute position
      reference, Ref_Link1, eye,             # absolute orientation
      reference, Ref_Link1, null,            # absolute velocity
      reference, Ref_Link1, null;            # absolute angular velocity

既存のreferenceを参照して別のreferenceを定義することも可能です。ここでは、reference「Ref_Link1」を参照して、reference「Ref_Link2」を定義します。(「Ref_Link2」は「Ref_Link1」をそのx方向にLだけ平行移動し、さらにそのy軸周りに-θ2だけ回転して得られます。)

   set: integer Ref_Link2 = 2;
   
   reference: Ref_Link2,
      reference, Ref_Link1, L, 0., 0.,              # absolute position
      reference, Ref_Link1, euler, 0., -theta2, 0., # absolute orientation
      reference, Ref_Link1, null,                   # absolute velocity
      reference, Ref_Link1, null;                   # absolute angular velocity

最後に、reference「Ref_Link2」を参照して、node「Node_Link2」を定義します。(「Node_Link2」は「Ref_Link2」をそのx方向にL/2だけ平行移動して得られます。)

   set: integer Node_Link2 = 2;
   
   structural: Node_Link2, dynamic,  
      reference, Ref_Link2, 1./2.*L, 0., 0., # absolute position
      reference, Ref_Link2, eye,             # absolute orientation
      reference, Ref_Link2, null,            # absolute velocity
      reference, Ref_Link2, null;            # absolute angular velocity

Referenceを用いない場合

ちなみに、referenceを用いずにnode「Node_Link2」を定義するとどのようになるでしょうか?node「Node_Link2」の絶対位置は、

Eq_Node_Link2_position

ですから、次のように定義できます。しかし、記述がかなり煩雑になってしまうことが分かります。

   set: integer Node_Link2 = 2;

   structural: Node_Link2, dynamic,  
      L*sin(theta1)+L*sin(theta1+theta2), 0., -L*cos(theta1)-L*cos(theta1+theta2), # absolute position
      euler, 0., pi-(theta1+theta2), 0., # absolute orientation
      null,                              # absolute velocity
      null;                              # absolute angular velocity

入力ファイル記述例

以上を踏まえて作成した、例題4の2重剛体振り子の解析を行うための入力ファイルをコード1に示します。

double_rigid_pendulum_2.mbd
# double_rigid_pendulum_2.mbd

begin: data;
   problem: initial value;
end: data;

begin: initial value;
   initial time:   0.;
   final time:     5.;
   time step:      1.e-3;
   max iterations: 10;
   tolerance:      1.e-6;
end: initial value;

begin: control data;
   structural nodes: 2;
   rigid bodies:     2;
   joints:           2;
   gravity;
end: control data;

# Design Variables
set: real M = 1.; # Mass of Link1 and Link2
set: real L = 1.; # Length of Link1 and Link2

set: real theta1 = pi/6.; # Initial angle of Link1 w.r.t vertical line
set: real theta2 = pi/6.; # Initial angle of Link2 w.r.t Link1

# Reference Labels
set: integer Ref_Link1 = 1;
set: integer Ref_Link2 = 2;

# Node Labels
set: integer Node_Link1 = 1;
set: integer Node_Link2 = 2;

# Body Labels
set: integer Body_Link1 = 1;
set: integer Body_Link2 = 2;

# Joint Labels
set: integer JoRevp_Link1       = 1;
set: integer JoRevh_Link1_Link2 = 2;

# Reference
reference: Ref_Link1,
   null,                        # absolute position
   euler, 0., pi/2.-theta1, 0., # absolute orientation
   null,                        # absolute velocity
   null;                        # absolute angular velocity
   
reference: Ref_Link2,
   reference, Ref_Link1, L, 0., 0.,              # absolute position
   reference, Ref_Link1, euler, 0., -theta2, 0., # absolute orientation
   reference, Ref_Link1, null,                   # absolute velocity
   reference, Ref_Link1, null;                   # absolute angular velocity

begin: nodes;
   structural: Node_Link1, dynamic,
      reference, Ref_Link1, 1./2.*L, 0., 0., # absolute position
      reference, Ref_Link1, eye,             # absolute orientation
      reference, Ref_Link1, null,            # absolute velocity
      reference, Ref_Link1, null;            # absolute angular velocity
      
   structural: Node_Link2, dynamic,  
      reference, Ref_Link2, 1./2.*L, 0., 0., # absolute position
      reference, Ref_Link2, eye,             # absolute orientation
      reference, Ref_Link2, null,            # absolute velocity
      reference, Ref_Link2, null;            # absolute angular velocity
      
end: nodes;

begin: elements;
   body: Body_Link1, Node_Link1,
      M,                                # mass
      null,                             # relative center of mass
      diag, 0., M*L^2./12., M*L^2./12.; # inertia matrix
      
   body: Body_Link2, Node_Link2, 
      M,                                # mass
      null,                             # relative center of mass
      diag, 0., M*L^2./12., M*L^2./12.; # inertia matrix
      
   joint: JoRevp_Link1, 
      revolute pin, 
         Node_Link1, 
            reference, Ref_Link1, null,                                # relative offset
            hinge, reference, Ref_Link1, 1, 1., 0., 0., 3, 0., 1., 0., # relative axis orientation
            reference, Ref_Link1, null,                                # absolute pin position
            hinge, reference, Ref_Link1, 1, 1., 0., 0., 3, 0., 1., 0.; # absolute pin orientation
            
   joint: JoRevh_Link1_Link2, 
      revolute hinge, 
         Node_Link1,
            reference, Ref_Link2, null,                                # relative offset
            hinge, reference, Ref_Link2, 1, 1., 0., 0., 3, 0., 1., 0., # relative axis orientation
         Node_Link2,
            reference, Ref_Link2, null,                                # relative offset
            hinge, reference, Ref_Link2, 1, 1., 0., 0., 3, 0., 1., 0.; # relative axis orientation
    
   gravity: 0., 0., -1., const, 9.81;
   
end: elements;
コード1: 例題4(2重剛体振り子)の入力ファイル記述例

アニメーション

θ1とθ2の初期値をどちらもπ/6とした時のシミュレーション結果のアニメーションを動画1に示します。




動画1: 2重剛体振り子シミュレーション