1 /* -------------------------------------------------------------------------- *
2 * OpenSim: BushingForce.cpp *
3 * -------------------------------------------------------------------------- *
4 * The OpenSim API is a toolkit for musculoskeletal modeling and simulation. *
5 * See http://opensim.stanford.edu and the NOTICE file for more information. *
6 * OpenSim is developed at Stanford University and supported by the US *
7 * National Institutes of Health (U54 GM072970, R24 HD065690) and by DARPA *
8 * through the Warrior Web program. *
9 * *
10 * Copyright (c) 2005-2017 Stanford University and the Authors *
11 * Author(s): Ajay Seth *
12 * *
13 * Licensed under the Apache License, Version 2.0 (the "License"); you may *
14 * not use this file except in compliance with the License. You may obtain a *
15 * copy of the License at http://www.apache.org/licenses/LICENSE-2.0. *
16 * *
17 * Unless required by applicable law or agreed to in writing, software *
18 * distributed under the License is distributed on an "AS IS" BASIS, *
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
20 * See the License for the specific language governing permissions and *
21 * limitations under the License. *
22 * -------------------------------------------------------------------------- */
23
24 //=============================================================================
25 // INCLUDES
26 //=============================================================================
27 #include <OpenSim/Simulation/Model/Model.h>
28 #include "simbody/internal/Force_LinearBushing.h"
29
30 #include "BushingForce.h"
31
32 using namespace std;
33 using namespace SimTK;
34 using namespace OpenSim;
35
36 //=============================================================================
37 // CONSTRUCTOR(S) AND DESTRUCTOR
38 //=============================================================================
39 // Uses default (compiler-generated) destructor, copy constructor, and copy
40 // assignment operator.
41
42 //_____________________________________________________________________________
43 // Default constructor.
BushingForce()44 BushingForce::BushingForce() : TwoFrameLinker<Force, PhysicalFrame>()
45 {
46 setNull();
47 constructProperties();
48 }
49
BushingForce(const std::string & name,const PhysicalFrame & frame1,const PhysicalFrame & frame2)50 BushingForce::BushingForce(const std::string& name,
51 const PhysicalFrame& frame1,
52 const PhysicalFrame& frame2)
53 : Super(name, frame1, frame2)
54 {
55 setNull();
56 constructProperties();
57 }
58
BushingForce(const std::string & name,const std::string & frame1Name,const std::string & frame2Name)59 BushingForce::BushingForce( const std::string& name,
60 const std::string& frame1Name,
61 const std::string& frame2Name)
62 : Super(name, frame1Name, frame2Name)
63 {
64 setNull();
65 constructProperties();
66 }
67
BushingForce(const std::string & name,const PhysicalFrame & frame1,const PhysicalFrame & frame2,const SimTK::Vec3 & transStiffness,const SimTK::Vec3 & rotStiffness,const SimTK::Vec3 & transDamping,const SimTK::Vec3 & rotDamping)68 BushingForce::BushingForce(const std::string& name,
69 const PhysicalFrame& frame1,
70 const PhysicalFrame& frame2,
71 const SimTK::Vec3& transStiffness,
72 const SimTK::Vec3& rotStiffness,
73 const SimTK::Vec3& transDamping,
74 const SimTK::Vec3& rotDamping)
75 : BushingForce(name, frame1, frame2)
76 {
77 set_rotational_stiffness(rotStiffness);
78 set_translational_stiffness(transStiffness);
79 set_rotational_damping(rotDamping);
80 set_translational_damping(transDamping);
81 }
82
BushingForce(const std::string & name,const std::string & frame1Name,const std::string & frame2Name,const SimTK::Vec3 & transStiffness,const SimTK::Vec3 & rotStiffness,const SimTK::Vec3 & transDamping,const SimTK::Vec3 & rotDamping)83 BushingForce::BushingForce( const std::string &name,
84 const std::string& frame1Name,
85 const std::string& frame2Name,
86 const SimTK::Vec3& transStiffness,
87 const SimTK::Vec3& rotStiffness,
88 const SimTK::Vec3& transDamping,
89 const SimTK::Vec3& rotDamping )
90 : BushingForce(name, frame1Name, frame2Name)
91 {
92 set_rotational_stiffness(rotStiffness);
93 set_translational_stiffness(transStiffness);
94 set_rotational_damping(rotDamping);
95 set_translational_damping(transDamping);
96 }
97
BushingForce(const std::string & name,const PhysicalFrame & frame1,const SimTK::Transform & transformInFrame1,const PhysicalFrame & frame2,const SimTK::Transform & transformInFrame2,const SimTK::Vec3 & transStiffness,const SimTK::Vec3 & rotStiffness,const SimTK::Vec3 & transDamping,const SimTK::Vec3 & rotDamping)98 BushingForce::BushingForce(const std::string& name, const PhysicalFrame& frame1,
99 const SimTK::Transform& transformInFrame1,
100 const PhysicalFrame& frame2,
101 const SimTK::Transform& transformInFrame2,
102 const SimTK::Vec3& transStiffness,
103 const SimTK::Vec3& rotStiffness,
104 const SimTK::Vec3& transDamping,
105 const SimTK::Vec3& rotDamping)
106 : Super(name, frame1, transformInFrame1, frame2, transformInFrame2)
107 {
108 setNull();
109 constructProperties();
110 set_rotational_stiffness(rotStiffness);
111 set_translational_stiffness(transStiffness);
112 set_rotational_damping(rotDamping);
113 set_translational_damping(transDamping);
114 }
115
BushingForce(const std::string & name,const std::string & frame1Name,const SimTK::Transform & transformInFrame1,const std::string & frame2Name,const SimTK::Transform & transformInFrame2,const SimTK::Vec3 & transStiffness,const SimTK::Vec3 & rotStiffness,const SimTK::Vec3 & transDamping,const SimTK::Vec3 & rotDamping)116 BushingForce::BushingForce(const std::string& name,
117 const std::string& frame1Name, const SimTK::Transform& transformInFrame1,
118 const std::string& frame2Name, const SimTK::Transform& transformInFrame2,
119 const SimTK::Vec3& transStiffness,
120 const SimTK::Vec3& rotStiffness,
121 const SimTK::Vec3& transDamping,
122 const SimTK::Vec3& rotDamping)
123 : Super(name,frame1Name, transformInFrame1, frame2Name, transformInFrame2)
124 {
125 setNull();
126 constructProperties();
127 set_rotational_stiffness(rotStiffness);
128 set_translational_stiffness(transStiffness);
129 set_rotational_damping(rotDamping);
130 set_translational_damping(transDamping);
131 }
132
BushingForce(const std::string & name,const std::string & frame1Name,const SimTK::Vec3 & locationInFrame1,const SimTK::Vec3 & orientationInFrame1,const std::string & frame2Name,const SimTK::Vec3 & locationInFrame2,const SimTK::Vec3 & orientationInFrame2,const SimTK::Vec3 & transStiffness,const SimTK::Vec3 & rotStiffness,const SimTK::Vec3 & transDamping,const SimTK::Vec3 & rotDamping)133 BushingForce::BushingForce(const std::string& name,
134 const std::string& frame1Name,
135 const SimTK::Vec3& locationInFrame1, const SimTK::Vec3& orientationInFrame1,
136 const std::string& frame2Name,
137 const SimTK::Vec3& locationInFrame2, const SimTK::Vec3& orientationInFrame2,
138 const SimTK::Vec3& transStiffness,
139 const SimTK::Vec3& rotStiffness,
140 const SimTK::Vec3& transDamping,
141 const SimTK::Vec3& rotDamping)
142 : TwoFrameLinker<Force, PhysicalFrame>(name,
143 frame1Name, locationInFrame1, orientationInFrame1,
144 frame2Name, locationInFrame2, orientationInFrame1)
145 {
146 setNull();
147 constructProperties();
148 set_rotational_stiffness(rotStiffness);
149 set_translational_stiffness(transStiffness);
150 set_rotational_damping(rotDamping);
151 set_translational_damping(transDamping);
152 }
153
154 //_____________________________________________________________________________
155 // Set the data members of this BushingForce to their null values.
setNull()156 void BushingForce::setNull()
157 {
158 setAuthors("Ajay Seth");
159 }
160
161 //_____________________________________________________________________________
162 // Allocate and initialize properties.
constructProperties()163 void BushingForce::constructProperties()
164 {
165 // default bushing material properties
166 constructProperty_rotational_stiffness(Vec3(0));
167 constructProperty_translational_stiffness(Vec3(0));
168 constructProperty_rotational_damping(Vec3(0));
169 constructProperty_translational_damping(Vec3(0));
170 }
171
172 // Add underly Simbody elements to the System after subcomponents
173 void BushingForce::
extendAddToSystemAfterSubcomponents(SimTK::MultibodySystem & system) const174 extendAddToSystemAfterSubcomponents(SimTK::MultibodySystem& system) const
175 {
176 Super::extendAddToSystemAfterSubcomponents(system);
177
178 const SimTK::Vec3& rotStiffness = get_rotational_stiffness();
179 const SimTK::Vec3& transStiffness = get_translational_stiffness();
180 const SimTK::Vec3& rotDamping = get_rotational_damping();
181 const SimTK::Vec3& transDamping = get_translational_damping();
182
183 // get connected frames
184 const PhysicalFrame& frame1 = getFrame1();
185 const PhysicalFrame& frame2 = getFrame2();
186
187 // Get underlying mobilized bodies
188 const SimTK::MobilizedBody& b1 = frame1.getMobilizedBody();
189 const SimTK::MobilizedBody& b2 = frame2.getMobilizedBody();
190
191 Vec6 stiffness(rotStiffness[0], rotStiffness[1], rotStiffness[2],
192 transStiffness[0], transStiffness[1], transStiffness[2]);
193 Vec6 damping(rotDamping[0], rotDamping[1], rotDamping[2],
194 transDamping[0], transDamping[1], transDamping[2]);
195
196 // Now create a Simbody Force::LinearBushing
197 SimTK::Force::LinearBushing simtkForce
198 (_model->updForceSubsystem(), b1, frame1.findTransformInBaseFrame(),
199 b2, frame2.findTransformInBaseFrame(),
200 stiffness, damping );
201
202 // Beyond the const Component get the index so we can access the
203 // SimTK::Force later.
204 BushingForce* mutableThis = const_cast<BushingForce *>(this);
205 mutableThis->_index = simtkForce.getForceIndex();
206 }
207
208 //=============================================================================
209 // SET
210 //=============================================================================
211 //_____________________________________________________________________________
212 // The following methods set properties of the bushing Force.
213
214
215 /* Potential energy is computed by underlying SimTK::Force. */
computePotentialEnergy(const SimTK::State & s) const216 double BushingForce::computePotentialEnergy(const SimTK::State& s) const
217 {
218 return _model->getForceSubsystem().getForce(_index)
219 .calcPotentialEnergyContribution(s);
220 }
221
222 //=============================================================================
223 // Reporting
224 //=============================================================================
225 /*
226 * Provide names of the quantities (column labels) of the force value(s) to be
227 * reported.
228 */
getRecordLabels() const229 OpenSim::Array<std::string> BushingForce::getRecordLabels() const
230 {
231 const string& frame1Name = getFrame1().getName();
232 const string& frame2Name = getFrame2().getName();
233
234 OpenSim::Array<std::string> labels("");
235 labels.append(getName()+"."+frame1Name+".force.X");
236 labels.append(getName()+"."+frame1Name+".force.Y");
237 labels.append(getName()+"."+frame1Name+".force.Z");
238 labels.append(getName()+"."+frame1Name+".torque.X");
239 labels.append(getName()+"."+frame1Name+".torque.Y");
240 labels.append(getName()+"."+frame1Name+".torque.Z");
241 labels.append(getName()+"."+frame2Name+".force.X");
242 labels.append(getName()+"."+frame2Name+".force.Y");
243 labels.append(getName()+"."+frame2Name+".force.Z");
244 labels.append(getName()+"."+frame2Name+".torque.X");
245 labels.append(getName()+"."+frame2Name+".torque.Y");
246 labels.append(getName()+"."+frame2Name+".torque.Z");
247
248 return labels;
249 }
250 /*
251 * Provide the value(s) to be reported that correspond to the labels
252 */
253 OpenSim::Array<double> BushingForce::
getRecordValues(const SimTK::State & state) const254 getRecordValues(const SimTK::State& state) const
255 {
256 const PhysicalFrame& frame1 = getFrame1();
257 const PhysicalFrame& frame2 = getFrame2();
258
259 //const string& frame1Name = frame1.getName();
260 //const string& frame2Name = frame2.getName();
261
262 OpenSim::Array<double> values(1);
263
264 const SimTK::Force::LinearBushing &simtkSpring =
265 (SimTK::Force::LinearBushing &)(_model->getForceSubsystem().getForce(_index));
266
267 SimTK::Vector_<SimTK::SpatialVec> bodyForces(0);
268 SimTK::Vector_<SimTK::Vec3> particleForces(0);
269 SimTK::Vector mobilityForces(0);
270
271 //get the net force added to the system contributed by the bushing
272 simtkSpring.calcForceContribution(state, bodyForces, particleForces, mobilityForces);
273 SimTK::Vec3 forces = bodyForces[frame1.getMobilizedBodyIndex()][1];
274 SimTK::Vec3 torques = bodyForces[frame1.getMobilizedBodyIndex()][0];
275 values.append(3, &forces[0]);
276 values.append(3, &torques[0]);
277
278 forces = bodyForces[frame2.getMobilizedBodyIndex()][1];
279 torques = bodyForces[frame2.getMobilizedBodyIndex()][0];
280
281 values.append(3, &forces[0]);
282 values.append(3, &torques[0]);
283
284 return values;
285 }
286