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