NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgStructureInfo.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 "tgStructureInfo.h"
29 // This library
30 #include "tgConnectorInfo.h"
31 #include "tgRigidAutoCompound.h"
32 #include "tgStructure.h"
33 #include "core/tgWorld.h"
34 #include "core/tgModel.h"
35 // The C++ Standard Library
36 #include <stdexcept>
37 
38 tgStructureInfo::tgStructureInfo(tgStructure& structure, tgBuildSpec& buildSpec) :
39  tgTaggable(),
40  m_structure(structure),
41  m_buildSpec(buildSpec)
42 {
43  createTree(*this, structure);
44 }
45 
46 tgStructureInfo::tgStructureInfo(tgStructure& structure, tgBuildSpec& buildSpec,
47  const tgTags& tags) :
48  tgTaggable(tags),
49  m_structure(structure),
50  m_buildSpec(buildSpec)
51 {
52  createTree(*this, structure);
53 }
54 
55 tgStructureInfo::~tgStructureInfo()
56 {
57  // Have to do this first, if all the rigids are deleted it segfaults
58  for (std::size_t i = 0; i < m_compounded.size(); i++)
59  {
60  const tgRigidInfo * const pRigidInfo = m_compounded[i];
61  assert(pRigidInfo != NULL);
62  // If this is true, rigid is in a group with itself, and
63  // will be deleted with m_rigids
64  if (pRigidInfo->getRigidInfoGroup() != pRigidInfo)
65  {
66  delete pRigidInfo;
67  }
68  }
69 
70  for (std::size_t i = 0; i < m_rigids.size(); i++)
71  {
72  delete m_rigids[i];
73  }
74 
75  for (std::size_t i = 0; i < m_connectors.size(); i++)
76  {
77  delete m_connectors[i];
78  }
79 
80  for (std::size_t i = 0; i < m_children.size(); i++)
81  {
82  delete m_children[i];
83  }
84 }
85 
86 void tgStructureInfo::createTree(tgStructureInfo& structureInfo,
87  const tgStructure& structure)
88 {
89  const std::vector<tgStructure*> children = structure.getChildren();
90  for (std::size_t i = 0; i < children.size(); i++)
91  {
92  tgStructure * const pStructure = children[i];
93  assert(pStructure != NULL);
94  tgStructureInfo* const pStructureInfo =
95  new tgStructureInfo(*pStructure, m_buildSpec, pStructure->getTags());
96  structureInfo.addChild(pStructureInfo);
97  }
98 }
99 
100 std::vector<tgRigidInfo*> tgStructureInfo::getAllRigids() const
101 {
102  std::vector<tgRigidInfo*> result;
103  result.insert(result.end(), m_rigids.begin(), m_rigids.end());
104 
105  // Collect child rigids
106  for (std::size_t i = 0; i < m_children.size(); i++)
107  {
108  tgStructureInfo * const pStructureInfo = m_children[i];
109  assert(pStructureInfo != NULL);
110  std::vector<tgRigidInfo*> childRigids = pStructureInfo->getAllRigids();
111  result.insert(result.end(), childRigids.begin(), childRigids.end());
112  }
113 
114  return result;
115 }
116 
118 // Build methods
120 
121 void tgStructureInfo::addRigidsAndConnectors() {
122  const std::vector<tgBuildSpec::RigidAgent*> rigidAgents = m_buildSpec.getRigidAgents();
123  const std::vector<tgBuildSpec::ConnectorAgent*> connectorAgents = m_buildSpec.getConnectorAgents();
124 
125  const tgNodes& nodes = m_structure.getNodes();
126  const tgPairs& pairs = m_structure.getPairs();
127 
128  // for each node, create a rigidInfo object using a matching rigidAgent
129  for (int i = 0; i < nodes.size(); i++) {
130  tgRigidInfo* nodeRigid = initRigidInfo<tgNode>(nodes[i], rigidAgents);
131  if (nodeRigid) {
132  m_rigids.push_back(nodeRigid);
133  }
134  }
135  // for each pair, create a rigidInfo or connectorInfo object using a matching rigidAgent or connectorAgent
136  for (int i = 0; i < pairs.size(); i++) {
137  tgRigidInfo* pairRigid = initRigidInfo<tgPair>(pairs[i], rigidAgents);
138  if (pairRigid) {
139  m_rigids.push_back(pairRigid);
140  }
141  else {
142  tgConnectorInfo* pairConnector = initConnectorInfo<tgPair>(pairs[i], connectorAgents);
143  if (pairConnector) {
144  m_connectors.push_back(pairConnector);
145  }
146  }
147  }
148 
149  // Children
150  for (std::size_t i = 0; i < m_children.size(); i++) {
151  tgStructureInfo* const pStructureInfo = m_children[i];
152 
153  assert(pStructureInfo != NULL);
154  pStructureInfo->addRigidsAndConnectors();
155  }
156 }
157 
158 template <class T>
159 tgRigidInfo* tgStructureInfo::initRigidInfo(const T& rigidCandidate, const std::vector<tgBuildSpec::RigidAgent*>& rigidAgents) const {
160  for (int i = rigidAgents.size() - 1; i >= 0; i--) {
161  const tgBuildSpec::RigidAgent* pRigidAgent = rigidAgents[i];
162  assert(pRigidAgent != NULL);
163 
164  tgTagSearch tagSearch = tgTagSearch(pRigidAgent->tagSearch);
165 
166  // Remove our tags so that subcomponents 'inherit' them (because of the
167  // way tags work, removing a tag from the search is the same as adding
168  // the tag to children to be searched)
169  tagSearch.remove(getTags());
170 
171  tgRigidInfo* pRigidInfo = pRigidAgent->infoFactory;
172  assert(pRigidInfo != NULL);
173 
174  tgRigidInfo* rigid = pRigidInfo->createRigidInfo(rigidCandidate, tagSearch);
175  if (rigid) {// check if a tgRigidInfo was found
176  return rigid;
177  }
178  }
179  return 0;
180 }
181 
182 template <class T>
183 tgConnectorInfo* tgStructureInfo::initConnectorInfo(const T& connectorCandidate, const std::vector<tgBuildSpec::ConnectorAgent*>& connectorAgents) const {
184  for (int i = connectorAgents.size() - 1; i >= 0; i--) {
185  const tgBuildSpec::ConnectorAgent* pConnectorAgent = connectorAgents[i];
186  assert(pConnectorAgent != NULL);
187 
188  tgTagSearch tagSearch = tgTagSearch(pConnectorAgent->tagSearch);
189 
190  // Remove our tags so that subcomponents 'inherit' them (because of the
191  // way tags work, removing a tag from the search is the same as adding
192  // the tag to children to be searched)
193  tagSearch.remove(getTags());
194 
195  tgConnectorInfo* pConnectorInfo = pConnectorAgent->infoFactory;
196  assert(pConnectorInfo != NULL);
197 
198  tgConnectorInfo* connector = pConnectorInfo->createConnectorInfo(connectorCandidate, tagSearch);
199  if (connector) // check if a tgConnectorInfo was found
200  return connector;
201  }
202  return 0;
203 }
204 
205 void tgStructureInfo::autoCompoundRigids()
206 {
207  tgRigidAutoCompound c(getAllRigids());
208  m_compounded = c.execute();
209 }
210 
211 void tgStructureInfo::chooseConnectorRigids()
212 {
213  chooseConnectorRigids(getAllRigids());
214 }
215 
216 void tgStructureInfo::chooseConnectorRigids(std::vector<tgRigidInfo*> allRigids)
217 {
218  for (std::size_t i = 0; i < m_connectors.size(); i++)
219  {
220  tgConnectorInfo * const pConnectorInfo = m_connectors[i];
221  assert(pConnectorInfo != NULL);
222  pConnectorInfo->chooseRigids(allRigids);
223  }
224 
225  // Children
226  for (std::size_t i = 0; i < m_children.size(); i++)
227  {
228  tgStructureInfo * const pStructureInfo = m_children[i];
229  assert(pStructureInfo != NULL);
230  pStructureInfo->chooseConnectorRigids(allRigids);
231  }
232 }
233 
234 void tgStructureInfo::initRigidBodies(tgWorld& world)
235 {
236  // Rigids
237  for (std::size_t i = 0; i < m_rigids.size(); i++)
238  {
239  tgRigidInfo * const pRigidInfo = m_rigids[i];
240  assert(pRigidInfo != NULL);
241  pRigidInfo->initRigidBody(world);
242  }
243 
244  // Children
245  for (std::size_t i = 0; i < m_children.size(); i++)
246  {
247  tgStructureInfo * const pStructureInfo = m_children[i];
248  assert(pStructureInfo != NULL);
249  pStructureInfo->initRigidBodies(world);
250  }
251 }
252 
253 void tgStructureInfo::initConnectors(tgWorld& world)
254 {
255  // Connectors
256  for (std::size_t i = 0; i < m_connectors.size(); i++)
257  {
258  tgConnectorInfo * const pConnectorInfo = m_connectors[i];
259  assert(pConnectorInfo != NULL);
260  pConnectorInfo->initConnector(world);
261  }
262 
263  // Children
264  for (std::size_t i = 0; i < m_children.size(); i++)
265  {
266  tgStructureInfo * const pStructureInfo = m_children[i];
267  assert(pStructureInfo != NULL);
268  pStructureInfo->initConnectors(world);
269  }
270 }
271 
278 {
279  // These take care of things on a global level
280  addRigidsAndConnectors();
281  autoCompoundRigids();
282  chooseConnectorRigids();
283  initRigidBodies(world);
284  // Note: Muscle2Ps won't show up yet --
285  // they need to be part of a model to have rendering...
286  initConnectors(world);
287  // Now build into the model
288  buildIntoHelper(model, world, *this);
289 
290  /*
291  // DEBUGGING: What are the connector infos and rigid infos that
292  // were created?
293  std::cout << "Inside tgStructureInfo: " << std::endl;
294  std::cout << "rigidInfo(s) and connectorInfo(s) that were created and built: " <<
295  std::endl;
296  // The vectors of pointers to info objects are m_rigids and m_connectors.
297  // Iterate through both lists.
298  for( size_t i = 0; i < m_rigids.size(); i++ ) {
299  // Print the info object. There should be overloaded methods for printing.
300  // this is a list of pointers, so need a dereference.
301  std::cout << *(m_rigids[i]) << std::endl;
302  }
303  for( size_t i = 0; i < m_connectors.size(); i++ ) {
304  // Print the info object. There should be overloaded methods for printing.
305  // this is a list of pointers, so need a dereference.
306  std::cout << "tgConnectorInfo: " << *(m_connectors[i]) << " with points " <<
307  m_connectors[i]->getFrom() << " and " <<
308  m_connectors[i]->getTo() << std::endl;
309  }
310  */
311 }
312 
313 void tgStructureInfo::buildIntoHelper(tgModel& model, tgWorld& world,
314  tgStructureInfo& structureInfo)
315 {
316 
317  const std::vector<tgRigidInfo*> rigids = structureInfo.getRigids();
318  for (std::size_t i = 0; i < rigids.size(); i++)
319  {
320  tgRigidInfo * const pRigidInfo = rigids[i];
321  assert(pRigidInfo != NULL);
322  tgModel* const pModel = pRigidInfo->createModel(world);
323  if (pModel != NULL)
324  {
325  pModel->setTags(pRigidInfo->getTags());
326  model.addChild(pModel);
327  }
328  }
329 
330  const std::vector<tgConnectorInfo*> connectors = structureInfo.getConnectors();
331  for (std::size_t i = 0; i < connectors.size(); i++)
332  {
333  tgConnectorInfo * const pConnectorInfo = connectors[i];
334  assert(pConnectorInfo != NULL);
335  tgModel* const pModel = pConnectorInfo->createModel(world);
336  if (pModel != NULL)
337  {
338  pModel->setTags(pConnectorInfo->getTags());
339  model.addChild(pModel);
340  }
341  }
342 
343  const std::vector<tgStructureInfo*> children = structureInfo.getChildren();
344  for (std::size_t i = 0; i < children.size(); i++)
345  {
346  tgStructureInfo * const pStructureInfo = children[i];
347  assert(pStructureInfo != NULL);
348  tgModel* const pModel = new tgModel();
349  assert(pModel != NULL);
350  buildIntoHelper(*pModel, world, *pStructureInfo);
351  model.addChild(pModel);
352  }
353 
354  model.setTags(structureInfo.getTags());
355 }
356 
357 void tgStructureInfo::addChild(tgStructureInfo* pChild)
358 {
359  if (pChild == NULL)
360  {
361  throw std::invalid_argument("Child is NULL");
362  }
363  else
364  {
365  m_children.push_back(pChild);
366  }
367 }
368 
369 std::string tgStructureInfo::toString(const std::string& prefix) const
370 {
371  std::string p = " ";
372  std::ostringstream os;
373  os << prefix << "tgStructureInfo(" << std::endl;
374 
375  os << prefix << p << "Rigids:" << std::endl;
376  for (std::size_t i = 0; i < m_rigids.size(); i++) {
377  os << prefix << p << p << *(m_rigids[i]) << std::endl;
378  }
379 
380  os << prefix << p << "Connectors:" << std::endl;
381  for (std::size_t i = 0; i < m_connectors.size(); i++) {
382  os << prefix << p << p << *(m_connectors[i]) << std::endl;
383  }
384 
385  os << prefix << p << "Children:" << std::endl;
386  for (std::size_t i = 0; i < m_children.size(); i++) {
387  os << m_children[i]->toString(prefix + p + p) << std::endl;
388  }
389 
390  os << prefix << p << "Tags: [" << getTags() << "]" << std::endl;
391 
392  os << prefix << ")" << std::endl;
393  return os.str();
394 }
395 
396 std::ostream&
397 operator<<(std::ostream& os, const tgStructureInfo& obj)
398 {
399  os << obj.toString() << std::endl;
400  return os;
401 }
402 
403 
404 
405 
const std::vector< tgStructure * > & getChildren() const
Definition: tgStructure.h:184
void addChild(tgModel *pChild)
Definition: tgModel.cpp:122
virtual tgRigidInfo * getRigidInfoGroup()
Definition: tgRigidInfo.h:149
const tgNodes & getNodes() const
Definition: tgStructure.h:138
Contains the definition of class tgModel.
const tgPairs & getPairs() const
Definition: tgStructure.h:165
Definition of class tgConnectorInfo.
Contains the definition of class tgWorld $Id$.
Definition of class tgStructure.
Definition of class tgStructureInfo.
void remove(const tgTags &tags)
Definition: tgTagSearch.h:89
std::ostream & operator<<(std::ostream &os, const tgStructureInfo &obj)
Definition of class tgRigidAutoCompound.
Definition: tgTags.h:44
void buildInto(tgModel &model, tgWorld &world)