Bullet Collision Detection & Physics Library
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),
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
97 const btContactSolverInfo& infoGlobal)
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;
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,
159 infoGlobal,
161 constraintRow.m_orgConstraint = this;
162 constraintRow.m_orgDofIndex = row;
163 break;
164 }
165 default:
166 {
167 btAssert(0);
168 }
169 };
170 }
171 }
172}
@ MULTIBODY_CONSTRAINT_SPHERICAL_MOTOR
btAlignedObjectArray< btMultiBodySolverConstraint > btMultiBodyConstraintArray
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:153
static bool matrixToEulerXYZ(const btMatrix3x3 &mat, btVector3 &xyz)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
Definition btMatrix3x3.h:50
void setIdentity()
Set the matrix to the identity.
btVector3 getColumn(int i) const
Get a column of the matrix as a vector.
btScalar * jacobianA(int row)
btMultiBodyConstraint(btMultiBody *bodyA, btMultiBody *bodyB, int linkA, int linkB, int numRows, bool isUnilateral, int type)
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)
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.
btVector3 can be used to represent 3D points and vectors.
Definition btVector3.h:82
1D constraint along a normal axis between bodyA and bodyB. It can be combined to solve contact and fr...