Performing Inverse Dynamics via Matlab API

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
David John Saxby
Posts: 83
Joined: Mon May 09, 2011 8:39 pm

Performing Inverse Dynamics via Matlab API

Post by David John Saxby » Wed Mar 13, 2013 7:53 pm

Hi All,

I'm working on Matlab scripts which will use the API to setup and run ID for x number of trials in v3.0.1.

I use a setupID.xml template, which functionally empty (model and file are unassigned), with the exception of the external loads xml file, which I have to generic templates based on a left or right foot strike. Which external loads file is passed to tool is to be controlled by some separate logic regarding foot markers to force plate COP distance.

All is good except I cannot seem to get/set the values in the external loads xml file.

In the InverseDynamicsTool, there are methods such as:

idTool.getExternalLoads().setExternalLoadsModelKinematicsFileName(motionFile);

idTool.getExternalLoads().setDataFileName(grfMOTfile);

I use these, but when I pause the script after printing the setup file the external force file is unmodified.

It may also be interesting that I am set the model name:

% Load the model
model = Model(modelFile);

% Instantiate the model
state = model.initSystem();

% Tell Tool to use the loaded model
idTool.setModel(model);

And when I verify the model is being pointed to in the printed setup file it remains unmodified.

Do I have the correct approach in trying to modify generic IDsetup and external loads xml via the ID tool? Is there a constructor method which would allow me to work on the external loads file directly? Any suspicions about why I'm not printing the xml with names I specify?

Many thanks for any suggestions of where to look.

David

User avatar
Ayman Habib
Posts: 2235
Joined: Fri Apr 01, 2005 12:24 pm

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Thu Mar 14, 2013 12:33 pm

Hi David,

If the functionality works (seems like it's using the correct model and external loads) then it could be a bug with the "properties" not being updated or not written because the code doesn't know they have been changed. Generally going through API calls may not modify properties as a side effect, for example setting the model will not set the model file_name property (as the passed in model may not have a file associated with it to begin with).
If you need an interface that affects the properties directly and you're not finding it please let us know.

Best regards,
-Ayman

User avatar
David John Saxby
Posts: 83
Joined: Mon May 09, 2011 8:39 pm

Re: Performing Inverse Dynamics via Matlab API

Post by David John Saxby » Thu Mar 14, 2013 6:55 pm

Hi Ayman,

Generally yes, it would be quite useful to be able to modify these properties of the external loads file through the API. I tried via matlab parsing, but as you pointed out quite rightly this messes us the xml file and then it is not handled by the API or GUI.
So trying to avoid manually changing input files in the xml or gui, I need to be able to control the source file for the loads, the matching model kinematics, and also potentially the assignment of the loads to bodies in the model, as my trials vary in foot and plate striking. I have logic to determine what is happening, but I'm stuck as to how to apply these settings via the API.

Regarding the models, I've also noticed this in the analysis tool. I load a generic muscle analysis xml which doesn't have a model associated with it, with the plan to set this explicitly in the API, but no setModel method exists for AnalyzeTool. Would it be sufficient to instantiate the model of interest, and then apply the AnalyzeTool? Would the tool then use the current instance of the model, plus whatever analysis specified in the generic template?

David

User avatar
Ayman Habib
Posts: 2235
Joined: Fri Apr 01, 2005 12:24 pm

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Fri Mar 15, 2013 9:20 am

Hi David,

Regarding the AnalyzeTool question, the answer is yes, if you instantiate it from a file then call setModel then you should be fine and the Analyses specified in the file will be executed.

For the first part related to specifying ExternalLoads, I'd create an ExternalLoads object programmatically, add ExternalForce(s) to it then write it to a file, and then call setExternalLoadsFileName() on the InverseDynamicsTool with the name of the file you created.

Please let me know how that goes.

Best regards,
-Ayman

User avatar
David John Saxby
Posts: 83
Joined: Mon May 09, 2011 8:39 pm

Re: Performing Inverse Dynamics via Matlab API

Post by David John Saxby » Fri Mar 15, 2013 4:12 pm

Hi Ayman,

Thanks a lot!

I'll give it a go and report back on the forum how it went.

David

User avatar
David John Saxby
Posts: 83
Joined: Mon May 09, 2011 8:39 pm

Re: Performing Inverse Dynamics via Matlab API

Post by David John Saxby » Sun Mar 17, 2013 10:03 pm

Hi Ayman,

Your suggestions worked very well.

For ID:
I looked at the source code for DynamicsTool to understand the construction of external loads by ExternalLoads constructor. Once made, I set the ID tool's external loads to the new file created. Works!

On an unrelated note, have you guys had any bugs reported on 3.0.1's ID solutions. I have very reasonable kinematics and normative GRFs, but my id moments are off by about a factor of 10. Forces and kinematics are synchronized, the forces applied to the correct bodies, and the shape of the torques looks normal for gait, but again the magnitudes are preposterous.

For MuscleAnalysis:
It worked as you suggested. Model is instantiated from a file: model = Model(ModelFile);
Then to analyzeToool.setModel(model), applied the current instance of the model. Tool executes.

David

User avatar
Ayman Habib
Posts: 2235
Joined: Fri Apr 01, 2005 12:24 pm

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Mon Mar 18, 2013 8:57 am

Hi David,

Thanks for reporting back to the forum on your progress. I'm sure many users will benefit from this.

For differences in ID results, I'm not aware of any changes in 3.0.1 that would change ID results relative to version 3.0 directly. We made a fix in the scaleTool so that "preserve mass distribution" flag is handled correctly. This has the potential to change ID results downstream but only if you rerun the whole pipeline including scaling. Please let us know how to reproduce the different results in version 3.0 vs. 3.0.1 and we'll take a look. If needed please feel free to file a bug report and attach all the necessary model/setup and data files.

Best regards,
-Ayman

User avatar
Günter Schneider
Posts: 29
Joined: Thu Jul 26, 2012 6:08 am

Re: Performing Inverse Dynamics via Matlab API

Post by Günter Schneider » Mon Dec 02, 2013 1:06 am

aymanh wrote:Hi David,
...
For the first part related to specifying ExternalLoads, I'd create an ExternalLoads object programmatically, add ExternalForce(s) to it then write it to a file, and then call setExternalLoadsFileName() on the InverseDynamicsTool with the name of the file you created. ...
Best regards,
-Ayman
saxbyd wrote:Hi Ayman,

Your suggestions worked very well.

For ID:
I looked at the source code for DynamicsTool to understand the construction of external loads by ExternalLoads constructor. Once made, I set the ID tool's external loads to the new file created. Works!
..

David
Hi David, hi Ayman!

I`ve got the same problem with my MATLAB script for ID. I need to add a specific external load file (that i created via matlab) to every single ID-simulation run!
I'm not really familiar with the ExternalLoads constructor or the source code, and the next problem i found is that matlab reports that ther is no method called "setExternalLoadsFileName" for class"org.opensim.modeling.InverseDanymicsTool" !?!?

Can you help me with that!?! THX a lot in advance and have a nice monday morning

Best regards

Günter

Edit: @David: is there a chance to get a look into your script for the part you add the external load files !?!?

User avatar
Ajay Seth
Posts: 136
Joined: Thu Mar 15, 2007 10:39 am

Re: Performing Inverse Dynamics via Matlab API

Post by Ajay Seth » Mon Dec 02, 2013 11:39 am

Inverse Dynamics considers all the applied loads on the model, not just external forces. If you have muscles in your model, you must exclude them if their state is not well defined. The IDTool can exclude them for you if you identify them by name or group, see:

Code: Select all

DynamicsTool::setExcludedForces(const Array<std::string>& )

This is the main cause for seeing large unexplainable forces in ID, since the muscle states will be at their default values which can lead to unreasonable forces. The ID setup file we provide excludes Muscles by default so that might be why you had not realized that they were being ignored by ID previously.

User avatar
David John Saxby
Posts: 83
Joined: Mon May 09, 2011 8:39 pm

Re: Performing Inverse Dynamics via Matlab API

Post by David John Saxby » Mon Dec 02, 2013 9:28 pm

Hi Gunter,

That is fairly weird regarding the method problem.


% Apply the generic xml to the constructor
idTool = InverseDynamicsTool(genericSetupForID);

% instantiate, set model, time, etc...

% Create an external loads object
extLoadsObject = ExternalLoads(model,activeExternalForceFile);

% Set the grf filename
extLoadsObject.setDataFileName(fullpathGRFFile);

% Set the model external loads file
extLoadsObject.setExternalLoadsModelKinematicsFileName(fullpathIKfile);

% Create name for a subject specific external loads xml
extLoadsXml = [data.Name '_' 'external_loads.xml'];

% Print the external load xml file
extLoadsObject.print([subjectDir '\' extLoadsXml]);


That is a snippet from my code and it works no problem from v3.0-3.1.

Hopefully that works for you too. Also check that your template xml which you feed to the constructor is correct. The safest way is make a blank one in the GUI and operate on that rather than creating one in matlab.

DJS

POST REPLY