NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgBoxInfo.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 
27 // This Module
28 #include "tgBoxInfo.h"
29 
30 // The NTRT Core library
32 
33 // The Bullet Physics Library
34 #include "LinearMath/btVector3.h"
35 #include "BulletCollision/CollisionShapes/btBoxShape.h"
36 
37 // The C++ Standard Library
38 #include <algorithm>
39 #include <stdexcept>
40 #include <cassert>
41 
42 // @todo: Need to take tags into account...
43 
45  tgRigidInfo(),
46  m_pair(),
47  m_config(config)
48 {}
49 
50 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, tgTags tags) :
51  tgRigidInfo(tags),
52  m_pair(),
53  m_config(config)
54 {}
55 
56 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, const tgPair& pair) :
57  tgRigidInfo(pair.getTags()),
58  m_pair(pair),
59  m_config(config)
60 {}
61 
62 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, tgTags tags, const tgPair& pair) :
63  tgRigidInfo( tags + pair.getTags() ),
64  m_pair(pair),
65  m_config(config)
66 {}
67 
69 {
70  return new tgBoxInfo(m_config, pair);
71 }
72 
74 {
75  tgRigidInfo::initRigidBody(world);
76  assert(m_collisionObject != NULL);
77  getRigidBody()->setFriction(m_config.friction);
78  getRigidBody()->setRollingFriction(m_config.rollFriction);
79  getRigidBody()->setRestitution(m_config.restitution);
80 }
81 
82 tgModel* tgBoxInfo::createModel(tgWorld& world)
83 {
84  // @todo: handle tags -> model
85  // @todo: check to make sure the rigidBody has been built
86  // @todo: Do we need to use the group here?
87 
88  // Just in case it hasn't been done already...
89  initRigidBody(world);
90 
91  #if (0)
92  std::cout << "creating box with tags " << getTags() << std::endl;
93  #endif
94 
95  tgBox* box = new tgBox(getRigidBody(), getTags(), getLength());
96 
97  return box;
98 }
99 
100 btCollisionShape* tgBoxInfo::getCollisionShape(tgWorld& world) const
101 {
102  if (m_collisionShape == NULL)
103  {
104  const double width = m_config.width;
105  const double height = m_config.height;
106  const double length = getLength();
107  // Nominally x, y, z should we adjust here or the transform?
109  new btBoxShape(btVector3(width, length / 2.0, height));
110 
111  // Add the collision shape to the array so we can delete it later
112  tgWorldBulletPhysicsImpl& bulletWorld =
114  bulletWorld.addCollisionShape(m_collisionShape);
115  }
116  return m_collisionShape;
117 }
118 
119 double tgBoxInfo::getMass() const
120 {
121  // NOTE that this function previously assumed that the full width and full height
122  // of the box are specified by the config. However, the box is actually
123  // twice that width and twice that height. See the call to btBoxShape inside
124  // the getCollisionShape method in this class.
125  // This function now corrects for a proper volume.
126  const double length = getLength();
127  const double width = m_config.width;
128  const double height = m_config.height;
129  const double density = m_config.density;
130  const double volume = length * (width*2) * (height*2);
131  return volume * density;
132 }
133 
134 btVector3
135 tgBoxInfo::getConnectionPoint(const btVector3& referencePoint,
136  const btVector3& destinationPoint) const
137 {
138  return getConnectionPoint(referencePoint, destinationPoint, 0);
139 }
140 
141 btVector3
142 tgBoxInfo::getConnectionPoint(const btVector3& referencePoint,
143  const btVector3& destinationPoint,
144  const double rotation) const
145 {
146  if (referencePoint == destinationPoint)
147  {
148  throw
149  std::invalid_argument("Destination point is the reference point.");
150  }
151  // Find the closest point on the radius from the referencePoint
152  const btVector3 cylinderAxis = (getTo() - getFrom()).normalize();
153  const btVector3 cylinderAxis2 = (getTo() - getFrom()).normalize();
154  // Vector from reference point to destination point
155  const btVector3 refToDest =
156  (referencePoint - destinationPoint).normalize();
157 
158  // Find a vector perpendicular to both the cylinder axis and refToDest
159  btVector3 rotationAxis = cylinderAxis.cross(refToDest);
160 
161  // Handle a vector crossed with itself
162  if (rotationAxis.length() == 0.0)
163  {
164  btScalar a = cylinderAxis[0];
165  btScalar b = cylinderAxis[1];
166  btScalar c = cylinderAxis[2];
167  // Find an arbitrary perpendicular vector
168  rotationAxis = btVector3(b - c, -a, a).normalize();
169  }
170 
171  const btVector3 directional =
172  cylinderAxis.rotate(rotationAxis, -M_PI / 2.0).normalize();
173 
174  // Apply one additional rotation so we can end up anywhere we
175  // want on the radius of the box
176 
177  // When added to any point along the cylinder axis, this will take you
178  // to the surface in the direction of the destinationPoint
179 
180  const btVector3 surfaceVector = directional.rotate(cylinderAxis2, rotation).normalize()
181  * m_config.width;
182 
183  // Return the the surface point closest to the reference point in the
184  // direction of the destination point.
185  return referencePoint + surfaceVector;
186 }
187 
188 std::set<tgRigidInfo*> tgBoxInfo::getLeafRigids()
189 {
190  std::set<tgRigidInfo*> leaves;
191  leaves.insert(this);
192  return leaves;
193 }
194 
195 std::set<btVector3> tgBoxInfo::getContainedNodes() const {
196  std::set<btVector3> contained;
197  contained.insert(getFrom());
198  contained.insert(getTo());
199  return contained;
200 }
const double restitution
Definition: tgBox.h:86
virtual btVector3 getConnectionPoint(const btVector3 &referencePoint, const btVector3 &destinationPoint) const
Definition: tgBoxInfo.cpp:135
const double height
Definition: tgBox.h:71
const double rollFriction
Definition: tgBox.h:82
virtual double getMass() const
Definition: tgBoxInfo.cpp:119
tgRigidInfo * createRigidInfo(const tgPair &pair)
Definition: tgBoxInfo.cpp:68
virtual std::set< tgRigidInfo * > getLeafRigids()
Definition: tgBoxInfo.cpp:188
Contains the definition of class tgWorldBulletPhysicsImpl.
virtual void initRigidBody(tgWorld &world)
Definition: tgBoxInfo.cpp:73
virtual btCollisionShape * getCollisionShape(tgWorld &world) const
Definition: tgBoxInfo.cpp:100
const double density
Definition: tgBox.h:74
Definition: tgBox.h:43
const btVector3 & getFrom() const
Definition: tgBoxInfo.h:110
Class that interfaces with Bullet to build the boxes.
virtual std::set< btVector3 > getContainedNodes() const
Definition: tgBoxInfo.cpp:195
const btVector3 & getTo() const
Definition: tgBoxInfo.h:113
virtual btRigidBody * getRigidBody()
btCollisionObject * m_collisionObject
Definition: tgRigidInfo.h:347
tgWorldImpl & implementation() const
Definition: tgWorld.h:108
Definition: tgPair.h:48
tgBoxInfo(const tgBox::Config &config)
Definition: tgBoxInfo.cpp:44
double getLength() const
Definition: tgBoxInfo.h:213
void addCollisionShape(btCollisionShape *pShape)
const double width
Definition: tgBox.h:68
Definition: tgTags.h:44
btCollisionShape * m_collisionShape
Definition: tgRigidInfo.h:332
const double friction
Definition: tgBox.h:78