I have been having troubles with getting my basic tank code to work with programming Sparks. The way that I understand it, I don’t need to program buttons to make my Drive() command run. It should just run when CommandScheduler.getInstance.run() runs in teleopPeriodic() right? I’ve tried looking at other’s posts with the same issues but haven’t been able to get anywhere troubleshooting the error. My code deploys successfully, my CAN IDs match, everything is updated, and I’ve looked at multiple other people’s drive trains and nothing seems to be wrong. I’m at a loss for what to do next, so any help is appreciated. We use CommandBased programming and this year we’re doing tankDrive.
The specific error that comes up is:
Shuffleboard.update(): 0.000115s LiveWindow.updateValues(): 0.048986s robotPeriodic(): 0.003558s disablePeriodic(): 0.004871s 0.008084s : Warning at edu.wpi.first.wpilibj.IterativeRobotBase.printLoopOverrunMessage(IterativeRobotBase.java:276): disabledInit()Loop time of 0.02s overrun Warning 1 Loop time of 0.02s overrun
edu.wpi.first.wpilibj.IterativeRobotBase.printLoopOverrunMessage(IterativeRobotBase.java:276) SmartDashboard.updateValues(): 0.009336s Watchdog not fed within 0.020000s Default disabledPeriodic() method… Override me! Default disabledInit() method… Override me.
The first thing I noticed in your code is your regDrive method in your Drivetrain subsystem.
Some things to think about (which I suspect will solve your loop overrun issue if nothing else):
When is that method called?
What happens in that method call?
Should everything that happens in that method happen every time that method is called?
What happens when you declare a new object (such as when you do leftdrive = new SpeedControllerGroup(sparkFL, sparkBL);?
How often does your execute method in your Drive command run? What is the purpose/use of that method?
If you don’t know how to answer some of these questions, I can help if you ask, but I think that thinking along these lines will help you debug similar issues in the future.
Okay, so I do agree that I shouldn’t have to set my SpeedControllerGroup objects every time that regdrive is called. regdrive should be called quite often as Drive will called quite often throughout any periodic() method. And so I’m willing to just create that once in the DriveTrain() constructor.
However, one thing that I don’t understand is that why if I put daryl = new DifferentialDrive(leftdrive, rightdrive); into the DriveTrain constructor (which based on the same logic, why would one need to create a new daryl every time that regDrive is called?) it causes an error. I deploy successfully and it gives me the error of
-ERROR 1 DifferentialDrive… Output not updated often enough. edu.wpi.first.wpilibj.MotorSafety.check(MotorSafety.java:101)
The way that I’ve come to an understanding of the way DriveTrain and Drive works, the execute of Drive should be called almost always? If CommandScheduler.getInstance.run(), goes periodically then doesn’t Drive get called quite often?
regDrive isn’t a complicated method in a sense of that it should, right now anyway as I just want the robot to drive currently, only call the build-in tankDrive method and set speeds to the SpeedControllerGroups (which will then send that speed to the motors).
It’s true that I don’t know the complex intricacies of how any SpeedControllerGroup works, or how DifferentialDrive works, and I think that is limiting my ability to debug my code. We haven’t had a great transfer of information from programmers to programmers over the years, and so I do feel behind in understanding even the basics of coding frc robots. While I understand java and objects and method calls because I’ve taken all the Computer Science classes, I still find myself lacking in the understanding of the capabilities of everything.
Thank you for responding and giving me a list of questions to approach the problem logically.
I just realized something: when do you call the initDefaultCommand method in Drive? Unless I’m missing it, you’re not calling it at all, so the Drive command is never running. This should explain both your motor safety and driving issues.
I wrote the below stuff before realizing this – if the above solves the issue, the process may still help with future issues.
Alright, that motor safety issue is odd and I don’t immediately see what could be causing it. My understanding of the motor safety issues is that they’re trying to prevent the motor from continually running on an old power setting, so it will error out if you don’t update the motor setting frequently enough. It is odd, though, that even if you update the power in an execute method of a command that it still throws this error. Perhaps this is the same issue that’s causing the robot to not drive?
Try putting in some print statements in your code in different methods you expect to get called – in execute in your command and in regDrive. If that seems normal, try printing the timestamps of each print statement (or better yet, keep track of the last timestamp and print the time since last method call). This should help you isolate the issue.
If you still can’t figure it out, try isolating the issue by bypassing the black box structures you aren’t sure about the inner workings of. A good debugging step is to try code you fully understand and know works before you add in the convenience or full feature list. In this case, since you are sure you know how the set method in the Spark MAX object works, try just using that instead of the speed controller groups or the DifferentialDrive. Most likely (almost certainly) the issue isn’t going to be inside those structures, especially for something like this, but it is possible that you introduced an error caused by not fully understanding what’s going on inside.