NTRT Simulator  v1.1
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
VerticalSpineModel.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 "VerticalSpineModel.h"
28 // This library
29 #include "core/tgCast.h"
30 #include "core/tgBasicActuator.h"
31 #include "core/tgString.h"
32 #include "tgcreator/tgBuildSpec.h"
35 #include "tgcreator/tgRodInfo.h"
36 #include "tgcreator/tgStructure.h"
38 #include "tgcreator/tgUtil.h"
39 // The Bullet Physics library
40 #include "btBulletDynamicsCommon.h"
41 // The C++ Standard Library
42 #include <iostream>
43 #include <stdexcept>
44 
45 // @todo move hard-coded parameters into config
46 
48  m_segments(segments),
49  tgModel()
50 {
51 }
52 
57 namespace
58 {
59  const struct Config
60  {
61  double densityA;
62  double densityB;
63  double radius;
64  double edge;
65  double height;
66  double stiffness;
67  double damping;
68  double friction;
69  double rollFriction;
70  double restitution;
71  double pretension;
72  bool hist;
73  double maxTens;
74  double targetVelocity;
75  } c =
76  {
77  0.026, // densityA (kg / length^3)
78  0.0, // densityB (kg / length^3)
79  0.5, // radius (length)
80  20.0, // edge (length)
81  tgUtil::round(c.edge / std::sqrt(2.0)), // height (length)
82  1000.0, // stiffness (kg / sec^2)
83  10.0, // damping (kg / sec)
84  0.99, // friction (unitless)
85  0.01, // rollFriction (unitless)
86  0.0, // restitution (?)
87  2452.0, // pretension
88  0, // History logging (boolean)
89  100000, // maxTens
90  10000, // targetVelocity
91 
92  };
93 
94 } // end namespace
95 
96 // Helper functions, with explicit scopes, moved from implicit namespace.
97 void VerticalSpineModel::trace(const tgStructureInfo& structureInfo, tgModel& model)
98 {
99  std::cout << "StructureInfo:" << std::endl
100  << structureInfo << std::endl
101  << "Model: " << std::endl
102  << model << std::endl;
103 }
104 
105 void VerticalSpineModel::addNodes(tgStructure& tetra, double edge, double height)
106 {
107  // right
108  tetra.addNode( c.edge / 2.0, 0, 0); // node 0
109  // left
110  tetra.addNode( -c.edge / 2.0, 0, 0); // node 1
111  // top
112  tetra.addNode(0, c.height, -edge / 2.0); // node 2
113  // front
114  tetra.addNode(0, c.height, edge / 2.0); // node 3
115  // middle
116  tetra.addNode(0, c.height/2, 0); // node 4
117 }
118 
119 void VerticalSpineModel::addPairs(tgStructure& tetra)
120 {
121  tetra.addPair(0, 4, "rod");
122  tetra.addPair(1, 4, "rod");
123  tetra.addPair(2, 4, "rod");
124  tetra.addPair(3, 4, "rod");
125 }
126 
127 void VerticalSpineModel::addPairsB(tgStructure& tetra)
128 {
129  tetra.addPair(0, 4, "rodB");
130  tetra.addPair(1, 4, "rodB");
131  tetra.addPair(2, 4, "rodB");
132  tetra.addPair(3, 4, "rodB");
133 }
134 
135 void VerticalSpineModel::addSegments(tgStructure& snake, const tgStructure& tetra,
136  double edge, size_t segmentCount)
137 {
138  //const btVector3 offset(0, 0, -edge * 1.15);
139  const btVector3 offset(0, 7.5, 0);
140  for (size_t i = 1; i < segmentCount; ++i)
141  {
142  tgStructure* const t = new tgStructure(tetra);
143  t->addTags(tgString("segment", i + 1));
144  t->move((i + 1) * offset);
145  // Add a child to the snake
146  snake.addChild(t);
147  }
148 
149 }
150 
151 // Add muscles that connect the segments
152 void VerticalSpineModel::addMuscles(tgStructure& snake)
153 {
154  const std::vector<tgStructure*> children = snake.getChildren();
155  for (size_t i = 1; i < children.size(); ++i)
156  {
157  tgNodes n0 = children[i-1]->getNodes();
158  tgNodes n1 = children[i ]->getNodes();
159 
160  // vertical muscles
161  snake.addPair(n0[0], n1[0], "vertical muscle a");
162  snake.addPair(n0[1], n1[1], "vertical muscle b");
163  snake.addPair(n0[2], n1[2], "vertical muscle c");
164  snake.addPair(n0[3], n1[3], "vertical muscle d");
165 
166  // saddle muscles
167  snake.addPair(n0[2], n1[1], tgString("saddle muscle seg", i-1));
168  snake.addPair(n0[3], n1[1], tgString("saddle muscle seg", i-1));
169  snake.addPair(n0[2], n1[0], tgString("saddle muscle seg", i-1));
170  snake.addPair(n0[3], n1[0], tgString("saddle muscle seg", i-1));
171  }
172 }
173 
174 void VerticalSpineModel::mapMuscles(VerticalSpineModel::MuscleMap& muscleMap,
175  tgModel& model, size_t segmentCount)
176 {
177  // create names for muscles (for getMuscles function)
178 
179  // vertical muscles
180  muscleMap["vertical a"] = model.find<tgBasicActuator>("vertical muscle a");
181  muscleMap["vertical b"] = model.find<tgBasicActuator>("vertical muscle b");
182  muscleMap["vertical c"] = model.find<tgBasicActuator>("vertical muscle c");
183  muscleMap["vertical d"] = model.find<tgBasicActuator>("vertical muscle d");
184 
185  // saddle muscles
186  for (size_t i = 1; i < segmentCount ; ++i)
187  {
188  muscleMap[tgString("saddle", i-1)] = model.find<tgBasicActuator>(tgString("saddle muscle seg", i-1));
189 
190  }
191 }
192 
193 /***************************************
194  * The primary functions., called from other classes.
195  **************************************/
197 {
198  // debugging output: edge and height length
199  std::cout << "edge: " << c.edge << "; height: " << c.height << std::endl;
200 
201  // Create the first fixed snake segment
202  // @todo move these hard-coded parameters into config
203  tgStructure tetraB;
204  addNodes(tetraB, c.edge, c.height);
205  addPairsB(tetraB);
206  tetraB.move(btVector3(0.0, 2, 0));
207 
208  // Create our snake segments
209  tgStructure snake;
210 
211  // add 1st child to snake
212  tgStructure* const tB = new tgStructure(tetraB);
213  snake.addChild(tB);
214  tB->addTags(tgString("segment", 1));
215 
216  // Create the first non-fixed tetrahedra
217  tgStructure tetra;
218  addNodes(tetra, c.edge, c.height);
219  addPairs(tetra);
220 
221  // Move the first tetrahedra
222  // @todo move these hard-coded parameters into config
223  tetra.move(btVector3(0.0, -6, 0));
224 
225  // add rest of segments using original tetra configuration
226  addSegments(snake, tetra, c.edge, m_segments);
227 
228  addMuscles(snake);
229 
230  // Create the build spec that uses tags to turn the structure into a real model
231  // Note: This needs to be high enough or things fly apart...
232 
233  // length of inner strut = 12.25 cm
234  // m = 1 kg
235  // volume of 1 rod = 9.62 cm^3
236  // total volume = 38.48 cm^3
237  //const double density = 1/38.48; = 0.026 // kg / length^3 - see app for length
238  const tgRod::Config rodConfigA(c.radius, c.densityA, c.friction,
239  c.rollFriction, c.restitution);
240  const tgRod::Config rodConfigB(c.radius, c.densityB, c.friction,
241  c.rollFriction, c.restitution);
242  tgBuildSpec spec;
243  spec.addBuilder("rod", new tgRodInfo(rodConfigA));
244  spec.addBuilder("rodB", new tgRodInfo(rodConfigB));
245 
246  // set muscle (string) parameters
247  // @todo replace acceleration constraint with tgKinematicActuator if needed...
248  tgBasicActuator::Config muscleConfig(c.stiffness, c.damping, c.pretension,
249  c.hist, c.maxTens, c.targetVelocity);
250  spec.addBuilder("muscle", new tgBasicActuatorInfo(muscleConfig));
251 
252 
253  // Create your structureInfo
254  tgStructureInfo structureInfo(snake, spec);
255  // Use the structureInfo to build ourselves
256  structureInfo.buildInto(*this, world);
257 
258  // We could now use tgCast::filter or similar to pull out the models (e.g. muscles)
259  // that we want to control.
260  allMuscles = tgCast::filter<tgModel, tgBasicActuator> (getDescendants());
261  mapMuscles(muscleMap, *this, m_segments);
262 
263  trace(structureInfo, *this);
264 
265  // Actually setup the children
266  tgModel::setup(world);
267 }
268 
270 {
271  if (dt < 0.0)
272  {
273  throw std::invalid_argument("dt is not positive");
274  }
275  else
276  {
277  // Notify observers (controllers) of the step so that they can take action
278  notifyStep(dt);
279  // Step any children
280  tgModel::step(dt);
281  }
282 }
283 
284 const std::vector<tgBasicActuator*>&
285 VerticalSpineModel::getMuscles (const std::string& key) const
286 {
287  const MuscleMap::const_iterator it = muscleMap.find(key);
288  if (it == muscleMap.end())
289  {
290  throw std::invalid_argument("Key '" + key + "' not found in muscle map");
291  }
292  else
293  {
294  return it->second;
295  }
296 }
297 
298 const std::vector<tgBasicActuator*>& VerticalSpineModel::getAllMuscles() const
299 {
300  return allMuscles;
301 }
302 
const std::vector< tgStructure * > & getChildren() const
Definition: tgStructure.h:131
virtual void step(const double dt)
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:57
void addChild(tgStructure *child)
Definition of class tgRodInfo.
virtual void setup(tgWorld &world)
Convenience function for combining strings with ints, mostly for naming structures.
virtual void step(double dt)
Definition: tgModel.cpp:84
Utility class for class casting and filtering collections by type.
Contains the definition of class VerticalSpineModel.
VerticalSpineModel(size_t segments)
std::map< std::string, std::vector< tgBasicActuator * > > MuscleMap
Definition of class tgBasicActuatorInfo.
void addPair(int fromNodeIdx, int toNodeIdx, std::string tags="")
Definition: tgStructure.cpp:66
const std::vector< tgBasicActuator * > & getMuscles(const std::string &key) const
Contains the definition of class tgBasicActuator.
std::string tgString(std::string s, int i)
Definition: tgString.h:33
Definition of class tgStructure.
std::vector< T * > find(const tgTagSearch &tagSearch)
Definition: tgModel.h:125
Definition of class tgStructureInfo.
Contains the definition of class tgUtil and overloaded operator<<() free functions.
Definition of class tgBuildSpec.
Definition of class tgRigidAutoCompound.
std::vector< tgModel * > getDescendants() const
Definition: tgModel.cpp:172
void addNode(double x, double y, double z, std::string tags="")
Definition: tgStructure.cpp:56