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
Reporting Quaternions instead of Euler Angles
- Brody Hicks
- Posts: 32
- Joined: Wed Jun 19, 2019 11:55 am
- Carmichael Ong
- Posts: 401
- Joined: Fri Feb 24, 2012 11:50 am
Re: Reporting Quaternions instead of Euler Angles
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
Alternatively, MATLAB has some functions to also handle this. For instance, euler angles to quaternions (eul2quat): https://www.mathworks.com/help/robotics ... 2quat.html
- Brody Hicks
- Posts: 32
- Joined: Wed Jun 19, 2019 11:55 am
Re: Reporting Quaternions instead of Euler Angles
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
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
- Carmichael Ong
- Posts: 401
- Joined: Fri Feb 24, 2012 11:50 am
Re: Reporting Quaternions instead of Euler Angles
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
- Brody Hicks
- Posts: 32
- Joined: Wed Jun 19, 2019 11:55 am
Re: Reporting Quaternions instead of Euler Angles
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
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
- Brody Hicks
- Posts: 32
- Joined: Wed Jun 19, 2019 11:55 am
Re: Reporting Quaternions instead of Euler Angles
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();
- Brody Hicks
- Posts: 32
- Joined: Wed Jun 19, 2019 11:55 am
Re: Reporting Quaternions instead of Euler Angles
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
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