/** * Simulation for the Locomotor Primitives (Dominici et. al 2012) in a Human * Leg model with 14 Muscles. * * Author: Tobias Klauser */ #include #include "LocomotorPrimitivesManager.h" #include "LocomotorPrimitivesController.h" #define FIXED_IN_SPACE 1 #define NO_SIM 0 static const std::string MODEL_NAME = "LocomotorPrimitives"; // Define the initial and final simulation time static const double initialTime = 0.0; static const double finalTime = 2.0; static void constructModel(OpenSim::Model &model, std::string actDataFile) { std::cout << "Constructing " << MODEL_NAME << " model" << std::endl; // Define controller for the model OpenSim::Storage actData(actDataFile); LocomotorPrimitivesController *control = new LocomotorPrimitivesController(actData, 0.01); control->setActuators(model.updActuators()); model.addController(control); // Set default activation and fiber length on all muscles of the model const OpenSim::Set &actSet = model.getActuators(); int sz = actSet.getSize(); std::cout << " + Defining initial muscle states for " << sz << " actuators:" << std::endl; // Set default activation and fiber length of all muscles for (int i = 0; i < sz; i++) { OpenSim::ActivationFiberLengthMuscle *m = dynamic_cast(&actSet.get(i)); std::cout << " " << m->getName() << std::endl; // m->setDefaultActivation(0.5); // m->setDefaultFiberLength(0.1); } // Create the force reporter for obtaining the forces applied to the model // during a forward simulation OpenSim::ForceReporter *reporter = new OpenSim::ForceReporter(&model); model.addAnalysis(reporter); std::cout << "Finished constructing model" << std::endl; } void simulateModel(OpenSim::Model &model) { if (NO_SIM) { std::cout << "Skipping simulation as per NO_SIM=" << NO_SIM << std::endl; return; } std::cout << "Simulating model " << MODEL_NAME << std::endl; std::cout << " + Initializing system" << std::endl; SimTK::State &si = model.initSystem(); std::cout << " + Creating integrator" << std::endl; // Create the integrator and manager for the simulation SimTK::RungeKuttaMersonIntegrator integrator(model.getMultibodySystem()); integrator.setAccuracy(1.0e-4); std::cout << " + Creating simulation manager" << std::endl; LocomotorPrimitivesManager manager(model, integrator); // Integrate from initial time to final time manager.setInitialTime(initialTime); manager.setFinalTime(finalTime); std::cout << " + Integrating from " << std::fixed << initialTime << " to " << std::fixed << finalTime << std::endl; manager.integrate(si); // Save the model states from forward integration OpenSim::Storage statesDegrees(manager.getStateStorage()); statesDegrees.print(MODEL_NAME + "_states.sto"); // Save the forces OpenSim::Analysis &reporter = model.getAnalysisSet()[0]; ((OpenSim::ForceReporter &)reporter).getForceStorage().print(MODEL_NAME + "_forces.mot"); } static void usage() { std::cout << "usage: " << MODEL_NAME << " [OPTION...]" << std::endl << std::endl << " -d FILE specify .sto datafile to use for muscle activation data" << std::endl << " -m FILE specify .osim to use as model" << std::endl << " -h show this help and exit" << std::endl; } int main(int argc, char **argv) { clock_t ts_start = clock(); /* set default values (to work on windows) */ std::string modelFile = FIXED_IN_SPACE ? "../../locomotor-primitives-fixed.osim" : "../../locomotor-primitives.osim"; std::string dataFile = "../../data/adults.sto"; for (int i = 1; (i < argc) && (argv[i][0] == '-'); i++) { switch (argv[i][1]) { case 'd': dataFile = argv[++i]; break; case 'm': modelFile = argv[++i]; break; case 'h': usage(); exit(0); default: std::cerr << "unknown option: -" << argv[i][1] << std::endl; usage(); exit(-1); } } std::cout << "Starting simulation " + MODEL_NAME << " with (" << modelFile << ", " << dataFile << ")" << std::endl; try { // Create an OpenSim model and set its name OpenSim::Model osimModel(modelFile); osimModel.setName(MODEL_NAME); constructModel(osimModel, dataFile); osimModel.setUseVisualizer(false); simulateModel(osimModel); } catch (OpenSim::Exception ex) { std::cout << ex.getMessage() << std::endl; std::cin.get(); return 1; } catch (std::exception ex) { std::cout << ex.what() << std::endl; std::cin.get(); return 1; } catch (...) { std::cout << "UNRECOGNIZED EXCEPTION" << std::endl; std::cin.get(); return 1; } std::cout << "main() routine time = " << 1.e3*(clock()-ts_start)/CLOCKS_PER_SEC << "ms" << std::endl; std::cout << "Simulation " + MODEL_NAME << " completed successfully." << std::endl; std::cin.get(); return 0; }