I have a gyroscope sensor that works in deg/s, I then integrate that value to get degrees. This works great, but I want the values to be constrained to -180 and 180 degrees (-Pi to Pi). When the value goes over 180 degrees, I want it to reset to -180 degrees, and when the value goes lower than -180 degrees, I want it to go back to 180.
Here is some sample code of what is happening right now.
axis_1 += gyro_data*gyro_time; //axis_1 is in degrees //gyro_data is in degrees per second
I thought about using an if statement:
if (axis_1 > 180) axis_1 = -180
if (axis_1 < -180) axis_1 = 180
But that would lose some of the information from the addition. If axis_1 = 179.8, and it adds 0.8, then axis_1 should be -179.6, not -180.
I also want the Arudino to calculate the error between the setpoint and the current state.
If axis_1 is at 10 degrees, and the setpoint is at 15. Then 15-10 = 5 degrees of error. But if axis_1 is at 175 degrees, and the setpoint is at 5 degrees. Then the error is 5-175 = -170, which is not true. It should be 10 degrees of error.
So you want the value to be whatever the number is greater than 180 degrees, so if the value is 184, you want it to be 4 (or 184-180 to state it mathematically). so just do that.
if (axis_1 > 180) axis_1 = axis_1 - 180
If your value can go past 360, then you basically want to keep subtracting 180 until it is in range, or:
while (axis_1 > 180) axis_1 = axis_1 - 180
You can also use shorthand notation by using the -= expression:
while (axis_1 > 180) axis_1 -= 180
and now do the same for the other side:
while (axis_1 > 180) axis_1 -= 180
while (axis_1 < -180) axis_1 += 180
You can also use the mod operator to prevent having to loop, but that only works for integers.
e.g. 184 % 180 = 4 and 364 % 180 = 4
TRex:
So you want the value to be whatever the number is greater than 180 degrees, so if the value is 184, you want it to be 4 (or 184-180 to state it mathematically). so just do that.
if (axis_1 > 180) axis_1 = axis_1 - 180
If your value can go past 360, then you basically want to keep subtracting 180 until it is in range, or:
while (axis_1 > 180) axis_1 = axis_1 - 180
You can also use shorthand notation by using the -= expression:
while (axis_1 > 180) axis_1 -= 180
and now do the same for the other side:
while (axis_1 > 180) axis_1 -= 180
while (axis_1 < -180) axis_1 += 180
You can also use the mod operator to prevent having to loop, but that only works for integers.
e.g. 184 % 180 = 4 and 364 % 180 = 4
for the range -180 to 180 degrees, I do not think that is entirely correct:
taking the value of 184 degress in @TRex example, the equivalent value for the range -180 to 180 degree would therefore be 184 -360 = -176 degree
so in effect, IMHO, the constraining rule should be
if (axis_1 > 180) axis_1 = axis_1 - 360;
and
if (axis_1 < -180) axis_1 = axis_1 + 360;
mschindl:
I also want the Arudino to calculate the error between the setpoint and the current state.
If axis_1 is at 10 degrees, and the setpoint is at 15. Then 15-10 = 5 degrees of error. But if axis_1 is at 175 degrees, and the setpoint is at 5 degrees. Then the error is 5-175 = -170, which is not true....
IMHO to be able to determing the error wrt to the setpoint you will also need to know the CURRENT direction of rotation (ie clockwise or counter-clockwise) in order to be able to evalute it correctly for the range -180 to 180 degrees.