NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
CaterpillarModel.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 "CaterpillarModel.h"
27 // This library
29 #include "core/tgRod.h"
30 #include "core/tgString.h"
31 #include "tgcreator/tgBuildSpec.h"
33 #include "tgcreator/tgRodInfo.h"
34 #include "tgcreator/tgStructure.h"
36 // The Bullet Physics library
37 #include "LinearMath/btVector3.h"
38 // The C++ Standard Library
39 #include <stdexcept>
40 
41 namespace
42 {
43  // see tgBaseString.h for a descripton of some of these rod parameters
44  // (specifically, those related to the motor moving the strings.)
45  // NOTE that any parameter that depends on units of length will scale
46  // with the current gravity scaling. E.g., with gravity as 98.1,
47  // the length units below are in decimeters.
48 
49  // Note: This current model of the SUPERball rod is 1.5m long by 3 cm radius,
50  // which is 0.00424 m^3.
51  // For SUPERball v1.5, mass = 3.5kg per strut, which comes out to
52  // 0.825 kg / (decimeter^3).
53 
54  // similarly, frictional parameters are for the tgRod objects.
55  const struct Config
56  {
57  double density;
58  double radius;
59  double stiffness;
60  double damping;
61  double rod_length;
62  double rod_space;
63  double friction;
64  double rollFriction;
65  double restitution;
66  double pretension;
67  bool hist;
68  double maxTens;
69  double targetVelocity;
70  } c =
71  {
72  0.688, // density (kg / length^3)
73  0.31, // radius (length)
74  613.0, // stiffness (kg / sec^2) was 1500
75  200.0, // damping (kg / sec)
76  16.84, // rod_length (length)
77  7.5, // rod_space (length)
78  0.99, // friction (unitless)
79  0.01, // rollFriction (unitless)
80  0.0, // restitution (?)
81  919.5, // pretension
82  0, // History logging (boolean)
83  100000, // maxTens
84  10000, // targetVelocity
85 
86  // Use the below values for earlier versions of simulation.
87  // 1.006,
88  // 0.31,
89  // 300000.0,
90  // 3000.0,
91  // 15.0,
92  // 7.5,
93  };
94 
95  void addSegments(tgStructure& snake, const tgStructure& tetra, double edge,
96  size_t segmentCount)
97  {
98 
99  const btVector3 offset(-edge, 0, 0.0);
100  for (size_t i = 0; i < segmentCount; ++i)
101  {
102  tgStructure* const t = new tgStructure(tetra);
103  t->addTags(tgString("segment", i + 1));
104  t->move((i + 1) * offset);
105  // Add a child to the snake
106  snake.addChild(t);
107  }
108  }
109 
110  // Add muscles that connect the segments
111  void addSegmentMuscles(tgStructure& snake)
112  {
113  const std::vector<tgStructure*> children = snake.getChildren();
114 
115  for (size_t i = 1; i < children.size(); ++i)
116  {
117  tgNodes n0 = children[i-1]->getNodes();
118  tgNodes n1 = children[i ]->getNodes();
119 
120  if (i % 2 == 0)
121  {
122  snake.addPair(n0[4], n1[5], "segment rod");
123  }
124  else
125  {
126  snake.addPair(n0[6], n1[7], "segment rod");
127  }
128  }
129  }
130 
131  // Add muscles that connect the segments
132  void addSegmentMusclesOld(tgStructure& snake)
133  {
134  const std::vector<tgStructure*> children = snake.getChildren();
135  for (size_t i = 1; i < children.size(); ++i)
136  {
137  tgNodes n0 = children[i-1]->getNodes();
138  tgNodes n1 = children[i ]->getNodes();
139 
140  tgNode mid0((n0[0] + n1[0])/2.0);
141  tgNode mid1((n0[1] + n1[1])/2.0);
142  tgNode mid2((n0[2] + n1[2])/2.0);
143  tgNode mid3((n0[3] + n1[3])/2.0);
144 #if (0)
145  if (i == 1)
146  {
147  btScalar segDist = (n0[0] - n1[0]).length() / 2.0;
148  tgNode start0 = n0[0] + btVector3(segDist, 0.0, 0.0);
149  tgNode start1 = n0[1] + btVector3(segDist, 0.0, 0.0);
150  tgNode start2 = n0[2] + btVector3(segDist, 0.0, 0.0);
151  tgNode start3 = n0[3] + btVector3(segDist, 0.0, 0.0);
152 
153  snake.addPair(start0, start1, "segment rod");
154  snake.addPair(start2, start3, "segment rod");
155 
156  snake.addPair(n0[5], start0, "segment muscle front one");
157  snake.addPair(n0[5], start2, "segment muscle front two");
158  snake.addPair(n0[7], start1, "segment muscle front three");
159  snake.addPair(n0[7], start3, "segment muscle front four");
160 
161  snake.addPair(n0[8], start0, "segment muscle rear one");
162  snake.addPair(n0[8], start1, "segment muscle rear two");
163  snake.addPair(n0[9], start2, "segment muscle rear three");
164  snake.addPair(n0[9], start3, "segment muscle rear four");
165 
166  }
167  if (i == children.size() - 1)
168  {
169  btScalar segDist = (n0[0] - n1[0]).length() / 2.0;
170  tgNode end0 = n1[0] - btVector3(segDist, 0.0, 0.0);
171  tgNode end1 = n1[1] - btVector3(segDist, 0.0, 0.0);
172  tgNode end2 = n1[2] - btVector3(segDist, 0.0, 0.0);
173  tgNode end3 = n1[3] - btVector3(segDist, 0.0, 0.0);
174 
175  snake.addPair(end0, end1, "segment rod");
176  snake.addPair(end2, end3, "segment rod");
177 
178  snake.addPair(n1[4], end0, "segment muscle rear one");
179  snake.addPair(n1[4], end2, "segment muscle rear two");
180  snake.addPair(n1[6], end1, "segment muscle rear three");
181  snake.addPair(n1[6], end3, "segment muscle rear four");
182 
183  snake.addPair(n1[10], end0, "segment muscle rear one");
184  snake.addPair(n1[10], end1, "segment muscle rear two");
185  snake.addPair(n1[11], end2, "segment muscle rear three");
186  snake.addPair(n1[11], end3, "segment muscle rear four");
187  }
188 #endif
189  snake.addPair(mid0, mid1, "segment rod");
190  snake.addPair(mid2, mid3, "segment rod");
191 
192  snake.addPair(n0[4], mid0, "segment muscle rear one");
193  snake.addPair(n0[4], mid2, "segment muscle rear two");
194  snake.addPair(n0[6], mid1, "segment muscle rear three");
195  snake.addPair(n0[6], mid3, "segment muscle rear four");
196 
197  snake.addPair(n1[5], mid0, "segment muscle front one");
198  snake.addPair(n1[5], mid2, "segment muscle front two");
199  snake.addPair(n1[7], mid1, "segment muscle front three");
200  snake.addPair(n1[7], mid3, "segment muscle front four");
201 
202  snake.addPair(n0[10], mid0, "segment muscle rear one");
203  snake.addPair(n0[10], mid1, "segment muscle rear two");
204  snake.addPair(n0[11], mid2, "segment muscle rear three");
205  snake.addPair(n0[11], mid3, "segment muscle rear four");
206 
207  snake.addPair(n1[8], mid0, "segment muscle rear one");
208  snake.addPair(n1[8], mid1, "segment muscle rear two");
209  snake.addPair(n1[9], mid2, "segment muscle rear three");
210  snake.addPair(n1[9], mid3, "segment muscle rear four");
211 
212 
213  }
214  }
215 } // namespace
216 
218 {
219 }
220 
222 {
223 }
224 
225 void CaterpillarModel::addNodes(tgStructure& s)
226 {
227  const double half_length = c.rod_length / 2;
228 
229  s.addNode(-c.rod_space, -half_length, 0); // 0
230  s.addNode(-c.rod_space, half_length, 0); // 1
231  s.addNode( c.rod_space, -half_length, 0); // 2
232  s.addNode( c.rod_space, half_length, 0); // 3
233  s.addNode(0, -c.rod_space, -half_length); // 4
234  s.addNode(0, -c.rod_space, half_length); // 5
235  s.addNode(0, c.rod_space, -half_length); // 6
236  s.addNode(0, c.rod_space, half_length); // 7
237  s.addNode(-half_length, 0, c.rod_space); // 8
238  s.addNode( half_length, 0, c.rod_space); // 9
239  s.addNode(-half_length, 0, -c.rod_space); // 10
240  s.addNode( half_length, 0, -c.rod_space); // 11
241 }
242 
243 void CaterpillarModel::addRods(tgStructure& s)
244 {
245  s.addPair( 0, 1, "y rod");
246  s.addPair( 2, 3, "y rod");
247  s.addPair( 4, 5, "z rod");
248  s.addPair( 6, 7, "z rod");
249  s.addPair( 8, 9, "x rod");
250  s.addPair(10, 11, "x rod");
251 }
252 
253 void CaterpillarModel::addMuscles(tgStructure& s)
254 {
255  s.addPair(0, 4, "muscle");
256  s.addPair(0, 5, "muscle");
257  s.addPair(0, 8, "muscle");
258  s.addPair(0, 10, "muscle");
259 
260  s.addPair(1, 6, "muscle");
261  s.addPair(1, 7, "muscle");
262  s.addPair(1, 8, "muscle");
263  s.addPair(1, 10, "muscle");
264 
265  s.addPair(2, 4, "muscle");
266  s.addPair(2, 5, "muscle");
267  s.addPair(2, 9, "muscle");
268  s.addPair(2, 11, "muscle");
269 
270  s.addPair(3, 7, "muscle");
271  s.addPair(3, 6, "muscle");
272  s.addPair(3, 9, "muscle");
273  s.addPair(3, 11, "muscle");
274 
275  s.addPair(4, 2, "muscle");
276  s.addPair(4, 10, "muscle");
277  s.addPair(4, 11, "muscle");
278 
279  s.addPair(5, 8, "muscle");
280  s.addPair(5, 9, "muscle");
281 
282  s.addPair(6, 10, "muscle");
283  s.addPair(6, 11, "muscle");
284 
285  s.addPair(7, 8, "muscle");
286  s.addPair(7, 9, "muscle");
287 
288 }
289 
291 {
292 
293  const tgRod::Config rodConfig(c.radius, c.density, c.friction,
294  c.rollFriction, c.restitution);
295 
296  tgSpringCableActuator::Config muscleConfig(c.stiffness, c.damping, c.pretension, c.hist,
297  c.maxTens, c.targetVelocity);
298 
299  // Start creating the structure
300  tgStructure s;
301  addNodes(s);
302  addRods(s);
303  addMuscles(s);
304 
305  btVector3 rotationPoint = btVector3(0, 0, 0); // origin
306  btVector3 rotationAxis = btVector3(0, 1, 0); // y-axis
307  double rotationAngle = M_PI/2;
308  s.addRotation(rotationPoint, rotationAxis, rotationAngle);
309 
310  s.move(btVector3(0, 10, 0));
311 
312  tgStructure caterpillar;
313  addSegments(caterpillar, s, 2.0 * c.rod_length, 5);
314  addSegmentMuscles(caterpillar);
315 
316  // Create the build spec that uses tags to turn the structure into a real model
317  tgBuildSpec spec;
318  spec.addBuilder("rod", new tgRodInfo(rodConfig));
319  spec.addBuilder("muscle", new tgBasicActuatorInfo(muscleConfig));
320 
321  // Create your structureInfo
322  tgStructureInfo structureInfo(caterpillar, spec);
323 
324  // Use the structureInfo to build ourselves
325  structureInfo.buildInto(*this, world);
326 
327  // We could now use tgCast::filter or similar to pull out the
328  // models (e.g. muscles) that we want to control.
329  allMuscles = tgCast::filter<tgModel, tgSpringCableActuator> (getDescendants());
330 
331  // call the onSetup methods of all observed things e.g. controllers
332  notifySetup();
333 
334  // Actually setup the children
335  tgModel::setup(world);
336 }
337 
338 void CaterpillarModel::step(double dt)
339 {
340  // Precondition
341  if (dt <= 0.0)
342  {
343  throw std::invalid_argument("dt is not positive");
344  }
345  else
346  {
347  // Notify observers (controllers) of the step so that they can take action
348  notifyStep(dt);
349  tgModel::step(dt); // Step any children
350  }
351 }
352 
354 {
355  tgModel::onVisit(r);
356 }
357 
358 const std::vector<tgSpringCableActuator*>& CaterpillarModel::getAllMuscles() const
359 {
360  return allMuscles;
361 }
362 
364 {
366 }
const std::vector< tgStructure * > & getChildren() const
Definition: tgStructure.h:184
virtual void teardown()
Definition: tgModel.cpp:68
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:57
void addChild(tgStructure *child)
Definition of class tgRodInfo.
const std::vector< tgSpringCableActuator * > & getAllMuscles() const
Convenience function for combining strings with ints, mostly for naming structures.
virtual void step(double dt)
Definition: tgModel.cpp:84
Definition of class tgBasicActuatorInfo.
virtual void onVisit(const tgModelVisitor &r) const
Definition: tgModel.cpp:107
void addPair(int fromNodeIdx, int toNodeIdx, std::string tags="")
Definition: tgStructure.cpp:80
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
void addRotation(const btVector3 &fixedPoint, const btVector3 &axis, double angle)
std::string tgString(std::string s, int i)
Definition: tgString.h:33
Definition: tgNode.h:45
Definition of class tgStructure.
Definition of class tgStructureInfo.
Contains the definition of class CaterpillarModel. $Id$.
virtual void setup(tgWorld &world)
Contains the definition of class tgRod.
Definition of class tgBuildSpec.
virtual void step(double dt)
std::vector< tgModel * > getDescendants() const
Definition: tgModel.cpp:170
virtual void onVisit(tgModelVisitor &r)
void buildInto(tgModel &model, tgWorld &world)
void addNode(double x, double y, double z, std::string tags="")
Definition: tgStructure.cpp:70