Loading Model Kinematics with OpenSim 4.0 MATLAB API

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Connor Pyles
Posts: 20
Joined: Wed Jul 19, 2017 1:46 pm

Loading Model Kinematics with OpenSim 4.0 MATLAB API

Post by Connor Pyles » Wed Jul 26, 2017 1:24 pm

Hi all,

I'm working on post-processing some simulation results in MATLAB, and I need to load in some previously run simulations. Right now my workflow is to load and initialize the .osim model, then read in the .mot file using a generic MATLAB parse command, loop through and update model coordinates based on .mot file, then ask for body positions with respect to ground frame, which is my desired output. Example code below:

Code: Select all

% Import opensim classes
import org.opensim.modeling.*

% Read in model from file
model_file = 'my_file.osim';
model = Model(model_file);

% Load in the .mot file output
mot_file = IK_Results.mot';
% Copy  as .txt so can be read as table
[path, name, ext] = fileparts(mot_file);
mot_txt_file = fullfile(path, [name, '.txt']);
copyfile(mot_file, mot_txt_file);
mot_table = readtable(mot_txt_file);
delete(mot_txt_file);

% Get a reference to the state
state = model.initSystem();

% Get a reference to all bodies in model
body_set = model.getBodySet();
num_bodies = body_set.getSize;

% Get a reference to all coordinates in model
coordinate_set = model.getCoordinateSet();
num_coordinates = coordinate_set.getSize;

% Initialize positions and rotations for each body
p = cell(length(time), num_bodies);
r = cell(length(time), num_bodies);

% Loop through time
time = mot_table.time;
for time_idx = 1:length(time)
    
    % Loop through each coordinate and update position
    num_coordinates_from_mot = size(mot_table,2) - 1; % First one is time
    assert(num_coordinates_from_mot == num_coordinates, 'Check that model matches output. Number of coordinates from model does not match number of coordinates in .mot file');
   
    for coordinate_idx = 1:num_coordinates;
        
        coordinate = coordinate_set.get(coordinate_idx - 1); % idx starts with zero
        coordinate_name = char(coordinate);
        % Pull coordinate position in local frame from .mot file
        coordinate_value_local = mot_table.(coordinate_name)(time_idx);
        % Change the coordinate position in local frame
        coordinate.setValue(state, coordinate_value_local);   
    
    end
    
    % Loop through bodies and pull position in ground frame
    for body_idx = 1:num_bodies
       
        body = body_set.get(body_idx - 1); % idx starts with zero
        this_p = body.getPositionInGround(state);
        this_r = body.getTransformInGround(state).R;
        
        % Update arrays
        p{time_idx, body_idx} = this_p;
        r{time_idx, body_idx} = this_r;
    end
end
My question is, are there API methods to load in .mot results and step through each state ? The web page below just says to load .mot into Matlab using Import Data interface.
http://simtk-confluence.stanford.edu:80 ... g+Commands

Best,
Connor Pyles
Johns Hopkins Applied Physics Laboratory

User avatar
Thomas Uchida
Posts: 1793
Joined: Wed May 16, 2012 11:40 am

Re: Loading Model Kinematics with OpenSim 4.0 MATLAB API

Post by Thomas Uchida » Wed Jul 26, 2017 2:09 pm

You should be able to read in the file using the STOFileAdapter class (http://myosin.sourceforge.net/1843/clas ... ter__.html) with something like

Code: Select all

timeSeriesTable = STOFileAdapter.read(filename);
and use the methods in the TimeSeriesTable and DataTable classes. These are new features in 4.0 and the documentation still needs to be improved, but you can find some use cases on GitHub. You could also try the old Storage class (http://myosin.sourceforge.net/1843/clas ... orage.html).

Note that the line

Code: Select all

coordinate.setValue(state, coordinate_value_local);
should be something like

Code: Select all

coordinate.setValue(state, coordinate_value_local, double(coordinate_idx==num_coordinates));
because you want to enforce the constraints only once all coordinates have been set. See the documentation for Coordinate::setValue() (http://myosin.sourceforge.net/1843/clas ... 0004213229).

User avatar
Connor Pyles
Posts: 20
Joined: Wed Jul 19, 2017 1:46 pm

Re: Loading Model Kinematics with OpenSim 4.0 MATLAB API

Post by Connor Pyles » Thu Jul 27, 2017 11:23 am

This worked, thank you very much.

-CP

User avatar
Christopher Dembia
Posts: 506
Joined: Fri Oct 12, 2012 4:09 pm

Re: Loading Model Kinematics with OpenSim 4.0 MATLAB API

Post by Christopher Dembia » Tue Aug 01, 2017 2:27 pm

You could also use

Code: Select all

StatesTrajectory.createFromStatesStorage()

POST REPLY