How to use custom goal plugin?

OpenSim Moco is a software toolkit to solve optimal control problems with musculoskeletal models defined in OpenSim using the direct collocation method.
POST REPLY
User avatar
Jiacheng Weng
Posts: 26
Joined: Wed Jan 15, 2020 1:05 pm

How to use custom goal plugin?

Post by Jiacheng Weng » Fri Dec 11, 2020 10:36 pm

Hi all,

I am currently trying to implement custom goals myself. I have reviewed materials on the Moco documentation page as well as the example files under opensim-moco-0.4.0/Resources/Code/CPP/Plugins/exampleMocoCustomEffortGoal. However, I am still not too sure how I should use it.

I have MATLAB and Python background and limited C++ knowledge. If anyone can provide me some advice on what procedures that I need to follow (in terms of making the provided exampleMocoCustomEffortGoal work in MATLAB) or what background knowledge I need to catch up (in terms of building C++ project?), that will be very appreciated.

Thanks in advance,
Jiacheng

User avatar
Jiacheng Weng
Posts: 26
Joined: Wed Jan 15, 2020 1:05 pm

Re: How to use custom goal plugin?

Post by Jiacheng Weng » Sun Dec 13, 2020 7:22 pm

After some experiment, I was able to compile the exampleMocoCustomEffortGoal using CMake and Visual Studio 16 2019. After compilation, I was able to run the .exe example file and obtained the osimMocoCustomEffortGoal.dll file. However, I am not sure how to include this .dll file in the MATLAB API (or is it even possible?). If anyone has experience with this, some tips will be very appreciated.

Note: for people who are also new to development with C++, I recommend going to the plugin page from OpenSim. It has some great background knowledge there.
https://simtk-confluence.stanford.edu/d ... ng+Plugins

User avatar
Nicholas Bianco
Posts: 1041
Joined: Thu Oct 04, 2012 8:09 pm

Re: How to use custom goal plugin?

Post by Nicholas Bianco » Sun Dec 13, 2020 9:37 pm

Hi Jiacheng,

There are instructions for including in Matlab the DLL you've compiled on the Confluence page you linked above. I haven't used a plug-in in Matlab in a while, so I'm not sure if you're able to use the class directly in scripting, or if it is only available via XML files. Try including it and let me know if there are any issues.

-Nick

User avatar
Jiacheng Weng
Posts: 26
Joined: Wed Jan 15, 2020 1:05 pm

Re: How to use custom goal plugin?

Post by Jiacheng Weng » Mon Dec 14, 2020 2:03 pm

Hi Hick,

Thanks for the reply. My apology first for the long response. Here is what I have tried:
- obtained the provided plugin source at opensim-moco-0.4.0-win\Resources\Code\CPP\Plugins\exampleMocoCustomEffortGoal
- Used CMake to generate Visual Studio project
- Built the MocoCustomEffortGoal plugin with Visual Studio 16 set to Windows-10.0.17763 and
Microsoft Visual C++ 14.1 (get these spec from opensimCommon.GetOSInfoVerbose() and opensimCommon.GetCompilerVersion())
- Copied the generated osimMocoCustomEffortGoal.dll to opensim-moco-0.4.0-win\plugins
- Called edit librarypath.txt from MATLAB and added C:\opensim-moco-0.4.0-win\plugins to the last line of librarypath.txt.
- Called opensimCommon.LoadOpenSimLibraryExact("C:\opensim-moco-0.4.0-win\plugins\osimMocoCustomEffortGoal.dll") and it returned 1
- However, I was unable to call MocoCustomEffortGoal() or osimMocoCustomEffortGoal() in MATLAB

Additional to the steps above, I also tried these things:
- Used Microsoft Visual C++ 14.2 and Windows10-10.0.19041 (newest available options)
- Used different paths in librarypath.txt (use / and \, include MocoCustomEffortGoal or MocoCustomEffortGoal.dll at the end)
- Tried opensimCommon.LoadOpenSimLibrary("C:\opensim-moco-0.4.0-win\plugins\osimMocoCustomEffortGoal") and another one with .dll at the end of the path name
None of these things affect the results (unable to call MocoCustomEffortGoal() or osimMocoCustomEffortGoal() in MATLAB)

I also tried building the entire Moco package from source (github master) but with no luck. I tried .ps1 script but got error saying missing dependencies. So, I tried building dependencies first but got over 100 errors :(

Additional question:
- when building the MocoCustomEffortGoal plugin, many .dll files are copied from the opensim-moco-0.4.0-win\bin folder. I am not quite sure about their purposes. is there any restrictions when it comes to moving files around?
- In this page https://simtk-confluence.stanford.edu/d ... ng+Plugins, it mentions about registration of classes. Is this what I am missing? Also, I am not quite sure how the registration can be done.

I checked the plugin implementation that Aaron provided: https://simtk.org/projects/gh-caps-sims. It seems the plugin is defined within the .osim file. He mentioned in his code that the plugin is not available in MATLAB API, but MATLAB is able to recognize the plugin component within the .osim file after loading the plugin library. In this case, the MocoCustomEffortGoal plugin is based on the MocoGoal class which I assume is not part of the .osim file. So I am not quite sure how to include the MocoCustomEffortGoal plugin with the xml format.

I have attached the osimMocoCustomEffortGoal.dll for reference.

Thanks,
Sola
Attachments
osimMocoCustomEffortGoal.zip
(11.18 KiB) Downloaded 40 times

User avatar
Nicholas Bianco
Posts: 1041
Joined: Thu Oct 04, 2012 8:09 pm

Re: How to use custom goal plugin?

Post by Nicholas Bianco » Mon Dec 14, 2020 3:50 pm

I checked the plugin implementation that Aaron provided: https://simtk.org/projects/gh-caps-sims. It seems the plugin is defined within the .osim file. He mentioned in his code that the plugin is not available in MATLAB API, but MATLAB is able to recognize the plugin component within the .osim file after loading the plugin library. In this case, the MocoCustomEffortGoal plugin is based on the MocoGoal class which I assume is not part of the .osim file. So I am not quite sure how to include the MocoCustomEffortGoal plugin with the xml format.
You can save a MocoStudy to an XML file (using the print() method) in the same way you can an OpenSim model (the MocoStudy either contains the OpenSim model used in the problem or at least a path to a separate model file). After doing this, you can add the custom goal to the MocoProblem under the goals XML tag and then you can load the modified study into Matlab. You can't use the class directly in scripting, since the class is not included in the Java wrapping.
- when building the MocoCustomEffortGoal plugin, many .dll files are copied from the opensim-moco-0.4.0-win\bin folder. I am not quite sure about their purposes. is there any restrictions when it comes to moving files around?
The plug-in needs to link against these DLLs, so they probably need to be copied to wherever you build the plug-in. It's fine to copy them as long as the files in the original location aren't changed/moved.
- In this page https://simtk-confluence.stanford.edu/d ... ng+Plugins, it mentions about registration of classes. Is this what I am missing? Also, I am not quite sure how the registration can be done.
Object registration is handled by RegisterTypes_osimMocoCustomEffortGoal.h/.cpp, so no need to worry about that.

If you think you will be making frequent custom modifications to Moco and would like help building from source, I'm happy to help with that too.

Best,
-Nick

User avatar
Jiacheng Weng
Posts: 26
Joined: Wed Jan 15, 2020 1:05 pm

Re: How to use custom goal plugin?

Post by Jiacheng Weng » Mon Dec 14, 2020 6:39 pm

Hi Nick,
You can save a MocoStudy to an XML file (using the print() method) in the same way you can an OpenSim model (the MocoStudy either contains the OpenSim model used in the problem or at least a path to a separate model file). After doing this, you can add the custom goal to the MocoProblem under the goals XML tag and then you can load the modified study into Matlab. You can't use the class directly in scripting, since the class is not included in the Java wrapping.
Thanks for the advice here! the plugin now worked in MATLAB!

Some notes here:
- It turned out that I did not need to specify the plugin path in the MATLAB librarypath.txt.
- For adjusting custom goal parameters in MATLAB, using MocoControlGoal.safeDownCast(problem.updGoal('customGoalName')) seems to cause empty return. Using just problem.updGoal('customGoalName') seems fine.



To other Moco users,

I put together a list of general steps to get started with custom goal plugins so that you do not feel as lost as I was at the beginning :).

In order to use the example MocoCustomEffortGoal in MATLAB with OpenSim Moco 0.4.0 on Windows 10:
1. learn some basics about CMake and Visual Studio and set them up (choose desktop development with C++ and necessary MSVC and window 10 SDK during VS installation)
2. Locate the plugin example at opensim-moco-0.4.0-win\Resources\Code\CPP\Plugins\exampleMocoCustomEffortGoal and generate the VS project using CMake (type in x64 for optional platform for generator when configure with VS 16 2019)
3. Open the generated VS project, right click on ALL_BUILD and set the OS and compiler properties to match what the OpenSim Moco has (check with opensimCommon.GetOSInfoVerbose() and opensimCommon.GetCompilerVersion() in MATLAB)
4. Build the entire project
5. locate the generated .dll file for the custom goal and load it into MATLAB using opensimCommon.LoadOpenSimLibraryExact("<filePath>\osimMocoCustomEffortGoal.dll")
6. Add the custom goal to the MocoStudy .xml file
7. Now load the MocoStudy .xml file to MATLAB (with the capability of modifying custom goal parameters within MATLAB)

Cheers,
Jiacheng (Sola)

User avatar
Tyler Morrison
Posts: 9
Joined: Wed Nov 06, 2019 7:00 am

Re: How to use custom goal plugin?

Post by Tyler Morrison » Mon Jan 11, 2021 2:31 pm

Jiacheng,

Thank you for writing this out! Your instructions were very helpful and probably saved me a bunch of time troubleshooting myself. Doing exactly as you described, I was able to solve the problem in both MATLAB and C++.

To add to this, for anyone else that is interested, I have included my MATLAB version of solving the problem which includes the .MOCO file which is the MocoStudy XML file and the .M file which is a direct transcription of the C++ version and includes the lines for adding the MocoCustomGoal DLLs and importing the MocoStudy.

To make this work for your system, you will have to change the address of the CustomGoal DLLs on line 22 as per Jiacheng's post.

-Tyler
Attachments
exampleMocoCustomEffortGoal.zip
(3.8 KiB) Downloaded 39 times

User avatar
Nicholas Bianco
Posts: 1041
Joined: Thu Oct 04, 2012 8:09 pm

Re: How to use custom goal plugin?

Post by Nicholas Bianco » Wed Jan 13, 2021 12:46 pm

Thanks Jiacheng! This will be helpful for many users.

The safeDownCast should work, you just need to use the custom goal class to perform the downcast:

Code: Select all

customGoal = MocoCustomEffortGoal.safeDownCast(problem.updGoal('customGoalName'))

User avatar
Hojin Song
Posts: 75
Joined: Wed Jul 08, 2020 9:46 am

Re: How to use custom goal plugin?

Post by Hojin Song » Mon Jul 05, 2021 7:28 pm

Hi Jiacheng,

May I ask if you can elaborate a bit more on the later steps particularly 6 and 7? I have no clue on how to write my cost terms using XML tags. I'd be very grateful if you can share some hints there.

Thank you
Hojin

User avatar
Jiacheng Weng
Posts: 26
Joined: Wed Jan 15, 2020 1:05 pm

Re: How to use custom goal plugin?

Post by Jiacheng Weng » Thu Jul 08, 2021 7:31 pm

hojin95 wrote:
Mon Jul 05, 2021 7:28 pm
May I ask if you can elaborate a bit more on the later steps particularly 6 and 7?
Hi Hojin,

When a plugin is created, the main OpenSim package does not have all the plugin information built into the binary. This means that you will not be able to call the plugin directly from scripting languages like Python or MATLAB. Instead, you will need to specify the use of plugin in the xml file for the MocoStudy.

For example, when you construct a study in MATLAB, you can export the MocoStudy as a markup file (using study.print("fileName.xml")) in the format of xml. This file is similar to the .osim file for the OpenSim model and includes all the parameters needed to recreate the study (note that default parameters will not be included in the xml file). Now, you can add in the markdown for the custom plugin to the study.xml file. This way, the custom goal will be loaded when the OpenSim backend processes the study.xml file instead of relying on the code you have in MATLAB.

In terms of how you can get the markdown format for your custom goal, you can print the study file when running the C++ example code which is compiled together with the plugin. So you can just copy the custom goal markdown from it.

If I explain anything incorrectly, please feel free to point it out.

Cheers,
Jiacheng

POST REPLY