...
Code Block |
---|
language | cpp |
---|
title | FlippinFelinesOptimizerSystem.h |
---|
|
// Set (nondimensional) parameter limits/bounds for the actuators.
SimTK::Vector lowerLimits(getNumParameters(), -1.0);
SimTK::Vector upperLimits(getNumParameters(), 1.0);
setParameterLimits(lowerLimits, upperLimits); |
C.4: Initial parameters
We wanted to make it really easy for the user to specify the initial parameters for the optimization. Since they parameters end up as Y-coordinates of splines, we thought this would be the easiest way for a user to specify the initial parameters. However, we need the initial parameters as a Vector. So, we wrote a method to convert the Y-coordinates from a FunctionSet of SimmSpline's into a Vector.
Code Block |
---|
language | cpp |
---|
title | FlippinFelinesOptimizerSystem.h |
---|
collapse | true |
---|
|
SimTK::Vector initialParameters()
{
SimTK::Vector initParams(getNumParameters(), 0.0);
if (_tool.get_initial_parameters_filename() != "")
{ // A file is specified.
// Deserialize the initial parameters XML file.
OpenSim::FunctionSet initFcns(_tool.get_initial_parameters_filename());
// Write a copy of the FunctionSet to the results directory.
initFcns.print(_name + "/" + _name + "_initial_parameters.xml");
OpenSim::Array<std::string> initNames;
initFcns.getNames(initNames);
// This loop is set up so that the initFcns do not need to be in the same
// order as the optimization parameters. Also, the number of initFcns
// specified by the initial parameters file can be greater than the
// number of actuators in the model (assuming that the initial parameters
// file AT LEAST contains the model's actuators).
using OpenSim::SimmSpline;
for (int iAct = 0; iAct < _numActuators; iAct++)
{
// Get index of the initFcn corresponding to the actuator.
int iFcn = initFcns.getIndex(_cat.getActuators().get(iAct).getName());
// Get access to the spline's methods.
SimmSpline * fcn =
dynamic_cast<SimmSpline *>(&initFcns.get(iFcn));
for (int iPts = 0; iPts < _numOptimSplinePoints; iPts++)
{
// Find the right index in the optimization parameters.
int paramIndex = iAct * _numOptimSplinePoints + iPts;
// Transfer y value from input to initial parameters.
initParams[paramIndex] = fcn->getY(iPts);
}
}
}
return initParams;
} |
...
We now return to objectiveFunc(), right after the code where we've finished assembling f
assembled f
. We update the log with new objective function value, and might print an updated model file and updated control functions.
Code Block |
---|
language | cpp |
---|
title | FlippinFelinesOptimizerSystem.h |
---|
collapse | true |
---|
|
_lastCallWasBestYet = _thisCallIsBestYet;
_thisCallIsBestYet = f <= _objectiveFcnValueBestYet;
if (_thisCallIsBestYet) _objectiveFcnValueBestYet = f;
if (_objectiveCalls % _outputPeriod == 0)
_optLog << " objfcn " << f << " objfcn_best_yet " << _objectiveFcnValueBestYet << std::endl;
// If this is the best yet (i.e., smallest objective function value),
// save a copy of the splines.
if (_thisCallIsBestYet)
{
for (unsigned int iFcn = 0; iFcn < _splinesBestYet.size(); iFcn++)
_splinesBestYet[iFcn] = *_splines[iFcn];
}
// If this is worse, print out the best-yet splines and current model
// (NOTE: current model is NOT "best yet", but the idea is that it will
// be close). Also print out nondimensionalized splines so that they can
// be used directly as input for a subsequent optimization.
if (_lastCallWasBestYet && !_thisCallIsBestYet)
{
printBestYetPrescribedControllerFunctionSet(
_name + "_best_yet_parameters.xml");
printBestYetPrescribedControllerFunctionSet(
_name + "_best_yet_parameters_nomdim.xml", true);
printModel(_name + "_best_yet.osim");
}
// Print out to the terminal/console every so often.
if (_objectiveCalls % _outputPeriod == 0)
std::cout << "Objective call # " << _objectiveCalls << std::endl;
return 0; |
...