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