Hi all, my team, 747, has been working constantly to get PID to work with the new Spark MAXs - and thankfully, we figured out the recipe on Monday, and we think we finally have a functional release! I am going to attach below the four classes that are used for PID, and a basic DriveCommand for anyone who is having trouble setting up the MAXs in general. If anyone is having trouble setting up a PID command for themselves, feel free to take parts or all of our code. We program our robot in Java and with the command-based system, so I do not know how applicable this code will be to other teams.
Robot Example Code.zip (7.7 KB)
I wish you and your team the best of luck for the remainder of the Build Season! If you have any questions about our code or how we got it to work, don’t be afraid to ask!
4 Likes
In your PIDDriveRotate command, you are calling a number of methods of getPIDController, what is this referencing? That’s not the method you have in your drivetrain subsystem
Thank you for posting this! We’re looking into using NEOs this year and this will be great resource. I do have one tip: if you want to avoid long If statements like this:
if((Robot.DRIVE_SUBSYSTEM.getLeftRevs() > leftGoal + stop_threshold_revs) && (Robot.DRIVE_SUBSYSTEM.getLeftRevs() < leftGoal - stop_threshold_revs) && (Robot.DRIVE_SUBSYSTEM.getRightRevs() > rightGoal - stop_threshold_revs)
you could do something like this
double leftError = leftGoal - Robot.DRIVE_SUBSYSTEM.getLeftRevs();
double rightError = rightGoal - Robot.DRIVE_SUBSYSTEM.getRightRevs();
if(Math.abs(leftError) < stop_threshold_revs && Math.abs(rightError) < stop_threshold_revs) {
// do something
}
1 Like
Those are methods from the PIDController class in WPILIB
Thanks for this! We’re going to work on this tonight.
Right but what does that have to do with the Spark’s PID?
It doesn’t have to do with the Sparks’ PID. It is just another PID solution for teams to use
Hi Sam,
Thanks for posting this reference code! Did you find you it necessary to repeatedly set the Spark’s motor type to brushless in the PID Command’s initialize() function a-la Robot.DRIVE_SUBSYSTEM.leftDrivePrimary.setMotorType(MotorType.kBrushless);
even after MotorType.kBrushless
is initially passed as an argument to the CANSparkMax’s constructor in DriveSubsystem?
It doesn’t have to do with the Sparks’ PID. It is just another PID solution for teams to use
I see, I didn’t look at PIDDriveInches to see the Spark implementation.
Is it necessary to continually call setReference over and over again in execute()? My understanding is that setReference only needs to be called once to set the setpoint.
We do it as a precaution, as we do not want it to be accidentally set somewhere else in the code. We do not expect it to, but if it does accidentally happen, it is much less of a cost to pay by adding this line. It is not required, but I would recommend it.
1 Like
A serious FYI: After changing a LOT of code tonight, the PIDRotateCommand sometimes goes in a random direction instead of doing a basic rotation. I do not feel that this error is included in the code I provided and it really only appreared at the end of the night, but be careful! This only happened in one command group that we made, so start your robots in the center of your carpets when you run it for the first time and have your finger on the enter key!