You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

325 lines
9.2 KiB

%TRPLOT Draw a coordinate frame
%
% TRPLOT(T, OPTIONS) draws a 3D coordinate frame represented by the homogeneous
% transform T (4x4).
%
% H = TRPLOT(T, OPTIONS) as above but returns a handle.
%
% TRPLOT(H, T) moves the coordinate frame described by the handle H to
% the pose T (4x4).
%
% TRPLOT(R, OPTIONS) draws a 3D coordinate frame represented by the orthonormal
% rotation matrix R (3x3).
%
% H = TRPLOT(R, OPTIONS) as above but returns a handle.
%
% TRPLOT(H, R) moves the coordinate frame described by the handle H to
% the orientation R.
%
% Options::
% 'color',C The color to draw the axes, MATLAB colorspec C
% 'noaxes' Don't display axes on the plot
% 'axis',A Set dimensions of the MATLAB axes to A=[xmin xmax ymin ymax zmin zmax]
% 'frame',F The frame is named {F} and the subscript on the axis labels is F.
% 'text_opts', opt A cell array of MATLAB text properties
% 'handle',H Draw in the MATLAB axes specified by the axis handle H
% 'view',V Set plot view parameters V=[az el] angles, or 'auto'
% for view toward origin of coordinate frame
% 'arrow' Use arrows rather than line segments for the axes
% 'width', w Width of arrow tips (default 1)
% 'thick',t Thickness of lines (default 0.5)
% '3d' Plot in 3D using anaglyph graphics
% 'anaglyph',A Specify anaglyph colors for '3d' as 2 characters for
% left and right (default colors 'rc'):
% 'r' red
% 'g' green
% 'b' green
% 'c' cyan
% 'm' magenta
% 'dispar',D Disparity for 3d display (default 0.1)
%
% Examples::
%
% trplot(T, 'frame', 'A')
% trplot(T, 'frame', 'A', 'color', 'b')
% trplot(T1, 'frame', 'A', 'text_opts', {'FontSize', 10, 'FontWeight', 'bold'})
%
% h = trplot(T, 'frame', 'A', 'color', 'b');
% trplot(h, T2);
%
% 3D anaglyph plot
% trplot(T, '3d');
%
% Notes::
% - The arrow option requires the third party package arrow3.
% - The handle H is an hgtransform object.
% - When using the form TRPLOT(H, ...) the axes are not rescaled.
% - The '3d' option requires that the plot is viewed with anaglyph glasses.
% - You cannot specify 'color'
%
% See also TRPLOT2, TRANIMATE.
% Copyright (C) 1993-2011, by Peter I. Corke
%
% This file is part of The Robotics Toolbox for Matlab (RTB).
%
% RTB is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published by
% the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% RTB is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU Lesser General Public License for more details.
%
% You should have received a copy of the GNU Leser General Public License
% along with RTB. If not, see <http://www.gnu.org/licenses/>.
% TODO
% need to decide how to handle scaling
% what does hold on mean? don't touch scaling?
function hout = trplot(T, varargin)
if isscalar(T) && ishandle(T)
% trplot(H, T)
H = T; T = varargin{1};
if isrot(T)
T = r2t(T);
end
set(H, 'Matrix', T);
% for the 3D case retrieve the right hgtransform and set it
hg2 = get(H, 'UserData');
if ~isempty(hg2)
set(hg2, 'Matrix', T);
end
return;
end
if size(T,3) > 1
error('trplot cannot operate on a sequence');
end
if ~ishomog(T) && ~isrot(T)
error('trplot operates only on transform (4x4) or rotation matrix (3x3)');
end
opt.color = [];
opt.axes = true;
opt.axis = [];
opt.frame = [];
opt.text_opts = [];
opt.view = [];
opt.width = 1;
opt.arrow = false;
opt.handle = [];
opt.anaglyph = 'rc';
opt.d_3d = false;
opt.dispar = 0.1;
opt.thick = 0.5;
opt = tb_optparse(opt, varargin);
if ~isempty(opt.color) && opt.d_3d
error('cannot specify ''color'' and ''3d'', use ''anaglyph'' option');
end
if isempty(opt.color)
opt.color = 'b';
end
if isempty(opt.text_opts)
opt.text_opts = {};
end
if opt.d_3d
opt.color = ag_color(opt.anaglyph(1));
end
if isempty(opt.axis)
% determine some default axis dimensions
% get the origin of the frame
if isrot(T)
c = [0 0 0]; % at zero for a rotation matrix
else
c = transl(T);
end
d = 1.2;
opt.axis = [c(1)-d c(1)+d c(2)-d c(2)+d c(3)-d c(3)+d];
end
% TODO: should do the 2D case as well
if ~isempty(opt.handle)
hax = opt.handle;
hold(hax);
else
ih = ishold;
if ~ih
% if hold is not on, then clear the axes and set scaling
cla
if ~isempty(opt.axis)
axis(opt.axis);
end
daspect([1 1 1]);
if opt.axes
xlabel( 'X');
ylabel( 'Y');
zlabel( 'Z');
rotate3d on
end
new_plot = true;
end
hax = gca;
hold on
end
% hax is the handle for the axis we will work with, either new or
% passed by option 'handle'
opt.text_opts = [opt.text_opts, 'Color', opt.color];
hg = hgtransform('Parent', hax);
% trplot( Q.R, fmt, color);
if isrot(T)
T = r2t(T);
end
% create unit vectors
o = [0 0 0]';
x1 = [1 0 0]';
y1 = [0 1 0]';
z1 = [0 0 1]';
% draw the axes
mstart = [o o o]';
mend = [x1 y1 z1]';
if opt.arrow
% draw the 3 arrows
S = [opt.color num2str(opt.width)];
ha = arrow3(mstart, mend, S);
for h=ha'
set(h, 'Parent', hg);
end
else
for i=1:3
plot2([mstart(i,1:3); mend(i,1:3)], 'Color', opt.color, ...
'LineWidth', opt.thick, ...
'Parent', hg);
end
end
% label the axes
if isempty(opt.frame)
fmt = '%c';
else
fmt = sprintf('%%c_{%s}', opt.frame);
end
% add the labels to each axis
h = text(x1(1), x1(2), x1(3), sprintf(fmt, 'X'), 'Parent', hg);
set(h, opt.text_opts{:});
h = text(y1(1), y1(2), y1(3), sprintf(fmt, 'Y'), 'Parent', hg);
set(h, opt.text_opts{:});
h = text(z1(1), z1(2), z1(3), sprintf(fmt, 'Z'), 'Parent', hg);
set(h, opt.text_opts{:});
% label the frame
if ~isempty(opt.frame)
h = text(o(1)-0.04*x1(1), o(2)-0.04*y1(2), o(3)-0.04*z1(3), ...
['\{' opt.frame '\}'], 'Parent', hg);
set(h, 'VerticalAlignment', 'middle', ...
'HorizontalAlignment', 'center', opt.text_opts{:});
end
if ~opt.axes
set(gca, 'visible', 'off');
end
if ischar(opt.view) && strcmp(opt.view, 'auto')
cam = x1+y1+z1;
view(cam(1:3));
elseif ~isempty(opt.view)
view(opt.view);
end
if isempty(opt.handle) && ~ih
grid on
hold off
end
% now place the frame in the desired pose
set(hg, 'Matrix', T);
if opt.d_3d
% 3D display. The original axes are for the left eye, and we add
% another set of axes to the figure for the right eye view and
% displace its camera to the right of that of that for the left eye.
% Then we recursively call trplot() to create the right eye view.
left = gca;
right = axes;
% compute the offset in world coordinates
off = -t2r(view(left))'*[opt.dispar 0 0]';
pos = get(left, 'CameraPosition');
set(right, 'CameraPosition', pos+off');
set(right, 'CameraViewAngle', get(left, 'CameraViewAngle'));
set(right, 'CameraUpVector', get(left, 'CameraUpVector'));
target = get(left, 'CameraTarget');
set(right, 'CameraTarget', target+off');
% set perspective projections
set(left, 'Projection', 'perspective');
set(right, 'Projection', 'perspective');
% turn off axes for right view
set(right, 'Visible', 'Off');
% set color for right view
hg2 = trplot(T, 'color', ag_color(opt.anaglyph(2)));
% the hgtransform for the right view is user data for the left
% view hgtransform, we need to change both when we rotate the
% frame.
set(hg, 'UserData', hg2);
end
% optionally return the handle, for later modification of pose
if nargout > 0
hout = hg;
end
end
function out = ag_color(c)
% map color character to an color triple, same as anaglyph.m
% map single letter color codes to image planes
switch c
case 'r'
out = [1 0 0]; % red
case 'g'
out = [0 1 0]; % green
case 'b'
% blue
out = [0 0 1];
case 'c'
out = [0 1 1]; % cyan
case 'm'
out = [1 0 1]; % magenta
case 'o'
out = [1 1 0]; % orange
end
end