1 /* -------------------------------------------------------------------------- *
2 * OpenSim: ForceSet.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-2018 Stanford University and the Authors *
11 * Author(s): Ajay Seth, Jack Middleton *
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 //=============================================================================
26 // INCLUDES
27 //=============================================================================
28 #include "ForceSet.h"
29
30 using namespace std;
31 using namespace OpenSim;
32
extendConnectToModel(Model & aModel)33 void ForceSet::extendConnectToModel(Model& aModel)
34 {
35 // BASE CLASS
36 Super::extendConnectToModel(aModel);
37
38 _actuators.setMemoryOwner(false);
39 _muscles.setMemoryOwner(false);
40
41 updateActuators();
42 updateMuscles();
43 }
44
45
46 //=============================================================================
47 // GET AND SET
48 //=============================================================================
49
50 //-----------------------------------------------------------------------------
51 // ACTUATOR
52 //-----------------------------------------------------------------------------
53 //_____________________________________________________________________________
54 /**
55 * Remove an actuator from the actuator set.
56 *
57 * @param aIndex Index of the actuator to be removed.
58 * @return True if the remove was successful; false otherwise.
59 */
remove(int aIndex)60 bool ForceSet::remove(int aIndex)
61 {
62 bool success = Super::remove(aIndex);
63
64 updateActuators();
65 updateMuscles();
66
67 return(success);
68 }
69
70 //_____________________________________________________________________________
71 /**
72 * Append an actuator on to the set. A copy of the specified actuator
73 * is not made.
74 *
75 * This method overrides the method in Set<Force> so that several
76 * internal variables of the actuator set can be updated.
77 *
78 * @param aActuator Pointer to the actuator to be appended.
79 * @return True if successful; false otherwise.
80 */
append(Force * aForce)81 bool ForceSet::append(Force *aForce)
82 {
83 bool success = Super::adoptAndAppend(aForce);
84
85 if (success && hasModel()) {
86 updateActuators();
87 updateMuscles();
88 }
89
90 return(success);
91 }
92 //_____________________________________________________________________________
93 /**
94 * Append an actuator on to the set. A copy of the specified actuator
95 * is made.
96 *
97 * This method overrides the method in Set<Force> so that several
98 * internal variables of the actuator set can be updated.
99 *
100 * @param aActuator reference to the actuator to be appended.
101 * @return True if successful; false otherwise.
102 */
103 bool ForceSet::
append(Force & aForce)104 append(Force &aForce)
105 {
106 bool success = Super::cloneAndAppend(aForce);
107
108
109 if (success && hasModel()) {
110 updateActuators();
111 updateMuscles();
112 }
113
114 return(success);
115 }
116 //_____________________________________________________________________________
117 /**
118 * Append actuators from an actuator set to this set. Copies of the actuators are not made.
119 *
120 * This method overrides the method in Set<Force> so that several
121 * internal variables of the actuator set can be updated.
122 *
123 * @param aForceSet The set of actuators to be appended.
124 * @param aAllowDuplicateNames If true, all actuators will be appended; If false, don't append actuators whose
125 * name already exists in this model's actuator set.
126 * @return True if successful; false otherwise.
127 */
append(ForceSet & aForceSet,bool aAllowDuplicateNames)128 bool ForceSet::append(ForceSet &aForceSet, bool aAllowDuplicateNames)
129 {
130 bool success = true;
131 for(int i=0;i<aForceSet.getSize() && success;i++) {
132 bool nameExists = false;
133 if(!aAllowDuplicateNames) {
134 std::string name = aForceSet.get(i).getName();
135 for(int j=0;j<getSize();j++) {
136 if(get(j).getName() == name) {
137 nameExists = true;
138 break;
139 }
140 }
141 }
142 if(!nameExists) {
143 if(!Super::adoptAndAppend(&aForceSet.get(i)))
144 success = false;
145 }
146 }
147
148 if(success) {
149 updateActuators();
150 updateMuscles();
151 }
152
153 return(success);
154 }
155 //_____________________________________________________________________________
156 /**
157 * Set the actuator at an index. A copy of the specified actuator is NOT made.
158 * The actuator previously set at the index is removed (and deleted).
159 *
160 * This method overrides the method in Set<Force> so that several
161 * internal variables of the actuator set can be updated.
162 *
163 * @param aIndex Array index where the actuator is to be stored. aIndex
164 * should be in the range 0 <= aIndex <= getSize();
165 * @param aActuator Pointer to the actuator to be set.
166 * @return True if successful; false otherwise.
167 */
set(int aIndex,Force * aActuator,bool preserveGroups)168 bool ForceSet::set(int aIndex,Force *aActuator, bool preserveGroups)
169 {
170 bool success = Super::set(aIndex, aActuator, preserveGroups);
171
172 if(success) {
173 updateActuators();
174 updateMuscles();
175 }
176
177 return(success);
178 }
179
insert(int aIndex,Force * aForce)180 bool ForceSet::insert(int aIndex, Force *aForce)
181 {
182 bool success = Super::insert(aIndex, aForce);
183
184 if(success) {
185 updateActuators();
186 updateMuscles();
187 }
188
189 return(success);
190 }
191
192 //_____________________________________________________________________________
193 /**
194 * Get the list of Actuators.
195 */
getActuators() const196 const Set<Actuator>& ForceSet::getActuators() const
197 {
198 return _actuators;
199 }
200
updActuators()201 Set<Actuator>& ForceSet::updActuators()
202 {
203 updateActuators();
204 return _actuators;
205 }
206 //_____________________________________________________________________________
207 /**
208 * Rebuild the list of Actuators.
209 */
updateActuators()210 void ForceSet::updateActuators()
211 {
212 _actuators.setMemoryOwner(false);
213 _actuators.setSize(0);
214 for (int i = 0; i < getSize(); ++i) {
215 Actuator* act = dynamic_cast<Actuator*>(&get(i));
216 if (act) _actuators.adoptAndAppend(act);
217 }
218 }
219
220 //=============================================================================
221 //_____________________________________________________________________________
222 /**
223 * Get the list of Muscles.
224 */
getMuscles() const225 const Set<Muscle>& ForceSet::getMuscles() const
226 {
227 return _muscles;
228 }
updMuscles()229 Set<Muscle>& ForceSet::updMuscles()
230 {
231 if (_muscles.getSize() == 0)
232 updateMuscles();
233 return _muscles;
234 }
235 //_____________________________________________________________________________
236 /**
237 * Rebuild the list of Muscles.
238 */
updateMuscles()239 void ForceSet::updateMuscles()
240 {
241 _muscles.setMemoryOwner(false);
242 _muscles.setSize(0);
243 for (int i = 0; i < getSize(); ++i) {
244 Muscle* m = dynamic_cast<Muscle*>(&get(i));
245 if (m) _muscles.adoptAndAppend(m);
246 }
247 }
248
249 //=============================================================================
250 // COMPUTATIONS
251 //=============================================================================
252 //_____________________________________________________________________________
253
254
255 //_____________________________________________________________________________
256 /**
257 * Get the names of the states of the actuators.
258 *
259 * @param rNames Array of names.
260 */
261 void ForceSet::
getStateVariableNames(OpenSim::Array<std::string> & rNames) const262 getStateVariableNames(OpenSim::Array<std::string> &rNames) const
263 {
264 for(int i=0;i<getSize();i++) {
265 ScalarActuator *act = dynamic_cast<ScalarActuator*>(&get(i));
266
267 if(act) {
268 rNames.append(act->getStateVariableNames());
269 }
270 }
271 }
272
273
274 //=============================================================================
275 // CHECK
276 //=============================================================================
277 //_____________________________________________________________________________
278 /**
279 * Check that all actuators are valid.
280 */
281 bool ForceSet::
check() const282 check() const
283 {
284 bool status=true;
285
286 // LOOP THROUGH ACTUATORS
287 ScalarActuator *act;
288 int size = getSize();
289 for(int i=0;i<size;i++) {
290 act = dynamic_cast<ScalarActuator *>(&get(i));
291 if(!act) continue;
292 }
293
294 return(status);
295 }
296