NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgModel.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 
25 // This module
26 #include "tgModel.h"
27 // This application
28 #include "tgModelVisitor.h"
29 #include "abstractMarker.h"
30 // The C++ Standard Library
31 #include <stdexcept>
32 
34 {
35  // Postcondition
36  assert(invariant());
37 }
38 
39 tgModel::tgModel(const tgTags& tags) :
40  tgTaggable(tags)
41 {
42  assert(invariant());
43 }
44 
46 {
47  const size_t n = m_children.size();
48  for (size_t i = 0; i < n; ++i)
49  {
50  tgModel * const pChild = m_children[i];
51  // It is safe to delete NULL, but this is an invariant
52  assert(pChild != NULL);
53  delete pChild;
54  }
55 }
56 
57 void tgModel::setup(tgWorld& world)
58 {
59  for (std::size_t i = 0; i < m_children.size(); i++)
60  {
61  m_children[i]->setup(world);
62  }
63 
64  // Postcondition
65  assert(invariant());
66 }
67 
69 {
70  for (std::size_t i = 0; i < m_children.size(); i++)
71  {
72  m_children[i]->teardown();
73  delete m_children[i];
74  }
75  m_children.clear();
76  //Clear the markers
77  this->m_markers.clear();
78 
79  // Postcondition
80  assert(invariant());
81  assert(m_children.empty());
82 }
83 
84 void tgModel::step(double dt)
85 {
86  if (dt <= 0.0)
87  {
88  throw std::invalid_argument("dt is not positive");
89  }
90  else
91  {
92  // Note: You can adjust whether to step children before notifying
93  // controllers or the other way around in your model
94  const size_t n = m_children.size();
95  for (std::size_t i = 0; i < n; i++)
96  {
97  tgModel* const pChild = m_children[i];
98  assert(pChild != NULL);
99  pChild->step(dt);
100  }
101  }
102 
103  // Postcondition
104  assert(invariant());
105 }
106 
107 void tgModel::onVisit(const tgModelVisitor& r) const
108 {
109  r.render(*this);
110 
111  // Call onRender for all children (if we have any)
112  const size_t n = m_children.size();
113  for (std::size_t i = 0; i < n; i++) {
114  tgModel * const pChild = m_children[i];
115  assert(pChild != NULL);
116  pChild->onVisit(r);
117  }
118  // Postcondition
119  assert(invariant());
120 }
121 
123 {
124  // Preconditoin
125  if (pChild == NULL)
126  {
127  throw std::invalid_argument("child is NULL");
128  }
129  else if (pChild == this)
130  {
131  throw std::invalid_argument("child is this object");
132  }
133  else
134  {
135  const std::vector<tgModel*> descendants = getDescendants();
136  if (std::find(descendants.begin(), descendants.end(), pChild) !=
137  descendants.end())
138  {
139  throw std::invalid_argument("child is already a descendant");
140  }
141  }
142 
143  m_children.push_back(pChild);
144 
145  // Postcondition
146  assert(invariant());
147  assert(!m_children.empty());
148  assert(std::find(m_children.begin(), m_children.end(), pChild) !=
149  m_children.end());
150 }
151 
152 std::string tgModel::toString(std::string prefix) const
153 {
154  std::string p = " ";
155  std::ostringstream os;
156  os << prefix << "tgModel(" << std::endl;
157  os << prefix << p << "Children:" << std::endl;
158  for(std::size_t i = 0; i < m_children.size(); i++) {
159  os << m_children[i]->toString(prefix + p) << std::endl;
160  }
161  os << prefix << p << "Tags: [" << getTags() << "]" << std::endl;
162  os << prefix << ")";
163  return os.str();
164 }
165 
170 std::vector<tgModel*> tgModel::getDescendants() const
171 {
172  std::vector<tgModel*> result;
173  const size_t n = m_children.size();
174  for (std::size_t i = 0; i < n; i++)
175  {
176  tgModel* const pChild = m_children[i];
177  assert(pChild != NULL);
178  result.push_back(pChild);
179  // Recursion
180  const std::vector<tgModel*> cd = pChild->getDescendants();
181  result.insert(result.end(), cd.begin(), cd.end());
182  }
183  return result;
184 }
185 
191 std::vector<tgSenseable*> tgModel::getSenseableDescendants() const
192 {
193  // TO-DO: why can't we just return the results of getDescendants?
194  // There seems to be some polymorphism issue here...
195  std::vector<tgModel*> myDescendants = getDescendants();
196  std::vector<tgSenseable*> mySenseableDescendants;
197  for (size_t i=0; i < myDescendants.size(); i++) {
198  mySenseableDescendants.push_back(myDescendants[i]);
199  }
200  return mySenseableDescendants;
201 }
202 
203 const std::vector<abstractMarker>& tgModel::getMarkers() const {
204  return m_markers;
205 }
206 
207 void tgModel::addMarker(abstractMarker a){
208  m_markers.push_back(a);
209 }
210 
211 bool tgModel::invariant() const
212 {
213  // No child is NULL
214  // No child appears more than once in the tree
215  return true;
216 }
217 
218 std::ostream&
219 operator<<(std::ostream& os, const tgModel& obj)
220 {
221  os << obj.toString() << std::endl;
222  return os;
223 }
virtual void teardown()
Definition: tgModel.cpp:68
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:57
virtual std::string toString(std::string prefix="") const
Definition: tgModel.cpp:152
void addChild(tgModel *pChild)
Definition: tgModel.cpp:122
virtual void step(double dt)
Definition: tgModel.cpp:84
std::ostream & operator<<(std::ostream &os, const tgModel &obj)
Definition: tgModel.cpp:219
virtual ~tgModel()
Definition: tgModel.cpp:45
Markers for specific places on a tensegrity.
virtual void onVisit(const tgModelVisitor &r) const
Definition: tgModel.cpp:107
Contains the definition of class tgModel.
virtual void render(const tgRod &rod) const
Contains the definition of interface class tgModelVisitor.
tgModel()
Definition: tgModel.cpp:33
virtual std::vector< tgSenseable * > getSenseableDescendants() const
Definition: tgModel.cpp:191
Definition: tgTags.h:44
std::vector< tgModel * > getDescendants() const
Definition: tgModel.cpp:170