NTRT Simulator  Version: Master
 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:184
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:80
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:128
virtual void setup(tgWorld &world)
Definition of class tgStructureInfo.
Tetraspine, configured for learning in the NTRT simulator.
Rand seeding simular to the evolution and terrain classes.
Definition of class tgBuildSpec.
virtual void step(double dt)
void buildInto(tgModel &model, tgWorld &world)
void addNode(double x, double y, double z, std::string tags="")
Definition: tgStructure.cpp:70