NTRT Simulator  v1.1
 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  {
115  tgModel * const pChild = m_children[i];
116  assert(pChild != NULL);
117  pChild->onVisit(r);
118  }
119 
120  // Postcondition
121  assert(invariant());
122 }
123 
125 {
126  // Preconditoin
127  if (pChild == NULL)
128  {
129  throw std::invalid_argument("child is NULL");
130  }
131  else if (pChild == this)
132  {
133  throw std::invalid_argument("child is this object");
134  }
135  else
136  {
137  const std::vector<tgModel*> descendants = getDescendants();
138  if (std::find(descendants.begin(), descendants.end(), pChild) !=
139  descendants.end())
140  {
141  throw std::invalid_argument("child is already a descendant");
142  }
143  }
144 
145  m_children.push_back(pChild);
146 
147  // Postcondition
148  assert(invariant());
149  assert(!m_children.empty());
150  assert(std::find(m_children.begin(), m_children.end(), pChild) !=
151  m_children.end());
152 }
153 
154 std::string tgModel::toString(std::string prefix) const
155 {
156  std::string p = " ";
157  std::ostringstream os;
158  os << prefix << "tgModel(" << std::endl;
159  os << prefix << p << "Children:" << std::endl;
160  for(std::size_t i = 0; i < m_children.size(); i++) {
161  os << m_children[i]->toString(prefix + p) << std::endl;
162  }
163  os << prefix << p << "Tags: [" << getTags() << "]" << std::endl;
164  os << prefix << ")";
165  return os.str();
166 }
167 
172 std::vector<tgModel*> tgModel::getDescendants() const
173 {
174  std::vector<tgModel*> result;
175  const size_t n = m_children.size();
176  for (std::size_t i = 0; i < n; i++)
177  {
178  tgModel* const pChild = m_children[i];
179  assert(pChild != NULL);
180  result.push_back(pChild);
181  // Recursion
182  const std::vector<tgModel*> cd = pChild->getDescendants();
183  result.insert(result.end(), cd.begin(), cd.end());
184  }
185  return result;
186 }
187 
188 const std::vector<abstractMarker>& tgModel::getMarkers() const {
189  return m_markers;
190 }
191 
192 void tgModel::addMarker(abstractMarker a){
193  m_markers.push_back(a);
194 }
195 
196 bool tgModel::invariant() const
197 {
198  // No child is NULL
199  // No child appears more than once in the tree
200  return true;
201 }
202 
203 std::ostream&
204 operator<<(std::ostream& os, const tgModel& obj)
205 {
206  os << obj.toString() << std::endl;
207  return os;
208 }
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:154
void addChild(tgModel *pChild)
Definition: tgModel.cpp:124
virtual void step(double dt)
Definition: tgModel.cpp:84
std::ostream & operator<<(std::ostream &os, const tgModel &obj)
Definition: tgModel.cpp:204
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
Definition: tgTags.h:44
std::vector< tgModel * > getDescendants() const
Definition: tgModel.cpp:172