NTRT Simulator
 All Classes Files Functions Variables Typedefs Friends Pages
FlemonsSpineModelLearningCL.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 
29 
30 // This library
31 #include "core/tgCast.h"
32 #include "core/tgLinearString.h"
33 #include "core/tgString.h"
34 #include "tgcreator/tgBuildSpec.h"
36 #include "tgcreator/tgRodInfo.h"
37 #include "tgcreator/tgStructure.h"
39 #include "tgcreator/tgUtil.h"
40 
41 #include "LinearMath/btVector3.h"
42 #include <iostream>
43 #include <algorithm> // std::fill
44 #include <map>
45 #include <set>
46 
47 FlemonsSpineModelLearningCL::FlemonsSpineModelLearningCL(int segments) :
48  BaseSpineModelLearning(segments)
49 {
50 }
51 
52 FlemonsSpineModelLearningCL::~FlemonsSpineModelLearningCL()
53 {
54 }
55 
57 {
58  // This is basically a manual setup of a model. There are things that do this for us (@todo: reference the things that do this for us)
59 
60  // Rod and Muscle configuration
61 
62  const double density = 4.2/300.0; // Note: This needs to be high enough or things fly apart...
63  const double radius = 0.5;
64  const tgRod::Config rodConfig(radius, density);
65 
66  const double radius2 = 0.15;
67  const double density2 = 1; // Note: This needs to be high enough or things fly apart...
68  const tgRod::Config rodConfig2(radius2, density2);
69 
70  const double stiffness = 1000.0;
71  const double damping = .01*stiffness;
72  //const int segments = 8;
73  const tgLinearString::Config stringConfig(stiffness, damping, false, 0, 7000, 24, 10000);
74  //const tgRBString::Config rbConfig(segments, rodConfig2, stringConfig, 10.0);
75 
76  tgLinearString::Config muscleConfig(2000, 20);
77 
78  // Calculations for the flemons spine model
79  double v_size = 10.0;
80 
81  // Create the tetrahedra
82  tgStructure tetra;
83 
84  tetra.addNode(0,0,0); // center
85  tetra.addNode(0.0, v_size, 0.0); // Top
86  tetra.addNode(0.0, -v_size, 0.0); // Bottom
87  tetra.addNode(0.0, 0.0, v_size); // front
88  tetra.addNode(0.0, 0.0, -v_size); // back
89  tetra.addNode(v_size, 0.0, 0.0); // right
90  tetra.addNode(-v_size, 0.0, 0.0); // left
91 
92  tetra.addPair(0,1, "top rod");
93  tetra.addPair(0,2, "bottom rod");
94  tetra.addPair(0,3, "front rod");
95  tetra.addPair(0,4, "back rod");
96  tetra.addPair(0,5, "right rod");
97  tetra.addPair(0,6, "left rod");
98 
99 
100  // Create our snake segments
101  tgStructure snake;
102  const double offsetDist = -v_size *1.25;
103  btVector3 offset(0,0,offsetDist); // @todo: there seems to be an issue with Muscle2P connections if the front of a tetra is inside the next one.
104  for(std::size_t i = 0; i < m_segments; i++) {
105  // @todo: the snake is a temporary variable -- will its destructor be called? If not, where do we delete its children?
106  tgStructure* t = new tgStructure(tetra);
107  t->addTags(tgString("segment num", i + 1));
108  t->move((i + 1)*offset);
109 
110  if (i % 2 == 1)
111  {
112  t->addRotation(btVector3(0.0, 0.0, (i + 1) * offsetDist), btVector3(1, 0, 0), M_PI/4.0);
113  }
114  else
115  {
116  t->addRotation(btVector3(0.0, 0.0, (i + 1) * offsetDist), btVector3(0, 1, 0), -M_PI/4.0);
117  }
118 
119  //t->addRotation(btVector3(0.0, 0.0, (i + 1) * offsetDist), btVector3(0, 0, 1), M_PI/4.0);
120 
121 
122  snake.addChild(t); // Add a child to the snake
123  }
124 
125  // Move the snake at the end, up to you.
126  snake.addRotation(btVector3(0.0, 0.0, 0.0), btVector3(0, 0, 1), M_PI/4.0);
127  snake.move(btVector3(0.0,15.0,100.0));
128  //conditionally compile for debugging
129  #if (1)
130  // Add muscles that connect the segments
131  // Tag the muscles with their segment numbers so CPGs can find
132  // them.
133  std::vector<tgStructure*> children = snake.getChildren();
134  for(std::size_t i = 1; i < children.size(); i++) {
135  tgNodes n0 = children[i-1]->getNodes();
136  tgNodes n1 = children[i]->getNodes();
137 
138  if (i % 2 == 0 )
139  {
140 
141  snake.addPair(n0[2], n1[3], tgString("inner front muscle seg", i-1) + tgString(" seg", i));
142  snake.addPair(n0[4], n1[3], tgString("inner right muscle seg", i-1) + tgString(" seg", i));
143  snake.addPair(n0[2], n1[5], tgString("inner left muscle seg", i-1) + tgString(" seg", i));
144  snake.addPair(n0[4], n1[5], tgString("inner back muscle seg", i-1) + tgString(" seg", i));
145 
146  #if (1) // Traditional interior crosslink
147  snake.addPair(n0[5], n1[3], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
148  snake.addPair(n0[6], n1[5], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
149  snake.addPair(n0[2], n1[1], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
150  snake.addPair(n0[4], n1[2], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
151 
152  #else
153  snake.addPair(n0[5], n1[5], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
154  snake.addPair(n0[6], n1[3], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
155  snake.addPair(n0[4], n1[1], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
156  snake.addPair(n0[2], n1[2], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
157  #endif
158 
159  }
160  else
161  {
162 
163  snake.addPair(n0[6], n1[1], tgString("inner front muscle seg", i-1) + tgString(" seg", i));
164  snake.addPair(n0[4], n1[1], tgString("inner right muscle seg", i-1) + tgString(" seg", i));
165  snake.addPair(n0[6], n1[3], tgString("inner left muscle seg", i-1) + tgString(" seg", i));
166  snake.addPair(n0[4], n1[3], tgString("inner back muscle seg", i-1) + tgString(" seg", i));
167 
168  #if (1)
169  snake.addPair(n0[1], n1[3], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
170  snake.addPair(n0[2], n1[1], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
171  snake.addPair(n0[6], n1[5], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
172  snake.addPair(n0[4], n1[6], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
173 
174  #else
175  snake.addPair(n0[4], n1[5], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
176  snake.addPair(n0[2], n1[3], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
177  snake.addPair(n0[1], n1[1], tgString("inner left muscle2 seg", i-1) + tgString(" seg", i));
178  snake.addPair(n0[6], n1[6], tgString("inner back muscle2 seg", i-1) + tgString(" seg", i));
179  #endif
180 
181  }
182  }
183  #endif
184  // Create the build spec that uses tags to turn the structure into a real model
185  tgBuildSpec spec;
186  spec.addBuilder("rod", new tgRodInfo(rodConfig));
187 
188  #if (1)
189  spec.addBuilder("muscle", new tgLinearStringInfo(muscleConfig));
190  spec.addBuilder("muscle2", new tgLinearStringInfo(stringConfig));
191  #endif
192 
193  // Create your structureInfo
194  tgStructureInfo structureInfo(snake, spec);
195 
196  // Use the structureInfo to build ourselves
197  structureInfo.buildInto(*this, world);
198 
199  // Setup vectors for control
200  m_allMuscles = find<tgLinearString> ("muscle2");
201  reflexMuscles = find<tgLinearString> ("muscle");
202  m_allSegments = this->find<tgModel> ("segment");
203 
204  #if (0)
205  // Debug printing
206  std::cout << "StructureInfo:" << std::endl;
207  std::cout << structureInfo << std::endl;
208 
209  std::cout << "Model: " << std::endl;
210  std::cout << *this << std::endl;
211 
212  #endif
213 
214  children.clear();
215 
216  // Actually setup the children
218 }
219 
221 {
222 
224 
225 }
226 
228 {
229 
230  // Probably should go in a controller eventually
231  for(int i = 0; i < reflexMuscles.size(); i++)
232  {
233  reflexMuscles[i]->setRestLength(reflexMuscles[i]->getStartLength() - 0.5, dt);
234  }
235 
236  /* CPG update occurs in the controller so that we can decouple it
237  * from the physics update
238  */
239 
240  BaseSpineModelLearning::step(dt); // Step any children
241 }
const std::vector< tgStructure * > & getChildren() const
Definition: tgStructure.h:130
virtual void setup(tgWorld &world)
void addChild(tgStructure *child)
Definition of class tgRodInfo.
Implementing the cross-linked octahedral complex spine inspired by Tom Flemons.
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)
void addPair(int fromNodeIdx, int toNodeIdx, std::string tags="")
Definition: tgStructure.cpp:65
void addRotation(const btVector3 &fixedPoint, const btVector3 &axis, double angle)
Definition: tgStructure.cpp:98
Contains the definition of class tgLinearString.
std::string tgString(std::string s, int i)
Definition: tgString.h:32
Definition of class tgStructure.
Definition of class tgStructureInfo.
Definition of class tgLinearStringInfo.
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:55