[76e9f4]: / tool_funcs / applyTorsionToMuscleAttachments.m

Download this file

157 lines (127 with data), 6.7 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
145
146
147
148
149
150
151
152
153
154
155
156
157
%-------------------------------------------------------------------------%
% Copyright (c) 2025 Modenese L. %
% Author: Luca Modenese, 2021 %
% email: l.modenese@unsw.edu.au %
% ----------------------------------------------------------------------- %
function osimModel = applyTorsionToMuscleAttachments(osimModel, aSegmentName, aTorsionAxisString, torsion_angle_func_rad)
import org.opensim.modeling.*
% default: deform viapoints (legacy option)
deformViapoint = 'yes';
disp('------------------------------');
disp(' ADJUSTING MUSCLE ATTACHMENTS ');
disp('------------------------------');
% check if segment is included in the model
if osimModel.getBodySet().getIndex(aSegmentName)<0
error('The specified segment is not included in the OpenSim model')
end
% converting the axis in the index used later
[RotMat, axis_ind] = getAxisRotMat(aTorsionAxisString);
% extracting muscleset
Muscles = osimModel.getMuscles();
N_mus = Muscles.getSize();
processed_muscles = '';
ntm = 1;
% state now required
state = osimModel.initSystem();
% loop through the muscles
for n_mus = 0:N_mus-1
% current muscles
curr_Mus = Muscles.get(n_mus);
% extracting the path
currentPathPointSet = curr_Mus.getGeometryPath().getPathPointSet();
% number of points
N_p = currentPathPointSet.getSize();
% looping through the points of the PathPointSet
for n_p = 0:N_p-1
% skip the point if viapoints are not be deformed
if strcmp(deformViapoint,'no') && (n_p~=0 || n_p~=N_p-1)
continue
end
% Body attached to each point of the PathPointSet
attachBodyName = char(currentPathPointSet.get(n_p).getBody().getName());
if strcmp(attachBodyName, aSegmentName)
% disp(['processing ', char(curr_Mus.getName())]);
% keep track
if max(strcmp(char(curr_Mus.getName()), processed_muscles))==0
processed_muscles{ntm} = char(curr_Mus.getName());
ntm = ntm + 1;
end
% point coordinates
% OpenSim 3.3
if getOpenSimVersion()<4.0
musAttachLocVec3 = currentPathPointSet.get(n_p).getLocation();
else
% OpenSim 4.x
musAttachLocVec3 = currentPathPointSet.get(n_p).getLocation(state);
end
curr_pathpoint_class = char(currentPathPointSet.get(n_p).getConcreteClassName());
if strcmp(curr_pathpoint_class, 'PathPoint') || strcmp(curr_pathpoint_class, 'ConditionalPathPoint')
% convert to Matlab var
musAttachLocCoords = [musAttachLocVec3.get(0),musAttachLocVec3.get(1),musAttachLocVec3.get(2)];
% compute torsion metric for the attachment point
TorsRotMat = RotMat(torsion_angle_func_rad(musAttachLocCoords(axis_ind)));
% compute new muscle attachment coordinates
new_musAttachLocCoords = (TorsRotMat*musAttachLocCoords')';%musCoord * M'
if getOpenSimVersion()<4.0 %OpenSim 3.3
currentPathPointSet.get(n_p).setLocationCoord(0,double(new_musAttachLocCoords(1)))
currentPathPointSet.get(n_p).setLocationCoord(1,double(new_musAttachLocCoords(2)))
currentPathPointSet.get(n_p).setLocationCoord(2,double(new_musAttachLocCoords(3)))
else %OpenSim 4.x
% getPathPoint returns an AbstractPathPointSet. Requires
% downcasting
eval(['currentPathPoint = ',curr_pathpoint_class,'.safeDownCast(currentPathPointSet.get(n_p));'])
% setting the muscle PathPointSet as Vec3
new_musAttachLocCoords_v3 = Vec3(new_musAttachLocCoords(1), new_musAttachLocCoords(2), new_musAttachLocCoords(3));
currentPathPoint.set_location(new_musAttachLocCoords_v3);
end
elseif strcmp(curr_pathpoint_class, 'MovingPathPoint')
currentPathPoint = MovingPathPoint.safeDownCast(currentPathPointSet.get(n_p));
%disp('Function on MovingPathPoint not supported. Please extend the bone deformation tool.')
%continue
% extract the pqthpoints
px = currentPathPoint.get_x_location();
py = currentPathPoint.get_y_location();
pz = currentPathPoint.get_z_location();
% extract functions
fx = SimmSpline.safeDownCast(px);
fy = SimmSpline.safeDownCast(py);
fz = SimmSpline.safeDownCast(pz);
coord_set = {'x','y','z'};
for nc=1:3
cur_coord = coord_set{nc};
% extract joint angles (x) from coordinate of interest
eval(['Np = f',cur_coord,'.getX.getSize();']);
eval(['Xpoints = f',cur_coord,'.getX();']);
for np=0:Np-1
% curr joint angle
cur_angle = Xpoints.get(np);
% compute point coordinates at that joint angle
Px = fx.calcValue(Vector(1,cur_angle));
Py = fy.calcValue(Vector(1,cur_angle));
Pz = fz.calcValue(Vector(1,cur_angle));
% build a point
musAttachLocCoords = [Px, Py, Pz];
% compute torsion metric for the attachment point
TorsRotMat = RotMat(torsion_angle_func_rad(musAttachLocCoords(axis_ind)));
% compute new muscle attachment coordinates
new_musAttachLocCoords = (TorsRotMat*musAttachLocCoords')';%musCoord * M'
% assign to spline
eval(['f',cur_coord,'.setY(np, new_musAttachLocCoords(nc));']);
end
end
end
end
end
end
disp(['Processed ', num2str(ntm-1), ' muscles:'])
print_str = '';
for nd = 1:length(processed_muscles)
if mod(nd, round((ntm-1)/2))==0
disp(print_str);
print_str = '';
end
print_str = [print_str, processed_muscles{nd}, ' '];
end
% remaining muscles
print_str = [print_str, processed_muscles{nd}, ' '];
end