[76e9f4]: / tool_funcs / applyTorsionToJoints.m

Download this file

144 lines (117 with data), 6.0 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
%-------------------------------------------------------------------------%
% Copyright (c) 2021 Modenese L. %
% Author: Luca Modenese, 2021 %
% email: l.modenese@imperial.ac.uk %
% ----------------------------------------------------------------------- %
function osimModel = applyTorsionToJoints(osimModel, bone_to_deform, aStringAxis, torsion_angle_func_rad)
import org.opensim.modeling.*
% get rotation matrix as implicit function for given deformation
[aRotMatFunc, axis_ind] = getAxisRotMat(aStringAxis);
disp('------------------');
disp(' ADJUSTING JOINTS ');
disp('------------------');
%% rotate the proximal joint
% OpenSim 3.3
if getOpenSimVersion()<4.0
proxJoint = osimModel.getBodySet.get(bone_to_deform).getJoint();
% initialise orientation and location (in body of interest)
orientation = Vec3(0);
location = Vec3(0);
% extract proximal joint params
proxJoint.getOrientation(orientation);
proxJoint.getLocation(location);
else
% OpenSim 4.x
proxJoint = getBodyJoint(osimModel, bone_to_deform, 0);
% extract proximal joint params
location = proxJoint.get_frames(1).get_translation();
orientation = proxJoint.get_frames(1).get_orientation();
end
disp(['* ', char(proxJoint.getName()), ' (', char(proxJoint.getConcreteClassName()),')']);
disp([' ', bone_to_deform, ' is CHILD.'])
disp([' orientation in child : ', sprintf('%.2f %.2f %.2f', [orientation.get(0), orientation.get(1), orientation.get(2)])]);
disp([' location in child : ', sprintf('%.2f %.2f %.2f', [location.get(0), location.get(1), location.get(2)])] )
% compute the torsion matrix for proximal joint
XYZ_location_vec = [location.get(0), location.get(1), location.get(2)];
% NOTE: no need to check for CustomJoint here, as the child is not affected
% by the SpatialTransform, which moves the child wrt the parent.
tors_angle = torsion_angle_func_rad(XYZ_location_vec(axis_ind));
torsion_RotMat = aRotMatFunc(tors_angle);
disp([' torsion of ', num2str(tors_angle*180/pi), ' deg applied.'])
% compute new location in child
new_Loc = XYZ_location_vec * torsion_RotMat';
newLocation = Vec3(new_Loc(1), new_Loc(2), new_Loc(3));
% compute new orientation in child
XYZ_orient_vec = [orientation.get(0), orientation.get(1), orientation.get(2)];
jointRotMat = orientation2MatRot(XYZ_orient_vec);
newJointRotMat = jointRotMat * torsion_RotMat;
new_Orientation = computeXYZAngleSeq(newJointRotMat);
newOrientation = Vec3(new_Orientation(1), new_Orientation(2), new_Orientation(3));
% assign params
% OpenSim 3.3
if getOpenSimVersion()<4.0
proxJoint.setOrientation(newOrientation);
proxJoint.setLocation(newLocation)
else
% OpenSim 4.x
proxJoint.get_frames(1).set_orientation(newOrientation);
proxJoint.get_frames(1).set_translation(newLocation);
end
%% update distal joints
jointNameSet = getDistalJointNames(osimModel, bone_to_deform);
% here the body is parent of the joint
for nj = 1:length(jointNameSet)
% initialise
orientation = Vec3(0);
location = Vec3(0);
% get current joint
cur_joint_name = jointNameSet{nj};
curDistJoint = osimModel.getJointSet.get(cur_joint_name);
% extract joint params
if getOpenSimVersion()<4.0
curDistJoint.getOrientationInParent(orientation);
curDistJoint.getLocationInParent(location);
else
orientation = curDistJoint.get_frames(0).get_orientation();
location = curDistJoint.get_frames(0).get_translation();
end
disp(['* ', cur_joint_name, ' (', char(curDistJoint.getConcreteClassName()),')']);
disp([' ', bone_to_deform, ' is PARENT.'])
disp([' orientation in parent : ', sprintf('%.2f %.2f %.2f', [orientation.get(0), orientation.get(1), orientation.get(2)])]);
disp([' location in parent : ', sprintf('%.2f %.2f %.2f', [location.get(0), location.get(1), location.get(2)])] )
% compute the torsion matrix
XYZ_location_vec = [location.get(0), location.get(1), location.get(2)];
% take into account the spatialTransform
jointOffset = [0 0 0];
if strcmp(char(curDistJoint.getConcreteClassName()), 'CustomJoint')
% offset from the spatial transform
% this is in parent, which is the bone of interest
jointOffset = computeSpatialTransformTranslations(osimModel, curDistJoint);
disp([' spatialTransf-transl : ', sprintf('%.2f %.2f %.2f', jointOffset)]);
disp([' location in parent (initSystem) : ', sprintf('%.2f %.2f %.2f', jointOffset)]);
end
% if CustomJoint add the translation from the CustomJoint
XYZ_location_torsion = XYZ_location_vec+jointOffset;
% actually compute the matrix
tors_angle = torsion_angle_func_rad(XYZ_location_torsion(axis_ind));
torsion_RotMat = aRotMatFunc(tors_angle);
disp([' torsion of ', num2str(tors_angle*180/pi), ' deg applied.'])
% compute new location in parent
new_Loc = XYZ_location_vec * torsion_RotMat';
newLocationInParent = Vec3(new_Loc(1), new_Loc(2), new_Loc(3));
% compute new orientation in parent
XYZ_orient_vec = [orientation.get(0), orientation.get(1), orientation.get(2)];
jointRotMat = orientation2MatRot(XYZ_orient_vec);
newJointRotMat = jointRotMat * torsion_RotMat;
new_OrientationInPar = computeXYZAngleSeq(newJointRotMat);
newOrientationInParent = Vec3(new_OrientationInPar(1), new_OrientationInPar(2), new_OrientationInPar(3));
% assign new parameters
if getOpenSimVersion()<4.0
curDistJoint.setOrientationInParent(newOrientationInParent);
curDistJoint.setLocationInParent(newLocationInParent)
else
curDistJoint.get_frames(0).set_orientation(newOrientationInParent);
curDistJoint.get_frames(0).set_translation(newLocationInParent);
end
end
end