Needs some help with tuning Turn PID

For some context, I am using an inertial sensor for my turn PID loop, and I am trying to determine the K values for them. I followed the recommended way of tuning by first setting Ki and Kd to 0 and increasing Kp till you have a steady oscillation, then Increasing Kd until the oscillation is stopped, then adding Ki. This method sort of works but the big problem I keep running into after tuning those values on 90 degrees, is when I try small turns like 5 degrees (Which is a turn we need to make for auto) it undershoots (I think cause the Ki is too low but if I increase it, it will overshoot) and for 180 it overshoots. I also tried using the Ziegler-Nichols method of tuning but that didn’t work either (Probably cause it’s not meant for drive-base PID tuning). I ended up having 2 sets of K values for different target angles but that doesn’t really work either (They don’t complete all the time). I’m just not sure how I can get 1 set of K values that will work on every target angle Any ideas on what I am doing wrong or if there is a better way to do this? Any help or suggestions are welcome cause I am completely lost.

Here are my current values

if (TurnTarget <= 65 && TurnTarget >= -65) { 
    TkP = .25; // .25 
    TkI = .00000025; // .000000005
    TkD = .22; // .22
  } else {
    TkP = .25; // .25 
    TkI = .00000002; //0.0
    TkD = .21; // .21
  }

And here is the part of the PID that starts and stops the motors

if ( (TurnPower <= .3 && TurnPower >= -.3) && (TurnError <= 1 && TurnError >= -1) ) {
      R1.stop(brake);
      L1.stop(brake);
      R2.stop(brake);
      L2.stop(brake);
      startTurnPID = false;
      this_thread::yield();
    } else {
      R1.spin(fwd, TurnPower * -1, volt);
      L1.spin(fwd, TurnPower, volt);
      R2.spin(fwd, TurnPower * -1, volt);
      L2.spin(fwd, TurnPower, volt);
    }

Make your i term only start integrating when the error is between 15 and negative 15. You have 65 right now which is a bit large. See how 15 does.

1 Like

I tried this but it still has the same problem.

My solution to this problem was to give the robot a minimum speed it can run at. We have this at 2 percent right now since the robot can come to a full stop immediately at this speed without overshooting. This also allowed me to remove the kI from the loop completely so I don’t have to worry about it ever overshooting.

Why is it so hard to tune the Integral value for the PID controller?

Edit:: I understand tuning is supposed to be done manually but from what I have read it seems like you have to find some way around correctly tuning it like adding an Integral Cap, setting a minimum speed, or simply cutting it out entirely.

Gotchu: Maximum Velocity. With unlimited speed and power, you never need to limit or cap the i term. If you were to run shorter runs with more resistance, the I term would always be relevant to integrate. However while the motor is at its top speed, the i term cannot help the motor spin any faster to get there.