29 #include "core/tgLinearString.h"
43 throw std::invalid_argument(
"Failed to provide arguments to tgRBString::Config");
48 const tgLinearString::Config& stringConf,
49 double minTotalLength) :
52 m_stringConfig(stringConf),
53 m_minTotalLength(minTotalLength)
58 tgRBString::tgRBString(
const tgTags& tags,
61 tgBaseString(tags, config.m_stringConfig, restLength, restLength),
69 allSegments = tgCast::filter<tgModel, tgRod> (getDescendants());
71 assert(allSegments.size() == m_config.m_segments);
73 allMuscles = this->find<tgLinearString> (
"muscle");
78 if (m_config.m_segments >= 2)
80 const double musclesPerSegment = (double) allMuscles.size() /
81 (double) (m_config.m_segments - 1);
86 m_effectiveStiffness = m_config.m_stringConfig.stiffness *
88 (double) (m_config.m_segments - 1);
93 m_effectiveStiffness = 0;
101 void tgRBString::teardown()
106 void tgRBString::step(
double dt)
110 throw std::invalid_argument(
"dt is not positive.");
119 std::cout <<
"Tension: " << getTension() <<
120 " Calculated Rest: " << getRestLength() <<
121 " Actual length: " << getCurrentLength() << std::endl;
128 void tgRBString::changeMuscles (
double lengthPercent,
double dt)
132 throw std::invalid_argument(
"dt is not positive.");
136 assert(lengthPercent > 0.0);
137 for(
int i = 0; i < allMuscles.size(); i++){
138 const double rl = allMuscles[i]->getRestLength();
142 std::cout <<
"Indiv Muscle " << rl * lengthPercent << std::endl;
145 allMuscles[i]->setRestLength(rl * lengthPercent, dt);
150 void tgRBString::moveMotors(
double dt)
156 double stepSize = m_config.m_stringConfig.targetVelocity * dt;
158 const double velChange = m_config.m_stringConfig.maxAcc * dt;
159 const double actualLength = getCurrentLength();
160 const double mostRecentVelocity = m_pHistory->lastVelocities.back();
161 m_restLength = getRestLength();
163 double diff = m_preferredLength - m_restLength;
164 const double fabsDiff = std::abs(diff);
167 if ((actualLength > m_config.m_stringConfig.minActualLength) ||
170 if (abs(diff) > stepSize)
173 if (std::abs((diff/fabsDiff) * m_config.m_stringConfig.targetVelocity -
174 mostRecentVelocity) >
178 stepSize = velChange * dt;
180 m_restLength += (diff/fabsDiff)*stepSize;
184 if (std::abs(diff/dt - mostRecentVelocity) > velChange)
189 diff = (diff/fabsDiff) * velChange * dt;
196 diff = -(mostRecentVelocity / std::abs(mostRecentVelocity)) *
200 m_restLength += diff;
205 if(m_restLength >= m_config.m_stringConfig.minRestLength)
207 changeMuscles(m_restLength / getRestLength(), dt);
212 void tgRBString::tensionMinLengthController(
const double targetTension,
215 const double stiffness = m_effectiveStiffness;
217 assert(stiffness > 0.0);
219 const double currentTension = getTension();
220 const double delta = targetTension - currentTension;
221 double diff = delta / stiffness;
222 m_restLength = getRestLength();
224 const double newLength = m_restLength - diff;
227 (newLength > m_config.m_stringConfig.minRestLength) ?
228 newLength : m_config.m_stringConfig.minRestLength;
230 std::cout <<
"m_preferred: " << m_preferredLength << std::endl;
235 const double tgRBString::getStartLength()
const
237 return m_pHistory->lastLengths.front();
240 const double tgRBString::getCurrentLength()
const
242 double currLength = 0;
245 std::size_t n = allSegments.size() - 1;
246 for (std::size_t i = 0; i < n; i++)
248 const btVector3 rodCenterOfMass1 = allSegments[i]->centerOfMass();
249 const btVector3 rodCenterOfMass2 = allSegments[i + 1]->centerOfMass();
251 currLength += (rodCenterOfMass2 - rodCenterOfMass1).length();
255 currLength += allSegments[0]->length();
260 const double tgRBString::getTension()
const
262 const double tension = (getCurrentLength() - getRestLength())
263 * m_effectiveStiffness;
264 return (tension < 0) ? 0.0 : tension;
269 const double tgRBString::getRestLength()
const
271 double muscleRest = 0;
274 std::size_t segSize = allSegments.size();
275 for (std::size_t i = 0; i < segSize; i++)
277 rodRest += allSegments[i]->length();
280 std::size_t mSize = allMuscles.size();
281 for (std::size_t i = 0; i < mSize; i++)
283 muscleRest += allMuscles[i]->getRestLength();
288 muscleRest /= ((double) mSize / (
double) (segSize - 1));
290 return rodRest + muscleRest;
293 const double tgRBString::getVelocity()
const
295 return m_pHistory->lastVelocities.back();
298 const double tgRBString::computeVelocity(
const double dt)
const
302 assert (m_pHistory->lastLengths.size() == m_pHistory->lastVelocities.size());
306 vel = (getCurrentLength() - m_pHistory->lastLengths.back()) / dt;
315 throw std::invalid_argument(
"dt is negitive.");
321 void tgRBString::logHistory(
const double dt)
323 const double currentVelocity = computeVelocity(dt);
325 m_pHistory->lastLengths.push_back(getCurrentLength());
327 m_pHistory->lastVelocities.push_back(currentVelocity);
328 if (m_config.m_stringConfig.hist)
331 m_pHistory->restLengths.push_back(getRestLength());
332 m_pHistory->tensionHistory.push_back(getTension());
virtual void setup(tgWorld &world)
virtual void step(double dt)
Utility class for class casting and filtering collections by type.
virtual void setup(tgWorld &world)
Contains the definition of class tgRBString. A string with small rigid bodies to create contact dynam...