NTRT Simulator  v1.1
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgUtil.h
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 #ifndef TG_UTIL_H
20 #define TG_UTIL_H
21 
31 #include "btBulletDynamicsCommon.h" // stream operations for collision shapes
32 #include "LinearMath/btQuaternion.h"
33 #include "LinearMath/btTransform.h"
34 #include "LinearMath/btVector3.h"
35 #include <cmath>
36 #include <iostream>
37 #include <sstream>
38 #include <string>
39 
40 #include "tgRigidInfo.h"
41 
46 class tgUtil
47 {
48 public:
49 
54  inline static btVector3 upVector()
55  {
56  return btVector3(0.0, 1.0, 0.0);
57  };
58 
63  inline static std::string degSymbol()
64  {
65  return "\u00B0";
66  }
67 
74  inline static btVector3 center(const btVector3& start,
75  const btVector3& end)
76  {
77  return (start + end) / 2.0;
78  }
79 
90  inline static btTransform getTransform(const btVector3& startOrientation,
91  const btVector3& start,
92  const btVector3& end)
93  {
94 
95  const btVector3 origin = center(start, end);
96  btTransform t = btTransform();
97  t.setIdentity();
98  t.setOrigin(origin);
99  // If they for some reason gave us the same vector, keep identity
100 
101  t.setRotation(getQuaternionBetween(startOrientation,
102  getVector(start, end)));
103 
104  return t;
105  }
106 
112  inline static btTransform getTransform(const btVector3& start,
113  const btVector3& end)
114  {
115  return getTransform(upVector(), start, end);
116  }
117 
118  inline static btTransform getTransform(const btVector3& center)
119  {
120  btTransform t = btTransform();
121  t.setIdentity();
122  t.setOrigin(center);
123  // No point in rotating, keep identity
124  return t;
125  }
126 
133  static btVector3 getVector(const btVector3& from,
134  const btVector3& to)
135  {
136  return to - from;
137  }
138 
157  static btVector3 getRadiusVector(btVector3 axis,
158  double radius,
159  btVector3 target)
160  {
161  // NOTE: axis and target are passed by value,
162  // so we can alter them.
163  axis.normalize();
164  target.normalize();
165  // Get a vector normal to both
166  const btVector3 norm = axis.cross(target);
167  // Rotate the axis by 90 degrees around the normal vector
168  axis.rotate(norm, (M_PI / 2.0));
169  return axis;
170  }
171 
180  static bool almostEqual(const btVector3& from,
181  const btVector3& to,
182  int precision = 5)
183  {
184  return from.distance(to) < pow(10.0, (precision < 0 ? 5 : -precision));
185  }
186 
196  static btQuaternion getQuaternionBetween(btVector3 a, btVector3 b)
197  {
198  a.normalize();
199  b.normalize();
200 
201  // The return value
202  btQuaternion result;
203 
204  // Account for equal vectors (can't calculate c in this case)
205  if (almostEqual(a, b)) {
206  result = btQuaternion::getIdentity();
207  } else if (almostEqual(a, -b)) {
208  // Account for opposing vectors (can't calculate c in
209  // this case either)
210  btVector3 xAxis(1.0, 0.0, 0.0);
211  if (a.dot(xAxis) == 0.0)
212  {
213  // Gets around bad btTransforms with an up vector
214  result = btQuaternion (-1.0, 0.0, 0.0, 0.0);
215  }
216  else
217  {
218  const btVector3 arb =
220  const btVector3 c = (a.cross(arb)).normalize();
221  result = btQuaternion(c, M_PI).normalize();
222  }
223  } else {
224  // Create a vector normal to both a and b
225  const btVector3 c = (a.cross(b)).normalize();
226 
227  // Create a quaternion that represents a rotation about
228  // c by the angle between a and b
229  result = btQuaternion(c, acos(a.dot(b))).normalize();
230  }
231  return result;
232  }
233 
239  inline static btVector3 getArbitraryNonParallelVector(btVector3 v)
240  {
241  btVector3 arb;
242  v.normalize();
243  do {
244  arb = btVector3(rand()%10, rand()%10, rand()%10).normalize();
245  } while (arb == v || arb == -v);
246  return arb;
247  }
248 
252  inline static void addRotation(btVector3& v,
253  const btVector3& fixedPoint,
254  const btVector3& axis,
255  double angle)
256  {
257  // Get a vector from fixedPoint to this
258  btVector3 relative = v - fixedPoint;
259 
260  // Rotate the relative vector
261  btVector3 rotated = relative.rotate(axis, angle);
262 
263  // Set our new values
264  v.setX(fixedPoint.x() + rotated.x());
265  v.setY(fixedPoint.y() + rotated.y());
266  v.setZ(fixedPoint.z() + rotated.z());
267  }
268 
272  inline static void addRotation(btVector3& v,
273  const btVector3& fixedPoint,
274  const btVector3& fromOrientation,
275  const btVector3& toOrientation)
276  {
277  btQuaternion rotation = getQuaternionBetween(fromOrientation, toOrientation);
278  addRotation(v, fixedPoint, rotation);
279  }
280 
284  inline static void addRotation(btVector3& v,
285  const btVector3& fixedPoint,
286  const btQuaternion& rotation)
287  {
288  addRotation(v, fixedPoint, rotation.getAxis(), rotation.getAngle());
289  }
290 
302  inline static double rad2deg(double radians)
303  {
304  return radians * 180.0 / M_PI;
305  }
306 
313  inline static double deg2rad(double degrees)
314  {
315  return degrees * (M_PI / 180.0);
316  }
317 
325  inline static std::string strDeg(double degrees) {
326  std::ostringstream s;
327  s << degrees << degSymbol();
328  return s.str();
329  }
330  //static std::string strDeg(double degrees);
331 
332  inline static double round(double d, int precision = 5)
333  {
334  const double base = 10.0;
335  const int m = static_cast<int>(pow(base, precision));
336  return floor(d * m + 0.5)/m;
337  }
338 
339 };
340 
348 inline std::ostream&
349 operator<<(std::ostream& os, const btQuaternion& q)
350 {
351  os << "btQuaternion( "
352  << q.x() << ", " << q.y() << ", " << q.z() << ", " << q.w()
353  << " )";
354  return os;
355 }
356 
364 inline std::ostream&
365 operator<<(std::ostream& os, const btVector3& v)
366 {
367  os << "btVector3( " << v.x() << ", " << v.y() << ", " << v.z() << " )";
368  return os;
369 }
370 
378 inline std::ostream&
379 operator<<(std::ostream& os, const btTransform& xf)
380 {
381  os << "btTransform: origin = " << xf.getOrigin()
382  << "; rotation = " << xf.getRotation();
383  return os;
384 }
385 
393 inline std::ostream&
394 operator<<(std::ostream& os, const btRigidBody& rb)
395 {
396  os << "btRigidBody: " << rb.getCollisionShape();
397  return os;
398 }
399 
407 inline std::ostream&
408 operator<<(std::ostream& os, const btCollisionShape& cs)
409 {
410  os << "btCollisionShape: " << cs.getShapeType();
411  return os;
412 }
413 
421 inline std::ostream&
422 operator<<(std::ostream& os, const btCompoundShape& cs)
423 {
424  os << "btCompoundShape: " << cs.getShapeType() << std::endl
425  << " # Children: " << cs.getNumChildShapes() << std::endl;
426  return os;
427 }
428 
429 
430 
431 #endif // TG_UTIL_H
Definition of abstract class tgRigidInfo.
std::ostream & operator<<(std::ostream &os, const btQuaternion &q)
Definition: tgUtil.h:349
static btVector3 getVector(const btVector3 &from, const btVector3 &to)
Definition: tgUtil.h:133
static btVector3 getArbitraryNonParallelVector(btVector3 v)
Definition: tgUtil.h:239
Definition: tgUtil.h:46
static std::string degSymbol()
Definition: tgUtil.h:63
static bool almostEqual(const btVector3 &from, const btVector3 &to, int precision=5)
Definition: tgUtil.h:180
static btQuaternion getQuaternionBetween(btVector3 a, btVector3 b)
Definition: tgUtil.h:196
static btVector3 upVector()
Definition: tgUtil.h:54
static void addRotation(btVector3 &v, const btVector3 &fixedPoint, const btVector3 &fromOrientation, const btVector3 &toOrientation)
Definition: tgUtil.h:272
static double deg2rad(double degrees)
Definition: tgUtil.h:313
static btVector3 center(const btVector3 &start, const btVector3 &end)
Definition: tgUtil.h:74
static void addRotation(btVector3 &v, const btVector3 &fixedPoint, const btQuaternion &rotation)
Definition: tgUtil.h:284
static btVector3 getRadiusVector(btVector3 axis, double radius, btVector3 target)
Definition: tgUtil.h:157
static btTransform getTransform(const btVector3 &startOrientation, const btVector3 &start, const btVector3 &end)
Definition: tgUtil.h:90
static btTransform getTransform(const btVector3 &start, const btVector3 &end)
Definition: tgUtil.h:112
static std::string strDeg(double degrees)
Definition: tgUtil.h:325
static void addRotation(btVector3 &v, const btVector3 &fixedPoint, const btVector3 &axis, double angle)
Definition: tgUtil.h:252
static double rad2deg(double radians)
Definition: tgUtil.h:302