Flywheel motor speed oscillating

Before I start I want to establish that I’m coding in blocks and am making this post because all similar threads pertain to text code

My team currently has a 2 motor 6:1 flywheel and when we have it spin we have the flywheel’s spinning speed set using the “set velocity to X rpm’s” but when we run it the rpm’s oscillates constantly.When it reaches the target rpm it goes a little over and then drops which I can only assume is the motor trying to correct itself and then proceeds to correct it’s correction over and over.One person mentioned how the motor is correcting itself and can’t account for things like momentum from added weights (We have 1 weight plate on the flywheel.)

1 Like

I would recommend using a PID controller to adjust the RPM. My team is using this very effectively.

If you use the default PID constants, then you can’t expect them to work with your motor. The solution here is to program your own flywheel controller. It can be PID or bang bang, but once you’ve made it yourself, you can tune it to settle on the desired velocity much more effectively.

1 Like

I keep hearing ab PIDs but I haven’t seen it been done in Blocks hence why I emphasized that in the post do you know where I can find some?

Try voltage instead of rpm or velocity control, Visit Voltage vs Velocity control to see why I think this happens.

I highly recommend Blocks for new teams but there will come a time when what they want to do exceeds the capabilities of the blocks format. Six-wheel chassis, PID, and other advanced logic require code. There are examples of PID in blocks code but it’s usually easier to extract the text code from the blocks program and start with Python or C++.

You can still add the devices and the drivetrain will work by default. You would need to transpose your autonomous instruction blocks to text.

As far as your concern about oscillation, some teams are having success by using Voltage instead of RPM / Percent to prevent this issue. I tested the following line of code in VEXcode IQ and it accepted it but I am not near an IQ brain where I can test it.

int main() {
  Motor1.setStopping(coast);
  while(true){
    if(Controller.ButtonFUp){
      Motor1.spin(forward,10, voltageUnits::volt);
    } else if(Controller.ButtonFDown){
      Motor1.stop();
    }
  }
}

I keep seeing comments about “voltage” mode, and half the time I don’t know if the comments are directed at V5 or IQ, so just to be clear.

IQ motors have no voltage mode.

VEXcode has an API, but it’s a compatibility API and does nothing.

4 Likes

You would need a variable to track the error, how far away the speed is from the target. You would also need a variable to store the Kp, or what you multiply the error by to get the proportional part of PID which is just a proportion of the error. You would need an integral and Ki. Integral is the running total of all errors and Ki is what you multiply by. You would need a last_error, Kd, to find the derivative or which way the error is moving. I would recommend looking this up online and going more in depth but this is a basic overview.
In text code:

target = 75
Kp = 0.7
Ki = 0.05
Kd = 0.025
last_error = 0
integral = 0
while True:
    if controller_1.buttonA.pressing:
        error = target - flywheel.velocity(RPM)
        p = Kp*error
        integral  = integral + error
        i = integral*Ki
        derivative = error - last_error
        d = derivative * Kd
        velocity = flywheel.velocity(RPM) + p + i + d
        last_error = error
        flywheel.set_velocity(velocity,RPM)
        flywheel.spin(FORWARD)
    else:
        flywheel.stop()

This is a very basic example of what a PID looks like in text code (specifically python) and should be fairly easy to translate to block code. Your Kp, Ki, and Kd values will need to be tuned to your specific application and I would go in order tuning Kp, Ki, and Kd.

Tuning Kp, Ki & Kd would seem to be more difficult with a flywheel where the errors are hard to see with the naked eye and displaying the speed on the output changes rapidly. Does anyone have advice on the best way to tune these values for a particular build?

I printed the current velocity, error, and integral on the brain and just adjusted based on observations. The p is the most important and I would make sure this is constantly at or around one number. The i is just designed to give it an extra boost to get it to that speed if it’s a little under. I would recommend doing this very small and if you only shoot at close range, you might not even need this at all. The d is very small and tries to push it in the opposite directions. I would think of this as resistance. The most important is p and you probably don’t even need the others. You just need to make sure that when it is spinning up, you don’t overshoot the speed and that it stays at constant speed.

I’m sorry if I’m restating etc, but what ur saying is I should use the “spin at X volts” instead for the “set velocity to X rpm”?

If you would like a flywheel with less oscillation, yes. You may want to do some math to get the same speed from volts as you would with velocity or rpm, but velocity is more consistent at maintaining a set speed, at least in my experience (albeit limited).

@Laser-Turret As was pointed out earlier in the thread by James, this is in an IQ topic; assuming that it’s not miscategorized, there is no voltage control mechanism for IQ.

Okay, thanks for the clarification. I’m not in IQ so I looked at Vexcode IQ blocks coding site to check after seeing jpearman’s comment and I think I mistook the setting velocity block for a spin using volts block.