NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgNodes.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_NODES_H
20 #define TG_NODES_H
21 
30 #include "LinearMath/btVector3.h"
31 #include <iostream>
32 #include <vector>
33 #include <map>
34 #include <set>
35 #include <stdexcept>
36 #include <sstream>
37 
38 #include "tgNode.h"
39 #include "core/tgTaggables.h"
40 
41 class tgPair;
42 
49 class tgNodes : public tgTaggables<tgNode> {
50 public:
51 
56  {
57  }
58 
65  tgNodes(std::vector<btVector3>& nodes) : tgTaggables()
66  {
67  // All elements must be unique
68  assertUniqueElements("All nodes must be unique.");
69 
70  // @todo: There has to be a better way to do this (maybe initializer lists with upcasting btVector3 => tgNode?)
71  for(std::size_t i = 0; i < nodes.size(); i++) {
72  addElement(tgNode(nodes[i]));
73  }
74 
75  }
76 
77  tgNodes(std::vector<tgNode>& nodes) : tgTaggables(nodes) {
78  // All elements must be unique
79  assertUniqueElements("All nodes must be unique.");
80 
81  }
82 
84  ~tgNodes() { }
85 
91  void setNode(int key, const btVector3& node)
92  {
93  setNode(key, tgNode(node));
94  };
95 
96  void setNode(int key, const tgNode& node)
97  {
98  setElement(key, node);
99  }
100 
101  std::vector<tgNode>& getNodes()
102  {
103  return getElements();
104  };
105 
106  const std::vector<tgNode>& getNodes() const
107  {
108  return getElements();
109  };
110 
111 
118  bool nodeExists(int key) const
119  {
120  return keyExists(key);
121  }
122 
129  int addNode(const btVector3& node) {
130  return addNode(tgNode(node));
131  };
132 
133  int addNode(const btVector3& node, std::string tags) {
134  return addNode(tgNode(node, tags));
135  };
136 
137  int addNode(const tgNode& node) {
138  return addElement(node);
139  }
140 
150  // @todo: Maybe replace this with something like:
151  // myNodes += tgNode(1,2,3, "some tags");
152  // or just use myNodes.addNode(tgNode(1,2,3, "tags here"));
153  int addNode(double x, double y, double z)
154  {
155  const btVector3 node(x, y, z);
156  return addNode(node);
157  }
158 
159  int addNode(double x, double y, double z, std::string tags)
160  {
161  const tgNode node(x, y, z, tags);
162  return addNode(node);
163  }
164 
168  tgPair pair(int from, int to, std::string tags = "");
169 
175  void move(const btVector3& offset)
176  {
178  std::vector<tgNode>& nodes = getElements();
179  for(std::size_t i = 0; i < nodes.size(); i++) {
180  nodes[i] += offset;
181  }
182  }
183 
184  void moveNode(int idx, const btVector3 offset)
185  {
186  (*this)[idx] += offset;
187  }
188 
189  void addRotation(const btVector3& fixedPoint,
190  const btVector3& axis,
191  double angle)
192  {
193  btQuaternion rotation(axis, angle);
194  addRotation(fixedPoint, rotation);
195  }
196 
197  void addRotation(const btVector3& fixedPoint,
198  const btVector3& fromOrientation,
199  const btVector3& toOrientation)
200  {
201  btQuaternion rotation = tgUtil::getQuaternionBetween(fromOrientation,
202  toOrientation);
203  addRotation(fixedPoint, rotation);
204  }
205 
206  void addRotation(const btVector3& fixedPoint,
207  const btQuaternion& rotation)
208  {
209  std::vector<tgNode>& nodes = getNodes();
210  for(std::size_t i = 0; i < nodes.size(); i++) {
211  nodes[i].addRotation(fixedPoint, rotation);
212  }
213  }
214 
215  /*
216  * Scales nodes relative to a reference point
217  * @param[in] referencePoint a btVector3 reference point to scale the nodes from/to
218  * @param[in] scaleFactor the scale factor by which to scale the nodes
219  */
220  void scale(const btVector3& referencePoint, double scaleFactor) {
221  std::vector<tgNode>& nodes = getNodes();
222  for(int i = 0; i < nodes.size(); i++) {
223  nodes[i].setX((nodes[i].x() - referencePoint.x()) * scaleFactor + referencePoint.x());
224  nodes[i].setY((nodes[i].y() - referencePoint.y()) * scaleFactor + referencePoint.y());
225  nodes[i].setZ((nodes[i].z() - referencePoint.z()) * scaleFactor + referencePoint.z());
226  }
227  }
228 
229 protected:
230 
231  // A map of m_nodes keys to names. Note that not all m_nodes will have names.
232  std::map<int, std::string> m_names; // @todo: remove this...
233 
234  void assertNodeExists(int key) const
235  {
236  if(!keyExists(key)) {
237  std::stringstream ss;
238  ss << key;
239  throw std::out_of_range("Node at index " + ss.str() + " does not exist");
240  }
241  }
242 
243  void assertUniqueNodes() const
244  {
245  assertUniqueElements("Nodes muse be unique.");
246  }
247 
248 };
249 
250 
258 inline std::ostream&
259 operator<<(std::ostream& os, const tgNodes& n)
260 {
261  os << "tgNodes(" << std::endl;
262  const std::vector<tgNode>& nodes = n.getNodes();
263  for(std::size_t i = 0; i < nodes.size(); i++) {
264  os << " " << nodes[i] << std::endl;
265  }
266  os << ")";
267 
268  return os;
269 };
270 
271 
276 inline std::string asYamlItems(const tgNodes& nodes, int indentLevel=0)
277 {
278  std::stringstream os;
279  std::string indent = std::string(2 * (indentLevel), ' ');
280 
281  if (nodes.size() == 0) {
282  os << indent << "nodes: []" << std::endl;
283  return os.str();
284  }
285 
286  os << indent << "nodes:" << std::endl;
287  for(size_t i = 0; i < nodes.size(); i++)
288  {
289  os << asYamlItem(nodes[i], indentLevel+1);
290  }
291  return os.str();
292 };
293 
294 
295 
296 #endif
static btQuaternion getQuaternionBetween(btVector3 a, btVector3 b, const btVector3 &fallbackAxis=btVector3(0, 0, 0))
Definition: tgUtil.h:199
void setNode(int key, const btVector3 &node)
Definition: tgNodes.h:91
~tgNodes()
Definition: tgNodes.h:84
bool nodeExists(int key) const
Definition: tgNodes.h:118
tgPair pair(int from, int to, std::string tags="")
Definition: tgNodes.cpp:30
Contains the definition of class tgTaggables.
Definition of class tgNode.
Definition: tgPair.h:48
Definition: tgNode.h:45
tgNodes()
Definition: tgNodes.h:55
std::string asYamlItems(const tgNodes &nodes, int indentLevel=0)
Definition: tgNodes.h:276
int addNode(double x, double y, double z)
Definition: tgNodes.h:153
tgNodes(std::vector< btVector3 > &nodes)
Definition: tgNodes.h:65
std::ostream & operator<<(std::ostream &os, const tgNodes &n)
Definition: tgNodes.h:259
std::string asYamlItem(const tgNode &node, int indentLevel=0)
Definition: tgNode.h:125
void move(const btVector3 &offset)
Definition: tgNodes.h:175
int addNode(const btVector3 &node)
Definition: tgNodes.h:129
bool keyExists(int key) const
Definition: tgTaggables.h:229