%SE2 Representation of 2D rigid-body motion
%
% This subclasss of RTBPose is an object that represents rigid-body motion in 2D.
% Internally this is a 3×3 homogeneous transformation matrix (3×3) belonging to
% the group SE(2).
%
% Constructor methods::
% SE2 general constructor
% SE2.exp exponentiate an se(2) matrix
% SE2.rand random transformation
% new new SE2 object
%
% Display and print methods::
% animate ^graphically animate coordinate frame for pose
% display ^print the pose in human readable matrix form
% plot ^graphically display coordinate frame for pose
% print ^print the pose in single line format
%
% Group operations::
% * ^mtimes: multiplication (group operator, transform point)
% / ^mrdivide: multiply by inverse
% ^ ^mpower: exponentiate (integer only):
% inv inverse
% prod ^product of elements
%
% Methods::
% det determinant of matrix component
% eig eigenvalues of matrix component
% log logarithm of rotation matrix
% inv inverse
% simplify* apply symbolic simplication to all elements
% interp interpolate between poses
% theta rotation angle
%
% Information and test methods::
% dim ^returns 2
% isSE ^returns true
% issym ^test if rotation matrix has symbolic elements
% SE2.isa test if matrix is SE(2)
%
% Conversion methods::
% char* convert to human readable matrix as a string
% SE2.convert convert SE2 object or SE(2) matrix to SE2 object
% double convert to rotation matrix
% R convert to rotation matrix
% SE3 convert to SE3 object with zero translation
% SO2 convert rotational part to SO2 object
% T convert to homogeneous transformation matrix
% Twist convert to Twist object
% t get.t: convert to translation column vector
%
% Compatibility methods::
% isrot2 ^returns false
% ishomog2 ^returns true
% tr2rt ^convert to rotation matrix and translation vector
% t2r ^convert to rotation matrix
% transl2 ^translation as a row vector
% trprint2 ^print single line representation
% trplot2 ^plot coordinate frame
% tranimate2 ^animate coordinate frame
%
% ^ inherited from RTBPose class.
%
% See also SO2, SE3, RTBPose.
% Copyright (C) 1993-2019 Peter I. Corke
%
% This file is part of The Spatial Math Toolbox for MATLAB (SMTB).
%
% Permission is hereby granted, free of charge, to any person obtaining a copy
% of this software and associated documentation files (the “Software”), to deal
% in the Software without restriction, including without limitation the rights
% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
% of the Software, and to permit persons to whom the Software is furnished to do
% so, subject to the following conditions:
%
% The above copyright notice and this permission notice shall be included in all
% copies or substantial portions of the Software.
%
% THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
% FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
% COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
% IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%
% https://github.com/petercorke/spatial-math
% Copyright (C) 1993-2017, 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.petercorke.com
classdef SE2 < SO2
properties (Dependent = true)
t
end
methods
function obj = SE2(varargin)
%SE2.SE2 Construct an SE(2) object
%
% Constructs an SE(2) pose object that contains a 3×3 homogeneous transformation
% matrix.
%
% T = SE2() is the identity element, a null motion.
%
% T = SE2(X, Y) is an object representing pure translation defined by X and Y.
%
% T = SE2(XY) is an object representing pure translation defined by XY
% (2×1). If XY (Nx2) returns an array of SE2 objects, corresponding to
% the rows of XY.
%
% T = SE2(X, Y, THETA) is an object representing translation, X and Y, and
% rotation, angle THETA.
%
% T = SE2(XY, THETA) is an object representing translation, XY (2×1), and
% rotation, angle THETA.
%
% T = SE2(XYT) is an object representing translation, XYT(1) and XYT(2),
% and rotation angle XYT(3). If XYT (Nx3) returns an array of SE2 objects, corresponding to
% the rows of XYT.
%
% T = SE2(T) is an object representing translation and rotation defined by
% the SE(2) homogeneous transformation matrix T (3×3). If T (3x3xN) returns an
% array (1xN) of SE2 objects, corresponding to the third index of T.
%
% T = SE2(R) is an object representing pure rotation defined by the
% SO(2) rotation matrix R (2×2)
%
% T = SE2(R, XY) is an object representing rotation defined by the
% orthonormal rotation matrix R (2×2) and position given by XY (2×1)
%
% T = SE2(T) is a copy of the SE2 object T. If T (Nx1) returns an array of SE2 objects,
% corresponding to the index of T.
%
% Options::
% ‘deg’ Angle is specified in degrees
%
% Notes::
% – Arguments can be symbolic
% – The form SE2(XY) is ambiguous with SE2(R) if XY has 2 rows, the second form is assumed.
% – The form SE2(XYT) is ambiguous with SE2(T) if XYT has 3 rows, the second form is assumed.
% – R and T are checked to be valid SO(2) or SE(2) matrices.
opt.deg = false;
[opt,args] = tb_optparse(opt, varargin);
if opt.deg
scale = pi/180.0;
else
scale = 1;
end
% if any of the arguments is symbolic the result will be symbolic
if any( cellfun(@(x) isa(x, ‘sym’), args) )
obj.data = sym(obj.data);
end
obj.data = eye(3,3);
switch length(args)
case 0
% null motion
return
case 1
% 1 argument
a = args{1};
if isvec(a, 2)
% (t)
obj.data = [ 1 0 a(1); 0 1 a(2); 0 0 1];
elseif isvec(a, 3)
% ([x y th])
a = a(:);
obj.data(1:2,1:2) = rot2(a(3)*scale);
obj.t = a(1:2);
elseif SO2.isa(a)
% (R)
obj.data(1:2,1:2) = a;
elseif SE2.isa(a)
% (T)
for i=1:size(a, 3)
obj(i).data = a(:,:,i);
end
elseif isa(a, ‘SE2’)
% (SE2)
for i=1:length(a)
obj(i).data = a(i).data;
end
elseif any( numcols(a) == [2 3] )
for i=1:numrows(a)
obj(i) = SE2(a(i,:));
end
return
else
error(‘SMTB:SE2:badarg’, ‘unknown arguments’);
end
case 2
% 2 arguments
a = args{1}; b = args{2};
if isscalar(a) && isscalar(b)
% (x,y)
obj.data = [ 1 0 a; 0 1 b; 0 0 1];
elseif isvec(a,2) && isscalar(b)
% ([x y], th)
obj.data = [ rot2(b*scale) a(:); 0 0 1];
elseif SO2.isa(a) && isvec(b,2)
% (R, t)
obj.data = [a b(:); 0 0 1];
else
error(‘SMTB:SE3:badarg’, ‘unknown arguments’);
end
case 3
% 3 arguments
a = args{1}; b = args{2}; c = args{3};
if isscalar(a) && isscalar(b) && isscalar(c)
% (x, y, th)
obj.data = [ rot2(c*scale) [a b]’; 0 0 1];
else
error(‘SMTB:SE3:badarg’, ‘unknown arguments’);
end
otherwise
error(‘SMTB:SE3:badarg’, ‘unknown arguments’);
end
% add the last row if required
% if numrows(obj.data) == 2
% obj.data = [obj.data; 0 0 1];
% end
assert(all(size(obj(1).data) == [3 3]), ‘SMTB:SE2:SE2’, ‘created wrong size data element’);
%% HACK
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% GET AND SET
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function t = get.t(obj)
%SE2.t Get translational component
%
% P.t is a column vector (2×1) representing the translational component of
% the rigid-body motion described by the SE2 object P.
%
% Notes::
% – If P is a vector the result is a MATLAB comma separated list, in this
% case use P.transl().
%
% See also SE2.transl.
t = obj.data(1:2,3);
end
function o = set.t(obj, t)
%SE2.t Set translational component
%
% P.t = TV sets the translational component of the rigid-body motion
% described by the SE2 object P to TV (2×1).
%
% Notes::
% – TV can be a row or column vector.
% – If TV contains a symbolic value then the entire matrix becomes
% symbolic.
if isa(t, ‘sym’) && ~isa(obj.data, ‘sym’)
obj.data = sym(obj.data);
end
obj.data(1:2,3) = t;
o = obj;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% conversion methods
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function v = xyt(obj)
%SE2.xyt Extract configuration
%
% XYT = P.xyt() is a column vector (3×1) comprising the minimum three
% configuration parameters of this rigid-body motion: translation (x,y)
% and rotation theta.
% TODO VECTORISE
v = obj.t;
v(3) = atan2(obj.data(2,1), obj.data(1,1));
end
function [tx,ty] = transl(obj)
%SE2.t Get translational component
%
% TV = P.transl() is a row vector (1×2) representing the translational component of
% the rigid-body motion described by the SE2 object P. If P is a vector of
% objects (1xN) then TV (Nx2) will have one row per object element.
if nargout == 1 || nargout == 0
tx = [obj.t]’;
else
t = obj.t;
tx = t(1);
ty = t(2);
end
end
function T = T(obj)
%SE2.T Get homogeneous transformation matrix
%
% T = P.T() is the homogeneous transformation matrix (3×3) associated with the
% SE2 object P, and has zero translational component. If P is a vector
% (1xN) then T (3x3xN) is a stack of homogeneous transformation matrices, with the third
% dimension corresponding to the index of P.
%
% See also SO2.T.
for i=1:length(obj)
T(:,:,i) = obj(i).data;
end
end
function t = SE3(obj)
%SE2.SE3 Lift to 3D
%
% Q = P.SE3() is an SE3 object formed by lifting the rigid-body motion
% described by the SE2 object P from 2D to 3D. The rotation is about the
% z-axis, and the translation is within the xy-plane.
%
% See also SE3.
t = SE3();
t.data(1:2,1:2) = obj.data(1:2,1:2);
t.data(1:2,4) = obj.data(1:2,3);
end
function out = SO2(obj)
%SE2.SO2 Extract SO(2) rotation
%
% Q = SO2(P) is an SO2 object that represents the rotational component of
% the SE2 rigid-body motion.
%
% See also SE2.R.
out = SO2( obj.R );
end
function tw = Twist(obj)
%SE2.Twist Convert to Twist object
%
% TW = P.Twist() is the equivalent Twist object. The elements of the twist are the unique
% elements of the Lie algebra of the SE2 object P.
%
% See also SE2.log, Twist.
tw = Twist( obj.log );
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% SE(2) OPERATIONS
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function it = inv(obj)
%SE2.inv Inverse of SE2 object
%
% Q = inv(P) is the inverse of the SE2 object P.
%
% Notes::
% – This is formed explicitly, no matrix inverse required.
% – This is a group operator: input and output in the SE(2) group.
% – P*Q will be the identity group element (zero motion, identity matrix).
it = SE2( obj.R’, -obj.R’*obj.t);
end
function S = log(obj)
%SE2.log Lie algebra
%
% se2 = P.log() is the Lie algebra corresponding to the SE2 object P. It is
% an augmented skew-symmetric matrix (3×3).
%
% See also SE2.Twist, logm, skewa, vexa.
S = logm(obj.data);
end
function Ti = interp(obj1, varargin)
%SE2.interp Interpolate between SO2 objects
%
% P1.interp(P2, s) is an SE2 object which is an interpolation
% between poses represented by SE2 objects P1 and P2. s varies from 0
% (P1) to 1 (P2). If s is a vector (1xN) then the result will be a vector
% of SE2 objects.
%
% Notes::
% – It is an error if S is outside the interval 0 to 1.
%
% See also SO2.angle.
if isa(varargin{1}, ‘SE2’)
% interp(SE2, SE2, s) interpolate between given values
obj2 = varargin{1};
varargin = varargin(2:end);
try
Ti = SE2( trinterp2(obj1.T, obj2.T, varargin{:}) );
catch me
switch me.identifier
case ‘SMTB:trinterp2:badarg’
throw( MException(‘SMTB:SE2:interp:badarg’, ‘value of S outside interval [0,1]’) );
otherwise
rethrow(me);
end
end
else
% interp(SE2, s) interpolate between null and given value
try
Ti = SE2( trinterp2( obj1.T, varargin{:}) );
catch me
switch me.identifier
case ‘SMTB:trinterp2:badarg’
throw( MException(‘SMTB:SE2:interp:badarg’, ‘value of S outside interval [0,1]’) );
otherwise
rethrow(me);
end
end
end
end
function print(obj, varargin)
for T=obj
theta = atan2(T.data(2,1), T.data(1,1)) * 180/pi;
fprintf(‘t = (%.4g, %.4g), theta = %.4g deg\n’, T.t, theta);
end
end
function n = new(obj, varargin)
%SE2.new Construct a new object of the same type
%
% P2 = P.new(X) creates a new object of the same type as P, by invoking the SE2 constructor on the matrix
% X (3×3).
%
% P2 = P.new() as above but defines a null motion.
%
% Notes::
% – Serves as a dynamic constructor.
% – This method is polymorphic across all RTBPose derived classes, and
% allows easy creation of a new object of the same class as an existing
% one without needing to explicitly determine its type.
%
% See also SE3.new, SO3.new, SO2.new.
n = SE2(varargin{:});
end
end
methods (Static)
% Static factory methods for constructors from exotic representations
function obj = exp(s)
%SE2.exp Construct SE2 from Lie algebra
%
% SE2.exp(SIGMA) is the SE2 rigid-body motion corresponding to the se(2)
% Lie algebra element SIGMA (3×3).
%
% SE3.exp(TW) as above but the Lie algebra is represented
% as a twist vector TW (1×1).
%
% Notes::
% – TW is the non-zero elements of X.
%
% Reference::
% – Robotics, Vision & Control: Second Edition, P. Corke, Springer 2016; p25-31.
%
%
% See also trexp2, skewa.
obj = SE2( trexp2(s) );
end
function T = convert(tr)
%SE2.check Convert to SE2
%
% Q = SE2.convert(X) is an SE2 object equivalent to X where X is either
% an SE2 object, or an SE(2) homogeneous transformation matrix (3×3).
if isa(tr, ‘SE2’)
T = tr;
elseif SE2.isa(tr)
T = SE2(tr);
else
error(‘expecting an SE2 or 3×3 matrix’);
end
end
function h = isa(tr, rtest)
%SE2.ISA Test if matrix is SE(2)
%
% SE2.isa(T) is true (1) if the argument T is of dimension 3×3 or 3x3xN, else
% false (0).
%
% SE2.isa(T, true) as above, but also checks the validity of the rotation
% sub-matrix.
%
% Notes::
% – This is a class method.
% – The first form is a fast, but incomplete, test for a transform in SE(3).
% – There is ambiguity in the dimensions of SE2 and SO3 in matrix form.
%
% See also SO3.ISA, SE2.ISA, SO2.ISA, ishomog2.
d = size(tr);
if ndims(tr) >= 2
h = all(d(1:2) == [3 3]);
if h && nargin > 1 && ~isa(tr, ‘sym’)
h = SO3.isa( tr(1:2,1:2) );
h = h && all(tr(4,:) == [0 0 0 1]); % test the bottom row
end
else
h = false;
end
end
function T = rand()
%SE2.rand Construct a random SE(2) object
%
% SE2.rand() is an SE2 object with a uniform random translation and a
% uniform random orientation. Random numbers are in the interval [-1 1]
% and rotations in the interval [-pi pi].
%
% See also RAND.
T = SE2(rand(1,3)*diag([2 2 2*pi]) + [-1 -1 -pi]);
end
end
end
一键复制
编辑
Web IDE
原始数据
按行查看
历史