Performing Inverse Dynamics via Matlab API

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
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 » Wed Dec 04, 2013 9:08 am

saxbyd wrote:Hi Gunter,

...
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
THX a lot David, I'll give it a try and we will see ...

g

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 » Thu Dec 05, 2013 3:01 am

hi,

and thx a lot for your response and the snippet of your code!

Did I get it right, that your code is to create a externalLoads File out of you GRFforcedata depending on the motion and model used for ID?

The problem of mine is, that i do not need to create the external load files (i did that via MATLAB, because I had to edit the recorded force data and synchronise them, ... anyway), i only need to include these specific file (depending on motion) in ID simulation.

So how do you define the externalLoadFile in the batch code for your ID? I'm sorry, but I didn't get that by now !?!?

many thanks ...

günter

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

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Tue Dec 10, 2013 1:24 am

Hi Gunter,

InverseDynamicsTool indeed has a method

Code: Select all

public void setExternalLoadsFileName(String aFileName)
that it inherits from DynamicsTool. Can you explain where you looked for it and didn't find it?

Thanks much,
-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 » Tue Dec 10, 2013 10:01 am

Hi Ayman,

and thanks for your reply.

I found the method (setExternalLoadsFileName) and I tried to implement it in my Batch-code. But I´m very new in scripting and so I didn´t get the right way to use that method. So this is what I figured out ...

Code: Select all

      ...
% Setup the idTool for this trial
        idTool.setName(name);
        idTool.setCoordinatesFileName(fullpath);
        idTool.setStartTime(initial_time);
        idTool.setEndTime(final_time);
        idTool.setOutputGenForceFileName([ 'resultID_' name '.sto' ]);
        idTool.setResultsDir(results_folder);
        idTool.setExternalLoadsFileName(fullpath_extLoad);
 
         % Save the settings in a setup file
        outfile = [ 'setup_ID_' name '.xml' ];
        idTool.print([genericSetupPath '\' outfile]);
 
        fprintf([ 'Performing ID on cycle #' num2str(trial_motion) ...
            ' of motion, and cycle #' num2str(trial_force) ...
            ' of force \n ... [' name '.mot]\n ... [' extLoadFile(trial_force).forceFile ']\n' ]);
       
        % Run ID
        idTool.run();
    end
end
And I always get that error message ..

Code: Select all

??? Java exception occurred:
java.io.IOException: InverseDynamicsTool Failed, please see messages window for
details...

     at org.opensim.modeling.opensimModelJNI.InverseDynamicsTool_run(Native
    Method)

     at
    org.opensim.modeling.InverseDynamicsTool.run(InverseDynamicsTool.java:121)


Error in ==> setupAndRunIDBatch_V2 at 109
        idTool.run();
When I exclude the line

Code: Select all

idTool.setExternalLoadsFileName(fullpath_extLoad);
there is no error and the simulation seems to be ok.
I´m sure it´s an easy problem for you or any other expert, but I didn´t get on the right track!?!?

So could you please give me a hint what I have to do!?!

many thanks for your time and best regards
Günter

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

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Tue Dec 10, 2013 10:45 am

Hi Gunter,

The error message seems to indicate that the file or one of the file names referred to inside it were not located correctly, which could be a Path issue (absolute/relative etc.) or could be that the files were found but the format is not what the code expects.

I'd troubleshoot the contents issue first and try to run the tool using your data files from the GUI, if that works I'd write the tool to xml and see what paths are used, and maybe use absolute paths first, and then try to simplify the files later.

Hope this helps,
-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 » Wed Dec 11, 2013 2:30 pm

aymanh wrote:...
The error message seems to indicate that the file or one of the file names referred to inside it were not located correctly, which could be a Path issue (absolute/relative etc.) or could be that the files were found but the format is not what the code expects.
...
Hi, Ayman!

Many THANKS, you were right. I had a little mistake in the filename of my external loads file. So shame on me, I checked it three times before and didn't find it! Sorry for that!

Now my IDBatch works fine and I`ll try to do the same with CMC ;)

thank you again and many thanks

günta

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 » Thu Jan 16, 2014 8:09 am

hi again,

the ID batch is doing a great job, THANKS one more time for your help.
Unfortunately I`ve another problem, now with the CMC batch.

My plan is to run a set of simulations for 18 different motion-files and five different external load files.
It seems that everything works fine, because when I check the specific setup-files, the batch stored for every single run, all parameter/filename and so on are set right.
The only failure that occures is:
OpenSim creates and stores result-files (..._states.sto, ..._Actuation_force.sto, ..._controls.sto, ... ) only for the first simulation run and not for all every!?!?

I don't have any idea what i can/should do or where the mistake is located.
I thought that maybe the batch stores the results of every simulation to the same-named file so that that migth be the reason for only one result-file set. Is there a possibility to define the prefix like in OpenSim? I know that this prefix is defined in the setup-file in the third line

Code: Select all

<CMCTool name="resultsCMC_isokinetic_force000_v050">
but maybe MATLAB or OpenSim executed via MATLAB ignores that? Because also that parameter is right in all of the generic setup-files!?!

Or is there another reason for that problem?

thanks a lot for every little tip that might solve that problem

best regards
günter
Attachments
setup_CMC_isokinetic_force000_v050.xml
setup-file out of CMCBatch
(5.08 KiB) Downloaded 139 times

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

Re: Performing Inverse Dynamics via Matlab API

Post by Ayman Habib » Thu Jan 16, 2014 10:56 am

Hi Gunter,

Do you change the name of the "results directory" in your script?

You can do this using the call

Code: Select all

setResultsDir(const std::string& aString)
on the tool object.

Please let us know if that solves the problem.

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 » Thu Jan 16, 2014 4:26 pm

hello Ayman,

and thanks a lot for your quick response ..

I define one result directory for all result files of all runs.
Here the code of my matlab script:

Code: Select all

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%                                                                        %
%                 B A T C H for multiple COMPUTER MUSCLE CONTROL         %
%                                                                        %

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

% setupAndRunCMCBatch.m                                                 
% Author: SCHNEIDER G¸nter

clc;
close all;
clear all;

% Pull in the modeling classes straight from the OpenSim distribution
import org.opensim.modeling.*

% move to directory where this subject's files are kept
subjectDir = uigetdir('C:\OpenSim 3.1\Models\', 'Select the folder that contains the current subject data');

% Go to the folder in the subject's folder where .mot files are
motion_data_folder = uigetdir(subjectDir, 'Select the folder that contains the motion data files in .mot format.');

% specify where results will be printed.
results_folder = uigetdir(subjectDir, 'Select the folder where the CMC Results will be printed.');

% Get and operate on the files
% Choose a generic setup file to work from
[genericSetupForCMC,genericSetupPath,FilterIndex] = ...
    uigetfile([subjectDir '\*.xml'],'Pick the/a generic setup file to/for this subject/model as a basis for changes.');
cmcTool = CMCTool([genericSetupPath genericSetupForCMC]);

% specify the folder where the external loads file are 
extLoad_folder = ... 
    uigetdir(subjectDir ,'Select the folder where the external loads files are located.');

% Get the model
[modelFile,modelFilePath,FilterIndex] = ...
    uigetfile([subjectDir '\*.osim'],'Pick the the model file to be used.');

% Load the model and initialize
model = Model([modelFilePath modelFile]);
model.initSystem();

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

trialsForCMC = dir(fullfile(motion_data_folder, '*.mot'));
nTrialsMotion = size(trialsForCMC);

% Loop through the trials of .mot files 
for trial_motion = 1:nTrialsMotion;
    
    % Get the name of the file for this trial
    motionFile = trialsForCMC(trial_motion).name;
     
    % create generic external load files
    ForceFile000 = ['PointForceCalcnL' motionFile(7:end-9) '_force000' motionFile(end-8:end-4) '.xml'];
    ForceFile025 = ['PointForceCalcnL' motionFile(7:end-9) '_force025' motionFile(end-8:end-4) '.xml'];
%     ForceFile050 = ['PointForceCalcnL' motionFile(7:end-9) '_force050' motionFile(end-8:end-4) '.xml'];
%     ForceFile075 = ['PointForceCalcnL' motionFile(7:end-9) '_force075' motionFile(end-8:end-4) '.xml'];
%     ForceFile100 = ['PointForceCalcnL' motionFile(7:end-9) '_force100' motionFile(end-8:end-4) '.xml'];
    
    extLoadFile = struct('forceFile',{ForceFile000,ForceFile025});%,ForceFile050,ForceFile075,ForceFile100});
     
    % Loop through the trails of div. external load files
    for trial_force = 1:length(extLoadFile);                      

        % Create name of trial_motion from .mot file name
%         name = regexprep(motionFile,'.mot','');
        name = (['resultsCMC' extLoadFile(trial_force).forceFile(17:end-4)]);
        fullpath = ([motion_data_folder '\' motionFile]);
        fullpath_extLoad = ([extLoad_folder '\' extLoadFile(trial_force).forceFile]);

        % Get .mot data to determine time range
        ImportMotionData = importdata(fullpath);
        motionData = ImportMotionData.data;
    %     motionData = motionData(fullpath);

        % Get initial and intial time 
    %     initial_time = motionData.getStartFrameTime();
          initial_time = motionData(1,1);
    %     final_time = motionData.getLastFrameTime();
          final_time = motionData(end,1);

        % Setup the cmcTool for this trial
        cmcTool.setName(name);
        cmcTool.setDesiredKinematicsFileName(fullpath);
        cmcTool.setInitialTime(initial_time);
        cmcTool.setFinalTime(final_time);
        cmcTool.setResultsDir(results_folder);
        cmcTool.setExternalLoadsFileName(fullpath_extLoad);

         % Save the settings in a setup file
        outfile = ['setup_CMC' extLoadFile(trial_force).forceFile(17:end-4)  '.xml'];
        cmcTool.print([genericSetupPath outfile]);

        fprintf(['Performing CMC: cycle #' num2str(trial_motion) ...
            ' of ' num2str(nTrialsMotion(1,1)) '(motion) / #' num2str(trial_force) ...
            ' of ' num2str(length(extLoadFile)) '(force) \n ... [' outfile ']\n ... [' extLoadFile(trial_force).forceFile ']\n']);
     
        % Run CMC
        cmcTool.run();
        
        fprintf([' ... [' name '_ ... .sto]\n']);
     
        % keep def. files and folders, clear all other
        keep subjectDir motion_data_folder results_folder genericSetupForCMC ... 
            genericSetupPath FilterIndex cmcTool extLoad_folder modelFile modelFilePath ... 
            model trialsForCMC nTrialsMotion trial_motion motionFile extLoadFile

    end
end
display('*** *** *** Computer Muscle Control(CMC) - D O N E *** *** ***');
edit 17/01/2014 - 3:30pm:
In the batch for ID I use

Code: Select all

        
% specify where results will be printed.
results_folder = uigetdir(subjectDir, 'Select the folder where the ID Results will be printed.');

..
idTool.setOutputGenForceFileName(['resultsID' extLoadFile(trial_force).forceFile(17:end-4) '.sto']);
        idTool.setResultsDir(results_folder);
to give the resulting file a unique name. Is there something similar for the cmcTool?


THX and best regards

günter

User avatar
Alice Mantoan
Posts: 29
Joined: Fri Feb 24, 2012 11:51 am

Re: Performing Inverse Dynamics via Matlab API

Post by Alice Mantoan » Wed Apr 23, 2014 3:54 am

Hi all,

I know this is almost a passed matter, but I'm trying to do exactly the same regarding the ID processing via API right now.
I followed all the indications in these posts, both for the setup of the idTool for each trial and David's solution for the external loads configuration, but I have a strange problem.
The code works fine for the first trial, but it gives completely wrong moments's values for all the others.
The stored xml setup files, including the one about external loads, seem correct for all trials, and I created the starting generic setup file from the GUI, checking the template (and Muscles are set in forces_to_exclude). I also tried to reset each variable each trial, without success.

Have you ever experienced this problem?Have you got an idea of what/where can be my mistake or any suggestions?

Thanks a lot.
Best regards,

Alice

POST REPLY