Another question, How do I properly use the Gyro sensor


#1

So I’ve been trying to program the gyro sensor looking at other peoples code and stuff to see what I did wrong and I cant find out what I did wrong, it just continuously spins and never stops. Please help

//Gyro Turning Clockwise
void GyroTurnCW (float DegreeAmount, int veloc)
{
    //Set speeds of both Drive motors
    LeftDrive.setVelocity(veloc,velocityUnits::pct);
    RightDrive.setVelocity(veloc,velocityUnits::pct);
    
    //Switches between degrees and hundreths of degrees
    float GyroDegrees;
    (GyroDegrees) = (DegreeAmount * 100);
    
    //While loop to do the spin
    while (Gyroo.value(rotationUnits::deg) <= GyroDegrees)
    {
       LeftDrive.spin(directionType::rev); // Assuming this is the polarity needed for a clockwise turn
       RightDrive.spin(directionType::rev);
    }
    
    //Stop motors after reached degree turn
    LeftDrive.stop();
    RightDrive.stop();
}


#2

Also I know I’m supposed to calibrate it but I am unaware how to do that in VCS.


#3

Don’t worry about calibration for now, we do that every time you run your program so just make sure the robot is still for 1 second after you hit run.

Gyro value is returned as a floating point number in degrees so no need to rescale DegreeAmount

positive values returned from the gyro should match the arrow printed on the gyro sensor which is generally turning to the right (clockwise)


#4

Even with the vex::task::sleep(1000); it still just continuously spins. Is the function solid like should it work because at the moment it just continuously spins.


#5

spinning clockwise ? did you make changes to GyroDegrees ? print on the screen the value returned by the gyro so you can debug.


#6

I did that and it printed 9000, because doesn’t the gyro get values in 100th of degrees?


#7

No, gyro returns as double in degrees. So 23 degrees should be 23.0. Let me drag one out and check it.


#8

Oh ok that explains why it spins forever lol


Yaw rate gyroscope problem
#9

Tested this, works fine. (ignore the device instances, you would do that in VCS config page)


motor mleft(vex::PORT3);
motor mright(vex::PORT4, true );
gyro  Gyro( Brain.ThreeWirePort.E );

int main() {
  int count = 0;
  
  // wait for calibration to finish, usually 1 second
  while( Gyro.isCalibrating() )
    task::sleep(100);
  
  
  while( Gyro.value( rotationUnits::deg ) < 90.0 ) {
    Brain.Screen.printAt( 10, 50, "Gyro %f", Gyro.value( rotationUnits::deg ) );
    mleft.spin( directionType::fwd, 50, velocityUnits::rpm );  
    mright.spin( directionType::rev, 50, velocityUnits::rpm );  

    this_thread::sleep_for(10);
  }

  mleft.stop();
  mright.stop();
}

#10

@jpearman So I was not able to test it, but I’m assuming this should work and turn 90 degrees correct?

//Gyro Turning Clockwise
void GyroTurnCW (double DegreeAmount, int veloc)
{
    //Set speeds of both Drive motors
    LeftDrive.setVelocity(veloc,velocityUnits::pct);
    RightDrive.setVelocity(veloc,velocityUnits::pct);
    
    //Prints the DegreeAmount for debugging puroses to ensure that it is going for the right degree amount
    Controller1.Screen.clearScreen();
    Controller1.Screen.print(DegreeAmount);
    
    //While loop to do the spin
    while (Gyroo.value(rotationUnits::deg) <= DegreeAmount)
    {
        LeftDrive.spin(directionType::fwd); // Assuming this is the polarity needed for a clockwise turn
        RightDrive.spin(directionType::rev);
        
        this_thread::sleep_for(10);
    }
    
    //Stop motors after reached degree turn
    LeftDrive.stop();
    RightDrive.stop();
    
    Controller1.Screen.clearScreen();
    Controller1.Screen.print("Gyro Turn Finished");
}
void autonomous( void ) {
  // ..........................................................................
  // Insert autonomous user code here.
  // ..........................................................................
    int FullSpeed = 100;
    int ThreeFourthsSpeed = 75; 
    int HalfSpeed = 50;
    int FourthSpeed = 25;
    
    while (Gyroo.isCalibrating())
    {
        task::sleep(100);
    }
    
    vex::task::sleep(1500);

    //Test of GyroTurnCW
    GyroTurnCW (90,FourthSpeed); //Should rotate counter clockwise for 90 degrees at 25%

#11

Looks ok to me assuming motors are setup correctly in robot config. I assume “Gyroo” was what the Gyro sensor is called in config.


#12

Yes I did that because earlier I messed up something in my code but it has been fixed and I just haven’t gone back and changed it to “Gyro”


#13

@jpearman Thank you for the help!


#14

may I ask you question? Is there a way to clear the gyro like in robotic? Somrthing like setting gyro to 0.I have been looking through the help page and can’t seem to find any function other than getting the current value :frowning: and seems like the value range of the gyro is from -180 to 180 so when I add value to it it will overfill after for say two turns.


#15

So I was looking at other threads mainly this one Encoder Ticks for V5 which showed how you clear the motor encoder. I looked through the command reference and found vex::gyro.startCalibration . Although this is in C++ Pro would it not still work for the Vex C++? (I haven’t had a chance to test it yet)


#16

Gyro.startCalibration() starts the calibration of the the gyro, and requires the robot to be perfectly still for ~1 or 2 seconds, so it’s not a realistic option for resetting the gyro in the competition. In practice the best method seems to be taking the current reading, and then adding a new target value and waiting until the gyro reaches that value, or something along the lines of that.


#17

That’s what we’ve been doing but it’s been finicky and for whatever reason after we reach 360 it won’t turn anymore. So I was hoping there would be a true reset command without requiring 2 to 3 seconds of stillness.


#18

There’s no way to clear the gyro (IIRC). The gyro returns values in the range +/- 3600. When it reaches either end it will roll over, for example, it would roll over from 3599 to 0. You can write code to allow absolute gyro values and perform reset, but that code would be written on top of the provided API, I believe this was true for ROBOTC also (this gyro class was written to more or less mimic ROBOTC).

edit: you can recalibrate the gyro, but as others have said, the robot needs to be stationary during that time.


#19

Back in robotc because I don’t need it to be cumulative I would just give the gyro value of 0 before my turn and start from there. The problem in c++ is there doesn’t seem to be a function to set the value for gyro