Quote:
Originally Posted by Tom Bottiglieri
Off topic a bit - I saw your team was using Java this year. Have you run into issues with the timing of the JVM's Timer? We have used this construct successfully over the past two years, but on the roborio the timing is complete garbage. We have ditched using derivatives on any control loops due to massive noise.
My best theory is the squawkVM was ported manually and used VXworks timers under the hood. The standard JRE we use now probably just sleeps or something.
|
Yes. Again and again, we run into weird timing issues with the roboRIO. The cRIO's timing jitter couldn't be measured with a millisecond timer, but the roboRIO's can be. The roboRIO occasionally gets suddenly very bad at timing for 10 or so seconds. I battled lots of weird intermittent timing bugs with the roboRIO when trying to get our autonomous down - we're driving, lifting, swatting, intaking all at the same time.
Our elevator control originally used PD control, but we had intermittent issues with oscillation.
Our PID controller is here:
https://github.com/dicarlo236/2015-R...robot/PID.java
Our Updater that deals with PID is here:
https://github.com/dicarlo236/2015-R...t/Updater.java
I assumed that I messed up something in my PID class for the derivative calculation, so I took it out, and we're only running P control now. However, we still experienced overshoot of 4" or more about 1 in 100 times. I've only had the bug happen once when I was analyzing loop timing, and it was caused by TimerTask waiting too long to call the run() method, and the P controller couldn't run and update the motor value. I was originally running all control loops (elevator PID, drive followers) in the same thread, and I split it up into separate threads for elevator and drive, but it did not solve the problem.
I have two videos from our competition that show the problem. In the first video, you can see that the robot drives smoothly and accurately in autonomous mode, and the elevator moves properly throughout the whole match. If you watch our robot load from the feeder station or place totes, you'll see that the elevator is tuned well to work well under any load. Randomly, this exact elevator code will have tiny issues/jerky movement, then go back to normal.
https://www.youtube.com/watch?v=7vw2...ature=youtu.be
In the second train wreck of an autonomous mode, our robot doesn't drive smoothly at the beginning, the swatter swats too early, the intake turns on too late, the turn begins too early, the drop happens too late, and the drive stops too late. In teleop, the elevator control has an issue and doesn't drop low enough. At that point, I switched to manual control.
https://www.youtube.com/watch?v=2pr8...ature=youtu.be
The second video was likely taken during our second finals match (the problem happened twice). The identical autonomous program ran in the first and third finals match, and worked correctly both times. This behavior was very close to costing us the event, and I'd really like to get a good idea of what's happening.
I am not 100% sure what caused the issues, but here is my current thought as to what went on.
The first time it happened, it was triggered by an e-stop of the field. The match was started while the announcer was in the middle of announcing the first alliance, and the field people e-stopped the robot. I went out, reset the robot, but when I got back to the driver station, the robot was in autonomous disabled, not teleop disabled like it normally is when it is first FMS connected. For some weird reason, this caused the FMS not to communicate the remaining match time to the robot. I detect whether the robot is connected to the FMS by checking to see if the time remaining returns a reasonable number, which decides if we should run the match version of autonomous mode vs. the practice mode. The two versions are exactly identical, except that the practice mode fails to run System.gc() at the beginning because I accidently commented out the wrong line in queue.
The second time it happened, I messed up a few changes when we dialed in our drop/back up for the carpet at the event, which was a little different from the old carpet back home. I removed only the line system.gc().
We don't have any mentors on our team who are familiar with Java or are programmers, so I've been unable to really figure out why System.gc() helps with loop timing.
There's also an issue of the roboRIO's internal clock. On powerup, it thinks it's 1970. If you start your timer task then, then connect to the driver station, which syncs the roboRIO's date/time, it thinks it has to make up for 45 years of not running your code, which causes other issues. Both times when our auto failed, this was NOT the problem, as the elevator won't run if this case happens, and the elevator ran both times.