NTRT Simulator
 All Classes 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 // The C++ Standard Library
30 #include <stdexcept>
31 
33 {
34  // Postcondition
35  assert(invariant());
36 }
37 
38 tgModel::tgModel(const tgTags& tags) :
39  tgTaggable(tags)
40 {
41  assert(invariant());
42 }
43 
44 tgModel::tgModel(std::string space_separated_tags) :
45  tgTaggable(space_separated_tags)
46 {
47  assert(invariant());
48 }
49 
51 {
52  const size_t n = m_children.size();
53  for (size_t i = 0; i < n; ++i)
54  {
55  tgModel * const pChild = m_children[i];
56  // It is safe to delete NULL, but this is an invariant
57  assert(pChild != NULL);
58  delete pChild;
59  }
60 }
61 
62 void tgModel::setup(tgWorld& world)
63 {
64  for (int i = 0; i < m_children.size(); i++)
65  {
66  m_children[i]->setup(world);
67  }
68 
69  // Postcondition
70  assert(invariant());
71 }
72 
74 {
75  for (int i = 0; i < m_children.size(); i++)
76  {
77  m_children[i]->teardown();
78  delete m_children[i];
79  }
80  m_children.clear();
81  // Postcondition
82  assert(invariant());
83  assert(m_children.empty());
84 }
85 
86 void tgModel::step(double dt)
87 {
88  if (dt <= 0.0)
89  {
90  throw std::invalid_argument("dt is not positive");
91  }
92  else
93  {
94  // Note: You can adjust whether to step children before notifying
95  // controllers or the other way around in your model
96  const size_t n = m_children.size();
97  for (int i = 0; i < n; i++)
98  {
99  tgModel* const pChild = m_children[i];
100  assert(pChild != NULL);
101  pChild->step(dt);
102  }
103  }
104 
105  // Postcondition
106  assert(invariant());
107 }
108 
109 void tgModel::onVisit(const tgModelVisitor& r) const
110 {
111  r.render(*this);
112 
113  // Call onRender for all children (if we have any)
114  const size_t n = m_children.size();
115  for (int i = 0; i < n; i++)
116  {
117  tgModel * const pChild = m_children[i];
118  assert(pChild != NULL);
119  pChild->onVisit(r);
120  }
121 
122  // Postcondition
123  assert(invariant());
124 }
125 
127 {
128  // Preconditoin
129  if (pChild == NULL)
130  {
131  throw std::invalid_argument("child is NULL");
132  }
133  else if (pChild == this)
134  {
135  throw std::invalid_argument("child is this object");
136  }
137  else
138  {
139  const std::vector<tgModel*> descendants = getDescendants();
140  if (std::find(descendants.begin(), descendants.end(), pChild) !=
141  descendants.end())
142  {
143  throw std::invalid_argument("child is already a descendant");
144  }
145  }
146 
147  m_children.push_back(pChild);
148 
149  // Postcondition
150  assert(invariant());
151  assert(!m_children.empty());
152  assert(std::find(m_children.begin(), m_children.end(), pChild) !=
153  m_children.end());
154 }
155 
156 std::string tgModel::toString(std::string prefix) const
157 {
158  std::string p = " ";
159  std::ostringstream os;
160  os << prefix << "tgModel(" << std::endl;
161  os << prefix << p << "Children:" << std::endl;
162  for(int i = 0; i < m_children.size(); i++) {
163  os << m_children[i]->toString(prefix + p) << std::endl;
164  }
165  os << prefix << p << "Tags: [" << getTags() << "]" << std::endl;
166  os << prefix << ")";
167  return os.str();
168 }
169 
174 std::vector<tgModel*> tgModel::getDescendants() const
175 {
176  std::vector<tgModel*> result;
177  const size_t n = m_children.size();
178  for (int i = 0; i < n; i++)
179  {
180  tgModel* const pChild = m_children[i];
181  assert(pChild != NULL);
182  result.push_back(pChild);
183  // Recursion
184  const std::vector<tgModel*> cd = pChild->getDescendants();
185  result.insert(result.end(), cd.begin(), cd.end());
186  }
187  return result;
188 }
189 
190 bool tgModel::invariant() const
191 {
192  // No child is NULL
193  // No child appears more than once in the tree
194  return true;
195 }
196 
197 std::ostream&
198 operator<<(std::ostream& os, const tgModel& obj)
199 {
200  os << obj.toString() << std::endl;
201  return os;
202 }
virtual void teardown()
Definition: tgModel.cpp:73
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:62
virtual std::string toString(std::string prefix="") const
Definition: tgModel.cpp:156
void addChild(tgModel *pChild)
Definition: tgModel.cpp:126
virtual void step(double dt)
Definition: tgModel.cpp:86
std::ostream & operator<<(std::ostream &os, const tgModel &obj)
Definition: tgModel.cpp:198
virtual ~tgModel()
Definition: tgModel.cpp:50
virtual void onVisit(const tgModelVisitor &r) const
Definition: tgModel.cpp:109
Contains the definition of class tgModel. $Id$.
virtual void render(const tgRod &rod) const
Contains the definition of interface class tgModelVisitor.
tgModel()
Definition: tgModel.cpp:32
Definition: tgTags.h:43
std::vector< tgModel * > getDescendants() const
Definition: tgModel.cpp:174