b2FrictionJoint.cpp
Go to the documentation of this file.
1 /*
2 * Copyright (c) 2006-2011 Erin Catto http://www.box2d.org
3 *
4 * This software is provided 'as-is', without any express or implied
5 * warranty. In no event will the authors be held liable for any damages
6 * arising from the use of this software.
7 * Permission is granted to anyone to use this software for any purpose,
8 * including commercial applications, and to alter it and redistribute it
9 * freely, subject to the following restrictions:
10 * 1. The origin of this software must not be misrepresented; you must not
11 * claim that you wrote the original software. If you use this software
12 * in a product, an acknowledgment in the product documentation would be
13 * appreciated but is not required.
14 * 2. Altered source versions must be plainly marked as such, and must not be
15 * misrepresented as being the original software.
16 * 3. This notice may not be removed or altered from any source distribution.
17 */
18 
20 #include <Box2D/Dynamics/b2Body.h>
22 
23 // Point-to-point constraint
24 // Cdot = v2 - v1
25 // = v2 + cross(w2, r2) - v1 - cross(w1, r1)
26 // J = [-I -r1_skew I r2_skew ]
27 // Identity used:
28 // w k % (rx i + ry j) = w * (-ry i + rx j)
29 
30 // Angle constraint
31 // Cdot = w2 - w1
32 // J = [0 0 -1 0 0 1]
33 // K = invI1 + invI2
34 
35 void b2FrictionJointDef::Initialize(b2Body* bA, b2Body* bB, const b2Vec2& anchor)
36 {
37  bodyA = bA;
38  bodyB = bB;
39  localAnchorA = bodyA->GetLocalPoint(anchor);
40  localAnchorB = bodyB->GetLocalPoint(anchor);
41 }
42 
44 : b2Joint(def)
45 {
48 
50  m_angularImpulse = 0.0f;
51 
52  m_maxForce = def->maxForce;
53  m_maxTorque = def->maxTorque;
54 }
55 
57 {
66 
67  float32 aA = data.positions[m_indexA].a;
68  b2Vec2 vA = data.velocities[m_indexA].v;
69  float32 wA = data.velocities[m_indexA].w;
70 
71  float32 aB = data.positions[m_indexB].a;
72  b2Vec2 vB = data.velocities[m_indexB].v;
73  float32 wB = data.velocities[m_indexB].w;
74 
75  b2Rot qA(aA), qB(aB);
76 
77  // Compute the effective mass matrix.
80 
81  // J = [-I -r1_skew I r2_skew]
82  // [ 0 -1 0 1]
83  // r_skew = [-ry; rx]
84 
85  // Matlab
86  // K = [ mA+r1y^2*iA+mB+r2y^2*iB, -r1y*iA*r1x-r2y*iB*r2x, -r1y*iA-r2y*iB]
87  // [ -r1y*iA*r1x-r2y*iB*r2x, mA+r1x^2*iA+mB+r2x^2*iB, r1x*iA+r2x*iB]
88  // [ -r1y*iA-r2y*iB, r1x*iA+r2x*iB, iA+iB]
89 
90  float32 mA = m_invMassA, mB = m_invMassB;
91  float32 iA = m_invIA, iB = m_invIB;
92 
93  b2Mat22 K;
94  K.ex.x = mA + mB + iA * m_rA.y * m_rA.y + iB * m_rB.y * m_rB.y;
95  K.ex.y = -iA * m_rA.x * m_rA.y - iB * m_rB.x * m_rB.y;
96  K.ey.x = K.ex.y;
97  K.ey.y = mA + mB + iA * m_rA.x * m_rA.x + iB * m_rB.x * m_rB.x;
98 
100 
101  m_angularMass = iA + iB;
102  if (m_angularMass > 0.0f)
103  {
104  m_angularMass = 1.0f / m_angularMass;
105  }
106 
107  if (data.step.warmStarting)
108  {
109  // Scale impulses to support a variable time step.
110  m_linearImpulse *= data.step.dtRatio;
111  m_angularImpulse *= data.step.dtRatio;
112 
114  vA -= mA * P;
115  wA -= iA * (b2Cross(m_rA, P) + m_angularImpulse);
116  vB += mB * P;
117  wB += iB * (b2Cross(m_rB, P) + m_angularImpulse);
118  }
119  else
120  {
122  m_angularImpulse = 0.0f;
123  }
124 
125  data.velocities[m_indexA].v = vA;
126  data.velocities[m_indexA].w = wA;
127  data.velocities[m_indexB].v = vB;
128  data.velocities[m_indexB].w = wB;
129 }
130 
132 {
133  b2Vec2 vA = data.velocities[m_indexA].v;
134  float32 wA = data.velocities[m_indexA].w;
135  b2Vec2 vB = data.velocities[m_indexB].v;
136  float32 wB = data.velocities[m_indexB].w;
137 
138  float32 mA = m_invMassA, mB = m_invMassB;
139  float32 iA = m_invIA, iB = m_invIB;
140 
141  float32 h = data.step.dt;
142 
143  // Solve angular friction
144  {
145  float32 Cdot = wB - wA;
146  float32 impulse = -m_angularMass * Cdot;
147 
148  float32 oldImpulse = m_angularImpulse;
149  float32 maxImpulse = h * m_maxTorque;
150  m_angularImpulse = b2Clamp(m_angularImpulse + impulse, -maxImpulse, maxImpulse);
151  impulse = m_angularImpulse - oldImpulse;
152 
153  wA -= iA * impulse;
154  wB += iB * impulse;
155  }
156 
157  // Solve linear friction
158  {
159  b2Vec2 Cdot = vB + b2Cross(wB, m_rB) - vA - b2Cross(wA, m_rA);
160 
161  b2Vec2 impulse = -b2Mul(m_linearMass, Cdot);
162  b2Vec2 oldImpulse = m_linearImpulse;
163  m_linearImpulse += impulse;
164 
165  float32 maxImpulse = h * m_maxForce;
166 
167  if (m_linearImpulse.LengthSquared() > maxImpulse * maxImpulse)
168  {
170  m_linearImpulse *= maxImpulse;
171  }
172 
173  impulse = m_linearImpulse - oldImpulse;
174 
175  vA -= mA * impulse;
176  wA -= iA * b2Cross(m_rA, impulse);
177 
178  vB += mB * impulse;
179  wB += iB * b2Cross(m_rB, impulse);
180  }
181 
182  data.velocities[m_indexA].v = vA;
183  data.velocities[m_indexA].w = wA;
184  data.velocities[m_indexB].v = vB;
185  data.velocities[m_indexB].w = wB;
186 }
187 
189 {
190  B2_NOT_USED(data);
191 
192  return true;
193 }
194 
196 {
198 }
199 
201 {
203 }
204 
206 {
207  return inv_dt * m_linearImpulse;
208 }
209 
211 {
212  return inv_dt * m_angularImpulse;
213 }
214 
216 {
217  b2Assert(b2IsValid(force) && force >= 0.0f);
218  m_maxForce = force;
219 }
220 
222 {
223  return m_maxForce;
224 }
225 
227 {
228  b2Assert(b2IsValid(torque) && torque >= 0.0f);
229  m_maxTorque = torque;
230 }
231 
233 {
234  return m_maxTorque;
235 }
236 
238 {
239  int32 indexA = m_bodyA->m_islandIndex;
240  int32 indexB = m_bodyB->m_islandIndex;
241 
242  b2Log(" b2FrictionJointDef jd;\n");
243  b2Log(" jd.bodyA = bodies[%d];\n", indexA);
244  b2Log(" jd.bodyB = bodies[%d];\n", indexB);
245  b2Log(" jd.collideConnected = bool(%d);\n", m_collideConnected);
246  b2Log(" jd.localAnchorA.Set(%.15lef, %.15lef);\n", m_localAnchorA.x, m_localAnchorA.y);
247  b2Log(" jd.localAnchorB.Set(%.15lef, %.15lef);\n", m_localAnchorB.x, m_localAnchorB.y);
248  b2Log(" jd.maxForce = %.15lef;\n", m_maxForce);
249  b2Log(" jd.maxTorque = %.15lef;\n", m_maxTorque);
250  b2Log(" joints[%d] = m_world->CreateJoint(&jd);\n", m_index);
251 }
b2Velocity * velocities
Definition: b2TimeStep.h:67
float32 m_invMass
Definition: b2Body.h:455
int32 m_islandIndex
Definition: b2Body.h:434
b2Vec2 b2Mul(const b2Mat22 &A, const b2Vec2 &v)
Definition: b2Math.h:433
b2Vec2 localAnchorA
The local anchor point relative to bodyA&#39;s origin.
void b2Log(const char *string,...)
Logging function.
Definition: b2Settings.cpp:38
float32 a
Definition: b2TimeStep.h:52
f
b2TimeStep step
Definition: b2TimeStep.h:65
b2Vec2 localAnchorB
The local anchor point relative to bodyB&#39;s origin.
float32 w
Definition: b2TimeStep.h:59
float32 GetMaxTorque() const
Get the maximum friction torque in N*m.
bool m_collideConnected
Definition: b2Joint.h:181
#define B2_NOT_USED(x)
Definition: b2Settings.h:26
float32 dtRatio
Definition: b2TimeStep.h:42
float32 maxForce
The maximum friction force in N.
float32 LengthSquared() const
Definition: b2Math.h:108
b2Vec2 GetWorldPoint(const b2Vec2 &localPoint) const
Definition: b2Body.h:556
Solver Data.
Definition: b2TimeStep.h:63
void SetZero()
Set this vector to all zeros.
Definition: b2Math.h:62
int32 m_index
Definition: b2Joint.h:178
A 2D column vector.
Definition: b2Math.h:53
b2Vec2 ey
Definition: b2Math.h:253
Friction joint definition.
signed int int32
Definition: b2Settings.h:31
b2Vec2 localCenter
local center of mass position
Definition: b2Math.h:393
float32 b2Cross(const b2Vec2 &a, const b2Vec2 &b)
Perform the cross product on two vectors. In 2D this produces a scalar.
Definition: b2Math.h:412
A rigid body. These are created via b2World::CreateBody.
Definition: b2Body.h:126
b2Vec2 v
Definition: b2TimeStep.h:58
bool b2IsValid(float32 x)
This function is used to ensure that a floating point number is not a NaN or infinity.
Definition: b2Math.h:26
float32 m_invI
Definition: b2Body.h:458
void SetMaxForce(float32 force)
Set the maximum friction force in N.
void InitVelocityConstraints(const b2SolverData &data)
float32 maxTorque
The maximum friction torque in N-m.
float32 m_angularImpulse
b2Body * m_bodyA
Definition: b2Joint.h:175
float32 GetReactionTorque(float32 inv_dt) const
Get the reaction torque on bodyB in N*m.
float32 y
Definition: b2Math.h:140
b2Vec2 GetLocalPoint(const b2Vec2 &worldPoint) const
Definition: b2Body.h:566
float32 GetMaxForce() const
Get the maximum friction force in N.
b2Position * positions
Definition: b2TimeStep.h:66
#define b2Assert(A)
Definition: b2Settings.h:27
void SetMaxTorque(float32 torque)
Set the maximum friction torque in N*m.
T b2Clamp(T a, T low, T high)
Definition: b2Math.h:654
void Initialize(b2Body *bodyA, b2Body *bodyB, const b2Vec2 &anchor)
b2Vec2 GetAnchorA() const
Get the anchor point on bodyA in world coordinates.
void SolveVelocityConstraints(const b2SolverData &data)
b2Vec2 ex
Definition: b2Math.h:253
A 2-by-2 matrix. Stored in column-major order.
Definition: b2Math.h:183
bool warmStarting
Definition: b2TimeStep.h:45
Rotation.
Definition: b2Math.h:299
float32 x
Definition: b2Math.h:140
b2Body * bodyA
The first attached body.
Definition: b2Joint.h:92
float32 Normalize()
Convert this vector into a unit vector. Returns the length.
Definition: b2Math.h:114
float32 dt
Definition: b2TimeStep.h:40
b2Mat22 GetInverse() const
Definition: b2Math.h:223
void Dump()
Dump joint to dmLog.
bool SolvePositionConstraints(const b2SolverData &data)
b2FrictionJoint(const b2FrictionJointDef *def)
b2Body * bodyB
The second attached body.
Definition: b2Joint.h:95
b2Body * m_bodyB
Definition: b2Joint.h:176
b2Vec2 GetAnchorB() const
Get the anchor point on bodyB in world coordinates.
b2Sweep m_sweep
Definition: b2Body.h:437
float float32
Definition: b2Settings.h:35
b2Vec2 GetReactionForce(float32 inv_dt) const
Get the reaction force on bodyB at the joint anchor in Newtons.


mvsim
Author(s):
autogenerated on Thu Jun 6 2019 19:36:40