As said before you still want to retain the actual angles somewhere.
Depending on your physical configuration one of the Euler angle variants (Tait–Bryan angles is another term to search for) could perfectly describe your case and you could just use these to store the angles. Euler angles can also be converted to quaternion. But you can't recover the original used angles from the quaternion alone because of the 2pi wrapping of angles.
For others still wondering why quaternion or orientation alone won't suffice, here is a different example: Imagine an axis which can rotate more than only one revolution, i.e. can have angles like 4 pi, for example motorized volume knobs. An orientation alone can't represent that as it wraps the angles to 2pi. User manually turns the knob to two full revolutions (4pi) and then increases the value by remote control, which results in motorized knob to rotate. Should the knob turn back to nearly zero revolutions (rotate back 4pi) plus the increase? No, it should rotate to 4pi+increase.
By the way, when you have internally stored the "multi revolution" angle and have a sensor reading in range [0..2pi[ you can recover an multi revolution angle equivalent to the sensor reading with wrapToPiSeq( angle in radians before, sensor reading).
# to equivalent angle in [0,2pi[ range
def wrapTo2Pi(rad):
return rad % (2*pi)
# to equivalent angle in ]-pi,pi] range
def wrapToPi(rad):
return wrapTo2Pi(rad + pi) - pi
# angle difference between rad0 and rad1, in range ]-pi,pi]
def angleDiff(rad0, rad1):
r0 = wrapToPi(rad0)
r1 = wrapToPi(rad1)
return wrapToPi(r1-r0)
# rad1 to equivalent angle so the jump from rad0won't be greater than |PI|
def wrapToPiSeq(rad0, rad1):
r0 = wrapToPi(rad0)
r1 = wrapToPi(rad1)
diff = wrapToPi(r1-r0)
return rad0+diff