NTRT Simulator  Version: Master
 All Classes Namespaces Files Functions Variables Typedefs Friends Pages
BaseQuadModelLearning.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 
28 // This module
29 #include "BaseQuadModelLearning.h"
30 // This library
31 #include "core/tgCast.h"
33 #include "core/tgBaseRigid.h"
34 #include "core/tgRod.h"
35 #include "core/tgString.h"
36 // The C++ Standard Library
37 #include <algorithm> // std::fill
38 #include <iostream>
39 #include <stdexcept>
40 
41 BaseQuadModelLearning::BaseQuadModelLearning(int segments, int hips) :
42  m_segments(segments),
43  m_hips(hips),
44  tgModel()
45 {
46  m_subStructures = m_hips + m_segments;
47 }
48 
49 BaseQuadModelLearning::~BaseQuadModelLearning()
50 {
51 }
52 
54 {
55 
56  notifySetup();
57 
58  // Actually setup the children
59  tgModel::setup(world);
60 }
61 
63 {
65 
67 
68  // These pointers will be freed by tgModel::teardown
69  m_allMuscles.clear();
70  m_allSegments.clear();
71  m_muscleMap.clear();
72 }
73 
75 {
76  /* CPG update occurs in the controller so that we can decouple it
77  * from the physics update
78  */
79  notifyStep(dt);
80 
81  tgModel::step(dt); // Step any children
82 }
83 
84 const std::vector<tgSpringCableActuator*>&
85 BaseQuadModelLearning::getMuscles (const std::string& key) const
86 {
87  const MuscleMap::const_iterator it = m_muscleMap.find(key);
88  if (it == m_muscleMap.end())
89  {
90  throw std::invalid_argument("Key '" + key + "' not found in muscle map");
91  }
92  else
93  {
94  return it->second;
95  }
96 }
97 
98 const std::vector<tgSpringCableActuator*>& BaseQuadModelLearning::getAllMuscles() const
99 {
100  return m_allMuscles;
101 }
102 
103 const std::vector<tgBaseRigid*> BaseQuadModelLearning::getAllRigids() const
104 {
105  if (m_allSegments.size() != m_subStructures)
106  {
107  throw std::runtime_error("Not initialized");
108  }
109 
110  std::vector<tgBaseRigid*> p_rods;
111 
112  for (std::size_t i = 0; i < m_allSegments.size(); i++)
113  {
114  std::vector<tgBaseRigid*> temp = tgCast::filter<tgModel, tgBaseRigid> (m_allSegments[i]->getDescendants());
115  p_rods.insert(p_rods.end(), temp.begin(), temp.end());
116  }
117 
118  return p_rods;
119 }
120 
121 const int BaseQuadModelLearning::getSegments() const
122 {
123  return m_segments;
124 }
125 
126 std::vector<double> BaseQuadModelLearning::getCOM(const int n)
127 {
128  if (m_allSegments.size() != m_subStructures)
129  {
130  throw std::runtime_error("Not initialized");
131  }
132  else if (n < 0)
133  {
134  throw std::range_error("Negative segment number");
135  }
136  else if (n >= m_subStructures)
137  {
138  throw std::range_error(tgString("Segment number > ", m_segments));
139  }
140 
141  std::vector<double> centerOfMass(3);
142  for (size_t i = 0; i < 3; ++i) { centerOfMass[i] = 0; }
143  double mass = 0.0;
144  for (std::size_t i = n; i < m_subStructures; i++)
145  {
146  std::vector<double> segmentCOM = getSegmentCOM(i);
147  for (std::size_t j = 0; j < 3; j++)
148  {
149  segmentCOM[j] *= segmentMasses[i];
150  }
151  for (std::size_t j = 0; j < 3; j++)
152  {
153  centerOfMass[j] += segmentCOM[j];
154  }
155  mass += segmentMasses[i];
156  }
157 
158  //assert(n == segmentMasses.size());
159 
160  for (std::size_t j = 0; j < 3; j++)
161  {
162  centerOfMass[j] /= mass;
163  }
164 
165  return centerOfMass;
166 }
167 
168 std::vector<double> BaseQuadModelLearning::getSegmentCOM(const int n)
169 {
170 
171  btVector3 segmentCenterOfMass = getSegmentCOMVector(n);
172 
173  // Copy to the result std::vector
174  std::vector<double> result(3);
175  for (size_t i = 0; i < 3; ++i) { result[i] = segmentCenterOfMass[i]; }
176 
177  return result;
178 }
179 
180 btVector3 BaseQuadModelLearning::getSegmentCOMVector(const int n)
181 {
182  if (m_allSegments.size() != m_subStructures)
183  {
184  throw std::runtime_error("Not initialized");
185  }
186  else if (n < 0)
187  {
188  throw std::range_error("Negative segment number");
189  }
190  else if (n >= m_subStructures)
191  {
192  throw std::range_error(tgString("Segment number > ", m_segments));
193  }
194 
195  std::vector<tgRod*> p_rods =
196  tgCast::filter<tgModel, tgRod> (m_allSegments[n]->getDescendants());
197 
198  // Ensure our segments are being populated correctly
199  assert(!p_rods.empty());
200 
201  btVector3 segmentCenterOfMass(0, 0, 0);
202  double segmentMass = 0.0;
203  for (std::size_t i = 0; i < p_rods.size(); i++)
204  {
205  const tgRod* const pRod = p_rods[i];
206  assert(pRod != NULL);
207  const double rodMass = pRod->mass();
208  //std::cout << "mass " << rodMass;
209  const btVector3 rodCenterOfMass = pRod->centerOfMass();
210  segmentCenterOfMass += rodCenterOfMass * rodMass;
211  segmentMass += rodMass;
212  }
213 
214  // Check to make sure the rods actually had mass
215  assert(segmentMass > 0.0);
216 
217  segmentMasses.push_back(segmentMass);
218 
219  segmentCenterOfMass /= segmentMass;
220 
221  return segmentCenterOfMass;
222 }
223 
224 double BaseQuadModelLearning::getSpineLength()
225 {
226  const btVector3 start = getSegmentCOMVector(0);
227  const btVector3 end = getSegmentCOMVector(m_segments - 1);
228 
229  return (start - end).length();
230 }
231 
virtual void teardown()
Definition: tgModel.cpp:68
virtual void setup(tgWorld &world)
Definition: tgModel.cpp:57
Create a box shape as an obstacle or add it to your tensegrity.
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.
virtual void step(double dt)
virtual btVector3 centerOfMass() const
Definition: tgBaseRigid.cpp:74
Contains the definition of abstract base class tgSpringCableActuator. Assumes that the string is line...
std::string tgString(std::string s, int i)
Definition: tgString.h:33
virtual double mass() const
Definition: tgBaseRigid.h:65
Contains the definition of class tgRod.
Definition: tgRod.h:43