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 this 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 chip, 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!

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 this 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 this in your case, then, can be done like this:

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 matching the order of Unity’s application of axes, in the correct order, but are then applied to the relative axes to which they now correlate.