[76e9f4]: / tool_funcs / getJointCentresForBone.m

Download this file

97 lines (78 with data), 3.4 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
%-------------------------------------------------------------------------%
% Copyright (c) 2021 Modenese L. %
% Author: Luca Modenese, 2021 %
% email: l.modenese@imperial.ac.uk %
% ----------------------------------------------------------------------- %
function [prox_P, dist_P, bone_length, V] = getJointCentresForBone(osimModel, bone_to_deform)
import org.opensim.modeling.*
% body of interest
cur_body = osimModel.getBodySet().get(bone_to_deform);
disp('---------------------');
disp(' COMPUTE BONE LENGTH ');
disp('---------------------');
disp(['Processing body: ', bone_to_deform])
% initialise model
si = osimModel.initSystem();
%% get proximal joint centre
% body joint extraction
if getOpenSimVersion()<4.0
% OpenSim 3.3
proxJoint = cur_body.getJoint();
% location in child
prox_loc = cur_body.getJoint().get_location;
else
% OpenSim 4.x
proxJoint = getBodyJoint(osimModel, bone_to_deform, 1);
prox_loc = proxJoint.get_frames(1).get_translation();
end
% transform in MATLAB vectors
prox_P = [prox_loc.get(0), prox_loc.get(1), prox_loc.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.
%% get distal joint(s) centre(s)
% here the body of interest is parent
jointNameSet = getDistalJointNames(osimModel, bone_to_deform);
for nj = 1:length(jointNameSet)
% get current joint
cur_joint_name = jointNameSet{nj};
distJoint = osimModel.getJointSet().get(cur_joint_name);
% location in parent
% OpenSim 3.3
if getOpenSimVersion()<4.0
dist_loc = distJoint.get_location_in_parent;
else
% OpenSim 4.x
dist_loc = distJoint.get_frames(0).get_translation();
end
% offset from the spatial transform (in local body)
% take into account the spatialTransform
jointOffset = [0, 0, 0];
if strcmp(char(distJoint.getConcreteClassName()), 'CustomJoint')
localJointOffset = computeSpatialTransformTranslations(osimModel, distJoint);
jointOffsetV3 = Vec3(localJointOffset(1), localJointOffset(2), localJointOffset(3));
jointOffset = [jointOffsetV3.get(0), jointOffsetV3.get(1), jointOffsetV3.get(2)];
end
% move to body of interest
% osimModel.getSimbodyEngine().transformPosition(si, distJoint.getBody(), jointOffsetV3, cur_body, jointOffsetV3);
% sum the contributions
dist_P = [dist_loc.get(0), dist_loc.get(1), dist_loc.get(2)];
dist_P(nj,1:3) = dist_P + jointOffset;
% lengths
L(nj) = norm(prox_P-dist_P(nj,1:3));
end
%% compute length
% in case of multiple joint centre take the further, so all joints are
% transformed, if needed.
% Example: tibiofemoral and patellofemoral joints.
[bone_length, max_ind] = max(L);
% distal point
dist_P = dist_P(max_ind, :);
% compute axis versor
V = (dist_P-prox_P)/bone_length;
% display output
disp(['Proximal joint name : ', char(proxJoint.getName())]);
disp(['Proximal joint centre: ', sprintf('%.2f %.2f %.2f', prox_P)]);
disp(['Distal joint name : ', jointNameSet{max_ind}]);
disp(['Distal joint centre : ', sprintf('%.2f %.2f %.2f', dist_P)]);
disp(['Total length of bone : ', sprintf('%.2f %.2f %.2f', bone_length), ' m']);
end