So, I’ve created a turn to angle command that uses a PIDContoller to rotate 180 degrees. The main problem is that it will only run once. It isn’t a problem with the command though because each time I press the button to run it, the gyro resets to zero so part of it at least works. Does anyone know what could possibly be causing this? Please let me know if you need information.
Have you tried creating two different commands, one that rotates 180 degrees and one the rotates 90 degrees? Also, are you dumping out values such as the current angle or when the robot starts the command? Finally, have you tried enabling and disabling the PID in a method different than the one containing your setpoint function?
Don’t have much time to deep dive the code, but I thought I’d offer those troubleshooting suggestions up to see if it did anything.
You’ve made a good start, here - your code is well-structured and readable - but I’ll need more information to make a guess at what’s happening. Try putting print statements in each part of your command to log the sequence of events.
Also, you have too much code in your drive subsystem that ought to be in your commands. In particular, for a “turn to angle” command like this one you really ought to use PIDCommand, which wraps a PIDController for you, rather than having the controller live in the subsystem. This takes care of having to reset the state every time the command runs.
Edit: As a wild guess, you’re not resetting your count on initialize, so it’s possible that the error value is within bound for a single iteration on command start and your count is still above 10 from the previous execution, resulting in an immediate exit from the command.
FWIW, I’d also use a timer rather than an iteration counter, but that’s kind of beside the point.
First off, I am c++ programmer so I may be wrong, and if I am wrong my bad.
One thing I noticed is that in your command you seem to initialize drivetrain again when it should be already done in the main robot.java file. My suggestion is to include the robot.java instead of subsystem.drivetrain then using the already declared drivetrain to be required.
Here is an example from our code. You can see how we required our drive subsystem by referencing to the main robot file instead of adding the actual subsystem to the command. It should work the same way in java, I believe.
My assumption is that because you are re-initializing the driveTrain subsystem within the command, it is having trouble running through the command.
He appears to be passing it through the method. Though it isn’t conventional (at least to me), there shouldn’t be anything wrong with it.
However, regarding making a subsystem object only once, This is a trick I picked up from my alumni team:
public static DriveSubsystem getInstance() {
if (instance == null) {
instance = new DriveSubsystem();
}
return instance;
}
Create the above static method and make your constructor private. This way, only one subsystem object can be created and then it is used in the future.
He is injecting the drive subsystem through the command constructor, which is a very good pattern that results in cleaner and more readable code than using globals.