이 질문을 팔로우합니다.
- 팔로우하는 게시물 피드에서 업데이트를 확인할 수 있습니다.
- 정보 수신 기본 설정에 따라 이메일을 받을 수 있습니다.
Convert Quaternion to Euler angle extrinsically
조회 수: 77 (최근 30일)
이전 댓글 표시
Hello,
I need to convert my results which are stored as quaternions into euler representation. The quat2eul and quat2angle functions seem the same and both will convert quaternions to euler angles. However, it is stated that they use intrinsic calculation (AKA rotation is done around Z axis, then Y' axis, then X'' axis). I need to convert extrinsically. I do not want each rotation to be based on the newly rotated axis. Is there any function in matlab to do this?
댓글 수: 1
James Tursa
2024년 1월 25일
Please give an example of input and desired output. Maybe all you need to do is reorder.
채택된 답변
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
Intrinsic euler angles can be converted to extrinsic euler angles just be reversing their order.
EDIT: In other words, a Z-Y'-X'' intrinsic rotation by psi, theta, and phi is the same as an X-Y-Z extrinsic rotation by phi, theta, and psi.
댓글 수: 25
Paul
2024년 1월 25일
Hi Matt,
Suppose I have three, intrinsic Euler angles applied in Z-Y-X order. Call these angles psi, theta, and phi.
Are you saying that the direction cosine matrix that corresponds to these angles can be constructed as if from extrinsic angles by reversing the order of the intrinsic angles and using their numerical values?
Paul
2024년 1월 25일
편집: Paul
2024년 1월 25일
Let's try it.
Define the elemental, single-axis direction cosine matrices (DCMs).
Cx = @(x) angle2dcm(x,0,0,'XYZ');
Cy = @(y) angle2dcm(y,0,0,'YXZ');
Cz = @(z) angle2dcm(z,0,0,'ZYX');
Pick some angles and define the associated elemental DCMs
psi = pi/3; theta = pi/6; phi = pi/7;
Cpsi = Cz(psi);
Ctheta = Cy(theta);
Cphi = Cx(phi);
DCM assuming intrinsic angles.
Cintrinsic = Cphi*Ctheta*Cpsi
Cintrinsic = 3×3
0.4330 0.7500 -0.5000
-0.6718 0.6384 0.3758
0.6010 0.1732 0.7803
DCM assuming extrinsic angles, reverse the order, am I doing this correctly?
Cextrinsic = Cpsi*Ctheta*Cphi
Cextrinsic = 3×3
0.4330 0.8887 0.1505
-0.7500 0.2626 0.6071
0.5000 -0.3758 0.7803
They don't match.
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
I will demonstrate using the AxelRot function from this FEX download,
which let's you compute the DCM about an arbitrary 3D axis.
Let's first choose some arbitrary angles in degrees,
psi =30; theta = 50; phi = 70;
Extrinsic Computation
For an extrinsic X-Y-Z rotation we compute 1-step DCMs as follows,
[Rx,~]=AxelRot(phi,[1;0;0]);
[Ry,~]=AxelRot(theta,[0;1;0]);
[Rz,~]=AxelRot(psi,[0;0;1]);
and compose the total extrinsic rotation as,
Rextrinsic=Rz*Ry*Rx
Rextrinsic = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
Intrinisc Computation
For an intrinsic Z-Y'-X'' rotation, we first compute the rotation about Z by psi,
[Rz,~]=AxelRot(psi,[0,0,1]);
Now, we compute the rotation by theta about Y'. The Y' axis, however, is a rotation by Rz of the fixed y-axis. It corresponds to the second column of Rz. Therefore, the 1-step DCM is,
[Ryp,~]=AxelRot(theta, Rz(:,2));
Similarly, the final rotation requires that we know the X'' axis. The X'' axis is the transformation of the original x-axis over the course of the first two rotation steps, and therefore,
[Rxpp,~]=AxelRot(phi, Ryp*Rz*[1;0;0]);
The total intrinsic rotation can now be computed as,
Rintrinsic=Rxpp*Ryp*Rz
Rintrinsic = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
As you can see, the intrinsic and extrinsic DCM computations match quite well,
Rextrinsic-Rintrinsic
ans = 3×3
1.0e-15 *
-0.1110 -0.1110 -0.1110
-0.0555 -0.1110 0.1110
0.1110 -0.1110 0.0833
Frank Martin
2024년 1월 25일
Aren't extrinsic rotations alwasy the same regardless of the order performed?
So should I be using quat2eul('XYZ')?
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
Aren't extrinsic rotations alwasy the same regardless of the order performed?
No, both extrinsic and intrinsic rotation angles depend on the choice and order of the 1-step rotation axes.
So should I be using quat2eul('XYZ')?
Impossible to answer because you haven't said what euler angle representation you are looking for, other than that it be extrinsic. In general, however, any time you use quat2eul(), there will always be two possible ways to interpret the result.
In the case of eul=quat2eul(__,'XYZ'), this can be interpreted as an extrinsic rotation by eul(3) about Z, then eul(2) about Y, then eul(1) about X.
It can also be interpreted as an intrinsic rotation by eul(1) about X, then eul(2) about Y', then eul(3) about Z''.
Paul
2024년 1월 25일
편집: Paul
2024년 1월 25일
Matt,
I agree with your edit: "a Z-Y'-X'' intrinsic rotation by psi, theta, and phi is the same as an X-Y-Z extrinsic rotation by phi, theta, and psi."
At the risk of adding to the confusion, there's really two reversals happening.
1) For a given sequence of intrinsic angles, say Z-Y'-X'', the elemental DCMs are multiplied in reverse order as for a Z-Y-X sequence of extrinsic angles when forming the DCM.
2) Therefore, to get the same DCM, we also have to reverse the order of the rotations, e.g., to X-Y-Z for the extrinsic angles.
When I see a statement like "reverse the order of the angles," I feel like that's referring to how the the DCM is formed, i.e., item (1), but not accounting for the need to also reverse the sequence of rotations, i.e., item (2). Maybe I'm not reading that statement correctly.
When I read the OP's question it sounded to me like he wanted to convert from Z-Y'-X'' intrinsic to Z-Y-X extrinsic, though that wasn't stated explicitly.
Paul
2024년 1월 25일
Referring to this comment, would you mind attaching AxelRot.m to that comment and also putting a rng(100) command at the top of the code and rerunning (or rerunning with deterministic values)? I'm having trouble recreating those results.
Paul
2024년 1월 25일
편집: Paul
2024년 1월 25일
No, I didn't run with AxelRot.m from the file exchange. I wasn't sure if it would be appopriate to download it from there and then attach it to a comment here. I was trying to recreate what I thought AxelRot does, but was unsuccessful. Did you run that code in that comment here on Answers? If so, how did you do that without uploading AxelRot.m to that comment? Did you upload it, run, then delete the file attachment?
Is Rextrinsic a point rotation or a frame rotation?
If I want to use Rextrinsic to operate on a vector, would post-multiply Rextrinic by a column vector on the right (new = Rextrinsic*old(:)) or would I premultiply by a row vector on the left (new = old(:).' * Rextrinsic) ?
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
Did you upload it, run, then delete the file attachment?
Yes, I did. I don't like to have the availability of FEX files decentralized by attaching permanent copies to Matlab Answers posts.
If I had to guess, though, the discrepancy between your home-brewed implementation and AxelRot is that the discrete cosines in your DCMs are organized row-wise instead of column-wise.
Paul
2024년 1월 25일
Then I'm glad I didn't attach it myself.
I think I got is sorted out. Would you mind answering my additional questions in this comment? We were probably typing at the same time ....
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
Is Rextrinsic a point rotation or a frame rotation?
I'm not familiar with that terminolgy. Is one the tranpose of the other?
If I want to use Rextrinsic to operate on a vector, would post-multiply Rextrinic by a column vector on the right (new = Rextrinsic*old(:)) or would I premultiply by a row vector on the left (new = old(:).' * Rextrinsic) ?
All rotation matrices in my example follow the convention that column vectors are points to be rotated by pre-multiplication with R, i.e. new=R*old.
Bruno Luong
2024년 1월 25일
편집: Bruno Luong
2024년 1월 25일
Pick some angles and define the associated elemental DCMs
Cx = @(x) angle2dcm(x,0,0,'XYZ');
Cy = @(y) angle2dcm(y,0,0,'YXZ');
Cz = @(z) angle2dcm(z,0,0,'ZYX');
psi = pi/3; theta = pi/6; phi = pi/7;
Cpsi = Cz(psi);
Ctheta = Cy(theta);
Cphi = Cx(phi);
DCM assuming intrinsic angles.
Cintrinsic = Cphi*Ctheta*Cpsi
Cintrinsic = 3×3
0.4330 0.7500 -0.5000
-0.6718 0.6384 0.3758
0.6010 0.1732 0.7803
% Bruno add
eul2rotm(-[phi theta psi], "XYZ") % intrinsic
ans = 3×3
0.4330 0.7500 -0.5000
-0.6718 0.6384 0.3758
0.6010 0.1732 0.7803
DCM assuming extrinsic angles, reverse the order, am I doing this correctly?
Cextrinsic = Cpsi*Ctheta*Cphi
Cextrinsic = 3×3
0.4330 0.8887 0.1505
-0.7500 0.2626 0.6071
0.5000 -0.3758 0.7803
% Bruno add
eul2rotm(-[psi theta phi], "ZYX") % intrinsic
ans = 3×3
0.4330 0.8887 0.1505
-0.7500 0.2626 0.6071
0.5000 -0.3758 0.7803
They don't match.
The first you compute Cintrinsic is intrinsic 'XYZ'
The second you compute Cextrinsic is actually intrinsic 'ZYX'; so it is normal they don't match
The correct extrinsic 'zyx' is actually
Cextrinsic_correct = Cphi*Ctheta*Cpsi
Cextrinsic_correct = 3×3
0.4330 0.7500 -0.5000
-0.6718 0.6384 0.3758
0.6010 0.1732 0.7803
which is equal to intrinsic 'XYZ', Cintrinsic
Bruno Luong
2024년 1월 25일
편집: Bruno Luong
2024년 1월 25일
"Is Rextrinsic a point rotation or a frame rotation?
I'm not familiar with that terminolgy. Is one the tranpose of the other?"
The terminogy seems to be in MATLAB quaternion function (PF argument). They are related in this way, if you reverse the sign of euler angle (inverse, transpose the rotation), you will get the conjugate quaternions to each other:
E = rand(1,3)*2*pi;
qF = quaternion(E, "euler","XYZ", "frame")
qF = quaternion
-0.51753 + 0.59469i + 0.30175j - 0.53614k
qP = quaternion(-E, "euler", "XYZ", "point")
qP = quaternion
-0.51753 - 0.59469i - 0.30175j + 0.53614k
norm(conj(qP)-qF)
ans = 1.9230e-16
I interpret it as if you consider the rotation is frame rotated by a rigid body (robot arm, airplane), the world coordinates of extrinsic objects in the new (intrinsic) frame, in which case the inverse of the rotation matrix is to be multiplied with the wod coordinates to get the intrinsic coordinates.
Paul
2024년 1월 25일
I'm following up on this comment
"All rotation matrices in my example follow the convention that column vectors are points to be rotated by pre-multiplication with R, i.e. new=R*old."
I'm going to ask some basic questions to make sure I'm crystal clear on what you're doing.
Suppose I define Rx and Rz using AxelRot as follows:
[Rx,~] = AxelRot(phi, [1,0,0]);
[Rz,~] = AxelRot(psi, [0,0,1]);
Now, I have a point in space, call it P1. The coordinates of P1 in the World frame, or W-frame, are
p1 = [p1x; p1y; p1z];
I pre-multiply p1 by Rx and call the result p2
p2 = Rx*p1;
My understanding is that the point in space represented by p2, call it P2, is NOT the same point as P1, i.e., they are two distinct points in space (assuming phi ~= 0 of course), and that the elements of p2 are the coordinates of P2 resolved in the W-frame. Correct?
If so, my understanding is that P2 is obtained by rotating P1 around the x-axis of the W-frame. Correct?
If so, then suppose my next operation is
p3 = Rz*p2;
Again, the point in space represented by p3, call it P3, is NOT the same point as P2, and the elements of p3 are the coordinates of P3 resolved in the W-Frame. Correct?
If so, around which axis is P2 rotated to arrive at P3?
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
If so, around which axis is P2 rotated to arrive at P3?
Around the world z-axis. All operations,
[R,~]=AxelRot(theta,w)
give a rotation matrix such that R*v rotates v by theta degrees about the world w-axis.
It may be important, though, to keep in mind that all of these things have dual interpretation. Rotating v around the axis w by theta is the same thing as finding the coordinates of v in a coordinate frame rotated by -theta about w.
Paul
2024년 1월 25일
Because you didn't say otherwise, I'll assume that you agree with all of my other assertions are correct, or, at least, valid interpretations.
" R*v rotates v by theta degrees about the world w-axis."
And R is a right handed rotation?
On this line
p3 = Rz*p2;
Is Rz acting as an intrinsic or extrinsic rotation?
Matt J
2024년 1월 25일
편집: Matt J
2024년 1월 25일
Because you didn't say otherwise, I'll assume that you agree with all of my other assertions are correct, or, at least, valid interpretations.
Yes, they were all valid.
And R is a right handed rotation?
Yes, you should see that det(R)=+1 in all of AxelRot's output.
Is Rz acting as an intrinsic or extrinsic rotation?
I don't know how concepts of intrinsic vs. extrinsic would apply to a single elementary rotation about the z-axis. Intrinsic and extrinsic has to do with how a non-elementary rotation decomposes into a sequence of simpler rotations.
Paul
2024년 1월 25일
The rotation of P1 to P3 is is decomposed into Rx and Rz
p3 = Rz*Rx*p1;
Is Rz acting as an intrinsic or extrinsic rotation?
Paul
2024년 1월 26일
편집: Paul
2024년 1월 26일
The 2023b documentation has improved a little bit (still far from really good) that makes it (maybe?) possible to follow the breadcrumbs and figure out (which shouldn't be necessary if the doc is really well-written) what all these toolbox functions are doing.
Define three angles
psi = 30; theta = 50; phi = 70; euld = [psi theta phi];
Define a direction cosine matrix (DCM) using a ZYX sequence angle2dcm
rmat0 = angle2dcm(psi*pi/180,theta*pi/180,phi*pi/180,'ZYX')
rmat0 = 3×3
0.5567 0.3214 -0.7660
0.4524 0.6561 0.6040
0.6967 -0.6828 0.2198
According to angle2dcm, "The rotation angles represent a passive transformation from frame A to frame B. The resulting direction cosine matrix represents a series of right-hand intrinsic passive rotations from frame A to frame B." (emphasis added). I'm also pleased to note that the 2023b doc page is much improved over what I see in 2022a, which does not explicitly say that the rotations are intrinsic. Note that passive rotation is synonymous with frame rotation. Unfortunately, the doc page doesn't say if rmat0 should pre-multiply a Matlab column vector or post-multiply a Matlab row vector. We'll get that sorted out below.
Next, we follow the code in the Matlab tutorial "Rotations, Orientation, and Quaternions" in the section Other Rotation Representations. Important: "Note here, and throughout, the rotations around each axis are intrinsic"
"Build a quaternion from these Euler angles for the purpose of frame rotation" in a ZYX sequence.
qeuldframe = quaternion(euld, 'eulerd', 'ZYX', 'frame');
"This same rotation can be represented as a rotation matrix:" rotmat
rmat = rotmat(qeuldframe, 'frame')
rmat = 3×3
0.5567 0.3214 -0.7660
0.4524 0.6561 0.6040
0.6967 -0.6828 0.2198
rmat is the same as rmat0.
"To find the location of the point in the rotated reference frame, right-multiply rotmatFrame by the transposed array pt." pt is defined on that doc page as a row, so the frame rotation, rmat, is intended to pre-multiply a column, and therefore so is rmat0.
rmat2 = eul2rotm([psi theta phi]*pi/180,'ZYX')
rmat2 = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
rmat2 is the transpose of rmat0 and rmat. BUT, according to the doc page: "When using the rotation matrix, premultiply it with the coordinates to be rotated (as opposed to postmultiplying)." So if v is expressed in Matlab as a column vector then
v = [1;2;3];
(rmat*v).' == v.'*rmat2
ans = 1×3 logical array
0 0 0
From this, I conclude that rmat2 is also a frame rotation based on intrinsic angles in a ZYX sequence.
Finally, using the code I posted above:
Cx = @(x) angle2dcm(x,0,0,'XYZ');
Cy = @(y) angle2dcm(y,0,0,'YXZ');
Cz = @(z) angle2dcm(z,0,0,'ZYX');
Cpsi = Cz(psi*pi/180);
Ctheta = Cy(theta*pi/180);
Cphi = Cx(phi*pi/180);
Cintrinsic = Cphi*Ctheta*Cpsi
Cintrinsic = 3×3
0.5567 0.3214 -0.7660
0.4524 0.6561 0.6040
0.6967 -0.6828 0.2198
Cintrinsic matches rmat and rmat0, and the transpose of rmat2. As previously claimed in my upstream comment, Cintrinsic is formed from an intrinsic, ZYX sequence. It is a frame rotation intended to premultiply a column vector.
Given the coordinates of a vector resolved in starting frame, i.e., the parent frame, the frame rotation is used to define the coordinates of the same vector resolved in the rotated, or child frame.
v_resolved_in_child = Cintrinsic * v_resolved_in_parent
I'm certain that's what the doc page means when it says: ""To find the location of the point in the rotated reference frame ..."
Comment: because the rotations are intrinsic, it would be better to use the noation that @Matt J used and call them all Z-Y'-X'' to be clear that the second and third rotations are rotations from intermediate frames, but I've been using ZYX as that's the convention used for the input argument to all the the TMW functions used above.
As an aside, suppose I want to generate a frame rotation, but using extrinsic angles in a ZYX sequence. Here, the rotations are successively around the Z-, Y-, and X-axes all of the parent frame. Call the respective rotation angles alpha, beta, and gamma. With these angles, the frame rotation from the parent frame to the child frame is
Cextrinsic = Cz(gamma)*Cy(beta)*Cx(alpha)
If Cextrinsic is to equal Cintrinsic, i.e., represent the same frame rotation from parent to child, then it's clear that, in general, the triplet (gamma,beta,alpha) won't be numerically the same as (psi,theta,phi). This conclusion is exactly what I was attempting to illustrate by showing that
Cintrinsic ~= Cz(psi)*Cy(theta)*Cx(phi)
where the right hand side is what I misunderstood to be the meaning of "Intrinsic euler angles can be converted to extrinsic euler angles just by reversing their order." My misunderstanding of what @Matt J meant.
I don't think that extrinsic rotation angles are conceptually useful for frame rotations.
Anyway, moving on to a point rotation, which is also called an active rotation. Point Rotation shows how it differs from a frame rotation. A point rotation moves the point (or the tip of a vector) to a new location in the same coordinate frame. There is only one coordinate frame.
Given a quaternion, rotmat can compute the associated point rotation matrix. Starting with the quaternion derived previously
rotmatPoint = rotmat(qeuldframe,'point')
rotmatPoint = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
which is the transpose of the frame rotation matrix
rotmatPoint - rmat.'
ans = 3×3
0 0 0
0 0 0
0 0 0
which is consistent with the doc page statement: "The rotation matrix for point rotation is the transpose of the matrix for frame rotation."
The point rotation is applied by post-multiplying on the right, i.e.,
pt1 = rotmatPoint * (pt')
where pt1 is " the location of the rotated point (emphasis added)" as compared to multiplication by the frame rotation that finds the "location of the point in the rotated reference frame (emphasis added)"
Rotx = @(x) [1 0 0; 0 cosd(x) -sind(x); 0 sind(x) cosd(x)]; % [Rx,~] = AxelRot(x,[1 0 0])
Roty = @(y) [cosd(y) 0 sind(y); 0 1 0; -sind(y) 0 cosd(y)]; % [Ry,~] = AxelRot(y,[0 1 0])
Rotz = @(z) [cosd(z) -sind(z) 0; sind(z) cosd(z) 0; 0 0 1]; % [Rz,~] = AxelRot(z,[0 0 1])
Compute the elementary rotations for the three angles
Rx = Rotx(phi); %[Rx,~] = AxelRot(phi, ,[1;0;0]);
Ry = Roty(theta); %[Ry,~] = AxelRot(theta,[0;1;0]);
Rz = Rotz(psi); %[Rz,~] = AxelRot(psi ,[0;0;1]);
Compute the rotation matrix
Rextrinsic = Rz*Ry*Rx
Rextrinsic = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
We see the same result as rotmatPoint. As suggested by Matt's variable name and his statement above regarding interpretation of successive multiplication of AxelRot elementary rotations, the angles phi, theta, psi define extrinsic angles in an XYZ sequence to define a point rotation matrix that pre-multiples a column vector of coordinates of a point to compute coordinates of a new (i.e., rotated) point in the same coordinate frame.
I don't think that intrinsic rotation angles are conceptually useful for point rotations.
The last point (no pun intended) I'll make is that our point rotation matrix can be found by
rotmat(quaternion([phi theta psi], 'eulerd', 'XYZ', 'point'),'point')
ans = 3×3
0.5567 0.4524 0.6967
0.3214 0.6561 -0.6828
-0.7660 0.6040 0.2198
where I think that @Matt J and I agree that phi, theta, and psi are extrinsic rotations. If we are correct, that is in contrast to this comment. I wonder if that's the reason that quaternion doesn't say anything about whether or not the Euler angles on input are intrinsic or extrinsic. Maybe that distinction depends on the 'point' or 'frame' argument.
Bruno Luong
2024년 1월 26일
편집: Bruno Luong
2024년 1월 26일
A 3 x 3 rotation matrix has three binary attributes/usage/interpretation.
- intrinsic/extrinsic when the matrix is decomposed as product of 3 rotation matrix about basis axis
- frame/point
- At usage level: left multiplication with 1 x 3 row vector, right multiplication of 3 x 1 column vector of 3d coordinates
You can flip two (even) of the above attributes, the matrix remains the same.
If you flip one or three (odd) of the above attribute(s) the matrix becomes its transpose/inverse, So the euler decomposition flip the order.
Therefore if you don't specify two of those attributes, telling the remaning attribute as such or such is confusing, since it is NOT enough to specify the whole situation.
It is entirely up to user to understand and adapt to his/her usage.
From my understading when Matt claims "extrinsic" in his convention, the assumption of the other two attributes are
- point rotation with
- right multication by vector of (word) coordinates.
However I can also see it as "intrinsic" of frame rotation for example. Nothing contradicts with the claim by @Brian Fanous in this thread
Paul
2024년 1월 26일
In this line:
rotmat(quaternion([phi theta psi], 'eulerd', 'XYZ', 'point'),'point')
we've specified one of the attributes as a point rotation. The usage of rotmat in the doc page ""Rotations, Orientation, and Quaternions" all show (at least as I recall) the output of rotmat is intended for right-multiplication by a vector. Given those two attributes are specified, are the Euler angles in that line of code intrinsic or extrinsic?
Bruno Luong
2024년 1월 26일
편집: Bruno Luong
2024년 1월 26일
q = quaternion([phi theta psi], 'eulerd', 'XYZ', 'point') returns quaternion for extrinsic point rotation (usage right multiplication by column vector of coordinates or q*v*conj(q))
phi = rand()*360;
theta = rand()*360;
psi = rand()*360;
q = quaternion([phi theta psi], 'eulerd', 'XYZ', 'point')
q = quaternion
-0.52669 + 0.56213i - 0.22555j - 0.59644k
% q = conj(quaternion(-[phi theta psi], 'eulerd', 'XYZ', 'frame'))
R = rotmat(q,'point')
R = 3×3
0.1868 -0.8819 -0.4330
0.3747 -0.3435 0.8612
-0.9081 -0.3231 0.2663
% Check euler decomposition of R
Rx = makehgtform('xrotate', deg2rad(phi));
Ry = makehgtform('yrotate', deg2rad(theta));
Rz = makehgtform('zrotate', deg2rad(psi));
R = Rz*Ry*Rx; R = R(1:3,1:3)
R = 3×3
0.1868 -0.8819 -0.4330
0.3747 -0.3435 0.8612
-0.9081 -0.3231 0.2663
% Verify point rotation using R and q
P = randn(3,1); % random point
RP1 = R*P
RP1 = 3×1
-0.2398
1.4719
-0.3082
v = quaternion(0,P(1),P(2),P(3));
tmp = q*v*conj(q);
[a,b,c,d] = parts(tmp);
RP2 = [b; c; d]
RP2 = 3×1
-0.2398
1.4719
-0.3082
추가 답변 (2개)
Bruno Luong
2024년 1월 26일
편집: Bruno Luong
2024년 1월 26일
Here is the answer by MATLAB code: extrinsic angles is flip intrinsic angles
% Generate random unit quaternion
q = quaternion(randn, randn, randn, randn);
q = q ./ norm(q)
q = quaternion
-0.50199 - 0.41335i + 0.75491j + 0.085223k
Order = 'ZYX'
Order = 'ZYX'
Ei = quat2eul(q, Order) % Intrinsic Euler angle
Ei = 1×3
-1.7849 -0.7580 2.2956
% Extrinsic Euler angle, simply flip order then flip resulting angles
Ee = fliplr(quat2eul(q, fliplr(Order)))
Ee = 1×3
1.8498 -0.9762 2.6051
% The rotation matrix corresponds to q
R = rotmat(q, 'frame')
R = 3×3
-0.1543 -0.7096 0.6875
-0.5385 0.6438 0.5437
-0.8284 -0.2863 -0.4815
% Check intrinsic frame decomposition, revers angle sign because we deal
% with "frame" rotation type, basic rotation compatible with specified
% Order 'ZYX'
Riz = makehgtform('zrotate', -Ei(1));
Riy = makehgtform('yrotate', -Ei(2));
Rix = makehgtform('xrotate', -Ei(3));
Ri = Rix*Riy*Riz; Ri = Ri(1:3,1:3) % it must match R
Ri = 3×3
-0.1543 -0.7096 0.6875
-0.5385 0.6438 0.5437
-0.8284 -0.2863 -0.4815
norm(Ri-R) % or this must be very small
ans = 4.8438e-16
% Check extrinsic frame decomposition
Rez = makehgtform('zrotate', -Ee(1));
Rey = makehgtform('yrotate', -Ee(2));
Rex = makehgtform('xrotate', -Ee(3));
Re = Rez*Rey*Rex; Re = Re(1:3,1:3) % it must match R
Re = 3×3
-0.1543 -0.7096 0.6875
-0.5385 0.6438 0.5437
-0.8284 -0.2863 -0.4815
norm(Re-R) % or this must be very small
ans = 6.5414e-16
Paul
2024년 1월 25일
Hi Frank,
According to a comment in this answer, there appears to be no function in any toolbox that works with extrinsic Euler angles.
It's possible that new functionality has been added in the intervening time or that the commenter was unaware of such functionality at that time.
Also, keep in mind that participants with a Staff flair are not providing official TMW responses here on Answers.
참고 항목
카테고리
Help Center 및 File Exchange에서 6DOF에 대해 자세히 알아보기
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!오류 발생
페이지가 변경되었기 때문에 동작을 완료할 수 없습니다. 업데이트된 상태를 보려면 페이지를 다시 불러오십시오.
웹사이트 선택
번역된 콘텐츠를 보고 지역별 이벤트와 혜택을 살펴보려면 웹사이트를 선택하십시오. 현재 계신 지역에 따라 다음 웹사이트를 권장합니다:
또한 다음 목록에서 웹사이트를 선택하실 수도 있습니다.
사이트 성능 최적화 방법
최고의 사이트 성능을 위해 중국 사이트(중국어 또는 영어)를 선택하십시오. 현재 계신 지역에서는 다른 국가의 MathWorks 사이트 방문이 최적화되지 않았습니다.
미주
- América Latina (Español)
- Canada (English)
- United States (English)
유럽
- Belgium (English)
- Denmark (English)
- Deutschland (Deutsch)
- España (Español)
- Finland (English)
- France (Français)
- Ireland (English)
- Italia (Italiano)
- Luxembourg (English)
- Netherlands (English)
- Norway (English)
- Österreich (Deutsch)
- Portugal (English)
- Sweden (English)
- Switzerland
- United Kingdom (English)
아시아 태평양
- Australia (English)
- India (English)
- New Zealand (English)
- 中国
- 日本Japanese (日本語)
- 한국Korean (한국어)