Linear Gyro PROS Coding Help

My team want’s to use the gyro to keep the base straight when driving.
I almost have it working except for turning, for that I figured I wanted the gyro to not reset when it gets to 360. This is what we have now. It’s a mess and only works as long as the gyro value is positive.

 int StoredPos = 0;
 int ActurlPos = 0;
 int CurrentPos = 0;
 while (true) {
   CurrentPos = (int(gyro.get_value()) / 10);
    if ((StoredPos - (int(gyro.get_value()) / 10)) > 345) {
      ActurlPos += 360 - StoredPos + (int(gyro.get_value()) / 10);
    }
    else {
      ActurlPos += (int(gyro.get_value()) / 10) - StoredPos;
    }
    printf("%d\n", ActurlPos);
    StoredPos = CurrentPos;
    pros::delay(200);
  }

There isn’t a good way to have the gyro value accumulate because just checking if the value jumped from round 360 to 0 could result in the value being off if the robot turns too fast. Since you said that you need to…

I would assume that you would need an error angle of how much to turn to get to the a target angle. This isn’t exactly what you asked for, but I think it would work better in this situation…

Easy to understand way

double targetAngle;
double errorAngle;

while(true)
{
    double gyroValue = gyro.get_value() / 10;

    errorAngle = targetAngle - gyroValue;
    while(errorAngle > 180) errorAngle -= 360;
    while(errorAngle < -180) errorAngle += 360;

    pros::delay(7);
}

Simply subtracting the current position from the target position will give you the angle you need to turn. This however is sometimes not the most optimal angle. We know that no angle is more than half a rotation way so the program checks to make sure and if it isn’t it adds or subtracts 360. This will result in the shortest angle (positive is one way, negative is the other). This will cover the issue of gyro values going from 360 to 0 and even let you set targetAngle to angles greater than 360 or less than 0.
We can also shorten the code and make it more efficient…

Slightly more efficient way

double targetAngle;
double errorAngle;

while(true)
{
    double gyroValue = gyro.get_value() / 10;

    errorAngle = targetAngle - gyroValue;
    errorAngle += std::round(-errorAngle / 360.0) * 360.0;

    pros::delay(7);
}
4 Likes

How about this code?

 int StoredPos = 0;
 int ActualPos = 0;
 while (true) {
   ActualPos = (int(gyro.get_value()) / 10);
   while( ActualPos - StoredPos < -345 ) // ActualPos jumped from 359->0
      ActualPos += 360;
   while( ActualPos - StoredPos > +345 ) // ActualPos jumped from 0->359
      ActualPos -= 360;
    printf("%d\n", ActualPos );
    StoredPos = ActualPos ;
    pros::delay(200);
  }

This code will keep ActualPos within +/- 15 deg from the previously stored position.

This should keep ActualPos accumulating angle even if you turn around multiple times, if that was what you were looking for.

3 Likes

That worked, correct me if I’m wrong but I think you mist some brackets on your while loops. and I had to up the loop speed.

int StoredPos = 0;
int ActualPos = 0;
while (true) {
    ActualPos = (int(gyro.get_value()) / 10);
    while( ActualPos - StoredPos < -345 ) {
        ActualPos += 360;
    } // ActualPos jumped from 359->0
    while( ActualPos - StoredPos > +345 ) {
        ActualPos -= 360;
    } // ActualPos jumped from 0->359
    printf("%d\n", ActualPos );
    StoredPos = ActualPos;
    pros::delay(20);
}
1 Like

(if/for/while in c and c++ will operate on a single statement if there are no braces)

1 Like

The braces aren’t required. All it means is that only the first statement will be read as part of the loop. If, for example I had:

if(x == sentinel)
x = 0;
sentinel = x;

Despite the indentation here, only that first line (x=0;) is read as part of the if statement. So, one line conditionals don’t need brackets, due to the single statement assumption. If you plan on adding more to a conditional though just be wary.

1 Like

How would it go directly into controlling the motors?

Is programming for Gyro different for V5 as to Cortex?