PID on Flywheel Not Functioning As Intended

(Sorry for the repost I had the wrong tags so I took the last one down)

Hey o/

I was wondering if someone could take a look at my code (below). Currently, it does work, however there are major drops in the speed. I have identified the issue causing these drops. As the flywheel reaches -2000 RPMs, the power to the motor turns from a negative number, to a positive number, making the motor attempt to turn in the opposite direction inertia is taking it. Although this would work for driving and positional movements, for the flywheel, this causes the motor to stop in the middle of its rotation. This “works”, however it causes rapid changes in the motor which causes it to heat up and is bad for the motor. How could we go about preventing the motor from stopping in the middle of its movement. Ant and all advice would help greatly! Thanks so much for your help! Have a fantastic day!

typedef struct { // init a reusable list of variables
	float current;
	float kP;
	float kI;
	float kD;
	float target;
	float error;
	float integral;
	float derivative;
	float lastError;
	float threshold;
	int   lastTime;
} pid;

pid sPID; // init struct "PID" with the prefix "sPID"
  // Cookie-Cutter PID loop for intelligently reaching a desired destination.
int iPID( int iDes , int rpm, float kP, float kI, float kD, float kILimit) {
	sPID.current    = rpm;
	sPID.error      = iDes - sPID.current;
  if( kI != 0 ) // integral - if Ki is not 0
      { // If we are inside controllable window then integrate the error
      if( fabs(sPID.error) < kILimit )
          sPID.integral = sPID.integral + sPID.error;
          sPID.integral = 0;
  else // Otherwise set integral to 0
      sPID.integral = 0;
  sPID.derivative = sPID.error - sPID.lastError; // Calculate Derivative
	sPID.lastError = sPID.error;

double thePower = (sPID.error * kP) + (sPID.integral * kI) + (sPID.derivative * kD);

 std::cout << "Deriv " << sPID.derivative <<" Error" << sPID.error << " RPM "<< flywheelEncoder.velocity(velocityUnits::rpm) << " Power " << thePower <<"\n";
	return ( thePower);
int thePower = iPID(-2000, flywheelEncoder.velocity(rpm), 0.1, 0, 0.00, 0);
  flywheel.spin(reverse, thePower, voltageUnits::volt);
1 Like

Look into a take back half controller which tend to be better than PID’s for flywheels.


Just did some more research on that and I think I have what I need. Thank you so much for your help!

Have a fantastic night!