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