@@ -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));
@@ -735,22 +765,36 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector ¶meters,SimTK::Vect
735
765
++j;
736
766
}
737
767
}
738
- try {
739
- _model->equilibrateMuscles (s);
740
- } catch (const Exception& x) {
741
- // If the muscle falls into some weird numerical error, try to just slightly change the activations
742
- // and reprocess it once, if it fails again in equilibrateMuscles, it throws the usual error
768
+
769
+ // If the muscle falls into some weird numerical error, try to just slightly change the activations
770
+ // and reprocess it until it works (maximum of 10 times)
771
+ double modifier (0 .);
772
+ int iter (0 );
773
+ while (true ){
743
774
for (int i=0 ,j=0 ;i<fs.getSize ();i++) {
744
- Muscle *mus = dynamic_cast <Muscle*>(&fs.get (i));
745
- if (mus){
746
- if (parameters[j] < 1 )
747
- mus->setActivation (s, parameters[j]+.001 );
748
- else
749
- mus->setActivation (s, parameters[j]-.001 );
750
- ++j;
775
+ // If the muscle falls into some weird numerical error, try to just slightly change the activations
776
+ // and reprocess it once, if it fails again in equilibrateMuscles, it throws the usual error
777
+ for (int i=0 ,j=0 ;i<fs.getSize ();i++) {
778
+ Muscle *mus = dynamic_cast <Muscle*>(&fs.get (i));
779
+ if (mus){
780
+ if (parameters[j]+modifier < 1 )
781
+ mus->setActivation (s, parameters[j]+modifier);
782
+ else
783
+ mus->setActivation (s, parameters[j]-modifier);
784
+ ++j;
785
+ }
751
786
}
752
787
}
753
- _model->equilibrateMuscles (s);
788
+ try {
789
+ _model->equilibrateMuscles (s);
790
+ } catch (const Exception& e) {
791
+ modifier += 0.001 ;
792
+ ++iter;
793
+ if (iter >= 10 )
794
+ throw e;
795
+ continue ;
796
+ }
797
+ break ;
754
798
}
755
799
#endif
756
800
_model->getMultibodySystem ().realize (s,SimTK::Stage::Acceleration);
@@ -766,3 +810,4 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector ¶meters,SimTK::Vect
766
810
767
811
// 1.45 ms
768
812
}
813
+
0 commit comments