開発者向け情報


Constraintの改良提案

以下のように、ヤコビアン J、λ、T、Aの行・列数を可変にして、constrフラグをなくすと良いのではないでしょうか?

  • 良くなると思われること:
    • 可動域拘束のための f や Jを統合できる。
    • フラグで切り替えるのは遅いかも。
    • T,Aの計算が若干軽くなる。
  • 悪くなるとおもわれること:
    • 拘束が増えると大変 → そんなことはめったにない。
    • 可変サイズ行列を使うと遅いかも → テンプレートにする???面倒なだけかも
  • なぜ回転や並進という概念や、Jsがのこるのか:
    • もともと姿勢がQuaternionで表現されているので、JsからJを計算するところでは、 6x6になってしまう。
    • そのため、1自由度ずつ拘束するのでは、どうしても計算効率が悪くなる。
class PHConstraint : public SceneObject, public PHConstraintDesc, public PHConstraintState{
public:
    SPR_OBJECTDEF_ABST(PHConstraint);
    ACCESS_DESC_STATE(PHConstraint);
    PHConstraintEngine* engine;
    bool        bFeasible;              ///< 両方の剛体がundynamicalな場合true
    bool        bArticulated;           ///< 関節系を構成している場合true
    bool        bInactive[2];           ///< 剛体が解析法に従う場合true 
    PHSolid*            solid[2];       ///< 拘束する剛体
    SpatialTransform    X[2];           ///< ワールド座標系の中心に対する親(子)剛体の位置と向き     #* 剛体から毎回取ってくる値
    SpatialTransform    Xj[2];          ///< 剛体の質量中心に対するソケット,プラグの位置と向き     #* 関節を作るときに設定する値
    SpatialTransform    Xjrel;          ///< ソケットに対するプラグの位置と向き                     #* Xから計算
    SpatialVector       vjrel;          ///< ソケットに対するプラグの相対速度,角速度                #* 剛体から計算
    
    SpatialTransform    Js[2];          ///< 拘束ヤコビアン SpatialTranform形式,                   #  Xj Xjrelから計算
                                                //[0]:親剛体中心からSocket座標系へ変換するヤコビアン
                                                //[1]:子剛体中心からSocket座標系へ変換するのヤコビアン
    SpatialMatrix       J[2];           ///< 拘束ヤコビアン 行列形式                                #[n_c x 6] Jsから計算。行列型が必要
                                                //[0]:親剛体の質量中心からSocket座標系へのヤコビアン
                                                //[1]:子剛体の質量中心からPlug座標系経由でSocket座標系へのヤコビアン
    SpatialMatrix       AinvJ[2];       //                                                          # 不使用変数
    SpatialMatrix       T[2];           //  T = M.inv() * J^t                                       #[6 x n_c] ガウスザイデルで使用 拘束のある列だけで良い
    
    SpatialVector b, db, B;             ///< LCPのbベクトルとその補正量                             #[n_c] 拘束のある行だけで良い
    SpatialVector A, dA, Ainv;          ///< LCPのA行列の対角成分とその補正量,逆数                 #[n_c]
    SpatialVector scale;                //  不使用
    
    bool        constr[6];              ///< 速度を拘束する自由度. 可動範囲,バネ・ダンパが有効な場合はtrueとなる   # 不要
    bool        constrCorrection[6];    ///< 位置を拘束する自由度. 可動範囲が有効な場合はtrueとなる                 # 不要

tazz [10/03/04] hase

現状のPHConstraintはSocket/Plug座標の相対運動の計算と,関節や接触を実現するための拘束力の計算の両方を行っています.

これを、相対運動計算クラスと(PHRelativeMotion?)、拘束力計算部とに分け、後者のカテゴリに既存のPHMotorやPHJointLimitも入れるのが良いと思います。

基本的にどの拘束も何らかの相対運動に働きかけるので、相対運動(ヤコビアン)計算クラスと拘束力計算クラスに分けるという方針でいかがでしょうか。

# 並進、回転、SwingTwist、軌道などの相対運動クラスと、等式、不等式、摩擦、可動域、軌道追従(バネダンパ(+トルク))、定速度に分けるってことなら了解。

# RelativeMotion側にfも入れたいな。J fはRelativeMotion側

# Projection, CompBias がConstraint側ですね。

# CompBiasは、軸ごとだと線形になってしまって、大きな誤差に対応出来ないかも(回転など)(hase)

##tazz A, B, fはConstraint側だと思います.MotorやJointLimitもそうなってるはずです。fをRelativeMotion側というのは合力ということでしょうか?計算するには拘束毎にfを持たせる必要があるかと思います。

##hase そうすると、上のソースで、Js[2] までがRelativeMotion J[2]以降がConstraintってことですね。 J[2]が6x6だから計算が一回で済むというのと、例えば並進だけを止めたいならJ[2]は3行でよいということがありますが、これはそれぞれConstraintをつくるということですね。

SwingTwistのように座標変換が多段でかかるものもあるので設計上留意が必要ですね。

#留意の内容が理解できてないです(hase)

##一筋縄では行かない程度の意です。座標変換が複数かかっていても拘束力計算側からはシームレスに見えていてほしいので。tazz

行列サイズ可変に関しては良くなるかは懐疑的です。やるならサイズ固定で中身を計算する行を節約する方が良いかと。あるいは並進のみ、回転のみ、とか。

#可変といっても、最初だけでめったに変わらないのだけどね。中身を節約は今もしていると思います。

#フラグは嫌い(hase)