NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
tgSimulation.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 
26 // This module
27 #include "tgSimulation.h"
28 // This application
29 #include "tgModel.h"
30 #include "tgSimView.h"
31 #include "tgSimViewGraphics.h"
32 #include "tgWorld.h"
33 #include "sensors/tgDataManager.h" //for loggers etc.
34 // The Bullet Physics Library
35 #include "LinearMath/btQuickprof.h"
36 
37 // The C++ Standard Library
38 #include <stdexcept>
39 
41  m_view(view)
42 {
43  m_view.bindToSimulation(*this);
44 
45  m_view.setup();
46 
47  // Postcondition
48  assert(invariant());
49 }
50 
51 tgSimulation::~tgSimulation()
52 {
53  teardown();
54  m_view.releaseFromSimulation();
55  for (std::size_t i = 0; i < m_models.size(); i++)
56  {
57  delete m_models[i];
58  }
59  // Delete the tgDataManagers here too.
60  for (std::size_t i=0; i < m_dataManagers.size(); i++) {
61  delete m_dataManagers[i];
62  }
63 }
64 
66 {
67  // Precondition
68  if (pModel == NULL)
69  {
70  throw std::invalid_argument("NULL pointer to tgModel");
71  }
72  else
73  {
74 
75  pModel->setup(m_view.world());
76  m_models.push_back(pModel);
77  }
78 
79  // Postcondition
80  assert(invariant());
81  assert(!m_models.empty());
82 }
83 
85 {
86  // Precondition
87  if (pObstacle == NULL)
88  {
89  throw std::invalid_argument("NULL pointer to tgModel");
90  }
91  else
92  {
93 
94  pObstacle->setup(m_view.world());
95  m_obstacles.push_back(pObstacle);
96  }
97 
98  // Postcondition
99  assert(invariant());
100  assert(!m_obstacles.empty());
101 }
102 
103 // Similar to models and obstacles, add a data manager.
105 {
106  // Precondition
107  if( pDataManager == NULL){
108  throw std::invalid_argument("NULL pointer to data manager, in tgSimulation.");
109  }
110  else {
111  // TO-DO: do data managers need knowledge of the world?
112  //pDataManager->setup(m_view.world());
113  pDataManager->setup();
114  m_dataManagers.push_back(pDataManager);
115  }
116  // Postcondition
117  assert(invariant());
118  assert(!m_dataManagers.empty());
119 }
120 
122 {
123 #ifndef BT_NO_PROFILE
124  BT_PROFILE("tgSimulation::onVisit");
125 #endif //BT_NO_PROFILE
126  // Removed sending the visitor to the world since it wasn't used
127  // Write a worldVisitor if its necessary
128  for (std::size_t i = 0; i < m_models.size(); i++) {
129  m_models[i]->onVisit(r);
130  }
131  for (std::size_t i = 0; i < m_obstacles.size(); i++) {
132  m_obstacles[i]->onVisit(r);
133  }
134 }
135 
137 {
138 
139  teardown();
140 
141  m_view.setup();
142  for (std::size_t i = 0; i != m_models.size(); i++)
143  {
144 
145  m_models[i]->setup(m_view.world());
146  }
147  // Also, need to set up the data managers again.
148  // Note that this MUST occur after calling setup on the models,
149  // otherwise the data manager will not create any sensors
150  // (since there are no tgRods, etc., inside the tgModel yet!)
151  for (std::size_t i = 0; i < m_dataManagers.size(); i++) {
152  // As in addDataManager: do the data managers need knowledge of the world?
153  m_dataManagers[i]->setup();
154  }
155 
156  // Don't need to set up obstacles since they will be added after this
157 }
158 
160 {
161 
162  teardown();
163 
164  // This will reset the world twice (once in teardown, once here), but that shouldn't hurt anything
165  m_view.world().reset(newGround);
166 
167  m_view.setup();
168  for (std::size_t i = 0; i != m_models.size(); i++)
169  {
170 
171  m_models[i]->setup(m_view.world());
172  }
173  // Also, need to set up the data managers again.
174  // Note that this MUST occur after calling setup on the models,
175  // otherwise the data manager will not create any sensors
176  // (since there are no tgRods, etc., inside the tgModel yet!)
177  for (std::size_t i = 0; i < m_dataManagers.size(); i++) {
178  // As in addDataManager: do the data managers need knowledge of the world?
179  m_dataManagers[i]->setup();
180  }
181 
182  // Don't need to set up obstacles since they were just added
183 }
184 
189 {
190  return m_view.world();
191 }
192 
193 void tgSimulation::step(double dt) const
194 {
195 // Trying to profile here creates trouble for tgLinearString - this is outside of the profile loop
196 
197  if (dt <= 0)
198  {
199  throw std::invalid_argument("dt for step is not positive");
200  }
201  else
202  {
203  // Step the world.
204  // This can be done before or after stepping the models.
205  m_view.world().step(dt);
206 
207  // Step the models
208  for (std::size_t i = 0; i < m_models.size(); i++)
209  {
210  m_models[i]->step(dt);
211  }
212 
213  // Step the obstacles
215  for (std::size_t i = 0; i < m_obstacles.size(); i++)
216  {
217  m_obstacles[i]->step(dt);
218  }
219 
220  // Step the data managers
221  for (std::size_t i = 0; i < m_dataManagers.size(); i++) {
222  m_dataManagers[i]->step(dt);
223  }
224  }
225 }
226 
227 void tgSimulation::teardown()
228 {
229  const size_t n = m_models.size();
230  for (std::size_t i = 0; i < n; i++)
231  {
232  tgModel * const pModel = m_models[i];
233  assert(pModel != NULL);
234 
235  pModel->teardown();
236  }
237 
238  while(m_obstacles.size() != 0)
239  {
240  tgModel * const pModel = m_obstacles.back();
241  assert(pModel != NULL);
242 
243  pModel->teardown();
244 
245  // Remove and destroy element
246  delete pModel;
247  m_obstacles.pop_back();
248  }
249  assert(m_obstacles.empty());
250 
251  // Similar to the models and obstacles, tear down the data managers.
252  const size_t num_DM = m_dataManagers.size(); //why not in the loop gaurd?...
253  for (std::size_t i = 0; i < num_DM; i++) {
254  tgDataManager* const pDataManager = m_dataManagers[i];
255  assert(pDataManager != NULL);
256  // perform the actual teardown
257  pDataManager->teardown();
258  }
259 
260  // Reset the world after the models - models need world info for
261  // their onTeardown() functions
262  m_view.world().reset();
263  // Postcondition
264  assert(invariant());
265 }
266 
267 void tgSimulation::run() const
268 {
269  m_view.run();
270 }
271 
272 void tgSimulation::run(int steps) const
273 {
274  m_view.run(steps);
275 }
276 
277 bool tgSimulation::invariant() const
278 {
279  return true;
280 }
void addDataManager(tgDataManager *pDataManager)
void addObstacle(tgModel *pObstacle)
virtual void teardown()
Definition: tgModel.cpp:68
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:57
void bindToSimulation(tgSimulation &simulation)
Definition: tgSimView.cpp:77
virtual void teardown()
void releaseFromSimulation()
Definition: tgSimView.cpp:96
tgWorld & getWorld() const
void addModel(tgModel *pModel)
Contains the definition of class tgDataManager.
Contains the definition of class tgModel.
Contains the definition of class tgSimulation.
Contains the definition of class tgSimViewGraphics.
virtual void setup()
Definition: tgSimView.cpp:109
void step(double dt) const
Definition: tgWorld.cpp:119
virtual void setup()
Contains the definition of class tgWorld $Id$.
tgSimulation(tgSimView &view)
void onVisit(const tgModelVisitor &r) const
void run() const
tgWorld & world()
Definition: tgSimView.h:65
Contains the definition of class tgSimView.
virtual void run()
Definition: tgSimView.cpp:132
void step(double dt) const
void reset()
Definition: tgWorld.cpp:90