Exit Statement for a P loop?

{
 double kP = 1.2432; // kP (scaling number)
  int x = 0; // Timer for exit condition
  while (true) {
    double error = target - Inertial21.rotation(deg); // error = (target - current)
    set_tank(error * kP, -error * kP); // Set motors to (error * kP)
    Controller1.Screen.clearScreen();
    Controller1.Screen.setCursor(1, 1);
    Controller1.Screen.print("%8.1f", Inertial21.rotation(deg));
    
    // If the velocity of the left and right motors are 0...
    if (left_back.velocity(pct) == 0 && right_back.velocity(pct) == 0) {
      x+=10; // Increase x by 10
      if (x >= 30) { // If x is 30 (meaning the motors were at 0 velocity for 50ms)...
        break; // Break the while loop
      }
    } 
    // If the velocity of the left and right motors are not 0...
    else {
      x = 0; // Set the timer to 0
    }
    wait(10, msec);
  }
  set_tank(0, 0); // Make sure motors are off before leaving this function
  Inertial21.setRotation(0, degrees);
}

Currently I have this p loop. However, when i run it the next part of the autonomous doesnt work. I think its my exist condiiton. How can I make a better exiit condition or fix this one?

I’m guessing the issue is that you only start to increment x if your wheels are spinning EXACTLY at 0. Because your error is rarely going to be exactly at 0, your velocity will likely never reach 0 as well. A simple fix for this would be replacing the 0 with a very small number and using an inequality. For example

 
    if (left_back.velocity(pct) < 0.5 && right_back.velocity(pct) > -0.5) {

Hope this helps!

4 Likes

I tried this but the turn no longer finishes now. For example if i tell it to turn 90 it turns 16 and stops. Still does not move onto the next part of the code.

Hi, this example code is from my vexcode tutorials. I find that 0 is pretty consistent because at the end of the motion the motors will be exactly 0.

This exiting is generally more consistent because it will timeout if something unexpected happens, and will still continue even if you’re not quite at your target.

4 Likes

I don’t feel my response from earlier was satisfactory, so I’m going to try to redeem myself here.


Other ways you can exit are by checking if you’re within a range of target for some amount of time. If you only had this, and due to something going wrong stop a little earlier then you’d like, the rest of your autonomous wouldn’t run.

I think the ideal exit condition is multiple potential triggers, maybe checking mA output, velocity and error. But for only having one condition, I find velocity is the best.

I’d suggest adding a printf("\nTurn Completed!"); at the end of the function to see if this function is exiting or if it’s something in your other code causing the issue.

I’d also suggest removing the setRotation at the end. The big appeal of the inertial is it tracking absolute angle for less error accumulation. You can even use it in your drive movements to make sure you’re driving straight.


Good luck, let us know what fixed it!

6 Likes

Depending on whether you drive on the flat surface or try to climb the platform you may need to use I and D components later. You may check out several good discussions about exit conditions for PID loops from before:

2 Likes