A few times this year, there have been programming posts, that seemed to lead me to believe the timing loops on the roborio are far less consistent than they were on the cRIO.
At TORC we log data to a .csv file every 100 milliseconds. Attached are sample match log files from 2014 crio based, and 2015 roborio based.
The 2014 data is pulled from a timed tasks control loop with a 50ms metronome timer, the 2015 data is pulled from a timed task control loop with a 20ms metronome timer. Labview picture attached.
The data from this year is all over the place as compared with the cRIO data.
We controlled our elevator with a home brew pid, so the students would learn how to pid, and not use the labview provided pid, but as typically is done, we ignored the delta-t as the loop time was to be consistent.
Which it was consistent enough to not give us issues with control, just not nearly as consistent as the crio.
2014 Avg = 49.9796 with STD = 0.21929
2015 AVG = 19.67855 with STD = 3.797736
FWIW, I teach our programmers (C++) to never depend on the grand loop timing in the robot, always using timers to calculate time offsets. There’s no stated SLA around the timing, and I have always been concerned that behavior on the field would vary from tethered operation in a meaningful way.
The difference could be from quite a number of factors. The most obvious one would be the difference in the loop times. Another big factor is the difference in what is running in the background and how it is being scheduled.
You should expect jitter from using the “Wait Until Next ms Multiple”, this is similar to the problem of using Thread.sleep() in Java. If you need more accurate timing you need to use a timed loop structure, which will also tell you if the loop runs too long and a couple of other useful things.
Along with the paper from 358 link, this paper from NI has some useful info on the wait functions in LabVIEW RT.
I posted about an issue in the Java implementation here. The actual task was not using a hardware interrupt for timing, but rather Thread.sleep(). Is it possible that the 2015 LabVIEW code is doing something similarly non-optimal?
Both Measured the same way as the shown in the snipit. Just different programmers from different years did the log heading text.
Both loops used the “Wait for next multiple” labview timer.
I had noticed this behavior when we were doing beta testing, and have not dug into much further. But wait, I forgot I published our 2014 code as part of the beta program, and we did get the logger working in linux os before publishing…
So attached is our 2014 code running on the roborio.
Avg = 49.95124
STD = 0.7159
Just seems like the RT scheduler in the roborio, is not as preemptive in scheduling the loop, as repetitive as the cRIO was.
By design. As someone else already stated, the metronome, or ‘wait’ in Labview means ‘execute no FASTER’ than your set time. It does not enforce timing, and if enough CPU is used elsewhere the loop times will vary. Our CPU usage this year was around 65%, and we could count on the wait loops to be very consistent.
If you require accurate timing, a timed-loop structure will give you sub-millisecon d accuracy at the price of substantially higher CPU utilization.
Ditto the experience here. We experienced less “jitter” (probably not really the correct application of the term, but you get the picture) this year than we historically did with the cRIO. Sorry, no metrics to support that.
Yet in all of the data the avg loop time is less than the set loop time. In the roborio 20ms loop time, there are loop times of 8,9 & 10ms.
This effectively, doubled the PID gains for these loops… Again we really did not see any issue with the elevator with stability… and as MrRoboSteve pointed out it is probably a better solution to incorporate the delta-t at this high school level, just in case the field impacts the control.
We had no programmers with calc yet this year, so we used NXT lego line following example as the start of the conversation, and 3 weeks later, ended with the white paper on the SRX internal PID code. The elevator code ended up with a separate P gain for raising the elevator, and a lower P gain for lowering the elevator, along with the SRX “IZone” implemented. This gave a very quick reacting and stable control for the elevator system. The mechanical gear ratio went from 35:1 minicim at Waterford, to 20:1 CIM at Championships.
Are we looking at the same files? The “20 ms” roboRIO data shows many records with times in the high 20s and 30s, and some greater than 40 ms. I wasn’t able to get them all to match up to show a clear smoking gun of simple timing jitter, and I’d still like to see how long the loop contents actually took to run.
This effectively, doubled the PID gains for these loops…
The P term is unaffected by loop time. The I term would indeed be overrepresented with a shorter than expected loop time, but the D term would have a reduced effect.
Again we really did not see any issue with the elevator with stability…
It appears that you were using the built-in SRX closed loop control, so any inconsistencies in your robot code’s timing should be irrelevant.
Look at the average and standard deviation data posted. All of the three files have an average that is less than the loop time programmed in the wait for next multiple.
Had to look this up, but you are correct, there is no delta-t term in the P.
No, we did not even have a SRX on the bot. The point was we started the conversation and code with simple NXT solution and it finished with reviewing the SRX whitepaper on the internal PID code CTE published. We implemented the SRX “IZone” feature in Labview, and drove a talon SR via PWM. This whole paragraph, was probably off topic to the conversation at hand, but sometimes I work that way.
So the conversation at hand, is based on the averages for the loop time, and standard deviation from our 2014 code on a cRio, and our 2014 code on the roborio, in the same 50ms loop.
The cRio data:
2014 Avg = 49.9796 with STD = 0.21929
The roboRIO data:
2014 Avg = 49.95124 with STD = 0.7159
The deviation of the loop by the roboRio is a factor of 3.2646 less repetitive than the same code on the cRio.