Switch to unified view

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