メインページ | ネームスペース一覧 | クラス階層 | 構成 | Directories | ファイル一覧 | ネームスペースメンバ | 構成メンバ | ファイルメンバ | 関連ページ

PHJoint.h

00001 #ifndef PH_JOINT_H
00002 #define PH_JOINT_H
00003 
00004 
00005 #include <Base/BaseUtility.h>
00006 #include <Base/TinyVec.h>
00007 #include <Base/TinyMat.h>
00008 #include <FileIO/FIDocScene.h>
00009 #include <SceneGraph/SGScene.h>
00010 #include <Physics/PHSolid.h>
00011 #include <WinBasis/WBPreciseTimer.h>
00012 #include <float.h>
00013 
00014 //  角速度の最大値.関節が高速に回りすぎて発散するのを防ぐ
00015 #define PHJOINT_MAX_VELOCITY    (1000*M_PI)
00016 
00017 /** @file 3次元連結剛体系
00018     解説:
00019     Featherstoneのアルゴリズムを利用してツリー状に連結された剛体の
00020     運動をシミュレートするクラス
00021 
00022     開発責任者:田崎勇一 tazaki@cyb.mei.titech.ac.jp
00023 
00024     参考文献:"Impulse-based Dynamic Simulation of Rigid Body Systems" Brian Mirtich 1996
00025 */
00026 namespace Spr{;
00027 
00028 /**@name    Featherstone's method で使われる"spatial matrix/vector"
00029     上3つが(力,角速度,角加速度など)をあらわし,
00030     下3つが(トルク,速度,加速度)をあらわす.(と思う) by hase
00031     力とトルクで回転と並進が逆なので注意.
00032 */
00033 //@{
00034 typedef PTM::TVector<6, double> SpVec6d;
00035 typedef PTM::TSubVector<3, SpVec6d::desc> SpSubVec3d;
00036 typedef PTM::TMatrixCol<6, 6, double> SpMatrix6d;
00037 typedef PTM::TSubMatrixCol<3, 3, SpMatrix6d::desc> SpSubMatrix3d;
00038 //@}
00039 
00040 typedef Vec3f Vector;
00041 typedef Matrix3f Matrix3x3;
00042 DEF_RECORD(XJointBase, {
00043     GUID Guid(){ return WBGuid("23F6D545-8987-4aa6-BBE1-2FE32C096D5A"); }   
00044     Matrix3x3   pRj;
00045     Vector      prj;
00046     Matrix3x3   cRj;
00047     Vector      crj;
00048 });
00049 
00050 /// 関節の基本クラス.ツリー構造を作る.PHJointEngineがツリーを持つ.
00051 class PHJointBase : public UTTreeNode<PHJointBase>, public SGObject{
00052 public:
00053     typedef std::vector<UTRef<PHJointBase> > array_type;
00054     friend class PHJointEngine;
00055     friend class PHJointClearForce;
00056     friend class PHJointLoader;
00057     friend class CRHuman;
00058 public:
00059     SGOBJECTDEFABST(PHJointBase);
00060     /// 積分の方法. Method of solver 
00061     enum IntType{
00062         SYMPLETIC,
00063         ANALYTIC,
00064     }intType;
00065 
00066     UTRef<PHSolid> solid;   ///<    子Solid.関節は親Solidと子Solidをつなぐ
00067     UTRef<SGFrame> frame;   ///<    ルートノードが固定の場合のFrame
00068     /** @name 座標系の説明
00069         関節フレームの説明
00070             関節の位置と傾きを表現するためのフレーム。
00071             関節フレーム原点は関節軸の位置を表す。
00072             軸と座標の関係は関節の種類(派生クラス)によって異なる.
00073             - PHJointHinge: フレームのZ軸が回転軸の向きを表す。
00074                             pRc = pRj * Rot(position, 'z') * cRj.trans()
00075                             prc = cRp*(-parent->solid->center + prj) - (crj - solid->center)
00076             - PHJointSlider:    フレームのZ軸が直動軸の向きを表す。
00077                             pRc = pRj * cRj.trans()
00078                             prc = cRp*(-parent->solid->center + prj) + cRj*(0,0,position) - (crj - solid->center)  
00079             - PHJointUniv:  フレームのX,Y軸が,第1軸・第2軸を表す.
00080                             pRc = pRj * Rot(position[0], 'x') * Rot(position[1], 'y') * cRj.trans()
00081                             prc = cRp*(-parent->solid->center + prj) - (crj - solid->center)
00082             - PHJointBall:  3軸動く.可動域はZ軸が動く範囲を円錐で指定する.
00083                             pRc = pRj * position * cRj.trans()
00084                             prc = cRp*(-parent->solid->center + prj) - (crj - solid->center)
00085         以下のコメントで,
00086         - Fc := child solid's frame     子剛体の座標系
00087         - Fp := parent solid's frame    親剛体の座標系
00088         - Fj := joint's frame           ジョイントの座標系(親側Fjpと子側Fjcがある)
00089         を意味する
00090     */
00091     //@{
00092     Matrix3d        pRj, cRj;           ///<    3x3回転行列  rotation matrix(Fp to Fjp, Fc to Fjc)
00093     Vec3d           prj, crj;           ///<    並進ベクトル radius vector(Fp to Fjp in Fp, Fc to Fjc in Fc)
00094 
00095 protected:
00096     Vec3d           prc;                ///<    並進ベクトル radius vector(Fp to Fc in Fc)
00097     Matrix3d        pRc, cRp;           ///<    3x3回転行列  rotation matrix(Fp to Fc, Fc to Fp)
00098     Matrix3d        R;                  ///<    orientation matrix
00099     Quaterniond     quat;               ///<    orientation quaternion
00100     Vec3d           p;                  ///<    position vector
00101     Vec3d           v, v_abs;           ///<    velocity in Fc/world coord.
00102     Vec3d           w, w_abs;           ///<    angular velocity in Fc/world coord.
00103     Vec3d           pvc, pwc;           ///<    [angular]velocity relative to Fp in Fc coord. 
00104     SpMatrix6d      Ii;                 ///<    spatial isolated inertia
00105     SpMatrix6d      Ia;                 ///<    spatial articulated inertia
00106     SpVec6d         Za;                 ///<    zero accelaration force in Fc coord.
00107     SpVec6d         c;                  ///<    Coriolis vector in Fc coord.
00108     SpVec6d         a;                  ///<    spatial accelaration in Fc coord.
00109     //@}
00110 
00111     //  sを含まない変数のキャッシュ.
00112     Matrix3d    rcross, rpcross, rcross_cRp, rpcross_pRc;
00113     SpVec6d     a_p, Ia_c, Z_plus_Ia_c;
00114 public:
00115     /// コンストラクタ
00116     PHJointBase();
00117     /// ロード後の初期化.再帰.
00118     void Loaded(SGScene* scene);
00119     /// 指定したPHSolidを小に持つノードを検索する
00120     PHJointBase* Search(PHSolid*);
00121     /// 親剛体のフレームから見た関節姿勢
00122     Affinef GetPostureFromParent(){ Affinef rv; rv.Pos()=prj; rv.Rot()=pRj; return rv; }
00123     /// 子剛体のフレームから見た関節姿勢
00124     Affinef GetPostureFromChild(){ Affinef rv; rv.Pos()=crj; rv.Rot()=cRj; return rv; }
00125     /// 子剛体の角加速度(World系)
00126     Vec3f GetSolidAngularAccel(){ return solid->GetRotation() * a.sub_vector(0, Vec3f()); }
00127     /// 子剛体の加速度(World系)
00128     Vec3f GetSolidAccel(){ return solid->GetRotation() * a.sub_vector(3, Vec3f()); }
00129     /// 子剛体の角加速度(World系)
00130     Vec3f GetSolidAngularVelocity(){ return w_abs; }
00131     /// 子剛体の加速度(World系)
00132     Vec3f GetSolidVelocity(){ return v_abs; }
00133     /// 絶対座標での関節の向き
00134     Matrix3d GetOrientation(){return R;}
00135     
00136     /// 関節の自由度
00137     virtual int GetJointDof()=0;
00138     /// 関節位置の取得
00139     virtual double GetJointPosition(int i)=0;
00140     /// 関節速度の取得
00141     virtual double GetJointVelocity(int i)=0;
00142     /// 関節加速度の取得
00143     virtual double GetJointAccel(int i)=0;
00144     /// 関節トルクの取得
00145     virtual double GetJointTorque(int i)=0;
00146     /// 関節トルクの設定
00147     virtual void SetJointTorque(double v, int i)=0;
00148     /// 関節トルクを加える
00149     virtual void AddJointTorque(double v, int i)=0;
00150 
00151     ///@name    Featherstone's algorithm
00152     //@{
00153     /// コリオリの力による加速度の計算
00154     void CompCoriolisAccelRecursive(double dt); 
00155     /// articulated inertia & ZA-force
00156     virtual void CompArticulatedInertia(double dt);
00157     /// 積分
00158     virtual void Integrate(SGScene* scene);
00159     /** このノードの加速度を計算したい場合に呼ぶ.
00160         親ノードの加速度は副作用で求まる.子ノードについては計算しない.
00161         
00162         呼び出しかた.
00163         1. root->CalcCoriolisAccelRecusive(dt);
00164         2. 全ジョイントについて,PHJointBase::torque に値を直接代入する.
00165         3. root->CalcArticulatedInertia(dt);
00166         4. CalcAccel(dt)
00167         5. ジョイントの a から加速度を読み出す(座標系に注意)
00168         6. 2-5をトルクパターンを変えながら呼び出す.
00169         
00170         Compute accelaration of the child solid of this joint.
00171         For partial use of Featherstone's algorithm.
00172     */
00173     virtual void CalcAccel(double dt)=0;
00174     //@}
00175 
00176     /// 所有しているオブジェクトの数
00177     virtual size_t NChildObjects();
00178     /// 所有しているオブジェクト
00179     virtual SGObject* ChildObject(size_t i);
00180     /// 参照しているオブジェクトの数
00181     virtual size_t NReferenceObjects();
00182     /// 参照しているオブジェクト
00183     virtual SGObject* ReferenceObject(size_t i);
00184     /// 子オブジェクトの追加
00185     virtual bool AddChildObject(SGObject* o, SGScene* s);
00186     /// 子オブジェクトの削除
00187     virtual bool DelChildObject(SGObject* o, SGScene* s);
00188     /// 子になりえるオブジェクトの型情報の配列
00189     virtual const UTTypeInfo** ChildCandidates();
00190 
00191     void SaveX(XJointBase& x) const;
00192     void LoadX(const XJointBase& x);
00193 
00194     //  関節角を-π〜πに制限する関数
00195     virtual void LimitAngle(double& d){}
00196 protected:
00197     /// 派生クラスが基本クラス型オブジェクトのメンバにアクセスするための手段
00198     template <class T> T& OfParent(T PHJointBase::* member){
00199         return GetParent()->*member;
00200     }
00201 
00202     inline SpMatrix6d pXc_Mat_cXp(SpMatrix6d& m);
00203     inline SpVec6d  pXc_Vec(SpVec6d& v);
00204     inline SpVec6d cXp_Vec(SpVec6d& v);
00205 
00206     virtual void CompJointAxis()=0;
00207     virtual void CompRelativePosition()=0;
00208     virtual void CompRelativeVelocity()=0;
00209     virtual void CompCoriolisAccel()=0;
00210     void UpdateSolid();
00211     void UpdateJointPosture();
00212     void PropagateState();              ///<    位置・速度の伝播(非再帰関数)  
00213     virtual void ClearTorqueRecursive();
00214     virtual void ClearForce();
00215     /** 姿勢などの再設定    非再帰
00216         基本的な状態量(PHJointStateの内容)がLoadedやLoadStateでセットされた後に、
00217         従属変数を計算するための関数    */
00218     virtual void Reset();
00219     virtual void LoadState(const SGBehaviorStates& states);
00220     virtual void SaveState(SGBehaviorStates& states) const;
00221     virtual double MassFactor(){ return 0; }
00222 };
00223 
00224 class PHJointRoot:public PHJointBase{
00225 public:
00226     SGOBJECTDEF(PHJointRoot);
00227     virtual void Reset();
00228     virtual void CalcAccel(double dt);
00229     virtual void CompJointAxis(){}
00230     virtual void CompRelativePosition(){}
00231     virtual void CompRelativeVelocity(){}
00232     virtual void CompCoriolisAccel(){}
00233     virtual void Integrate(SGScene* scene);
00234     /// 状態の読み出し
00235     virtual void LoadState(const SGBehaviorStates& states);
00236     /// 状態の保存
00237     virtual void SaveState(SGBehaviorStates& states) const; 
00238 protected:
00239     virtual int GetJointDof(){ return 0; }
00240     virtual double GetJointPosition(int i){ return 0; }
00241     virtual double GetJointVelocity(int i){ return 0; }
00242     virtual double GetJointAccel(int i){ return 0; }
00243     virtual double GetJointTorque(int i){ return 0; }
00244     virtual void SetJointTorque(double v, int i){}
00245     virtual void AddJointTorque(double v, int i){}
00246 };
00247 
00248 
00249 /** PHJointEngine
00250     関節エンジン.1つのArticulated Bodyに対応する.
00251 */
00252 class PHJointEngine : public PHSolverBase{
00253 public:
00254     SGOBJECTDEF(PHJointEngine);
00255     typedef PHJointBase::array_type array_type;     ///<    ジョイントの配列
00256     UTRef<PHJointBase> root;                        ///<    ルートノード.関節ではない.
00257     void ClearForce(){ root->ClearForce(); }
00258     typedef std::set< UTRef<PHSolid> > PHSolidSet;  ///<    剛体のセット.
00259     PHSolidSet solids;
00260 
00261     //  Featherstone法にかかる時間の計測
00262     WBPreciseTimer timer;
00263     
00264 
00265     int GetPriority() const {return SGBP_JOINTENGINE;}
00266     void Step (SGScene* s);
00267     void Loaded(SGScene* scene);
00268     void Clear(SGScene* s){}
00269     PHJointEngine::PHJointEngine(){}
00270 
00271     /// 所有しているオブジェクトの数
00272     virtual size_t NChildObjects();
00273     /// 所有しているオブジェクト
00274     virtual SGObject* ChildObject(size_t i);
00275     /// 子オブジェクトの追加
00276     virtual bool AddChildObject(SGObject* o, SGScene* s);
00277     /// 子オブジェクトの削除
00278     virtual bool DelChildObject(SGObject* o, SGScene* s);
00279     /// 子になりえるオブジェクトの型情報の配列
00280     virtual const UTTypeInfo** ChildCandidates();
00281     /// オブジェクトを子孫に持っているかどうか.
00282     bool Has(SGObject*);
00283 
00284     /// 状態の読み出し
00285     virtual void LoadState(const SGBehaviorStates& states);
00286     /// 状態の保存
00287     virtual void SaveState(SGBehaviorStates& states) const;
00288 
00289     ///
00290     template <class CT> void EnumJoint(CT& ct){
00291         typedef void (PHJointEngine::*Func)(PHJointBase* b, CT& ct);
00292         Func func = &PHJointEngine::EnumJointFunc;
00293         root->MemberTraverse(this, func, ct);
00294     }
00295 protected:
00296     template <class CT> void EnumJointFunc(PHJointBase* p, CT& ct){
00297         CT::value_type v = DCASTP(CT::value_type, p);
00298         if (v) ct.push_back(v);
00299     }
00300 };
00301 
00302 /** ステップの最初でJointのトルクをクリアする. */
00303 class PHJointClearForce:public SGBehaviorEngine{
00304     SGOBJECTDEF(PHJointClearForce);
00305 public:
00306     UTRef<PHJointEngine> je;
00307     /// クリアする
00308     virtual void Step(SGScene* s);
00309     virtual int GetPriority() const { return SGBP_CLEARFORCE; }
00310 };
00311 
00312 //----------------------------------------------------------------------------
00313 //  実装
00314 
00315 /// 要素アクセス
00316 inline SpSubVec3d& svitem(SpVec6d& v, int i){
00317     return *(SpSubVec3d*)((double*)&v + i*3);
00318 }
00319 inline SpSubMatrix3d& smitem(SpMatrix6d& m, int i, int j){
00320     return m.sub_matrix(i * 3, j * 3, PTM::TMatDim<3, 3>());
00321 }
00322 /// 独自の内積定義(v1^T * v2)
00323 inline double svdot(const SpVec6d& v1, const SpVec6d& v2){
00324     return 
00325         v1[0] * v2[3] + v1[1] * v2[4] + v1[2] * v2[5] + 
00326         v1[3] * v2[0] + v1[4] * v2[1] + v1[5] * v2[2];
00327 }
00328 
00329 /// v1 * v2^T で得られる行列
00330 inline Matrix3d mat(const Vec3d& v1, const Vec3d& v2){
00331     return Matrix3d(
00332         v1[0] * v2[0], v1[0] * v2[1], v1[0] * v2[2],
00333         v1[1] * v2[0], v1[1] * v2[1], v1[1] * v2[2],
00334         v1[2] * v2[0], v1[2] * v2[1], v1[2] * v2[2]);
00335 }
00336 inline SpMatrix6d svmat(const SpVec6d& v1, const SpVec6d& v2){
00337     PTM::TVecDim<3> dim3;
00338     const SpSubVec3d& v11 = v1.sub_vector(0, dim3), v12 = v1.sub_vector(3, PTM::TVecDim<3>());
00339     const SpSubVec3d& v21 = v2.sub_vector(0, dim3), v22 = v2.sub_vector(3, PTM::TVecDim<3>());
00340     SpMatrix6d y;
00341     y.sub_matrix(0, 0, PTM::TMatDim<3, 3>()) = mat(v11, v22);
00342     y.sub_matrix(0, 3, PTM::TMatDim<3, 3>()) = mat(v11, v21);
00343     y.sub_matrix(3, 0, PTM::TMatDim<3, 3>()) = mat(v12, v22);
00344     y.sub_matrix(3, 3, PTM::TMatDim<3, 3>()) = mat(v12, v21);
00345     return y;
00346 }
00347 SpMatrix6d PHJointBase::pXc_Mat_cXp(SpMatrix6d& m){
00348     static Matrix3d pRc_m11_cRp, pRc_m12_cRp, pRc_m21_cRp, pRc_m22_cRp, tmp;
00349     pRc_m11_cRp = pRc * smitem(m, 0, 0) * cRp;
00350     pRc_m12_cRp = pRc * smitem(m, 0, 1) * cRp;
00351     pRc_m21_cRp = pRc * smitem(m, 1, 0) * cRp;
00352     pRc_m22_cRp = pRc * smitem(m, 1, 1) * cRp;
00353     tmp = pRc_m11_cRp - pRc * smitem(m, 0, 1) * rcross_cRp;
00354     SpMatrix6d  y;
00355     smitem(y, 0, 0) = tmp;
00356     smitem(y, 0, 1) = pRc_m12_cRp;
00357     smitem(y, 1, 0) = rpcross * tmp + pRc_m21_cRp - pRc * smitem(m, 1, 1) * rcross_cRp;
00358     smitem(y, 1, 1) = rpcross * pRc_m12_cRp + pRc_m22_cRp;
00359     return y;
00360 }
00361 
00362 SpVec6d PHJointBase::pXc_Vec(SpVec6d& v){
00363     Vec3d pRc_v1 = pRc * svitem(v, 0);
00364     SpVec6d y;
00365     svitem(y, 0) = pRc_v1;
00366     svitem(y, 1) = rpcross * pRc_v1 + pRc * svitem(v, 1);
00367     return y;
00368 }
00369 
00370 SpVec6d PHJointBase::cXp_Vec(SpVec6d& v){
00371     Vec3d cRp_v1 = cRp * svitem(v, 0);
00372     SpVec6d y;
00373     svitem(y, 0) = cRp_v1;
00374     svitem(y, 1) = -rcross * cRp_v1 + cRp * svitem(v, 1);
00375     return y;
00376 }
00377 
00378 
00379 }
00380 
00381 #endif

Springheadに対してSun Apr 16 01:57:54 2006に生成されました。  doxygen 1.4.1