GteRigidBody.h
Go to the documentation of this file.
1 // David Eberly, Geometric Tools, Redmond WA 98052
2 // Copyright (c) 1998-2017
3 // Distributed under the Boost Software License, Version 1.0.
4 // http://www.boost.org/LICENSE_1_0.txt
5 // http://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
6 // File Version: 3.0.0 (2016/06/19)
7 
8 #pragma once
9 
12 #include <functional>
13 #include <limits>
14 
15 namespace gte
16 {
17 
18 template <typename Real>
19 class RigidBody
20 {
21 public:
22  // Construction and destruction. The rigid body state is uninitialized.
23  // Use the set functions to initialize the state before starting the
24  // simulation.
25  virtual ~RigidBody();
26  RigidBody();
27 
28  // Set rigid body state.
29  void SetMass(float mass);
30  void SetBodyInertia(Matrix3x3<Real> const& inertia);
31  inline void SetPosition(Vector3<Real> const& position);
32  void SetQOrientation(Quaternion<Real> const& quatOrient);
33  void SetLinearMomentum(Vector3<Real> const& linearMomentum);
34  void SetAngularMomentum(Vector3<Real> const& angularMomentum);
35  void SetROrientation(Matrix3x3<Real> const& rotOrient);
36  void SetLinearVelocity(Vector3<Real> const& linearVelocity);
37  void SetAngularVelocity(Vector3<Real> const& angularVelocity);
38 
39  // Get rigid body state.
40  inline Real GetMass() const;
41  inline Real GetInverseMass() const;
42  inline Matrix3x3<Real> const& GetBodyInertia() const;
43  inline Matrix3x3<Real> const& GetBodyInverseInertia() const;
46  inline Vector3<Real> const& GetPosition() const;
47  Quaternion<Real> const& GetQOrientation() const;
48  inline Vector3<Real> const& GetLinearMomentum() const;
49  inline Vector3<Real> const& GetAngularMomentum() const;
50  inline Matrix3x3<Real> const& GetROrientation() const;
51  inline Vector3<Real> const& GetLinearVelocity() const;
52  inline Vector3<Real> const& GetAngularVelocity() const;
53 
54  // Force/torque function format.
55  typedef std::function
56  <
58  (
59  Real, // time of application
60  Real, // mass
61  Vector3<Real> const&, // position
62  Quaternion<Real> const&, // orientation
63  Vector3<Real> const&, // linear momentum
64  Vector3<Real> const&, // angular momentum
65  Matrix3x3<Real> const&, // orientation
66  Vector3<Real> const&, // linear velocity
67  Vector3<Real> const& // angular velocity
68  )
69  >
71 
72  // Force and torque functions.
75 
76  // Runge-Kutta fourth-order differential equation solver
77  void Update(Real t, Real dt);
78 
79 protected:
80  // Constant quantities (matrices in body coordinates).
81  Real mMass, mInvMass;
82  Matrix3x3<Real> mInertia, mInvInertia;
83 
84  // State variables.
85  Vector3<Real> mPosition;
86  Quaternion<Real> mQuatOrient;
87  Vector3<Real> mLinearMomentum;
88  Vector3<Real> mAngularMomentum;
89 
90  // Derived state variables.
91  Matrix3x3<Real> mRotOrient;
92  Vector3<Real> mLinearVelocity;
93  Vector3<Real> mAngularVelocity;
94 };
95 
96 
97 template <typename Real>
99 {
100 }
101 
102 template <typename Real>
104  :
105  mMass(std::numeric_limits<Real>::max()),
106  mInvMass((Real)0),
107  mInertia(Matrix3x3<Real>::Identity()),
108  mInvInertia(Matrix3x3<Real>::Zero()),
109  mPosition(Vector3<Real>::Zero()),
110  mQuatOrient(Quaternion<Real>::Identity()),
111  mLinearMomentum(Vector3<Real>::Zero()),
112  mAngularMomentum(Vector3<Real>::Zero()),
113  mRotOrient(Matrix3x3<Real>::Identity()),
114  mLinearVelocity(Vector3<Real>::Zero()),
115  mAngularVelocity(Vector3<Real>::Zero())
116 {
117  // The default body is immovable.
118 }
119 
120 template <typename Real>
121 void RigidBody<Real>::SetMass(float mass)
122 {
123  if ((Real)0 < mass && mass < std::numeric_limits<Real>::max())
124  {
125  mMass = mass;
126  mInvMass = ((Real)1) / mass;
127  }
128  else
129  {
130  // Assume the body as immovable.
131  mMass = std::numeric_limits<Real>::max();
132  mInvMass = (Real)0;
141  }
142 }
143 
144 template <typename Real>
146 {
147  mInertia = inertia;
149 }
150 
151 template <typename Real> inline
153 {
154  mPosition = position;
155 }
156 
157 template <typename Real>
159 {
160  mQuatOrient = quatOrient;
162 }
163 
164 template <typename Real>
166 {
167  mLinearMomentum = linearMomentum;
169 }
170 
171 template <typename Real>
173 {
174  mAngularMomentum = angularMomentum;
176  mAngularVelocity = mInvInertia * mAngularVelocity; // V = J^{-1}*R^T*M
177  mAngularVelocity = mRotOrient * mAngularVelocity; // V = R*J^{-1}*R^T*M
178 }
179 
180 template <typename Real>
182 {
183  mRotOrient = rotOrient;
185 }
186 
187 template <typename Real>
189 {
190  mLinearVelocity = linearVelocity;
192 }
193 
194 template <typename Real>
196 {
197  mAngularVelocity = angularVelocity;
199  mAngularMomentum = mInertia * mAngularMomentum; // M = J*R^T*V
200  mAngularMomentum = mRotOrient * mAngularMomentum; // M = R*J*R^T*V
201 }
202 
203 template <typename Real> inline
205 {
206  return mMass;
207 }
208 
209 template <typename Real> inline
211 {
212  return mInvMass;
213 }
214 
215 template <typename Real> inline
217 {
218  return mInertia;
219 }
220 
221 template <typename Real> inline
223 {
224  return mInvInertia;
225 }
226 
227 template <typename Real>
229 {
230  return MultiplyABT(mRotOrient * mInertia, mRotOrient); // R*J*R^T
231 }
232 
233 template <typename Real>
235 {
236  return MultiplyABT(mRotOrient * mInvInertia, mRotOrient); // R*J^{-1}*R^T
237 }
238 
239 template <typename Real> inline
241 {
242  return mPosition;
243 }
244 
245 template <typename Real> inline
247 {
248  return mQuatOrient;
249 }
250 
251 template <typename Real> inline
253 {
254  return mLinearMomentum;
255 }
256 
257 template <typename Real> inline
259 {
260  return mAngularMomentum;
261 }
262 
263 template <typename Real> inline
265 {
266  return mRotOrient;
267 }
268 
269 template <typename Real> inline
271 {
272  return mLinearVelocity;
273 }
274 
275 template <typename Real> inline
277 {
278  return mAngularVelocity;
279 }
280 
281 template <typename Real>
282 void RigidBody<Real>::Update(Real t, Real dt)
283 {
284  // TODO: When GTE_USE_VEC_MAT is the convention, test to see whether
285  // dq/dt = 0.5 * w * q (mat-vec convention) needs to become a different
286  // equation.
287  Real halfDT = ((Real)0.5)*dt;
288  Real sixthDT = dt / ((Real)6);
289  Real TpHalfDT = t + halfDT;
290  Real TpDT = t + dt;
291 
292  Vector3<Real> newPosition, newLinearMomentum, newAngularMomentum,
293  newLinearVelocity, newAngularVelocity;
294  Quaternion<Real> newQuatOrient;
295  Matrix3x3<Real> newRotOrient;
296 
297  // A1 = G(T,S0), B1 = S0 + (DT/2)*A1
300  mAngularVelocity[1], mAngularVelocity[2], (Real)0);
301  Quaternion<Real> A1DQDT = ((Real)0.5) * W * mQuatOrient;
302 
303  Vector3<Real> A1DPDT = mForce(t, mMass, mPosition, mQuatOrient,
305  mAngularVelocity);
306 
307  Vector3<Real> A1DLDT = mTorque(t, mMass, mPosition, mQuatOrient,
309  mAngularVelocity);
310 
311  newPosition = mPosition + halfDT * A1DXDT;
312  newQuatOrient = mQuatOrient + halfDT * A1DQDT;
313  newLinearMomentum = mLinearMomentum + halfDT * A1DPDT;
314  newAngularMomentum = mAngularMomentum + halfDT * A1DLDT;
315  newRotOrient = Rotation<3, Real>(newQuatOrient);
316  newLinearVelocity = mInvMass * newLinearMomentum;
317  newAngularVelocity = newAngularMomentum * newRotOrient;
318  newAngularVelocity = mInvInertia * newAngularVelocity;
319  newAngularVelocity = newRotOrient * newAngularVelocity;
320 
321  // A2 = G(T+DT/2,B1), B2 = S0 + (DT/2)*A2
322  Vector3<Real> A2DXDT = newLinearVelocity;
323  W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
324  newAngularVelocity[2], (Real)0);
325  Quaternion<Real> A2DQDT = ((Real)0.5) * W * newQuatOrient;
326 
327  Vector3<Real> A2DPDT = mForce(TpHalfDT, mMass, newPosition,
328  newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
329  newLinearVelocity, newAngularVelocity);
330 
331  Vector3<Real> A2DLDT = mTorque(TpHalfDT, mMass, newPosition,
332  newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
333  newLinearVelocity, newAngularVelocity);
334 
335  newPosition = mPosition + halfDT * A2DXDT;
336  newQuatOrient = mQuatOrient + halfDT * A2DQDT;
337  newLinearMomentum = mLinearMomentum + halfDT * A2DPDT;
338  newAngularMomentum = mAngularMomentum + halfDT * A2DLDT;
339  newRotOrient = Rotation<3, Real>(newQuatOrient);
340  newLinearVelocity = mInvMass * newLinearMomentum;
341  newAngularVelocity = newAngularMomentum * newRotOrient;
342  newAngularVelocity = mInvInertia * newAngularVelocity;
343  newAngularVelocity = newRotOrient * newAngularVelocity;
344 
345  // A3 = G(T+DT/2,B2), B3 = S0 + DT*A3
346  Vector3<Real> A3DXDT = newLinearVelocity;
347  W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
348  newAngularVelocity[2], (Real)0);
349  Quaternion<Real> A3DQDT = ((Real)0.5) * W * newQuatOrient;
350 
351  Vector3<Real> A3DPDT = mForce(TpHalfDT, mMass, newPosition,
352  newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
353  newLinearVelocity, newAngularVelocity);
354 
355  Vector3<Real> A3DLDT = mTorque(TpHalfDT, mMass, newPosition,
356  newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
357  newLinearVelocity, newAngularVelocity);
358 
359  newPosition = mPosition + dt * A3DXDT;
360  newQuatOrient = mQuatOrient + dt * A3DQDT;
361  newLinearMomentum = mLinearMomentum + dt * A3DPDT;
362  newAngularMomentum = mAngularMomentum + dt * A3DLDT;
363  newRotOrient = Rotation<3, Real>(newQuatOrient);
364  newLinearVelocity = mInvMass * newLinearMomentum;
365  newAngularVelocity = newAngularMomentum * newRotOrient;
366  newAngularVelocity = mInvInertia * newAngularVelocity;
367  newAngularVelocity = newRotOrient * newAngularVelocity;
368 
369  // A4 = G(T+DT,B3), S1 = S0 + (DT/6)*(A1+2*(A2+A3)+A4)
370  Vector3<Real> A4DXDT = newLinearVelocity;
371  W = Quaternion<Real>(newAngularVelocity[0], newAngularVelocity[1],
372  newAngularVelocity[2], (Real)0);
373  Quaternion<Real> A4DQDT = ((Real)0.5) * W * newQuatOrient;
374 
375  Vector3<Real> A4DPDT = mForce(TpDT, mMass, newPosition,
376  newQuatOrient, newLinearMomentum, newAngularMomentum, newRotOrient,
377  newLinearVelocity, newAngularVelocity);
378 
379  Vector3<Real> A4DLDT = mTorque(TpDT, mMass, newPosition, newQuatOrient,
380  newLinearMomentum, newAngularMomentum, newRotOrient,
381  newLinearVelocity, newAngularVelocity);
382 
383  mPosition += sixthDT * (A1DXDT + ((Real)2) * (A2DXDT + A3DXDT) + A4DXDT);
384  mQuatOrient += sixthDT * (A1DQDT + ((Real)2)*(A2DQDT + A3DQDT) + A4DQDT);
385  mLinearMomentum += sixthDT * (A1DPDT + ((Real)2)*(A2DPDT + A3DPDT) +
386  A4DPDT);
387  mAngularMomentum += sixthDT * (A1DLDT + ((Real)2)*(A2DLDT + A3DLDT) +
388  A4DLDT);
389 
392  mAngularVelocity = mAngularMomentum * mRotOrient;
393  mAngularVelocity = mInvInertia * mAngularVelocity;
394  mAngularVelocity = mRotOrient * mAngularVelocity;
395 }
396 
397 
398 }
Vector3< Real > mLinearVelocity
Definition: GteRigidBody.h:92
std::function< Vector3< Real > Real, Real, Vector3< Real > const &, Quaternion< Real > const &, Vector3< Real > const &, Vector3< Real > const &, Matrix3x3< Real > const &, Vector3< Real > const &, Vector3< Real > const &) > Function
Definition: GteRigidBody.h:70
virtual ~RigidBody()
Definition: GteRigidBody.h:98
Matrix3x3< Real > const & GetROrientation() const
Definition: GteRigidBody.h:264
Vector3< Real > const & GetPosition() const
Definition: GteRigidBody.h:240
Vector3< Real > const & GetAngularVelocity() const
Definition: GteRigidBody.h:276
Matrix3x3< Real > mRotOrient
Definition: GteRigidBody.h:91
Vector3< Real > mLinearMomentum
Definition: GteRigidBody.h:87
Quaternion< Real > const & GetQOrientation() const
Definition: GteRigidBody.h:246
Matrix3x3< Real > const & GetBodyInertia() const
Definition: GteRigidBody.h:216
Quaternion< Real > mQuatOrient
Definition: GteRigidBody.h:86
Matrix3x3< Real > GetWorldInertia() const
Definition: GteRigidBody.h:228
void SetLinearMomentum(Vector3< Real > const &linearMomentum)
Definition: GteRigidBody.h:165
void SetMass(float mass)
Definition: GteRigidBody.h:121
Function mTorque
Definition: GteRigidBody.h:74
Real GetInverseMass() const
Definition: GteRigidBody.h:210
void SetBodyInertia(Matrix3x3< Real > const &inertia)
Definition: GteRigidBody.h:145
void SetLinearVelocity(Vector3< Real > const &linearVelocity)
Definition: GteRigidBody.h:188
void SetPosition(Vector3< Real > const &position)
Definition: GteRigidBody.h:152
Vector3< Real > mPosition
Definition: GteRigidBody.h:85
Matrix3x3< Real > mInvInertia
Definition: GteRigidBody.h:82
Vector3< Real > const & GetLinearMomentum() const
Definition: GteRigidBody.h:252
Matrix3x3< Real > const & GetBodyInverseInertia() const
Definition: GteRigidBody.h:222
static Vector Zero()
Definition: GteVector.h:295
void SetAngularVelocity(Vector3< Real > const &angularVelocity)
Definition: GteRigidBody.h:195
Real GetMass() const
Definition: GteRigidBody.h:204
void SetAngularMomentum(Vector3< Real > const &angularMomentum)
Definition: GteRigidBody.h:172
GLdouble GLdouble t
Definition: glext.h:239
Vector3< Real > mAngularVelocity
Definition: GteRigidBody.h:93
Vector3< Real > mAngularMomentum
Definition: GteRigidBody.h:88
void SetQOrientation(Quaternion< Real > const &quatOrient)
Definition: GteRigidBody.h:158
void SetROrientation(Matrix3x3< Real > const &rotOrient)
Definition: GteRigidBody.h:181
Vector3< Real > const & GetAngularMomentum() const
Definition: GteRigidBody.h:258
static Quaternion Identity()
void Update(Real t, Real dt)
Definition: GteRigidBody.h:282
GMatrix< Real > MultiplyABT(GMatrix< Real > const &A, GMatrix< Real > const &B)
Definition: GteGMatrix.h:715
Quaternion< Real > Inverse(Quaternion< Real > const &d)
static Matrix Identity()
Definition: GteMatrix.h:490
Function mForce
Definition: GteRigidBody.h:73
Vector3< Real > const & GetLinearVelocity() const
Definition: GteRigidBody.h:270
Matrix3x3< Real > mInertia
Definition: GteRigidBody.h:82
Matrix3x3< Real > GetWorldInverseInertia() const
Definition: GteRigidBody.h:234
static Matrix Zero()
Definition: GteMatrix.h:473


geometric_tools_engine
Author(s): Yijiang Huang
autogenerated on Thu Jul 18 2019 04:00:01