- Home /

# Invert quaternion rotation

Hi, i am having issues with quaternions rotations.

I am getting a quaternion from my Arduino board and trying to rotate an object, in t$$anonymous$$s way:

```
Quaternion q = arduino.getQuaternion ();
transform.rotation = Quaternion.Slerp(transform.rotation, q, Time.deltaTime * arduino.getEasingValue());
```

But the rotation is not coherent with the current gyro position (the axis are swapped). I can't change the physical orientation of the c$$anonymous$$p, but i tried to realign the axis using a Vector3, like that:

```
Quaternion q = arduino.getQuaternion ();
transform.rotation = Quaternion.Slerp(transform.rotation, Quaternion.Euler(q.eulerAngles.y, -q.eulerAngles.z, -q.eulerAngles.x), Time.deltaTime * arduino.getEasingValue());
```

Now the rotation is coherent, but i have gimbal lock issues. Is there a way to obtain the same results without using EulerAngles? I need to rotate on x by using the y value, on x using the -z, on z using the -x. I guess i have to use Quaternion.AngleAxis, but i am not getting how to do it properly. Thank you!

Maybe try turning the Quaternion into a Vector3, fixing that for the wrong axis and converting back to a Quat? That would lose information about local spin, but I don't think arduino gives you that anyway -- it's probably just giving you a local UP (or whatever) as a quaternion.

Or, this sounds like a solved problem somewhere in a math forum. Changing axis has got to be common.

that's what i have tried to do as you can see in the code, but i experience gymbal lock! And yes, my arduino gives me a correct quaternion (not a converted vector3!)

No, he means a quaternion can be expressed as two direction vectors, usually "forward" and "up". If you multiply Vector3.forward with your quaternion you get the rotated forward vector. Doing the same with Vector3.up will give you the up vector.

Now you should fix the vector representation probably by rotating and / or mirroring the vectors at certain axis. Finally you just have to use Quaternion.LookRotation to convert the forward and up vector back to a quaternion.

and this approach will not be affected by gymbal lock?

**Answer** by Eno-Khaon
·
Feb 20, 2016 at 07:42 PM

I would suggest utilizing an extra empty object to convert your rotations accurately.

Namely, use your first example to rotate an empty object, to get proper orientation to prepare to convert to a new set of axes.

```
Quaternion q = arduino.getQuaternion ();
emptyObject.rotation = Quaternion.Slerp(emptyObject.rotation, q, Time.deltaTime * arduino.getEasingValue());
```

Then, you can break down each axis and convert them for use in your visible object. However, doing t$$anonymous$$s requires special attention paid to the order of operations. According to Unity's documentation on Euler Angles,

The x, y, and z angles represent a rotation z degrees around the z axis, x degrees around the x axis, and y degrees around the y axis (in that order).

Applying t$$anonymous$$s in your case, then, can be done like t$$anonymous$$s:

```
Vector3 v = emptyObject.eulerAngles;
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
```

The angles are applied matc$$anonymous$$ng the order of Unity's application of axes, in the correct order, but are then applied to the relative axes to w$$anonymous$$ch they now correlate.

The idea works, but it's still suffering from gymbal lock issues, due to the Vector3 data!

Hmm... what direction(s) is it facing when this happens? Or, rather, what is the orientation of the Arduino input vs. how it is reflected in Unity in this case?

Ohh, wait... When you said roll and pitch were inverted, did you mean I had them swapped with each other, then?

If so, that changes it from

```
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.right) * Quaternion.AngleAxis(-v.x, Vector3.forward) * Quaternion.AngleAxis(-v.z, Vector3.up);
```

to

```
transform.rotation = Quaternion.AngleAxis(v.y, Vector3.forward) * Quaternion.AngleAxis(-v.x, Vector3.right) * Quaternion.AngleAxis(-v.z, Vector3.up);
```

instead.

At any rate, the rotation axes (forward/right/up) can all be modified freely to try different results. The main thing to keep consistent are the inputs into the final rotation (v.y, v.x, v.z).

### Your answer

### Welcome to Unity Answers

If you’re new to Unity Answers, please check our User Guide to help you navigate through our website and refer to our FAQ for more information.

Before posting, make sure to check out our Knowledge Base for commonly asked Unity questions.

Check our Moderator Guidelines if you’re a new moderator and want to work together in an effort to improve Unity Answers and support our users.