NTRT Simulator  v1.1
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgWorldBulletPhysicsImpl.cpp
Go to the documentation of this file.
1 /*
2  * Copyright © 2012, United States Government, as represented by the
3  * Administrator of the National Aeronautics and Space Administration.
4  * All rights reserved.
5  *
6  * The NASA Tensegrity Robotics Toolkit (NTRT) v1 platform is licensed
7  * under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * http://www.apache.org/licenses/LICENSE-2.0.
11  *
12  * Unless required by applicable law or agreed to in writing,
13  * software distributed under the License is distributed on an
14  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
15  * either express or implied. See the License for the specific language
16  * governing permissions and limitations under the License.
17  */
18 
19 
27 // This module
29 // This application
30 #include "tgWorld.h"
31 #include "tgCast.h"
32 #include "terrain/tgBulletGround.h"
33 #include "terrain/tgEmptyGround.h"
34 // The Bullet Physics library
35 #include "BulletCollision/BroadphaseCollision/btBroadphaseInterface.h"
36 #include "BulletCollision/BroadphaseCollision/btDbvtBroadphase.h"
37 #include "BulletCollision/BroadphaseCollision/btAxisSweep3.h" // New broadphase
38 #include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
39 #include "BulletCollision/CollisionDispatch/btDefaultCollisionConfiguration.h"
40 #include "BulletCollision/CollisionShapes/btBoxShape.h"
41 #include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
42 #include "BulletCollision/CollisionShapes/btCompoundShape.h"
43 #include "BulletDynamics/Dynamics/btRigidBody.h"
44 #include "BulletDynamics/Dynamics/btDynamicsWorld.h"
45 #include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
46 #include "BulletSoftBody/btSoftBodyRigidBodyCollisionConfiguration.h"
47 #include "BulletSoftBody/btSoftRigidDynamicsWorld.h"
48 #include "LinearMath/btDefaultMotionState.h"
49 #include "LinearMath/btScalar.h"
50 #include "LinearMath/btTransform.h"
51 #include "LinearMath/btVector3.h"
52 #include "LinearMath/btQuickprof.h"
53 
54 // Ghost objects
55 #include "BulletCollision/CollisionDispatch/btGhostObject.h"
56 #include "BulletCollision/BroadphaseCollision/btOverlappingPairCache.h"
57 
58 #define MCLP_SOLVER
59 
60 #ifdef MLCP_SOLVER
61 
62 #include "BulletDynamics/MLCPSolvers/btDantzigSolver.h"
63 #include "BulletDynamics/MLCPSolvers/btSolveProjectedGaussSeidel.h"
64 #include "BulletDynamics/MLCPSolvers/btMLCPSolver.h"
65 
66 #endif //MLCP_SOLVER
67 
73 {
74  public:
75  IntermediateBuildProducts(double worldSize) :
76  corner1 (-worldSize,-worldSize, -worldSize),
77  corner2 (worldSize, worldSize, worldSize),
78  dispatcher(&collisionConfiguration),
79  ghostCallback(),
80 #ifndef MLCP_SOLVER
81  #if (1) // More acc broadphase - remeber the comma (consider doing ifndef)
82  broadphase(corner1, corner2, 16384)
83  #endif // Broadphase
84 #else
85  broadphase(corner1, corner2, 16384),
86  solver(&mlcp)
87 #endif //MLCP_SOLVER
88 
89  {
90  broadphase.getOverlappingPairCache()->setInternalGhostPairCallback(&ghostCallback);
91  }
92  const btVector3 corner1;
93  const btVector3 corner2;
94  btSoftBodyRigidBodyCollisionConfiguration collisionConfiguration;
95  btCollisionDispatcher dispatcher;
96  btGhostPairCallback ghostCallback;
97 #if (0) // Default broadphase
98  btDbvtBroadphase broadphase;
99 #else
100  // More accurate broadphase:
101  btAxisSweep3 broadphase;
102 #endif
103 
104 #ifdef MLCP_SOLVER
105  //btDantzigSolver mlcp;
106  btSolveProjectedGaussSeidel mlcp;
107  btMLCPSolver solver;
108 #else
109  btSequentialImpulseConstraintSolver solver;
110 #endif
111 
112 };
113 
115  tgBulletGround* ground) :
116  tgWorldImpl(config, ground),
117  m_pIntermediateBuildProducts(new IntermediateBuildProducts(config.worldSize)),
118  m_pDynamicsWorld(createDynamicsWorld())
119 {
120 
121  // Gravitational acceleration is down on the Y axis
122  const btVector3 gravityVector(0, -config.gravity, 0);
123  m_pDynamicsWorld->setGravity(gravityVector);
124 
125  if (!tgCast::cast<tgBulletGround, tgEmptyGround>(ground) && ground != NULL)
126  {
127  m_pDynamicsWorld->addRigidBody(ground->getGroundRigidBody());
128  }
129 
130  /*
131  * These are lines from the old BasicLearningApp.cpp that we aren't using.
132  * http://bulletphysics.org/mediawiki-1.5.8/index.php/BtContactSolverInfo
133  */
134  #if (0)
135  // Split impulse does not appear to apply to MLCP solver
136  m_pDynamicsWorld->getSolverInfo().m_splitImpulse = true;
137  m_pDynamicsWorld->getSolverInfo().m_splitImpulsePenetrationThreshold = -0.02;
138 
139  // Default is 10 - increases runtime but decreases odds of penetration
140  // Makes tetraspine sine waves more accurate and static test less accurate
141  m_pDynamicsWorld->getSolverInfo().m_numIterations = 20;
142  #endif
143 
144  // Postcondition
145  assert(invariant());
146 }
147 
149 {
150  // Delete all the collision objects. The dynamics world must exist.
151  // Delete in reverse order of creation.
152  const size_t nco = m_pDynamicsWorld->getNumCollisionObjects();
153  btCollisionObjectArray& oa = m_pDynamicsWorld->getCollisionObjectArray();
154  for (int i = nco - 1; i >= 0; --i)
155  {
156  btCollisionObject * const pCollisionObject = oa[i];
157 
158  // If the collision object is a rigid body, delete its motion state
159  const btRigidBody* const pRigidBody =
160  btRigidBody::upcast(pCollisionObject);
161  if (pRigidBody)
162  {
163  delete pRigidBody->getMotionState();
164  }
165 
166  // Remove the collision object from the dynamics world
167  m_pDynamicsWorld->removeCollisionObject(pCollisionObject);
168  // Delete the collision object
169  delete pCollisionObject;
170  }
171  // All collision objects have been removed and deleted
172  assert(m_pDynamicsWorld->getNumCollisionObjects() == 0);
173 
174  // Delete all the collision shapes. This can be done at any time.
175  const size_t ncs = m_collisionShapes.size();
176 
177  for (size_t i = 0; i < ncs; ++i) { delete m_collisionShapes[i]; }
178 
179  delete m_pDynamicsWorld;
180 
181  // Delete the intermediate build products, which are now orphaned
182  delete m_pIntermediateBuildProducts;
183 }
184 
189 btDynamicsWorld* tgWorldBulletPhysicsImpl::createDynamicsWorld() const
190 {
191  btSoftRigidDynamicsWorld* const result =
192  new btSoftRigidDynamicsWorld(&m_pIntermediateBuildProducts->dispatcher,
193  &m_pIntermediateBuildProducts->broadphase,
194  &m_pIntermediateBuildProducts->solver,
195  &m_pIntermediateBuildProducts->collisionConfiguration);
196 #ifdef MLCPSOLVER
197  result ->getSolverInfo().m_minimumSolverBatchSize = 1;//for direct solver it is better to have a small A matrix
198 #endif
199  return result;
200 }
201 
203 {
204  // Precondition
205  assert(dt > 0.0);
206 
207  const btScalar timeStep = dt;
208  const int maxSubSteps = 1;
209  const btScalar fixedTimeStep = dt;
210  m_pDynamicsWorld->stepSimulation(timeStep, maxSubSteps, fixedTimeStep);
211 
212  // Postcondition
213  assert(invariant());
214 }
215 
216 void tgWorldBulletPhysicsImpl::addCollisionShape(btCollisionShape* pShape)
217 {
218 #ifndef BT_NO_PROFILE
219  BT_PROFILE("addCollisionShape");
220 #endif //BT_NO_PROFILE
221 
222  if (pShape)
223  {
224  m_collisionShapes.push_back(pShape);
225  }
226 
227  // Postcondition
228  assert(invariant());
229 }
230 
232 {
233 #ifndef BT_NO_PROFILE
234  BT_PROFILE("deleteCollisionShape");
235 #endif //BT_NO_PROFILE
236 
237  if (pShape)
238  {
239  btCompoundShape* cShape = tgCast::cast<btCollisionShape, btCompoundShape>(pShape);
240  if (cShape)
241  {
242  std::size_t n = cShape->getNumChildShapes();
243  for( std::size_t i = 0; i < n; i++)
244  {
245  deleteCollisionShape(cShape->getChildShape(i));
246  }
247  }
248  m_collisionShapes.remove(pShape);
249  delete pShape;
250  }
251 
252  // Postcondition
253  assert(invariant());
254 }
255 
256 bool tgWorldBulletPhysicsImpl::invariant() const
257 {
258  return (m_pDynamicsWorld != 0);
259 }
260 
Contains the definition of class tgBulletGround.
Contains the definition of class tgWorldBulletPhysicsImpl.
Utility class for class casting and filtering collections by type.
tgWorldBulletPhysicsImpl(const tgWorld::Config &config, tgBulletGround *ground)
double gravity
Definition: tgWorld.h:53
virtual btRigidBody * getGroundRigidBody() const =0
Contains the definition of class tgWorld $Id$.
void addCollisionShape(btCollisionShape *pShape)
void deleteCollisionShape(btCollisionShape *pShape)
Contains the definition of class tgEmptyGround.