@@ -115,19 +115,47 @@ prepareToOptimize(SimTK::State& s, double *x)
115
115
}
116
116
117
117
// Initialize the system at given activations and state
118
+ double modifier (0 .);
119
+ int iter (0 );
118
120
const ForceSet& fSet = _model->getForceSet ();
119
- for (int i=0 ,j=0 ;i<fSet .getSize ();i++) {
120
- Muscle *mus = dynamic_cast <Muscle*>(&fSet .get (i));
121
- if (mus){
122
- mus->overrideActuation (s, false );
123
- mus->setActivation (s, x[j]);
124
- ++j;
121
+ while (true ){
122
+ for (int i=0 ,j=0 ;i<fSet .getSize ();i++) {
123
+ Muscle *mus = dynamic_cast <Muscle*>(&fSet .get (i));
124
+ if (mus){
125
+ mus->overrideActuation (s, false );
126
+ if (x[i] + modifier <= 1 )
127
+ mus->setActivation (s, x[j] + modifier);
128
+ else
129
+ mus->setActivation (s, x[j] - modifier);
130
+ ++j;
131
+ }
132
+ CoordinateActuator* coord = dynamic_cast <CoordinateActuator*>(&fSet .get (i));
133
+ if (coord)
134
+ coord->setOverrideActuation (s, x[i] * coord->getOptimalForce ());
135
+ }
136
+ try {
137
+ _model->equilibrateMuscles (s);
138
+ } catch (const Exception& e) {
139
+ // If the muscle falls into some weird numerical error, try to just slightly change the activations
140
+ // and reprocess it until it works (maximum of 10 times)
141
+ modifier += 0.001 ;
142
+ ++iter;
143
+ if (iter >= 10 )
144
+ throw e;
145
+ continue ;
125
146
}
147
+ break ;
126
148
}
127
- _model->equilibrateMuscles (s); // No need to test for error, since it is the same activation as previous state
128
- _model->getMultibodySystem ().realize (s,SimTK::Stage::Velocity);
129
149
130
150
#ifdef USE_LINEAR_CONSTRAINT_MATRIX
151
+ // Remove residual actuator to compute sole effects of passive and active forces
152
+ for (int i=0 , j=0 ; i<fSet .getSize (); i++) {
153
+ CoordinateActuator* coord = dynamic_cast <CoordinateActuator*>(&fSet .get (i));
154
+ if (coord)
155
+ coord->setOverrideActuation (s, 0 );
156
+ }
157
+ _model->getMultibodySystem ().realize (s,SimTK::Stage::Velocity);
158
+
131
159
// Compute passive forces at state s
132
160
Vector passiveForces (np);
133
161
for (int i=0 , j=0 ; i<fSet .getSize (); i++) {
@@ -141,23 +169,24 @@ prepareToOptimize(SimTK::State& s, double *x)
141
169
Vector qddotPassive (nc);
142
170
for (int i=0 ,j=0 ;i<fSet .getSize ();i++) {
143
171
Muscle* mus = dynamic_cast <Muscle*>(&fSet .get (i));
144
- if ( mus ) {
145
- mus->overrideActuation (s, true );
146
- mus->setOverrideActuation (s, passiveForces[j]);
147
- ++j;
148
- }
172
+ if ( mus ) {
173
+ mus->overrideActuation (s, true );
174
+ mus->setOverrideActuation (s, passiveForces[j]);
175
+ ++j;
176
+ }
149
177
}
178
+ // Don't reequilibrate muscle since it has the right length!
150
179
_model->getMultibodySystem ().realize (s,SimTK::Stage::Acceleration);
151
180
SimTK::Vector udot = _model->getMatterSubsystem ().getUDot (s);
152
181
for (int i=0 ; i<_accelerationIndices.getSize (); i++)
153
182
qddotPassive[i] = udot[_accelerationIndices[i]];
154
183
155
- // Compute linear qqdot from the non linear effects
184
+ // Compute linear qqdot from the non linear effects (coriolis and gravity)
156
185
Vector qddotNonLinear (nc);
157
186
for (int i=0 ,j=0 ;i<fSet .getSize ();i++) {
158
- Muscle* mus = dynamic_cast <Muscle *>(&fSet .get (i));
159
- if ( mus ) {
160
- mus ->setOverrideActuation (s, 0 );
187
+ ScalarActuator* act = dynamic_cast <ScalarActuator *>(&fSet .get (i));
188
+ if ( act ) {
189
+ act ->setOverrideActuation (s, 0 );
161
190
j++;
162
191
}
163
192
}
@@ -204,6 +233,7 @@ prepareToOptimize(SimTK::State& s, double *x)
204
233
_constraintVector = _targetAcceleration - qddotPassive;
205
234
206
235
#else
236
+ _model->getMultibodySystem ().realize (s,SimTK::Stage::Velocity);
207
237
// Set modeling options for Actuators to be overridden
208
238
for (int i=0 ; i<fSet .getSize (); i++) {
209
239
ScalarActuator* act = dynamic_cast <ScalarActuator*>(&fSet .get (i));
@@ -733,22 +763,36 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector ¶meters,SimTK::Vect
733
763
++j;
734
764
}
735
765
}
736
- try {
737
- _model->equilibrateMuscles (s);
738
- } catch (const Exception& x) {
739
- // If the muscle falls into some weird numerical error, try to just slightly change the activations
740
- // and reprocess it once, if it fails again in equilibrateMuscles, it throws the usual error
766
+
767
+ // If the muscle falls into some weird numerical error, try to just slightly change the activations
768
+ // and reprocess it until it works (maximum of 10 times)
769
+ double modifier (0 .);
770
+ int iter (0 );
771
+ while (true ){
741
772
for (int i=0 ,j=0 ;i<fs.getSize ();i++) {
742
- Muscle *mus = dynamic_cast <Muscle*>(&fs.get (i));
743
- if (mus){
744
- if (parameters[j] < 1 )
745
- mus->setActivation (s, parameters[j]+.001 );
746
- else
747
- mus->setActivation (s, parameters[j]-.001 );
748
- ++j;
773
+ // If the muscle falls into some weird numerical error, try to just slightly change the activations
774
+ // and reprocess it once, if it fails again in equilibrateMuscles, it throws the usual error
775
+ for (int i=0 ,j=0 ;i<fs.getSize ();i++) {
776
+ Muscle *mus = dynamic_cast <Muscle*>(&fs.get (i));
777
+ if (mus){
778
+ if (parameters[j]+modifier < 1 )
779
+ mus->setActivation (s, parameters[j]+modifier);
780
+ else
781
+ mus->setActivation (s, parameters[j]-modifier);
782
+ ++j;
783
+ }
749
784
}
750
785
}
751
- _model->equilibrateMuscles (s);
786
+ try {
787
+ _model->equilibrateMuscles (s);
788
+ } catch (const Exception& e) {
789
+ modifier += 0.001 ;
790
+ ++iter;
791
+ if (iter >= 10 )
792
+ throw e;
793
+ continue ;
794
+ }
795
+ break ;
752
796
}
753
797
#endif
754
798
_model->getMultibodySystem ().realize (s,SimTK::Stage::Acceleration);
@@ -764,3 +808,4 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector ¶meters,SimTK::Vect
764
808
765
809
// 1.45 ms
766
810
}
811
+
0 commit comments