OpenSimulationInterface / open-simulation-interface

A generic interface for the environmental perception of automated driving functions in virtual scenarios.
Other
267 stars 125 forks source link

Matrix order in definition of Euler Angles is wrong #495

Open joullsson opened 3 years ago

joullsson commented 3 years ago

Describe the bug

In https://opensimulationinterface.github.io/osi-documentation/open-simulation-interface/structosi3_1_1Orientation3d.html there are two different issues

Describe the expected behavior

The expected behavior can simply be taken from wikipedia https://de.wikipedia.org/wiki/Eulersche_Winkel#Roll-,_Nick-_und_Gierwinkel:_z-y%E2%80%B2-x%E2%80%B3-Konvention. This means that

joullsson commented 3 years ago

Since I wasn't able to create a branch as a non-member here is the PR from my fork https://github.com/OpenSimulationInterface/open-simulation-interface/pull/496

jola6897 commented 3 years ago

The order of rotation is correct. ISO specifies z-y'-x'' This means yaw first, pitch second, roll last. Rotation of a vector p is done by multiplying the rotation matrix from the left side e.g. R * p. That is why the right most rotation has to be yaw.

For euler angles there are a lot of different conventions ISO 8855 is basically equivalent to what Wikipedia refers to as intrinsic Tait-Bryan-Angles. You can find them in the wikipedia article you linked their equation is given by R_GNR^T in the section Roll-, Nick- und Gierwinkel: z-y′-x″-Konvention. You can see here that the order is indeed R{yaw,pitch,roll} = R{roll} R_{pitch} R_{yaw}.

For the ranges I agree that pitch shall be limited to [-pi/2,pi/2] to make the rotation unique.

joullsson commented 3 years ago

Hi Jonas, thanks for considering this issue and for the detailed answer!

As you have said. ISO specifies z-y'-x'' and in the standard it is also described what this means: it means that first, the vector p is rotated around the z-axis. This results in a rotated intermediate frame with new x and y- axes. The rotated y- axis is called y'. Then second rotation for pitch then is performed with respect to this intermediate axis y'. This clearly creates another x-axis which is called x''. The final roll rotation is performed around this x'' axis, resulting in the vehicle frame.

The procedure described above is referred to as the intrinsic rotations, as you have correctly pointed out. For intrinsic rotations however, the reasoning "from right to left" is not applicable. In fact, the order of rotation matrices is reversed for intrinsic rotations compared to simple extrinsic rotations, as is, e.g., explained in https://de.wikipedia.org/wiki/Eulersche_Winkel#Matrix-Herleitung_im_allgemeinen_Fall.

jola6897 commented 3 years ago

Following your detailed description of changing the axis this means:

  1. Starting in system with axis, x, y, z. A point here is p.
  2. yaw rotation in x, y, z to system x', y', z'. To transform p to a point p' in the new coordinate system, this would mean p' = R_{yaw} * p
  3. pitch rotation in x', y', z' to system x'', y'', z''. To transform p' to a point p'' in the new coordinate system, this would mean p'' = R_{pitch} * p'
  4. roll in x'', y'', z''. To get the final position R_{roll} * p''

You can look at it as incremental rotations and each transition between the coordinate system is quite clear. Now if you put it together: R{roll} * (R{pitch} (R_{yaw} p)) This gives you the order of rotation.

I think there is a misunderstanding as the chapter that you quoted describes how to get the intrinsic rotation from an EXTRINSIC rotation. Basically if you have angles as extrinsic their value will change when transforming them to intrinsic. This would mean your oder is correct if the values given are extrinsic but they should be intrinsic. This means

Does this resolve your question? Please let me know.

joullsson commented 3 years ago

Unfortunately this does not resolve the problem. First of all, I would like to get back to the wikipedia article, where it is clearly explicitly stated what is the correct order for Gier-Nick-Roll, for ISO8855 https://de.wikipedia.org/wiki/Eulersche_Winkel#Roll-,_Nick-_und_Gierwinkel:_z-y%E2%80%B2-x%E2%80%B3-Konvention. Please, simply read off R_GNR, the transposed one just adds more confusion.

But I agree that there is no derivation given in the article, therefore we can do it here if you like: Just consider an intrinsic rotation where you do yaw = pi/2 first and then you any pitch. After the yaw rotation, the new x'-axis of the vehicle clearly points in the direction of the y-axis of the world fixed frame, the one you started with. But if you now simply apply R{pitch}, you only rotate around the y-axis of the world fixed frame, which is not what you want to do. In fact, for an intrinsic rotation around y' you have to do a change of basis in the following way: R{pitch,y'} = R{yaw} R{pitch,y} R{yaw}^{T}. In this way we get p'' = R{yaw} R{pitch,y} R{yaw}^{T} R{yaw} p = R{yaw} R{pitch,y} p. Now for the last rotation you want to perform a roll in the double primed frame, that is, R{roll,x''} = R{yaw} R{pitch,y} R{roll,x} ( R{yaw} R{pitch,y})^{T} which gives you, after applying to p'', the desired result R{yaw} R{pitch,y} R{roll,x}.

jola6897 commented 3 years ago

Hi, I am very sorry, you are right. It has to be indeed R{yaw,pitch,roll} = R{yaw} R_{pitch} R_{roll}.

This means that the second equation in https://opensimulationinterface.github.io/osi-documentation/open-simulation-interface/structosi3_1_1Orientation3d.html is also wrong. It should read:

vector{gobal coord system} := Rotation{yaw, pitch, roll} * vector{local coord system} + local{origin}::position

Since the Rotation_{yaw, pitch, roll} rotates from local to global already and therefore the inverse is not needed. @joullsson do you also see it that way?

jdsika commented 3 years ago

I am having a litte "Déja vu" here as I think the disccusion came already up here. I was pretty confident we solved it correctly at that time?

joullsson commented 3 years ago

Hey, I do agree that it should read: vector{gobal coord system} := Rotation{yaw, pitch, roll} * vector{local coord system} + local{origin}::position I overlooked this one as well, good point!

Edit: I am not sure what the formatting is about, but local_{origin::position} would make more sense to me.

kmeids commented 3 years ago

Output from ArchitectureGroup Meeting 28.05.2021

  1. @joullsson Is this issue now solved or should we have a pull request to integrate your suggestion regarding "local_{origin::position} "
joullsson commented 3 years ago

Hey, from my side it is important to merge the PR https://github.com/OpenSimulationInterface/open-simulation-interface/pull/496 which correct the problems mentioned and settled here.