-
Notifications
You must be signed in to change notification settings - Fork 67
/
prepareVisualization.m
202 lines (178 loc) · 8.73 KB
/
prepareVisualization.m
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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
function [Visualizer,Objects]=prepareVisualization(KinDynModel,meshFilePrefix,varargin)
% Creates the figures, loads the meshes, handles some visual effects, and creates the transform objects
% - Inputs:
% - `KinDynModel` : iDyntreewrappers main variable. Contains the model.
% - `meshFilePrefix` : Path in which we can find the meshes. As an example the path to the mesh in a iCub urdf is `'package://iCub/meshes/simmechanics/sim_sea_2-5_root_link_prt-binary.stl'
% `. `meshFilePrefix` should replace package to allow to find the rest of the path. If the value is "", the standard iDynTree workflow of locating the mesh via the ExternalMesh.getFileLocationOnLocalFileSystem method is used.
% - Optional Inputs:
% - `view` : Selects the angle in which the figure is seen.
% - `material` : Selects effect with which the patch is rendered. Options are : 'dull','metal','shiny';
% - `debug` : Enables having extra information for debugging purposes.
% - `groundOn` : Enables showing a plane as the ground.
% - `groundColor` : Selects the color of the ground.
% - `groundTransparency` : Selects the transparency of the ground.
% - `groundFrame` : Selects the frame in which the ground is attached.
% - `name` : The name of the figure
% - `reuseFigure` : Enable the reuse of an already open figure. It can be the following values:
% - 'name': Reuse the figure with the same name (the figure is cleared before reusing it). The name must be set.
% - 'gcf': Reuse the figure returned by gcf.
% - 'none': Do not reuse the figure (Default).
% Note: all extra variables are sent to `plotMeshInWorld`
% - Outputs:
% - `Visualizer` : Struct containing the following fields
% - `transforms` : Is the transform objects array. There is one transform for each link
% - `linkNames` : The name of the links in the same order of the transforms
% - `linkNames_idyn` : The idyntree string vector equivalent to `linkNames`
% - `NOBJ` : Contains the number of visual objects in the visualizer
% - `meshHandles` : Has the handles of the mesh objects.
% - `parent` : Contains the axes object of the parent figure.
% - `mainHandler`: Is the handle of the overall figure.
% - `DEBUG` : Flag stating if the debug mode was set or not.
% Fields included if debug mode is on:
% - `map` : Cell array having both the names of the meshes and the associated link
% - `linkMeshInfo` : Contains the link name and a struct (meshInfo) that contains the name of file or if is a simple geometry, the triangulation ( edges and vertices of the mesh ) and the link to geometry transform.% Author : Francisco Andrade ([email protected])
%
% SPDX-FileCopyrightText: Fondazione Istituto Italiano di Tecnologia (IIT)
% SPDX-License-Identifier: BSD-3-Clause
%% input parser section
p = inputParser;
p.StructExpand = false;
p.KeepUnmatched= true;
% Default values
default_view=[128.0181 16.8000];
default_material='dull';
default_debug=false;
default_groundOn=false;
default_groundColor=[0 0.5 0.5];
default_groundTransparency=0.8;
default_groundFrame='none';
default_name='iDynTreeVisualizer';
default_reuseFigure='none';
% accepted values
expected_materials={'dull','metal','shiny'};
expected_reuseFigure={'name', 'gcf', 'none'};
% add parameters and validity funcitons
addRequired(p,'structInput');
addRequired(p,'meshFilePrefix',@(x) isstring(x) || ischar(x));
addParameter(p,'view',default_view,@isnumeric);
addParameter(p,'material',default_material,@(x) any(validatestring(x,expected_materials)));
addParameter(p,'debug',default_debug,@(x) islogical(x));
addParameter(p,'groundOn',default_groundOn,@(x) islogical(x));
addParameter(p,'groundColor',default_groundColor,@(x)validateattributes(x,{'numeric'},{'numel', 3}));
addParameter(p,'groundTransparency',default_groundTransparency,@(x) isnumeric(x) && isscalar(x));
addParameter(p,'groundFrame',default_groundFrame,@(x) isstring(x) || ischar(x));
addParameter(p,'name',default_name,@(x) isstring(x) || ischar(x));
addParameter(p,'reuseFigure',default_reuseFigure,@(x) any(validatestring(x,expected_reuseFigure)));
% Parse inputs
parse(p,KinDynModel,meshFilePrefix,varargin{:});
options = p.Results;
isNameSet = ~any(strcmp(p.UsingDefaults, 'name'));
%% Get meshes from the model variable
model = KinDynModel.kinDynComp.model;
[linkMeshInfo,map] = iDynTreeWrappers.getMeshes(model,meshFilePrefix);
numberOfLinks = length(linkMeshInfo);
linkNames = cell(numberOfLinks,1);
switch options.reuseFigure
case 'gcf'
mainHandler = gcf;
cla(mainHandler.Children);
case 'name'
figHandles = findobj('Type', 'figure', 'Name', options.name);
if isNameSet && ~isempty(figHandles)
mainHandler = figHandles(1,1);
cla(mainHandler.Children);
else
mainHandler = figure;
end
otherwise
mainHandler = figure;
end
if isNameSet
set(mainHandler,'Name', options.name,'numbertitle','off')
end
% Set the figure as current figure such that gca works
set(0, 'CurrentFigure', mainHandler)
parent = gca;
hold on
linkNames_idyn = iDynTree.StringVector();
for it=1:numberOfLinks
w_H_link = iDynTreeWrappers.getWorldTransform(KinDynModel,linkMeshInfo(it).linkName);
[meshHandles(it,:),transforms(it)] = iDynTreeWrappers.plotMeshInWorld(linkMeshInfo(it),w_H_link,varargin{:});
linkNames{it} = linkMeshInfo(it).linkName;
linkNames_idyn.push_back(linkNames{it});
end
% Add a camera light, and tone down the specular highlighting
camlight('headlight');
material(options.material);
% Make axis pretty and add grid for visual reference
axis equal;
axis tight;
grid on;
% Apply views
view(parent,options.view);
% Add world reference frame
hold on;
currentAxisValues=axis;
axisRange=currentAxisValues([2,4,6])-currentAxisValues([1,3,5]);
frameAxisSize = min(axisRange)/4;
% linewidth value 1 = to 0.35mm. It is better if we increase the linewidth
% in proportion to the axisSize of the frame.c
linewidthSize=frameAxisSize*50;
iDynTreeWrappers.plotFrame(eye(4), frameAxisSize, linewidthSize);
% Axis labels
title('Robot Visualizer ');
xlabel('{x}');
ylabel('{y}');
zlabel('{z}');
% Draw the ground
if options.groundOn
% Create plane on x-y axis
normal_vector = [0,0,1];
point_on_plane = [0,0,0];
d = normal_vector*point_on_plane';
x = [1 -1 -1 1]*max(axisRange(1:2)); % Generate data for x vertices
y = [1 1 -1 -1]*max(axisRange(1:2)); % Generate data for y vertices
z = 1/normal_vector(3)*(normal_vector(1)*x + normal_vector(2)*y + d); % Solve for z vertices data
groundHandle = patch('XData',x,'YData',y,'ZData',z,'FaceColor', options.groundColor);
alpha(groundHandle,options.groundTransparency);
% apply transform
groundTransform = hgtransform('Parent',parent);
set(groundHandle,'Parent',groundTransform);
if any(ismember(p.UsingDefaults,'groundFrame'))
w_H_plane = eye(4,4);
options.groundFrame = linkNames{1};
else
w_H_plane_idyn = KinDynModel.kinDynComp.getWorldTransform(options.groundFrame);
w_H_plane = w_H_plane_idyn.asHomogeneousTransform.toMatlab();
w_H_plane(1:2,4) = 0;
end
set(groundTransform,'Matrix',w_H_plane);
objectFrames_idyn = iDynTree.StringVector();
objectFrames_idyn.push_back(options.groundFrame);
% Build Object struct
Objects.frames_idyn = objectFrames_idyn;
Objects.transform = groundTransform;
Objects.frames = options.groundFrame;
Objects.types = {'plane'};
Objects.names = {'ground'};
Objects.handle = groundHandle;
if options.debug
Objects.map = [Objects.names',Objects.frames'];
end
else
Objects=[];
end
% Build Output struct
Visualizer.transforms = transforms;
Visualizer.linkNames_idyn = linkNames_idyn;
Visualizer.linkNames = linkNames;
Visualizer.NOBJ = length(transforms);
Visualizer.meshHandles = meshHandles;
Visualizer.mainHandler = mainHandler;
Visualizer.parent = parent;
Visualizer.DEBUG = options.debug;
if options.debug
Visualizer.map = map;
Visualizer.linkMeshInfo = linkMeshInfo;
end
end