Hi,
I am trying to use NEOs with their built-in encoders to control a flywheel. I am using the SparkMax on-board PIDF controller. When applying just feedforward control (setting appropriate kFF on SparkMax, PID gains set to 0 each), we get relatively good tracking (within 40 RPM, mostly on the side below the setpoint). The gains were computed using SysId.
In order to study the effects of the P gain on my flywheel as I tuned them, I elected to use 2 PID slots on the SparkMax (one as just a feedforward controller, the other is a feedforward plus feedback controller) and switch between them to apply the P gain. I figured that because I wasn’t reaching my setpoint with only feedforward, the disparity between my reference and measured signals would make my controller supply additional output such that I would reach my setpoint.
However, what I observed was that when applying the P gain, it was as if itbelonged to a separate controller that was tracking to 0 RPM as opposed to trying to track the RPM setpoint I set. For example in the following image, the setpoint I want to track is 3700RPM, the feedforward only controller gets me to 3660 (prior to 26 seconds on the graph). The moment I switch to feedforward+feedback, the controller output moves towards 0.
This behaviour is consistent when I invert my motors. When I increase my P gain, the controller pulls me more towards 0RPM. When I remove feedforward control, my controller tracks to 0, even though my setpoint is still 3700. When I increase the P gain to a large enough value, it even oscillates around 0. As far as I know, SparkMax doesn’t let you set negative gains (not that that solution is ideal anyways).
Any ideas as to what is causing this, or any suggestions are appreciated, thanks.
Code that initializes SparkMax’s:
m1 = new CANSparkMax(0, MotorType.kBrushless);
m2= new CANSparkMax(1, MotorType.kBrushless);
m1.setIdleMode(IdleMode.kCoast);
m2.setIdleMode(IdleMode.kCoast);
m2.follow(m1, true);
enc = m1.getEncoder();
c = m1.getPIDController();
c.setFeedbackDevice(enc);
c.setP(0, 0);
c.setFF(kFF0, 0);
c.setP(kP1, 1);
c.setFF(kFF1, 1);
Code that sets reference:
if (using_pid){
c.setReference(rpm/60, ControlType.kVelocity, 1);
} else {
c.setReference(rpm/60, ControlType.kVelocity, 0);
}
Hypothesis: Issue is cause by the RPM to RPS conversion I do before setting reference, thus the solution would be to scale my kFF by 1/60 and set the reference as RPM (kinda occured to me right this moment that this might be going on, not in the shop right now to test it, but I already wrote out the Chief post so I may as well post it incase my hypothesis is wrong).