Reporting Quaternions instead of Euler Angles

Provide easy-to-use, extensible software for modeling, simulating, controlling, and analyzing the neuromusculoskeletal system.
POST REPLY
User avatar
Brody Hicks
Posts: 32
Joined: Wed Jun 19, 2019 11:55 am

Reporting Quaternions instead of Euler Angles

Post by Brody Hicks » Fri Feb 11, 2022 10:09 am

Hello,

I am using OpenSim to analyze some athletic movements (e.g. cutting). I am interested in analyzing the global position and orientation of some of the bodies in my model. I am utilizing the "BodyKinematics" analysis tool, which gives me the body-fixed X-Y-Z Euler angles.

Is it possible to represent these quantities with quaternions, or rotation matrices, or even reporting different Euler angle sequences to avoid singularities? Specifically, I am interested in doing this in Matlab, so if there is a some documentation on this I would appreciate knowing where to look.

Thanks,
Brody

Tags:

User avatar
Carmichael Ong
Posts: 401
Joined: Fri Feb 24, 2012 11:50 am

Re: Reporting Quaternions instead of Euler Angles

Post by Carmichael Ong » Fri Feb 11, 2022 11:53 am

Simbody's Rotation class can be used in OpenSim's MATLAB scripting. You can see its documentation here: https://simbody.github.io/3.7.0/classSi ... ion__.html

Alternatively, MATLAB has some functions to also handle this. For instance, euler angles to quaternions (eul2quat): https://www.mathworks.com/help/robotics ... 2quat.html

User avatar
Brody Hicks
Posts: 32
Joined: Wed Jun 19, 2019 11:55 am

Re: Reporting Quaternions instead of Euler Angles

Post by Brody Hicks » Mon Feb 14, 2022 9:02 am

Carmichael,

Thanks for the reply. Are you aware of a method to specifically adjust the Euler sequence the BodyKinematics Analysis tool is using to report a different sequence or quaternions?

Thanks,
Brody

User avatar
Carmichael Ong
Posts: 401
Joined: Fri Feb 24, 2012 11:50 am

Re: Reporting Quaternions instead of Euler Angles

Post by Carmichael Ong » Mon Feb 14, 2022 11:34 am

Unfortunately it looks like the BodyKinematics Analysis tool is hard-coded to report body-fixed XYZ: https://github.com/opensim-org/opensim- ... s.cpp#L464

User avatar
Brody Hicks
Posts: 32
Joined: Wed Jun 19, 2019 11:55 am

Re: Reporting Quaternions instead of Euler Angles

Post by Brody Hicks » Mon Feb 14, 2022 2:25 pm

Carmichael,

Thank you. That is very helpful.

If I want access to quaternions directly from OpenSim's Matlab scripting, is it feasible to use the StatesReporter analysis tool to get states for a given trial, and then load those states into the model and utilize the same syntax from the BodyKinematics tool to pull out a quaternion or different euler sequence from the state?

For Example:
all_states = Storage(statesPath);

for i = 0:(all_states.getSize()-1)
% get current states
% update model with current states
body = model.getBodySet.get('0); % get whatever body I want
osim_rotation = body.getTransformInGround(s).R();
osim_quaternion = osim_rotation.convertRotationToQuaternion();

% then store each quaternion as the loop iterates through each state
end

^ Above is my general idea, but I am struggling to figure out how to use Matlab to get the current state for all_states and how to update the model to possess the current state. Thank you for your time and please let me know if I can add any clarification.

Brody

User avatar
Brody Hicks
Posts: 32
Joined: Wed Jun 19, 2019 11:55 am

Re: Reporting Quaternions instead of Euler Angles

Post by Brody Hicks » Tue Feb 15, 2022 12:37 pm

As a follow up, I want to understanding how to utilize the "body.getTransformInGround(s).R()" command where "s" is some state other than the state returned from s = model.initSystem();

User avatar
Brody Hicks
Posts: 32
Joined: Wed Jun 19, 2019 11:55 am

Re: Reporting Quaternions instead of Euler Angles

Post by Brody Hicks » Wed Feb 16, 2022 11:29 am

Solved.

I ended up being able to use "StatesTrajectory" to create a StatesTrajectory, and then iterate through the states to do my calculations at each time step.

Here is my code:

%%%%%%%%%%%%%%%%%%
states_sto = Storage(statesPath);

stateTrajectory = StatesTrajectory.createFromStatesStorage(model,states_sto);
nRows = stateTrajectory.getSize();
calcn_r = model.getBodySet.get('calcn_r'); %get body reference

for n = 0:nRows-1
state = stateTrajectory.get(n); %now I have a reference to the current state
model.realizePosition(state);
rotation = calcn_r.getTransformInGround(state).R();
quat = rotation.convertRotationToQuaternion();
calcn_rotation(n+1,:) = [quat.get(0) quat.get(1) quat.get(2) quat.get(3)];
end

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

Perhaps this might help someone else.

Thanks!

Brody

POST REPLY