Gyro for Turning?

We have the Grove 3 axis gyroscope and we're trying to use it to turn our robot a given number of degrees. For example, we want to tell the robot to turn 90 degrees and use the gyroscope to determine how far it has turned and when to stop turning.

The gyroscope is returning x, y, and z values as well as angular velocities for each axis, but when the robot stops turning, the gyroscrope x, y, and z values are reset to what they started at - they do not hold true relative to the position they started at.

How do we determine how far it has rotated with this gyroscope? The gyro is currently in the dead-center of our robot but we can of course move it if that would help. We are coming from the Vex gyroscope though, which holds the reading for relative position (if you rotate the robot 15 degrees clockwise, the gyroscope will keep returning 150, the degrees by a factor of 10, until you rotate it back to its relative starting position).

Thanks

The gyroscope is returning x, y, and z values as well as angular velocities for each axis,

Actually, the gyro returns only the x, y and z angular velocities, in degrees per second (with some scale factor). After calibration to remove drift, you need to integrate the rotation rates with respect to time to determine the total rotation.

Apart from the issues of magnetic noise from the motors and etc in the robot, I think you would be better off using a magnetometer or combined magnetometer and gyro etc

I'm using the MPU9150 and the RTImuLib and it gives quite stable and repeatable values for rotations in x y and z (albeit you only want the Z value)

However I have not confirmed how accurate the magnetometer in the MPU9150 actually is, e.g. To an external reference

You may like to read the thread that @jremminton has been helping me with, on the 3d maths to remove the gravity component of the accelerometer values from the MPU9150, as I'm now at a point where I need to calibrate the magnetometer (and the accelerometers) to give me much more accurate data.

I suspect that using the calibration procedure etc that @jremminton has described would give very accurate values for absolute rotation, I.e magnetic heading

jremington:

The gyroscope is returning x, y, and z values as well as angular velocities for each axis,

Actually, the gyro returns only the x, y and z angular velocities, in degrees per second (with some scale factor). After calibration to remove drift, you need to integrate the rotation rates with respect to time to determine the total rotation.

Well we can get back both the x, y, and z values, as well as the angular velocities, using the two different functions from the Grove library for the 3 axis gyro:

void getXYZ(int16_t *x,int16_t *y,int16_t *z);
void getAngularVelocity(float *ax,float *ay,float *az);

But as far as the angular velocities are concerned, we were trying calculate this...

void turn(int speed, int degrees) {

    float ax,ay,az;
    float temp = 0.0;
    
    while (temp < degrees) {
    
      gyro.getAngularVelocity(&ax,&ay,&az);
      Serial.print("Angular Velocity of X , Y , Z: ");
      Serial.print(ax);
      Serial.print(" , ");
      Serial.print(ay);
      Serial.print(" , ");
      Serial.print(az);
      Serial.println(" degrees per second");
      Serial.println("*************");
      Serial.println(temp);
      Serial.println("*************");

      ST.motor(rM, speed);
      ST.motor(lM, -speed);
    
      temp += abs(az) / (float)100;
      delay(10);
    
  }

  ST.motor(rM, 0);
  ST.motor(lM, 0);
}

Now one big issue was that, which temp += abs(az) / (float)100; every 10ms makes perfect sense to me, some experimenting proved that (if we feed the speed 65 to the robot) temp += abs(az) / (float)7; seems to get the robot to do a perfect 90 degree turn. It baffles me though how if the delay is for 10ms, and angular velocity is per second, why we would be dividing by 7 instead of by 100.

I believe we have the "idea" correct, but sample code and/or help with what's wrong with the code above would be very helpful.

Thanks

temp += abs(az) / (float)100;

This line does an approximate integration of the Z rotation rate, assuming a constant time step per loop interval, to get the total angle rotated. However, you should not use abs(). For a reasonably accurate integration, you must have the time step and scale of the gyro output data correct -- it is probably just happenstance that it worked in the one case.

I haven't looked at what the Grover library does, but the output scale for that gyro (the sensitivity) is 14.375 LSBs per °/sec,
so to get degrees/second, you have to divide the output data by 14.375.