NTRT Simulator
 All Classes Files Functions Variables Typedefs Friends Pages
Muscle2P.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 
26 // This module
27 #include "Muscle2P.h"
28 // The BulletPhysics library
29 #include "BulletDynamics/Dynamics/btRigidBody.h"
30 
31 #include <iostream>
32 
33 Muscle2P::Muscle2P(btRigidBody * body1,
34  btVector3 pos1,
35  btRigidBody * body2,
36  btVector3 pos2,
37  double coefK,
38  double dampingCoefficient) :
39 m_velocity(0.0),
40 m_damping(0.0),
41 m_coefK (coefK),
42 m_dampingCoefficient(dampingCoefficient)
43 
44 {
45  anchor1 = new muscleAnchor(body1, pos1);
46  anchor2 = new muscleAnchor(body2, pos2);
47  m_restLength = pos1.distance(pos2);
48  m_prevLength = m_restLength;
49 }
50 
51 btVector3 Muscle2P::calculateAndApplyForce(double dt)
52 {
53  btVector3 force(0.0, 0.0, 0.0);
54  double magnitude = 0.0;
55  const btVector3 dist =
56  anchor2->getWorldPosition() - anchor1->getWorldPosition();
57 
58  // These computations should occur for history regardless of motion
59  const double currLength = dist.length();
60  const btVector3 unitVector = dist / currLength;
61  const double stretch = currLength - m_restLength;
62 
63  magnitude = m_coefK * stretch;
64 
65  const double deltaStretch = currLength - m_prevLength;
66  m_velocity = deltaStretch / dt;
67 
68  m_damping = m_dampingCoefficient * m_velocity;
69 
70  if (abs(magnitude) * 1.0 < abs(m_damping))
71  {
72  m_damping =
73  (m_damping > 0.0 ? magnitude * 1.0 : -magnitude * 1.0);
74  }
75 
76  magnitude += m_damping;
77 
78  #if (0)
79  std::cout << "Length: " << dist.length() << " rl: " << m_restLength <<std::endl;
80  #endif
81 
82  if (dist.length() > m_restLength)
83  {
84  force = unitVector * magnitude;
85  }
86  else
87  {
88  // Leave force as the zero vector
89  }
90 
91  // Finished calculating, so can store things
92  m_prevLength = currLength;
93 
94  //Now Apply it to the connected two bodies
95  btVector3 point1 = this->anchor1->getRelativePosition();
96  this->anchor1->attachedBody->activate();
97  this->anchor1->attachedBody->applyForce(force,point1);
98 
99  btVector3 point2 = this->anchor2->getRelativePosition();
100  this->anchor2->attachedBody->activate();
101  this->anchor2->attachedBody->applyForce(-force,point2);
102 
103  return force;
104 }
105 
106 void Muscle2P::setRestLength( const double newRestLength)
107 {
108  // Assume we've already put this through a motor model
109  // But check anyway
110  assert(newRestLength > 0.0);
111 
112  m_restLength = newRestLength;
113 }
114 
115 const double Muscle2P::getRestLength() const
116 {
117  return m_restLength;
118 }
119 
120 const btScalar Muscle2P::getActualLength() const
121 {
122  const btVector3 dist =
123  this->anchor2->getWorldPosition() - this->anchor1->getWorldPosition();
124  return dist.length();
125 }
126 
127 const double Muscle2P::getTension() const
128 {
129  double tension = (getActualLength() - m_restLength) * m_coefK;
130  tension = (tension < 0.0) ? 0.0 : tension;
131  return tension;
132 }
133 
134 Muscle2P::~Muscle2P()
135 {
136  #if (0)
137  std::cout << "Destroying Muscle2P" << std::endl;
138  #endif
139  delete anchor1;
140  delete anchor2;
141 }
142 
143 // todo: make seperate class
144 
145 muscleAnchor::muscleAnchor()
146 {
147 }
148 
149 muscleAnchor::muscleAnchor(btRigidBody * body,
150  btVector3 worldPos) :
151  attachedBody(body),
152  // Find relative position
153  // This should give relative position in a default orientation.
154  attachedRelativeOriginalPosition(attachedBody->getWorldTransform().inverse() *
155  worldPos),
156  height(999.0)
157 {
158 }
159 
160 muscleAnchor::~muscleAnchor()
161 {
162  // World should delete this
163  attachedBody = NULL;
164 
165 }
166 
167 // This returns current position relative to the rigidbody.
168 btVector3 muscleAnchor::getRelativePosition()
169 {
170  const btTransform tr = attachedBody->getWorldTransform();
171  const btVector3 worldPos = tr * attachedRelativeOriginalPosition;
172  return worldPos-this->attachedBody->getCenterOfMassPosition();
173 }
174 
175 btVector3 muscleAnchor::getWorldPosition()
176 {
177  const btTransform tr = attachedBody->getWorldTransform();
178  return tr * attachedRelativeOriginalPosition;
179 }
Definitions of classes Muscle2P and MuscleAnchor.