MocoExtendProblem

MocoExtendProblem: Interface Between OpenSim and MATLAB for Rapidly Developing Direct Collocation Goals in Moco - Published in JOSS (2025)

https://github.com/aravind-sundararajan/mocoextendproblem

Science Score: 93.0%

This score indicates how likely this project is to be science-related based on various indicators:

  • CITATION.cff file
  • codemeta.json file
    Found codemeta.json file
  • .zenodo.json file
    Found .zenodo.json file
  • DOI references
    Found 1 DOI reference(s) in JOSS metadata
  • Academic publication links
    Links to: joss.theoj.org
  • Academic email domains
  • Institutional organization owner
  • JOSS paper metadata
    Published in Journal of Open Source Software

Scientific Fields

Earth and Environmental Sciences Physical Sciences - 40% confidence
Last synced: 4 months ago · JSON representation

Repository

this is an example of how to add custom Moco goals to existing matlab scripts instead of constructing an omoco file or porting your existing matlab code to c++

Basic Info
  • Host: GitHub
  • Owner: Aravind-Sundararajan
  • License: mit
  • Language: C++
  • Default Branch: main
  • Size: 31.1 MB
Statistics
  • Stars: 4
  • Watchers: 2
  • Forks: 1
  • Open Issues: 2
  • Releases: 1
Created almost 4 years ago · Last pushed 9 months ago
Metadata Files
Readme Contributing License Code of conduct

README.md

status License: GPL v3

skelemen

Table of contents

Summary

MocoExtendProblem (MEP) is a framework to rapidly develop novel goals for biomechanical optimal control problems using OpenSim Moco and MATLAB (The Mathworks, Inc., Natick, MA, USA). MEP features several templates for testing and prototyping novel MocoGoals. In lieu of rebuilding OpenSim or generating an .omoco file from C++ to load the problem into MATLAB, users design and structure custom goals in C++, build them using the provided build tool, and call custom goals from MATLAB scripts using the newly generated MEX and ExtendProblem class.

Setup and Requirements

  • MEP was developed with Windows in mind, MacOS and linux are not supported at this time.
  • MEPsupports OpenSim versions 4.5 and has compatability for OpenSim 4.2-4.4, but does not support OpenSim versions below 4.2.
  • MEP runs on MATLAB (tested on 2022a and above) and was tested with visual studio 2019+ as well as CMake 3.23.3+

Matlab 2022b

MEP was tested with cmake version 3.23.3, Matlab 2022b, and visual studio 2022 with Desktop development with C++.

cmake

  • be sure to use visual studio installer's modify menu to install the workload for Desktop Development with C++.

visual studio 2022

  • Download and install an OpenSim version from 4.2-4.5 from SimTK and follow the documentation for setting up OpenSim’s MATLAB scripting environment.
  • Follow the instructions (OpenSim) to download necessary dependencies for both MATLAB Scripting and C++ development.
  • In MATLAB, configure MEX by running mex -setup C++ in the MATLAB command window to use MS VisualStudio 2019+.

Getting Started

Compile MEX interface

From the top-level directory (MocoExtendProblem) there is a build.m script. Running this script will regenerate the ExtendProblem class and the MEX interface. Each time any goal implementations need to be changed/updated, build.m should be run. NOTE: building and testing the class requires being in the top-level directory (MocoExtendProblem); however, after the build is successful, you are free to add the bin\relwithdebinfo to your matlab path so you can access MEP outside the top-level directory.

The preferred method of including MEP to a new or existing project is to fork and add it as a submodule to your project. This way you can add your own custom goals with version control managed within your lab.

Creating a new goal

  1. OpenSim 4.5+ users should copy and paste a goal to serve as a template in the custom_goals directory such as MocoActivationGoal, while 4.2-4.4 users should copy and paste a goal in custom_goals_compat.
  2. Replace mentions of the original goal name to that of your new custom goal name in each of the 5 files and file names, being careful to also modify the include guards in the osimGoalNameDLL.h and RegisterTypes_osimGoalName.h header files.
  3. In the MocoGoalNameGoal.cpp and MocoGoalNameGoal.h, reimplement constructProperties(), initializeOnModelImpl(), calcIntegrandImpl(), calcGoalImpl() such that they describe your custom goal.

To incorporate extendproblem goals into an existing MATLAB script, a C-style pointer to the instantiated MocoProblem is passed as a constructor argument to the `extendproblem.mclass that wraps theMEPMEX. Class methods ofextend_problem.m` are then used to add custom goals to the MocoProblem. In your matlab script using moco, after instantiating a MocoProblem, add the following 3 lines to pass the c-style pointer to your MocoProblem to the ExtendProblem class constructor and call the addMocoGoalName method to inject your custom goal into your problem. For additional examples see the test subdirectory.

C++ cptr = uint64(problem.getCPtr(problem)); ep = extend_problem(cptr); ep.addMocoCustomGoal('custom_goal',weight,power,divide_by_distance);

Tutorial

first clone MocoExtend Problem. git clone git@github.com:Aravind-Sundararajan/MocoExtendProblem.git Next, open MATLAB and run build.m to see that your setup is working. image

After building, you should see the following in the command window: image

To build a new goal, we are going to copy a goal folder to serve as a template, I'll call this new goal MocoCustomGoal.

image

image

We need to change the naming conventions of the 5 files (GoalName.cpp, GoalName.h, osimGoalNameDLL.h, RegisterTypesosimGoalName.cpp, RegisterTypesosimGoalName.h) from MocoActivationGoal to MocoCustomGoal You can do this by hand or using an ide/editor like vscode or notepad++.

image

We also need to change the naming conventions within each of the files. This is relatively easy to regex replace or find&replace with vscode, but also not challenging by hand either. I am going to do this with vscode. You should have 45 replacements across the 5 files. (Note I am checking the box for Preserve Case so I can change the class names and includeguards in one go.)

image

Now let's run build.m again and make sure our new MocoCustomGoal works.

image

If we look in the bin/RelWithDebInfo directory, we will see that our new custom goal has been created.

image

And if we check bin/RelWithDebInfo/extend_problem.m you will see we have a new method for adding the MocoCustomGoal to a MocoProblem.

image

Let's try adding MocoCustomGoal to a problem. Quickly we can edit test\test_ExtendProblem_simple.m

Comment line 102, and add a new line ep.addMocoCustomGoal('custom_goal',1.0, true, false, false, false); To know what the boolean arguments do, see the interface that we just lookled at (bin/RelWithDebInfo/extend_problem.m)

image

Now if we hit run, and Add to Path, we should see

``` Adding MocoCustomGoal goal

List of user-set options:

                                Name   Value                used
               hessian_approximation = limited-memory        yes
                  print_user_options = yes                   yes

This is Ipopt version 3.12.8, running with linear solver mumps. NOTE: Other linear solvers might be more efficient (see Ipopt documentation).

Number of nonzeros in equality constraint Jacobian...: 2884 Number of nonzeros in inequality constraint Jacobian.: 0 Number of nonzeros in Lagrangian Hessian.............: 0

Total number of variables............................: 599 variables with only lower bounds: 0 variables with lower and upper bounds: 599 variables with only upper bounds: 0 Total number of equality constraints.................: 500 Total number of inequality constraints...............: 0 inequality constraints with only lower bounds: 0 inequality constraints with lower and upper bounds: 0 inequality constraints with only upper bounds: 0

Warning: intermediatecallback is disfunctional in your installation. You will only be able to use stats(). See https://github.com/casadi/casadi/wiki/enableIpoptCallback to enable it. iter objective infpr infdu lg(mu) ||d|| lg(rg) alphadu alpha_pr ls 0 0.0000000e+00 1.99e+00 0.00e+00 0.0 0.00e+00 - 0.00e+00 0.00e+00 0 1 0.0000000e+00 3.55e-15 9.58e+00 0.3 2.34e+01 - 9.13e-01 1.00e+00f 1 2 0.0000000e+00 3.55e-15 9.58e-02 -4.6 6.53e-06 - 9.90e-01 1.00e+00h 1 3 0.0000000e+00 1.29e-11 7.57e-02 -0.7 1.45e+03 - 2.10e-01 1.62e-01f 1 4 0.0000000e+00 1.50e-11 4.15e-03 -1.4 6.61e+01 - 9.45e-01 1.00e+00f 1 5 0.0000000e+00 6.00e-12 4.36e-04 -2.1 4.10e+01 - 8.95e-01 1.00e+00f 1 6 0.0000000e+00 3.24e-12 2.51e-05 -3.1 1.10e+01 - 9.42e-01 1.00e+00f 1 7 0.0000000e+00 7.11e-15 2.35e-06 -4.6 2.35e-06 - 1.00e+00 1.00e+00h 1 8 0.0000000e+00 2.84e-14 1.15e-08 -6.9 1.15e-08 - 1.00e+00 1.00e+00h 1 9 0.0000000e+00 3.55e-15 8.93e-11 -9.0 8.93e-11 - 1.00e+00 1.00e+00h 1

Number of Iterations....: 9

                               (scaled)                 (unscaled)

Objective...............: 0.0000000000000000e+00 0.0000000000000000e+00 Dual infeasibility......: 8.9299948853747289e-11 8.9299948853747289e-11 Constraint violation....: 3.5527136788005009e-15 3.5527136788005009e-15 Complementarity.........: 9.0909090923115354e-10 9.0909090923115354e-10 Overall NLP error.......: 9.0909090923115354e-10 9.0909090923115354e-10

Number of objective function evaluations = 10 Number of objective gradient evaluations = 10 Number of equality constraint evaluations = 10 Number of inequality constraint evaluations = 0 Number of equality constraint Jacobian evaluations = 10 Number of inequality constraint Jacobian evaluations = 0 Number of Lagrangian Hessian evaluations = 0 Total CPU secs in IPOPT (w/o function evaluations) = 0.534 Total CPU secs in NLP function evaluations = 6.216

EXIT: Optimal Solution Found. nlp : tproc (avg) twall (avg) neval callbackfun | 1.00ms (100.00us) 1.63ms (163.21us) 10 nlpf | 556.00ms ( 55.60ms) 556.47ms ( 55.65ms) 10 nlpg | 1.15 s (114.80ms) 1.15 s (114.57ms) 10 nlpgradf | 1.25 s (113.18ms) 1.25 s (113.21ms) 11 nlpjacg | 3.73 s (339.18ms) 3.73 s (339.02ms) 11 total | 6.75 s ( 6.75 s) 6.75 s ( 6.75 s) 1

Breakdown of objective (including weights): custom_goal: 0 max goal failed to match reference output for goal

Solver duration (h:m:s): 0:0:7 ```

Now feel free to modify MocoCustomGoal.cpp and MocoCustomGoal.h for new goals! For help reference the OpenSim API reference documentation.

Included Goals

  • MocoActivationGoal
    • A simple MocoGoal that allows you to minimize activations, note this is not activations squared and also is not the same as the MocoControlEffortGoal which minimizes all controls.
  • MocoActivationSquaredGoal
    • a slight modification to the MocoActivationGoal that squares the activations, note this is still different from the MocoControlEffortGoal that is built into Moco
  • MocoBOSGoal
    • "Base of Support" goal that has the model mass center track the centroid of the base of support between the two feet.
  • MocoCoordinateAccelerationGoal
    • explicit coordinate acceleration minimization, this is different from the implicit coordinate acceleration minimization that is available with Moco.
  • MocoCOPGoal
    • "center of pressure" goal that has the model center of mass track the center of pressure between the two feet.
  • MocoCustomOutputGoal
    • back-port of the MocoOutputGoal from 4.5 to moco 4.2-4.4 that allows you to set different exponents
  • MocoMarkerAccelerationGoal
    • minimizes the cartesian acceleration of a specified marker on the model
  • MocoMaxCoordinateGoal
    • smoothed approximation for maximized coordinate value, allows you to maximize or minimize a coordinate while adhering to path and endpoint constraints
  • MocoMuscleStrainGoal
    • minimizes the muscle strain using a proxy for muscle volume
  • MocoZMPGoal
    • "Zero-tilting Moment Point" has the model center of mass track the point projected to the floor that produces zero tilting moments

Testing

In the test subdirectory, we have provided some test scripts to be run with MATLAB desktop GUI: - test_ExtendProblem_simple.m - runs a simulation with the Max Coordinate Goal with result depicted below. - example2DWalking/WalkSim_Tracking.m -runs a tracking simulation with MEP - example2DWalking/WalkSim_predictive.m - runs a predictive simulation with MEP (uses the MocoTrack class with tracking weights set to zero) - driver.m - a driver program for selecting the simulation type and if the simulation is tracking or predictive (for regenerating results from the Manuscript) The 3 goals investigated are the before-mentioned MocoMarkerAccelerationGoal, MocoBOSGoal, and MocoZMPGoal.

Max Coordinate Goal

Additionally, if using an opensim version that is lower than 4.5, there are compatibility versions of WalkSim_predictive.m and test_extendProblem_simple.m to handle OpenSim version 4.2-4.4. The output of these scripts are compared against an OutputReference within the MocoExtendProble\output directory. Note: you should stay on the top-level directory MocoExtendProblem.

Please refer to the API documentation for more detailed information.

License

MEP is provided under: License: MIT

Contributing

Please read our contributing guidelines.

Code of Conduct

See CODEOFCONDUCT.

Owner

  • Name: Aravind Sundararajan
  • Login: Aravind-Sundararajan
  • Kind: user
  • Company: MWU

Robotics. Controls systems. Optimization. Dynamical models. etc. you name it.

JOSS Publication

MocoExtendProblem: Interface Between OpenSim and MATLAB for Rapidly Developing Direct Collocation Goals in Moco
Published
April 28, 2025
Volume 10, Issue 108, Page 7110
Authors
Aravind Sundararajan ORCID
Department of Anatomy, Midwestern University, Glendale Arizona, United States of America
Varun Joshi ORCID
School of Kinesiology, University of Michigan, Ann Arbor, Michigan, United States of America
Brian R. Umberger ORCID
School of Kinesiology, University of Michigan, Ann Arbor, Michigan, United States of America
Matthew C. O'Neill ORCID
Department of Anatomy, Midwestern University, Glendale Arizona, United States of America
Editor
Kevin M. Moerman ORCID
Tags
locomotion kinematics biomechanics optimal control musculoskeletal model simulation toolchain

GitHub Events

Total
  • Create event: 1
  • Release event: 1
  • Issues event: 2
  • Watch event: 4
  • Issue comment event: 9
  • Push event: 32
  • Fork event: 1
Last Year
  • Create event: 1
  • Release event: 1
  • Issues event: 2
  • Watch event: 4
  • Issue comment event: 9
  • Push event: 32
  • Fork event: 1

Issues and Pull Requests

Last synced: 4 months ago

All Time
  • Total issues: 6
  • Total pull requests: 1
  • Average time to close issues: 2 days
  • Average time to close pull requests: 1 day
  • Total issue authors: 3
  • Total pull request authors: 1
  • Average comments per issue: 2.33
  • Average comments per pull request: 3.0
  • Merged pull requests: 1
  • Bot issues: 0
  • Bot pull requests: 0
Past Year
  • Issues: 2
  • Pull requests: 0
  • Average time to close issues: N/A
  • Average time to close pull requests: N/A
  • Issue authors: 2
  • Pull request authors: 0
  • Average comments per issue: 5.0
  • Average comments per pull request: 0
  • Merged pull requests: 0
  • Bot issues: 0
  • Bot pull requests: 0
Top Authors
Issue Authors
  • Aravind-Sundararajan (2)
  • 0todd0000 (2)
  • v9joshi (2)
Pull Request Authors
  • Aravind-Sundararajan (1)
Top Labels
Issue Labels
Pull Request Labels

Dependencies

.github/workflows/main.yml actions
  • EndBug/add-and-commit v9 composite
  • actions/checkout v4 composite
  • actions/upload-artifact v3 composite
  • openjournals/openjournals-draft-action master composite