Blender V4.3
btMultiBodySphericalJointMotor.cpp
Go to the documentation of this file.
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2018 Erwin Coumans http://bulletphysics.org
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
17
19#include "btMultiBody.h"
24
26 : btMultiBodyConstraint(body, body, link, body->getLink(link).m_parent, 3, true, MULTIBODY_CONSTRAINT_SPHERICAL_MOTOR),
27 m_desiredVelocity(0, 0, 0),
28 m_desiredPosition(0,0,0,1),
29 m_kd(1.),
30 m_kp(0.2),
31 m_erp(1),
32 m_rhsClamp(SIMD_INFINITY)
33{
34
35 m_maxAppliedImpulse = maxMotorImpulse;
36}
37
38
40{
42 // note: we rely on the fact that data.m_jacobians are
43 // always initialized to zero by the Constraint ctor
44 int linkDoF = 0;
45 unsigned int offset = 6 + (m_bodyA->getLink(m_linkA).m_dofOffset + linkDoF);
46
47 // row 0: the lower bound
48 // row 0: the lower bound
49 jacobianA(0)[offset] = 1;
50
52}
53
54
58
60{
61 if (this->m_linkA < 0)
62 {
63 btMultiBodyLinkCollider* col = m_bodyA->getBaseCollider();
64 if (col)
65 return col->getIslandTag();
66 }
67 else
68 {
69 if (m_bodyA->getLink(m_linkA).m_collider)
70 {
71 return m_bodyA->getLink(m_linkA).m_collider->getIslandTag();
72 }
73 }
74 return -1;
75}
76
78{
79 if (m_linkB < 0)
80 {
81 btMultiBodyLinkCollider* col = m_bodyB->getBaseCollider();
82 if (col)
83 return col->getIslandTag();
84 }
85 else
86 {
87 if (m_bodyB->getLink(m_linkB).m_collider)
88 {
89 return m_bodyB->getLink(m_linkB).m_collider->getIslandTag();
90 }
91 }
92 return -1;
93}
94
98{
99 // only positions need to be updated -- data.m_jacobians and force
100 // directions were set in the ctor and never change.
101
103 {
105 }
106
107 //don't crash
109 return;
110
111
112 if (m_maxAppliedImpulse == 0.f)
113 return;
114
115 const btScalar posError = 0;
116 const btVector3 dummy(0, 0, 0);
117
118
119 btVector3 axis[3] = { btVector3(1, 0, 0), btVector3(0, 1, 0), btVector3(0, 0, 1) };
120
121 btQuaternion desiredQuat = m_desiredPosition;
122 btQuaternion currentQuat(m_bodyA->getJointPosMultiDof(m_linkA)[0],
123 m_bodyA->getJointPosMultiDof(m_linkA)[1],
124 m_bodyA->getJointPosMultiDof(m_linkA)[2],
125 m_bodyA->getJointPosMultiDof(m_linkA)[3]);
126
127btQuaternion relRot = currentQuat.inverse() * desiredQuat;
128 btVector3 angleDiff;
129 btGeneric6DofSpring2Constraint::matrixToEulerXYZ(btMatrix3x3(relRot), angleDiff);
130
131
132
133 for (int row = 0; row < getNumRows(); row++)
134 {
135 btMultiBodySolverConstraint& constraintRow = constraintRows.expandNonInitializing();
136
137 int dof = row;
138
139 btScalar currentVelocity = m_bodyA->getJointVelMultiDof(m_linkA)[dof];
140 btScalar desiredVelocity = this->m_desiredVelocity[row];
141
142 btScalar velocityError = desiredVelocity - currentVelocity;
143
144 btMatrix3x3 frameAworld;
145 frameAworld.setIdentity();
146 frameAworld = m_bodyA->localFrameToWorld(m_linkA, frameAworld);
147 btScalar posError = 0;
148 {
149 btAssert(m_bodyA->getLink(m_linkA).m_jointType == btMultibodyLink::eSpherical);
150 switch (m_bodyA->getLink(m_linkA).m_jointType)
151 {
153 {
154 btVector3 constraintNormalAng = frameAworld.getColumn(row % 3);
155 posError = m_kp*angleDiff[row % 3];
156 fillMultiBodyConstraint(constraintRow, data, 0, 0, constraintNormalAng,
157 btVector3(0,0,0), dummy, dummy,
158 posError,
160 -m_maxAppliedImpulse, m_maxAppliedImpulse, true);
161 constraintRow.m_orgConstraint = this;
162 constraintRow.m_orgDofIndex = row;
163 break;
164 }
165 default:
166 {
167 btAssert(0);
168 }
169 };
170 }
171 }
172}
btMatrix3x3
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:50
@ MULTIBODY_CONSTRAINT_SPHERICAL_MOTOR
int m_numDofsFinalized
int m_linkB
btMultiBody * m_bodyB
int m_linkA
void allocateJacobiansMultiDof()
int m_jacSizeBoth
btScalar fillMultiBodyConstraint(btMultiBodySolverConstraint &solverConstraint, btMultiBodyJacobianData &data, btScalar *jacOrgA, btScalar *jacOrgB, const btVector3 &constraintNormalAng, const btVector3 &constraintNormalLin, const btVector3 &posAworld, const btVector3 &posBworld, btScalar posError, const btContactSolverInfo &infoGlobal, btScalar lowerLimit, btScalar upperLimit, bool angConstraint=false, btScalar relaxation=1.f, bool isFriction=false, btScalar desiredVelocity=0, btScalar cfmSlip=0)
btScalar * jacobianA(int row)
int getNumRows() const
btMultiBodySolverConstraint
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...
const btMultibodyLink & getLink(int index) const
btMultiBody
Definition btMultiBody.h:51
btScalar m_erp
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition btScalar.h:314
#define SIMD_INFINITY
Definition btScalar.h:544
#define btAssert(x)
Definition btScalar.h:295
btSequentialImpulseConstraintSolverMt int btPersistentManifold int btTypedConstraint int const btContactSolverInfo & infoGlobal
btVector3
btVector3 can be used to represent 3D points and vectors. It has an un-used w component to suit 16-by...
Definition btVector3.h:82
SIMD_FORCE_INLINE T & expandNonInitializing()
btMultiBodySphericalJointMotor(btMultiBody *body, int link, btScalar maxMotorImpulse)
This file was written by Erwin Coumans.
virtual void createConstraintRows(btMultiBodyConstraintArray &constraintRows, btMultiBodyJacobianData &data, const btContactSolverInfo &infoGlobal)
The btQuaternion implements quaternion to perform linear algebra rotations in combination with btMatr...
btQuaternion inverse() const
Return the inverse of this quaternion.
uint col