• 旋转矩阵R的微分

  对于线性位移$x(t)$和线性速度$v(t)$,很容易得出$v(t)=\frac{d}{dt}x(t)$。那么旋转矩阵$R(t)$和角速度$\omega(t)$之间的关系是怎样的呢?显然$\dot{R}(t)$不等于$\omega(t)$,因为$R(t)$是一个矩阵,而$\omega(t)$是向量。为了回答这个问题,回忆一下矩阵$R(t)$的实际意义。我们知道$R(t)$的列向量就是其坐标系在世界坐标系中的方向向量,因此$\dot{R}(t)$的列向量描述了刚体旋转时$x$,$y$,$z$轴的“速度”。下图描述了一个刚体以角速度$\omega(t)$进行旋转,考虑刚体上某一位置向量$r(t)$,其速度很容易推导出为:$$\dot{r}(t)=\omega(t) \times r(t)$$

 

物理引擎中的刚体转动2

  $t$时刻,刚体$x$轴的方向向量在世界坐标系下的坐标为矩阵$R(t)$的第一列:$(r_{xx},r_{xy},r_{xz})^T$,则在$t$时刻$R(t)$第一列的微分就是该向量的变化率。根据上面的推论,我们可得到该微分为:$\omega(t) \times (r_{xx},r_{xy},r_{xz})^T$  

  对$R(t)$的另外两个列向量情况也一样。因此,我们可以写出:

$$\dot{R(t)}=\begin{pmatrix}
\omega(t) \times\begin{pmatrix} r_{xx}\\ r_{xy}\\ r_{xz} \end{pmatrix}
& \omega(t) \times\begin{pmatrix} r_{yx}\\ r_{yy}\\ r_{yz} \end{pmatrix}
& \omega(t) \times\begin{pmatrix} r_{zx}\\ r_{zy}\\ r_{zz} \end{pmatrix}
\end{pmatrix}$$

  根据角速度$\omega$定义斜对称矩阵(skew-symmetric matrix)$\Omega$,斜对称矩阵满足$\Omega^T=-\Omega$:

$$\Omega=\begin{pmatrix}
0 & -\omega_z & \omega_y\\
\omega_z & 0 & -\omega_x\\
-\omega_y & \omega_x & 0
\end{pmatrix}$$

  可以证明,对任意向量$P$均有:$$\omega \times P = \Omega P$$

   则旋转矩阵$R(t)$的微分可以用角速度的斜对称矩阵表示为:$$\dot{R}(t)=\Omega R(t)$$

 

  • 惯性参考系中的Euler方程

  通常Euler方程中各量均为在与刚体固连的坐标系中表达,但这并不意味着此方程只在与刚体固连的坐标系中才成立。事实上很容易证明:对任一坐标系均有$$I \dot{\omega}+\omega \times I \omega =N$$

  式中各量均为在上述给定坐标系中的表达式。当然,将Euler方程表示在与刚体固连坐标系中尤其特殊的优点,即惯性张量矩阵是常值矩阵,它可以预先计算或辨识出来,这给Euler方程的应用带来很大方便。如果欧拉方程在惯性坐标系中描述,那么惯性张量是个随着刚体运动而变化的变量,需要实时计算该值。

   下面从动量矩定理开始推导惯性坐标系下的欧拉方程。等式中物理量下标$I$表示该量在惯性参考系(Inertia frame)中描述,这里刚体的惯性张量$I$不再恒定,而是随时间变化的量,因此在求导时要注意:

$$\boldsymbol\tau_I = \frac d{dt} (\mathrm I_I\, \boldsymbol \omega_I) =
\mathrm I_I \, \dot {\boldsymbol \omega}_I
+ \dot {\mathrm I}_I \,\boldsymbol \omega_I$$

   惯性参考系下的惯性张量$I_I$和刚体局部参考系下的惯性张量$I_b$($I_b$是常量)之间的关系如下:$$I_I=RI_bR^T$$

  其中,矩阵$R$是刚体局部坐标系相对于惯性坐标系(世界坐标系)的变换,即$^I_bR$。考虑惯性张量$I_I$对时间的导数:$\dot{I}_I=\dot{R}I_bR^T+RI_b \dot{R}^T$

  变换矩阵$R$的导数可以表示为:$\dot{R}=Sk(\omega_I)R$,$Sk(\omega_I)$是根据角速度$\omega_I$构造的斜对称矩阵。则有:$\dot{I}_I=Sk(\omega_I)RI_bR^T+RI_bR^TSk^T(\omega_I)=Sk(\omega_I)I_I-I_ISk(\omega_I)$

  于是$\dot{I}_I\omega_I=Sk(\omega_I)I_I\omega_I-I_ISk(\omega_I)\omega_I=\omega_I \times (I_I\omega_I)-I_I(\omega_I \times \omega_I)=\omega_I \times (I_I\omega_I)$

  因此,惯性参考系中的欧拉公式为:

$$\boldsymbol\tau_I =
\mathrm I_I \, \dot {\boldsymbol \omega}_I
+ \boldsymbol \omega_I \times (\mathrm I_I \,\boldsymbol \omega_I)$$

  可以看出,惯性参考系下欧拉公式与刚体局部坐标系下欧拉公式形式一致,只是物理量的参照基准不同。

 

  •  陀螺力矩

  欧拉方程$I \dot{\omega}+\omega \times I\omega=\tau$中的$\omega \times I\omega$项在物理引擎中被称为陀螺力矩(gyroscopic torque),因为其有力矩的量纲。陀螺力矩的产生是由于角速度与角动量方向不一致,$\omega \times I\omega$叉乘结果不为零。

  在某些游戏物理引擎中为了避免复杂计算影响实时性和稳定性,通常会忽略陀螺力矩,即直接使用公式:$$I\dot{\omega}=\tau$$

  那么对于物理引擎中的刚体转动1中描述的那个问题,添加$\omega \times I\omega$项后准确的计算如下面Mathematica代码所示:

  物理引擎中的刚体转动2

  画出结果,可以发现与bullet2.83、ODE物理引擎中模拟的结果一致(仿真时间设为5s):

物理引擎中的刚体转动2

   

  bullet物理引擎从2.83版本开始才默认开启了陀螺力矩的计算。

// bullet 2.83
enum    btRigidBodyFlags
{
    BT_DISABLE_WORLD_GRAVITY = 1,
    ///BT_ENABLE_GYROPSCOPIC_FORCE flags is enabled by default in Bullet 2.83 and onwards.
    ///and it BT_ENABLE_GYROPSCOPIC_FORCE becomes equivalent to BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY
    ///See Demos/GyroscopicDemo and computeGyroscopicImpulseImplicit
    BT_ENABLE_GYROSCOPIC_FORCE_EXPLICIT = 2,
    BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_WORLD=4,
    BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY=8,
    BT_ENABLE_GYROPSCOPIC_FORCE = BT_ENABLE_GYROSCOPIC_FORCE_IMPLICIT_BODY,
};



// bullet 2.82
enum    btRigidBodyFlags
{
    BT_DISABLE_WORLD_GRAVITY = 1,
    ///The BT_ENABLE_GYROPSCOPIC_FORCE can easily introduce instability
    ///So generally it is best to not enable it. 
    ///If really needed, run at a high frequency like 1000 Hertz:    ///See Demos/GyroscopicDemo for an example use
    BT_ENABLE_GYROPSCOPIC_FORCE = 2
};
View Code

相关文章:

  • 2021-07-02
  • 2022-12-23
  • 2021-08-30
  • 2022-12-23
  • 2022-12-23
  • 2021-05-26
猜你喜欢
  • 2021-05-17
  • 2021-12-24
  • 2021-11-19
  • 2021-12-02
  • 2021-10-05
  • 2022-12-23
相关资源
相似解决方案