Skip to content

Commit ea5d7a7

Browse files
committed
Made the update static optimization compliant to residual forces
1 parent 1b0ff30 commit ea5d7a7

File tree

2 files changed

+76
-30
lines changed

2 files changed

+76
-30
lines changed

OpenSim/Analyses/StaticOptimizationTarget.cpp

Lines changed: 75 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -115,19 +115,47 @@ prepareToOptimize(SimTK::State& s, double *x)
115115
}
116116

117117
// Initialize the system at given activations and state
118+
double modifier(0.);
119+
int iter(0);
118120
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;
125146
}
147+
break;
126148
}
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);
129149

130150
#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+
131159
// Compute passive forces at state s
132160
Vector passiveForces(np);
133161
for(int i=0, j=0; i<fSet.getSize(); i++) {
@@ -141,23 +169,24 @@ prepareToOptimize(SimTK::State& s, double *x)
141169
Vector qddotPassive(nc);
142170
for(int i=0,j=0;i<fSet.getSize();i++) {
143171
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+
}
149177
}
178+
// Don't reequilibrate muscle since it has the right length!
150179
_model->getMultibodySystem().realize(s,SimTK::Stage::Acceleration);
151180
SimTK::Vector udot = _model->getMatterSubsystem().getUDot(s);
152181
for(int i=0; i<_accelerationIndices.getSize(); i++)
153182
qddotPassive[i] = udot[_accelerationIndices[i]];
154183

155-
// Compute linear qqdot from the non linear effects
184+
// Compute linear qqdot from the non linear effects (coriolis and gravity)
156185
Vector qddotNonLinear(nc);
157186
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);
161190
j++;
162191
}
163192
}
@@ -204,6 +233,7 @@ prepareToOptimize(SimTK::State& s, double *x)
204233
_constraintVector = _targetAcceleration - qddotPassive;
205234

206235
#else
236+
_model->getMultibodySystem().realize(s,SimTK::Stage::Velocity);
207237
// Set modeling options for Actuators to be overridden
208238
for(int i=0; i<fSet.getSize(); i++) {
209239
ScalarActuator* act = dynamic_cast<ScalarActuator*>(&fSet.get(i));
@@ -733,22 +763,36 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector &parameters,SimTK::Vect
733763
++j;
734764
}
735765
}
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){
741772
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+
}
749784
}
750785
}
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;
752796
}
753797
#endif
754798
_model->getMultibodySystem().realize(s,SimTK::Stage::Acceleration);
@@ -764,3 +808,4 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector &parameters,SimTK::Vect
764808

765809
// 1.45 ms
766810
}
811+

OpenSim/Analyses/StaticOptimizationTarget.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "OpenSim/Common/Array.h"
3131
#include <OpenSim/Common/GCVSplineSet.h>
3232
#include <simmath/Optimizer.h>
33+
#include "OpenSim/Actuators/CoordinateActuator.h"
3334

3435
//=============================================================================
3536
//=============================================================================

0 commit comments

Comments
 (0)