NTRT Simulator  v1.1
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
TetraSpineLearningModel.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 
19 // This module
21 // This library
22 #include "core/tgCast.h"
24 #include "core/tgString.h"
25 #include "tgcreator/tgBuildSpec.h"
27 #include "tgcreator/tgRodInfo.h"
28 #include "tgcreator/tgStructure.h"
30 #include "tgcreator/tgUtil.h"
31 // The Bullet Physics library
32 #include "LinearMath/btVector3.h"
33 // The C++ Standard Library
34 #include <iostream>
35 #include <stdexcept>
36 
46 TetraSpineLearningModel::TetraSpineLearningModel(size_t segments) :
47  BaseSpineModelLearning(segments)
48 {
49 }
50 
51 TetraSpineLearningModel::~TetraSpineLearningModel()
52 {
53 }
54 namespace
55 {
56  void addNodes(tgStructure& tetra, double edge, double height)
57  {
58  // right
59  tetra.addNode(-edge / 2.0, 0, 0);
60  // left
61  tetra.addNode( edge / 2.0, 0, 0);
62  // top
63  tetra.addNode(0, height, 0);
64  // front
65  tetra.addNode(0, height / 2.0, tgUtil::round(std::sqrt(3.0) / 2.0 * height));
66  }
67 
68  void addPairs(tgStructure& tetra)
69  {
70  tetra.addPair(0, 1, "back bottom rod");
71  tetra.addPair(0, 2, "back right rod");
72  tetra.addPair(0, 3, "front right rod");
73  tetra.addPair(1, 2, "back left rod");
74  tetra.addPair(1, 3, "front left rod");
75  tetra.addPair(2, 3, "front top rod");
76  }
77 
78  void addSegments(tgStructure& snake, const tgStructure& tetra, double edge,
79  size_t segmentCount)
80  {
83  const btVector3 offset(0, 0, -edge * 0.75);
84  for (size_t i = 0; i < segmentCount; ++i)
85  {
88  tgStructure* const t = new tgStructure(tetra);
89  t->addTags(tgString("segment num", i + 1));
90  t->move((i + 1) * offset);
91  // Add a child to the snake
92  snake.addChild(t);
93  }
94  }
95 
96  // Add muscles that connect the segments
97  void addMuscles(tgStructure& snake)
98  {
99  const std::vector<tgStructure*> children = snake.getChildren();
100  for (size_t i = 1; i < children.size(); ++i)
101  {
102  tgNodes n0 = children[i-1]->getNodes();
103  tgNodes n1 = children[i ]->getNodes();
104 
105  snake.addPair(n0[0], n1[0], "outer right muscle");
106  snake.addPair(n0[1], n1[1], "outer left muscle");
107  snake.addPair(n0[2], n1[2], "outer top muscle");
108 
109  snake.addPair(n0[0], n1[3], "inner right muscle");
110  snake.addPair(n0[1], n1[3], "inner left muscle");
111  snake.addPair(n0[2], n1[3], "inner top muscle");
112  }
113  }
114 
115  void mapMuscles(TetraSpineLearningModel::MuscleMap& muscleMap,
116  tgModel& model)
117  {
118  // Note that tags don't need to match exactly, we could create
119  // supersets if we wanted to
120  muscleMap["inner left"] = model.find<tgSpringCableActuator>("inner left muscle");
121  muscleMap["inner right"] = model.find<tgSpringCableActuator>("inner right muscle");
122  muscleMap["inner top"] = model.find<tgSpringCableActuator>("inner top muscle");
123  muscleMap["outer left"] = model.find<tgSpringCableActuator>("outer left muscle");
124  muscleMap["outer right"] = model.find<tgSpringCableActuator>("outer right muscle");
125  muscleMap["outer top"] = model.find<tgSpringCableActuator>("outer top muscle");
126  }
127 
128  void trace(const tgStructureInfo& structureInfo, tgModel& model)
129  {
130  std::cout << "StructureInfo:" << std::endl
131  << structureInfo << std::endl
132  << "Model: " << std::endl
133  << model << std::endl;
134  // Showing the find function
135  const std::vector<tgSpringCableActuator*> outerMuscles =
136  model.find<tgSpringCableActuator>("outer");
137  for (size_t i = 0; i < outerMuscles.size(); ++i)
138  {
139  const tgSpringCableActuator* const pMuscle = outerMuscles[i];
140  assert(pMuscle != NULL);
141  std::cout << "Outer muscle: " << *pMuscle << std::endl;
142  }
143  }
144 
145 } // namespace
146 
147 // This is basically a manual setup of a model.
148 // There are things that do this for us (@todo: reference the things that do this for us)
150 {
151  const double edge = 38.1;
152  const double height = tgUtil::round(std::sqrt(3.0)/2 * edge);
153  std::cout << "edge: " << edge << "; height: " << height << std::endl;
154 
155  // Create the tetrahedra
156  tgStructure tetra;
157  addNodes(tetra, edge, height);
158  addPairs(tetra);
159 
160  // Move the first one so we can create a longer snake.
161  // Or you could move the snake at the end, up to you.
162  tetra.move(btVector3(0.0, 2.0, 100.0));
163 
164  // Create our snake segments
165  tgStructure snake;
166  addSegments(snake, tetra, edge, m_segments);
167  addMuscles(snake);
168 
169  // Create the build spec that uses tags to turn the structure into a real model
170  // Note: This needs to be high enough or things fly apart...
171 
172 #if (0) // Original parameters
173  const double density = 4.2 / 300.0;
174  const double radius = 0.5;
175  const double friction = 0.5;
176  const tgRod::Config rodConfig(radius, density, friction);
177  tgBuildSpec spec;
178  spec.addBuilder("rod", new tgRodInfo(rodConfig));
179 
181  tgSpringCableActuator::Config muscleConfig(1000, 100, 0, false, 7000, 24);
182  spec.addBuilder("muscle", new tgBasicActuatorInfo(muscleConfig));
183 #else // Params for In Won
184  const double density = .00311;
185  const double radius = 0.635;
186  const double friction = 0.5;
187  const tgRod::Config rodConfig(radius, density, friction);
188  tgBuildSpec spec;
189  spec.addBuilder("rod", new tgRodInfo(rodConfig));
190 
192  tgSpringCableActuator::Config muscleConfig(10000, 10, false, 0, 7000, 7.0);
193  spec.addBuilder("muscle", new tgBasicActuatorInfo(muscleConfig));
194 #endif
195  // Create your structureInfo
196  tgStructureInfo structureInfo(snake, spec);
197 
198  // Use the structureInfo to build ourselves
199  structureInfo.buildInto(*this, world);
200 
201  // We could now use tgCast::filter or similar to pull out the models (e.g. muscles)
202  // that we want to control.
203  m_allMuscles = this->find<tgSpringCableActuator> ("muscle");
204  m_allSegments = this->find<tgModel> ("segment");
205  mapMuscles(m_muscleMap, *this);
206 
207  #if (0)
208  trace(structureInfo, *this);
209  #endif
210 
211  // Actually setup the children
213 }
214 
216 {
217 
219 
220 }
221 
223 {
224  if (dt < 0.0)
225  {
226  throw std::invalid_argument("dt is not positive");
227  }
228  else
229  {
230  // Step any children, notify observers
232  }
233 }
const std::vector< tgStructure * > & getChildren() const
Definition: tgStructure.h:131
void addChild(tgStructure *child)
Definition of class tgRodInfo.
Convenience function for combining strings with ints, mostly for naming structures.
Utility class for class casting and filtering collections by type.
virtual void setup(tgWorld &world)
Definition of class tgBasicActuatorInfo.
void addPair(int fromNodeIdx, int toNodeIdx, std::string tags="")
Definition: tgStructure.cpp:66
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
virtual void step(const double dt)
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
virtual void setup(tgWorld &world)
Definition of class tgStructureInfo.
Tetraspine, configured for learning in the NTRT simulator.
Contains the definition of class tgUtil and overloaded operator<<() free functions.
Definition of class tgBuildSpec.
virtual void step(double dt)
void addNode(double x, double y, double z, std::string tags="")
Definition: tgStructure.cpp:56