equation.go 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245
  1. // Copyright 2016 The G3N Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. // Package equation implements SPOOK equations based on
  5. // the 2007 PhD thesis of Claude Lacoursière titled
  6. // "Ghosts and Machines: Regularized Variational Methods for
  7. // Interactive Simulations of Multibodies with Dry Frictional Contacts"
  8. package equation
  9. import (
  10. "github.com/g3n/engine/math32"
  11. )
  12. // IBody is the interface of all body types.
  13. type IBody interface {
  14. Index() int
  15. Position() math32.Vector3
  16. Velocity() math32.Vector3
  17. AngularVelocity() math32.Vector3
  18. Force() math32.Vector3
  19. Torque() math32.Vector3
  20. InvMassEff() float32
  21. InvRotInertiaWorldEff() *math32.Matrix3
  22. }
  23. // IEquation is the interface type for all equations types.
  24. type IEquation interface {
  25. SetBodyA(IBody)
  26. BodyA() IBody
  27. SetBodyB(IBody)
  28. BodyB() IBody
  29. JeA() JacobianElement
  30. JeB() JacobianElement
  31. SetEnabled(state bool)
  32. Enabled() bool
  33. MinForce() float32
  34. MaxForce() float32
  35. Eps() float32
  36. SetMultiplier(multiplier float32)
  37. ComputeB(h float32) float32
  38. ComputeC() float32
  39. }
  40. // Equation is a SPOOK constraint equation.
  41. type Equation struct {
  42. id int
  43. minForce float32 // Minimum (read: negative max) force to be applied by the constraint.
  44. maxForce float32 // Maximum (read: positive max) force to be applied by the constraint.
  45. bA IBody // Body "i"
  46. bB IBody // Body "j"
  47. a float32 // SPOOK parameter
  48. b float32 // SPOOK parameter
  49. eps float32 // SPOOK parameter
  50. jeA JacobianElement
  51. jeB JacobianElement
  52. enabled bool
  53. multiplier float32 // A number, proportional to the force added to the bodies.
  54. }
  55. // NewEquation creates and returns a pointer to a new Equation object.
  56. func NewEquation(bi, bj IBody, minForce, maxForce float32) *Equation {
  57. e := new(Equation)
  58. e.initialize(bi, bj, minForce, maxForce)
  59. return e
  60. }
  61. func (e *Equation) initialize(bi, bj IBody, minForce, maxForce float32) {
  62. //e.id = Equation.id++
  63. e.minForce = minForce //-1e6
  64. e.maxForce = maxForce //1e6
  65. e.bA = bi
  66. e.bB = bj
  67. e.a = 0
  68. e.b = 0
  69. e.eps = 0
  70. e.enabled = true
  71. e.multiplier = 0
  72. // Set typical spook params
  73. e.SetSpookParams(1e7, 3, 1/60)
  74. }
  75. func (e *Equation) SetBodyA(ibody IBody) {
  76. e.bA = ibody
  77. }
  78. func (e *Equation) BodyA() IBody {
  79. return e.bA
  80. }
  81. func (e *Equation) SetBodyB(ibody IBody) {
  82. e.bB = ibody
  83. }
  84. func (e *Equation) BodyB() IBody {
  85. return e.bB
  86. }
  87. func (e *Equation) JeA() JacobianElement {
  88. return e.jeA
  89. }
  90. func (e *Equation) JeB() JacobianElement {
  91. return e.jeB
  92. }
  93. // SetMinForce sets the minimum force to be applied by the constraint.
  94. func (e *Equation) SetMinForce(minForce float32) {
  95. e.minForce = minForce
  96. }
  97. // MinForce returns the minimum force to be applied by the constraint.
  98. func (e *Equation) MinForce() float32 {
  99. return e.minForce
  100. }
  101. // SetMaxForce sets the maximum force to be applied by the constraint.
  102. func (e *Equation) SetMaxForce(maxForce float32) {
  103. e.maxForce = maxForce
  104. }
  105. // MaxForce returns the maximum force to be applied by the constraint.
  106. func (e *Equation) MaxForce() float32 {
  107. return e.maxForce
  108. }
  109. // Returns epsilon - the regularization constant which is multiplied by the identity matrix.
  110. func (e *Equation) Eps() float32 {
  111. return e.eps
  112. }
  113. // SetMultiplier sets the multiplier.
  114. func (e *Equation) SetMultiplier(multiplier float32) {
  115. e.multiplier = multiplier
  116. }
  117. // MaxForce returns the multiplier.
  118. func (e *Equation) Multiplier() float32 {
  119. return e.multiplier
  120. }
  121. // SetEnable sets the enabled flag of the equation.
  122. func (e *Equation) SetEnabled(state bool) {
  123. e.enabled = state
  124. }
  125. // Enabled returns the enabled flag of the equation.
  126. func (e *Equation) Enabled() bool {
  127. return e.enabled
  128. }
  129. // SetSpookParams recalculates a, b, eps.
  130. func (e *Equation) SetSpookParams(stiffness, relaxation float32, timeStep float32) {
  131. e.a = 4.0 / (timeStep * (1 + 4*relaxation))
  132. e.b = (4.0 * relaxation) / (1 + 4*relaxation)
  133. e.eps = 4.0 / (timeStep * timeStep * stiffness * (1 + 4*relaxation))
  134. }
  135. // ComputeB computes the RHS of the SPOOK equation.
  136. func (e *Equation) ComputeB(h float32) float32 {
  137. GW := e.ComputeGW()
  138. Gq := e.ComputeGq()
  139. GiMf := e.ComputeGiMf()
  140. return -Gq*e.a - GW*e.b - GiMf*h
  141. }
  142. // ComputeGq computes G*q, where q are the generalized body coordinates.
  143. func (e *Equation) ComputeGq() float32 {
  144. xi := e.bA.Position()
  145. xj := e.bB.Position()
  146. spatA := e.jeA.Spatial()
  147. spatB := e.jeB.Spatial()
  148. return (&spatA).Dot(&xi) + (&spatB).Dot(&xj)
  149. }
  150. // ComputeGW computes G*W, where W are the body velocities.
  151. func (e *Equation) ComputeGW() float32 {
  152. vA := e.bA.Velocity()
  153. vB := e.bB.Velocity()
  154. wA := e.bA.AngularVelocity()
  155. wB := e.bB.AngularVelocity()
  156. return e.jeA.MultiplyVectors(&vA, &wA) + e.jeB.MultiplyVectors(&vB, &wB)
  157. }
  158. // ComputeGiMf computes G*inv(M)*f, where M is the mass matrix with diagonal blocks for each body, and f are the forces on the bodies.
  159. func (e *Equation) ComputeGiMf() float32 {
  160. forceA := e.bA.Force()
  161. forceB := e.bB.Force()
  162. iMfA := forceA.MultiplyScalar(e.bA.InvMassEff())
  163. iMfB := forceB.MultiplyScalar(e.bB.InvMassEff())
  164. torqueA := e.bA.Torque()
  165. torqueB := e.bB.Torque()
  166. invIiTaui := torqueA.ApplyMatrix3(e.bA.InvRotInertiaWorldEff())
  167. invIjTauj := torqueB.ApplyMatrix3(e.bB.InvRotInertiaWorldEff())
  168. return e.jeA.MultiplyVectors(iMfA, invIiTaui) + e.jeB.MultiplyVectors(iMfB, invIjTauj)
  169. }
  170. // ComputeGiMGt computes G*inv(M)*G'.
  171. func (e *Equation) ComputeGiMGt() float32 {
  172. rotA := e.jeA.Rotational()
  173. rotB := e.jeB.Rotational()
  174. rotAcopy := e.jeA.Rotational()
  175. rotBcopy := e.jeB.Rotational()
  176. result := e.bA.InvMassEff() + e.bB.InvMassEff()
  177. result += rotA.ApplyMatrix3(e.bA.InvRotInertiaWorldEff()).Dot(&rotAcopy)
  178. result += rotB.ApplyMatrix3(e.bB.InvRotInertiaWorldEff()).Dot(&rotBcopy)
  179. return result
  180. }
  181. // ComputeC computes the denominator part of the SPOOK equation: C = G*inv(M)*G' + eps.
  182. func (e *Equation) ComputeC() float32 {
  183. return e.ComputeGiMGt() + e.eps
  184. }