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