PID controller not working well at all for flywheel

So i made a PID controller for my fly wheel for my autonomus mode but… First of all the 100% rpm is supposed to be 3000 rpm but i want my flywheel to spin at 80% so that’s 2400 rpm but when i look at how fast the fly wheel is going it says: 90%

There also that when i apply a little bit of pression the PID does nothings at all

int flywheelPID(){
  int desiredValue = 2400;
	int kP = 100;
	int kI = 10000;
	int kD = 100;
	int totalError = 0;
	int lastError = Rotation20.velocity(rpm) / desiredValue * 100;
	while (1) {
    int currValue = Rotation20.velocity(rpm) / desiredValue * 100;
		int currError = currValue - desiredValue;
		totalError += currError;
		int diffError = currError - lastError;
		int currSpeed = currError / kP + totalError / kI + diffError / kD;
		LauncherMotorA.setVelocity(-currSpeed, percent);
    LauncherMotorB.setVelocity(-currSpeed, percent);
		lastError = currError;
		task::sleep(20);
  }
  return 1;
}

The first issue I see is you are setting the velocity of the motors but not telling them to spin in the portion of the code you posted. Your Ki may also be a little bit high.

I am quite confused at what this code is meant to mean. Could you elaborate what purpose this serves?

1 Like

To not address your problem, but offer additional helpful info:

I’d go look at User Sylvie’s personal website. It’s got some good notes regarding error in reading RPMs from the encoder.

1 Like

I have found better results using spin(forward, #, volt) instead of set velocity. I think when you feed it the number of volts, it bypasses the default PID

2 Likes

i tell the motor to spin in an other portion of the code but this code is getting the % of what the motor is spinning so like if the motor run at 2000 rpm it would do 2000 / 2400 * 100 to get the % of the desired value that the motor is spinning

maybe but i sadly don’t really know how to use the voltage thingy

mmmm ill try to check it out too thank you!

The way you use volts (to the best of my memory) is percent*12.

so for exemple if the motor is running at 100% i would need to do 100 * 12?

Yes, the code would be motor.spin(fwd, percent*12, volt).

1 Like

alrighty ill try that out and see if it works well thank you!

Short version… the encoder sometimes misreads and reports back values that are very low as a result.

1 Like

so i have a question how can i set voltage on the motor other then motor.spin(forward, percent*12, volt)? because i’m trying to use set velocity work but i clearly see that this is not going to work

Volts is not a velocity unit, so no that probably won’t work. Set velocity takes either pct units or velocity units, which include rpm and dps (degrees per second). Using motor.spin lets you use volts.

From the code you posted before, it seems your currError will never be anything but a large negative value, as you are dividing currValue by 2400*100, which will get you a very small fraction, and then you subtract 2400 from currError, which will give you a large negative number. A better way to do this is to just make currError whatever your desired value is and subtract the current rpm from the motors, which will give you the difference in rpm, and then you can do the rest of your math.

yea i’ve found that out a long time ago but i wasn’t able to post it on the vex forum because it like died somewhy but i find what wasn’t working! so i was trying to put the % at like 2000% and yea i also found out about the negative value but thank you! all i need now is to tune it (which i have trouble doing lol)

@ZipperXYZ, like @EcstaticPilot said you will need to use a version of the spin command that takes voltage argument if you want to keep your own PID code:

vex::motor::spin(directionType dir, double voltage, voltageUnits units)

V5 motors employ their own built in PID loop, if you choose to set target velocity or position at the arguments.

4 Likes

I haven’t really worked with I values, only really P and D, but I’ve found a pretty nice method to tune them. You start with the I and D at 0, then increase your P value up from 0 until it starts barely oscillating at the target value (which might be a bit hard to tell, but print the velocity to the brain and it should be fine). Then you do the D term, increasing it slowly until the robot stops oscillating at the target. For the I, when I did use it, i increased it until the robot overshot the target value, and then toned it back down. I believe the I is to help speed the process up over time, so its not that big an issue for a flywheel PID.

In addition to comments made below about PID and reading RPM values from the motors, be aware that PID is not the only control algorithm around, and it may not even be the best velocity control algorithm. Also consider:

4 Likes

ill try looking at these one too thank you!

ive tried that too but sadly this didnt work at all