NTRT Simulator  v1.1
 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  m_pair(),
46  m_config(config),
47  tgRigidInfo()
48 {}
49 
50 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, tgTags tags) :
51  m_pair(),
52  m_config(config),
53  tgRigidInfo(tags)
54 {}
55 
56 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, const tgPair& pair) :
57  m_pair(pair),
58  m_config(config),
59  tgRigidInfo(pair.getTags())
60 {}
61 
62 tgBoxInfo::tgBoxInfo(const tgBox::Config& config, tgTags tags, const tgPair& pair) :
63  m_pair(pair),
64  m_config(config),
65  tgRigidInfo( tags + pair.getTags() )
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  const double length = getLength();
122  const double width = m_config.width;
123  const double height = m_config.height;
124  const double density = m_config.density;
125  const double volume = length * width * height;
126  return volume * density;
127 }
128 
129 btVector3
130 tgBoxInfo::getConnectionPoint(const btVector3& referencePoint,
131  const btVector3& destinationPoint) const
132 {
133  return getConnectionPoint(referencePoint, destinationPoint, 0);
134 }
135 
136 btVector3
137 tgBoxInfo::getConnectionPoint(const btVector3& referencePoint,
138  const btVector3& destinationPoint,
139  const double rotation) const
140 {
141  if (referencePoint == destinationPoint)
142  {
143  throw
144  std::invalid_argument("Destination point is the reference point.");
145  }
146  // Find the closest point on the radius from the referencePoint
147  const btVector3 cylinderAxis = (getTo() - getFrom()).normalize();
148  const btVector3 cylinderAxis2 = (getTo() - getFrom()).normalize();
149  // Vector from reference point to destination point
150  const btVector3 refToDest =
151  (referencePoint - destinationPoint).normalize();
152 
153  // Find a vector perpendicular to both the cylinder axis and refToDest
154  btVector3 rotationAxis = cylinderAxis.cross(refToDest);
155 
156  // Handle a vector crossed with itself
157  if (rotationAxis.length() == 0.0)
158  {
159  btScalar a = cylinderAxis[0];
160  btScalar b = cylinderAxis[1];
161  btScalar c = cylinderAxis[2];
162  // Find an arbitrary perpendicular vector
163  rotationAxis = btVector3(b - c, -a, a).normalize();
164  }
165 
166  const btVector3 directional =
167  cylinderAxis.rotate(rotationAxis, -M_PI / 2.0).normalize();
168 
169  // Apply one additional rotation so we can end up anywhere we
170  // want on the radius of the box
171 
172  // When added to any point along the cylinder axis, this will take you
173  // to the surface in the direction of the destinationPoint
174 
175  const btVector3 surfaceVector = directional.rotate(cylinderAxis2, rotation).normalize()
176  * m_config.width;
177 
178  // Return the the surface point closest to the reference point in the
179  // direction of the destination point.
180  return referencePoint + surfaceVector;
181 }
182 
183 std::set<tgRigidInfo*> tgBoxInfo::getLeafRigids()
184 {
185  std::set<tgRigidInfo*> leaves;
186  leaves.insert(this);
187  return leaves;
188 }
189 
190 std::set<btVector3> tgBoxInfo::getContainedNodes() const {
191  std::set<btVector3> contained;
192  contained.insert(getFrom());
193  contained.insert(getTo());
194  return contained;
195 }
const double restitution
Definition: tgBox.h:86
virtual btVector3 getConnectionPoint(const btVector3 &referencePoint, const btVector3 &destinationPoint) const
Definition: tgBoxInfo.cpp:130
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:183
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:190
const btVector3 & getTo() const
Definition: tgBoxInfo.h:113
virtual btRigidBody * getRigidBody()
btCollisionObject * m_collisionObject
Definition: tgRigidInfo.h:347
tgWorldImpl & implementation() const
Definition: tgWorld.h:102
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