Help with my Flywheel PID

Hello forumers…
Today when testing my flywheel, I noticed that if I changed the “targetSpeed” value of my PID, then the flywheel would spin up to that speed and then do a weird brake thing and drop the speed and then go again…
This is obviously not ideal, but it will do it with any value that is not the base motor RPM (600 rpm in my case). I need the RPM to be lower, but I cannot figure out how other than changing the physical gear ratio. (which we cannot do right now)
Here is my PID:

bool maintainSpeed = false;
double targetspeed = 600;
double kp = 0.5;
double ki = 0.10;
double kd = 0.05;
double preverror = 0.0;
double error = 0.0;
double totalError = 0.0; // += error
double derivative = 0.0; // = error-preverror
double flyspeed;
double Power = 0;
bool ReadyShoot = false;
int FlyPID(){
    flyspeed = (flywheel.velocity(rpm)); 
    error = targetspeed - flyspeed;
    if (error <= 0.1){
      ReadyShoot = true;
      ReadyShoot = false;
    Power = (error*kp + totalError * ki + (error - preverror) * kd)/12;
    flywheel.spin(forward, Power, volt);
    preverror = error;
    totalError += error;

  return 1;

Am I tuning it wrong? Am I changing the wrong value (s)?
Any help would be appreciated!

Thanks in advance,
Henry 344E

Your integral value is way too high. Even adding 10% of the sum 50 times a second adds to a huge amount to be compensated. Instead, don’t use an integral value at first and then tune the P value to something that gets you up to speed fast enough. Then, you can use the D value to smooth out some of the jittering in the motor’s speed. If necessary, you may use an integral value to speed up acceleration, however I doubt you will actually need it.

1 Like

From what I’ve read and what I’ve implemented into my own flywheel PID, you need a thing called feedforward in your PID to maintain speed.

Remember that P is directly proportional to your error and will change as your flywheel speeds up or slows down. As your error decreases the closer you get to your targetRPM, your PID is outputs less and less voltage to your motors, until eventually it provides no power and causes your flywheel RPM to drop, causing oscillations.

Feedforward is basically a constant value that scales proportionally to your targetRPM. This keeps a constant voltage applied to the flywheel for it to keep its speed, while the PID will work in the background to remove the error in RPM.

For example,

double kF = 13;

targetRPM = 600;
motorPower = targetRPM * kF; // Outputs a constant voltage of 8000 millivolts

targetRPM = 450;
motorPower = targetRPM * kF; // Outputs a constant voltage of 5850 millivolts

Of course, you’ll need to tune your own kF values to find the right voltage for you.


The rest this is happening is because a flywheel is really not meant to be used with this type of PID. When the actual rpm goes above the target, the error becomes negative thus dramatically reducing the flywheel speed.

How we can get around this is using something called feelforward. Feedforward uses previous knowledge of the system to assist the PID.

Let’s take an example flywheel PID where kp=1 and we use percent as an input and output (you will need to convert it to volts for your code). The code for the output would be speed=(target+error*kp). What this code does is says that whenever error is zero it will still spin at roughly the correct speed which eliminates the previous problem. People usually use a kf constant for converting their input to output.

In addition, I recommend pairing this with a filter for your flywheel speed. Vex motor speed readings can be noisy and could cause the feedforward to increase the oscillation due to the noise. I use a simple moving average which takes the average of the last 10 flywheel speed data points and uses that to compute the error.


I’ll try something like that. In this case would the TargetRPM be targetSpeed in my case?

Yes, targetRPM would be targetSpeed in your case.

1 Like

That worked, thank you!

1 Like