Page 1 of 1
Clone and move wrap object in Matlab API
Posted: Fri Dec 03, 2021 7:22 am
by delyle
I have models with muscles and wrap objects on the right side, and I want to write a MATLAB script to mirror them onto the left side.
I've managed to mirror the muscles but I can't figure out how to do this for the wrap objects.
Using the Arm26 model as an example, let's say I wanted to clone the
TRIlonghh WrapEllipsoid attached to the
r_humerus body and attach it to the
r_ulna_radius_hand body at an arbitrary location.
I can access the Wrap Set for
r_humerus with the following script, but then I can't seem to get individual wrap objects. Since
wrapSet is an Abstract Property I probably need to safeDownCast, but to what derived class?
Code: Select all
clear
import org.opensim.modeling.*
model = Model('arm26.osim');
bodySet = model.getBodySet();
body = bodySet.getPropertyByIndex(0).getValueAsObject(1);
bodyName = cell2mat(body.getName.string);
wrapSet = body.updPropertyByName('WrapObjectSet');
Unfortunately I'm restricted to using 3.3 for these models. I'm using Matlab 2020b in Windows 10.
Thanks for your help!
Re: Clone and move wrap object in Matlab API
Posted: Tue Dec 07, 2021 5:26 am
by delyle
I've managed to duplicate the wrap object of interest and attach it to a new body.
It seems the key is to safeDownCast the wrap object from the WrapEllipsoid derived class.
But I can't figure out how to move the wrap object in the script! I can access the translation and transform properties, but I can't update them. Help?
Code: Select all
clear; clc
import org.opensim.modeling.*
model = Model('arm26.osim');
model.setName('arm26_newWrap')
% get the r_humerus Body
bodySet = model.getBodySet();
r_humerus = Body().safeDownCast(bodySet.getPropertyByIndex(0).getValueAsObject(1)); % gets the
% get the TRIlonghh wrap object
wrapSet = r_humerus.updPropertyByName('WrapObjectSet'); % possibly getWrapObjectSet() instead?
wrapSetObj = wrapSet.getValueAsObject(0);
wrapSetArray = wrapSetObj.updPropertyByIndex(0);
wrapObj = WrapEllipsoid().safeDownCast(wrapSetArray.updValueAsObject(0)); % gets first wrap object
wrapObj2 = wrapObj.clone();% duplicate wrap object
nameOld = wrapObj.getName.string;
nameNew = ['new',nameOld{1}(1:end)];
wrapObj2.setName(nameNew); % give it a new name
% get translation and transform. How to edit?
T = wrapObj2.updPropertyByName('translation');
transform = wrapObj2.getTransform();
% add new wrap object to the r_ulna_radius_hand Body.
r_ulna_radius_hand = Body().safeDownCast(bodySet.updPropertyByIndex(0).updValueAsObject(2));
r_ulna_radius_hand.addWrapObject(wrapObj2);
model.initSystem(); % check model consistency
model.print('arm26_newWrap.osim');
Re: Clone and move wrap object in Matlab API
Posted: Tue Dec 07, 2021 11:50 pm
by akoussou
Hi Delyle,
Below is a snippet of a code I use on MatLab, with OpenSim 4.1, to modify translation and rotation of a wrapping object. I hope it will help you and you will find a way to adapt it to OpenSim 3.3.
Code: Select all
% body of interest
cur_body = osimModel.getBodySet().get(aSegmentName);
% current wrapping surfaces
curr_wrap = cur_body.getWrapObject(cur_body.getWrapObjectSet.get(n_wrap_surfaces).getName);
% current wrapping translation
wrapSurfLocVec3 = curr_wrap.get_translation();
wrapSurfLocCoords = [wrapSurfLocVec3.get(0),wrapSurfLocVec3.get(1),wrapSurfLocVec3.get(2)];
%I do some modifications to wrapSurfLocCoords (not in this snippet). Then, I can compute new wrap surfaces translation.
% compute/define new wrap surfaces translation
new_wrapSurfLocCoords =[X X X];
% setting the wrap surfaces translation as Vec3
new_wrapSurfLocCoords_v3 = Vec3(new_wrapSurfLocCoords(1), new_wrapSurfLocCoords(2), new_wrapSurfLocCoords(3));
curr_wrap.set_translation(new_wrapSurfLocCoords_v3);
% current wrapping rotation
wrapSurfRotVec3 = curr_wrap.get_xyz_body_rotation();
wrapSurfRotCoords = [wrapSurfRotVec3.get(0),wrapSurfRotVec3.get(1),wrapSurfRotVec3.get(2)];
%I do some modifications to wrapSurfRotCoords (not in this snippet). Then, I can compute new wrap surfaces rotation.
% compute/define new wrap surfaces orientation
new_Orientation =[X X X];
new_wrapSurfRot = Vec3(new_Orientation(1), new_Orientation(2), new_Orientation(3));
% setting the wrap surfaces rotation as Vec3
curr_wrap.set_xyz_body_rotation(new_wrapSurfRot);
Regards
Re: Clone and move wrap object in Matlab API
Posted: Wed Dec 08, 2021 4:37 am
by delyle
Thanks for looking into this, Axel! That code looks great for v4.
OpenSim 4 added some functionality that the v3.3 API doesn't seem to have.
There is no set_translation or set_xyz_body_rotation function in the WrapObject class for v3.3. I can get the translation and rotation via getTransform.T and getTransform.R respectively. But there doesn't seem to be a way to set or update the transform of the wrap object.
Re: Clone and move wrap object in Matlab API
Posted: Wed Dec 08, 2021 6:26 pm
by aymanh
Hi Delyle,
Not sure the complete list of features that were available to version 3.3 (few years ago) but there's always a PropertyHelper class that would allow you to exploit the "Properties" interface to set/get values on AbstractProperty if you know the concrete type. This mechanism has always been used by the GUI to make changes/edits to models. If you look up the documentation of PropertyHelper in version 3.3 you maybe able to do what you want, alternatively you can upgrade to version 4.0+
Hope this helps,
-Ayman
Re: Clone and move wrap object in Matlab API
Posted: Fri Dec 10, 2021 8:30 am
by delyle
Brilliant, that worked! Thanks Ayman.