Skip to content

Commit 2d50f04

Browse files
committed
Made the update static optimization compliant to residual forces
1 parent c0b71c8 commit 2d50f04

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));
@@ -735,22 +765,36 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector &parameters,SimTK::Vect
735765
++j;
736766
}
737767
}
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){
743774
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+
}
751786
}
752787
}
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;
754798
}
755799
#endif
756800
_model->getMultibodySystem().realize(s,SimTK::Stage::Acceleration);
@@ -766,3 +810,4 @@ computeAcceleration(SimTK::State& s, const SimTK::Vector &parameters,SimTK::Vect
766810

767811
// 1.45 ms
768812
}
813+

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)