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
http://simtk-confluence.stanford.edu:80 ... g+Commands
Best,
Connor Pyles
Johns Hopkins Applied Physics Laboratory