This code is a fork based on

PredictiveSim developed and published by

Dorn, T. W., Wang, J. M., Hicks, J. L., & Delp, S. L. (2015).
Predictive Simulation Generates Human Adaptations during Loaded and Inclined Walking.
Plos One, 10(4), e0121407. doi:10.1371/journal.pone.0121407

The code serves as the foundation of Jakob Welner's bachelor project in Mechanical Engineering at DTU, Denmark
Through the project the code will be extended, annotated and documented and everything will be put here for others to use.


Quick guide to try out the code:

Run cmake to build the executable, specify the installation location for OpenSim. This source code has most recently been tested using OpenSim 3.2, Simbody 3.3.1, and gcc-4.9 on OSX Yosemite (10.10.3).

Some auxiliary files need to be generated by running createOptInitFiles.m using either Matlab or Octave.

To visualize the example controller normalwalk.sto using the model Humanoid2D.osim for 10 seconds:

./pdsim -m ../Humanoid2D.osim -cf ../normalwalk.sto -t 10 -viz

This will simulate the model which most likely can't run in realtime.
The simulation will generate a _results.sto file with kinematics data ================================================================================
To view the _results.sto file run

./pdsim -m ../Humanoid2D.osim -replay \_results.sto -t 10 -viz

the _results.sto file is probably very big and will take some time to load.
After having run it once, a _resultsSampled.sto will be generated which is much lighter

To optimize for flat ground walking at 1.5 m/s using CMA and MPI:

mpiexec -n 50 ./pdsim -m ../Humanoid2D.osim -opt 0.005 -target 1.5 -t 10

The above command spawns 50 processes in parallel, the code uses 50-1=49 CMA samples per iteration by default. The initial CMA stepsize is set to 0.005.

A controller solution is saved (result_itrXX.sto) when the current best value is improved at a given iteration. These files can be visualized using the -cf flag.

The .osim file describes the problem environment. For example, -m Humanoid2DUphill10deg.osim simulates walking up a 10 degree incline.
The initialization for CMA can be modified by specifying a controller using the -cf flag. For example, using -cf normalwalk.sto and -m Humanoid2DUphill10deg.osim seeds the 10 degree incline optimization using the walking controller optimized for flat ground.

In practice, you might need to run MPI across multiple machines to handle the amount of parallel processing necessary. You will have to consult your own system admin to set this up.

Known Issues

  • Optimization crashes without MPI and minimum 1 slave


  • add data on:
  • # nodes / cores
  • size of population, total & per core
  • add elapsed time in the (core#, fitness) return in the output files @ CMAOptimizer line 213
  • Auto-restart or cancel when iterations take much too long (usually > 10min)
  • Save initial itr sto


Last successful compile using, Windows 7 and Linux Redhat - Virtual Studio 2015 pro - gcc 4.9.2 - cmake 3.2.2 (dtu 3.2.1) - simbody 3.5.3 - opensim 3.3

Linux Environment Setup

Set environment variables before compiling

export CC=mpicc
export CXX=mpic++
export OPENSIM_HOME=~/opensim/install

System Parameters


  • type: SimTK::SemiExplicitEuler2Integrator
  • minimum stepsize of integrator: 1e-6
  • accuracy: 1e-2


Each Leg has 8 muscles of custom-defined type SimpleMuscle:
- TA (Tibialis Anterior) - SOL (Soleus) - GAS (Gastrocnemius) - VAS (Vasti) - RF (Rectus Femoris) - Different from Geyer, Herr 2010 - HAMS (Biarticulate Hamstring) - GMAX (Gluteus Maximus) - ILPSO (Iliopsoas)

Neural setup


  • 0.005s: hipArea - (hipAngle, trunkAngle, GMAX->GMAX, HFL->ILPSO, HAMS->ILPSO, HAMS->HAMS)
  • 0.010s: thigh - (kneeAngle, GRF, VAS->VAS)
  • 0.020s: shank - (TA->TA, GAS->GAS, SOL->SOL, SOL->TA)




  • ESC: End Simulation
  • Space: Pause sim
  • PageUp: Zoom in
  • PageDown: Zoom out
  • 8: Translate camera up
  • 5: Translate down
  • 6: Rotate left
  • 7: Rotate right


From: CMA-ES : A Function Value Free Second- Order Optimization Method Black-Box Optimization if several updates go into the same/similar direction (if they have the same sign) increase the step-size

Command-line argumenter:

  • "-m [modelFile]" specify setup model in .osim
  • "-cf [ctrlFile]" when previewing, specify file for controls
  • "-t [finalTime]" How many seconds to simulate
  • "-target [targetVel]" set target speed to aim for in m/s
  • "-resume [resumeIndex]" not sure really. Set an index for one of the iterators
  • "-load [backpackLoad]" specify whether the model is carrying load [in kg]
  • "-visualize" to start the visualizer
  • "-printDetails" prints details to file "_details.txt" with latest best values
  • "-replay [replayFile]" Specify file to replay. Det virker med "_results.sto" filen
  • "-opt [stepSize]" specify that it should optimize and sets stepsize for the optimizer (Default 0.005)
  • "-optAccel [stepsize]" uses target to optimize for acceleration instead of speed. [NOT IMPLEMENTED YET]
  • "-optDelay [time]" Will start calculating fitness after delay [in seconds] [NOT IMPLEMENTED YET]
  • "-ctrlPrefix [string]" Enables switching between generated control-files, ie: [prefix]_values.sto, [prefix]_activeparams.sto
  • "-pertAmp [multiplier]" Sets the multiplier for perturbation amplitude.
  • "-version" (Excluding all other paraters), printing the current version name and number

Generated Files

  • "_results.sto": Contains results in some way
  • "results_itr#.sto": printed when a new and better result is achieved, (# is current iteration)
  • "resumecmaes.dat": donno
  • "errcmaes.err": Output from the cmaes algorithm
  • "result_opt_progress.csv": For each outer iteration write (iteration, f, bestVal)
  • "err.log": donno
  • "out.log": normal output as written to terminal

Objective function

f = w_task(Kfail + Kvel + Kheadv + KGRF) + (1.0/_systemMass)*effortPenalty; - OBJ_SKIP_FRAMES: ? - STATE_UPD_STEPSIZE: ? - w_task: Weight of Task - factor/(OBJ_SKIP_FRAMESSTATE_UPD_STEPSIZE) - Kfail: 100finalTime/(OBJ_SKIP_FRAMESSTATE_UPD_STEPSIZE) - Kvel: (body velocity) = TARGET_VELOCITY_PENALTY_WEIGHTQ(vx - _targetVel, 0.05); - Kheadv (head velocity) for hver N += HEAD_VELOCITY_WEIGHTQ(headv[0], 0.2); - KGRF: (Disabled) - timeDerivative of ground impulse (Impact) - effortPenalty: Metabolic cost + total ligament torque