Robot Code State starving loops

During teleop, the teleop vi is starved by the WPI_DriverStationReport Robot Code State.vi and keeps running and aborting. Same thing happens to Disabled.vi, but Autonomous runs perfect.

This video will show you what’s happening better than I can explain it with words.

VIDEO

I can’t tell what you want the video to be telling me. It’s too blurry for me to read the Driver Station chart or window titles with any confidence, and none of the windows show any code.

I’m not sure what you mean by “keeps running and aborting”. Teleop and Disabled are each supposed to be called and run to completion repeatedl. Is that not what you are seeing?

I guess the video did not upload in 720P like I wanted it to.

If you look at the tops of the running code windows and at the driver station’s “Robot Code” LED you will (faintly) see that they are blinking, not running continuously like they are supposed to do. This happens in Teleop and Disabled but not Autonomous, for some reason.

By “running and aborting”, I mean that the code starts for about 50-100ms, then stops for a various amount of time, then repeats. All without us touching a single control.

The lower chart has a plot of CPU usage. It is a red line and it appears to be at 100% the entire time. That is a much better indication of an issue than the Code LED.

First let me explain that the blinking Code LED doesn’t indicate that your code is aborting and restarting. If you think about it, how does it know your code is running anyway??? The Code LED is based on whether or not the cRIO program transmits the battery voltage. If it doesn’t, the DS presents this as the cRIO code not running – for that period of time.

So the bigger question is, why is your CPU at 100% causing everything including your battery values to be behind? I assume you were opening all the windows and exploring the code expecting the issue to be in disabled, teleop, or in something they call. You found that they both call Robot Code State and figured that was the culprit. But there are a number of parallel loops running on your robot, and they are far more likely to be the issue.

So, the first thing I’d do is to close the panels of all those subVIs. That will in fact increase cRIO CPU since it has to run the debugging protocol for each of the opened panels. After this, is your CPU usage still at 100%?

I assume so. So the next step is to identify what the CPU is working on. There are two ways that I’d recommend. Once involves using a tool, the profiler, to identify which functions the CPU is spending its time on. The second is to inspect the code you most recently changed looking for loops with no delay.

My suspicion is that your vision code or your periodic tasks are the culprit. Post images of those. A simple jpeg will do – 720P or even a 480P video with soundtrack and an indignant and misspelled question to the universe is really not that helpful.

If you would like, you can also search CD for info on how to use the Performance Profiler. It will indicate how much CPU each VI is using.

Greg McKaskle

I fixed the problem, sort of.

Vision was using a lot of CPU, so I offloaded that to the dashboard. After that, I just had to remake the entire robot project adding items one at a time and eventually I got to where it levels at about 70% CPU instead of 100%. I didn’t find the actual culprit, though.

I plan on running the previous, non-working code and using the Performance Profiler to figure out what not to do.

Thanks guys!

Sounds like a good approach.

My suspicion is that your vision loop was not able to keep up with the camera. Think of it this way. If processing an image from the camera takes 100ms, then the CPU can keep up with a 5fps camera setting. It may be able to keep up with 9fps. But if the camera is set to 15 or 30 fps, the loop will skip frames and will always have an image it is working on. It will never stop running, and therefore the CPU will be at 100%.

If you look a the rate of the vision loop, it will help you determine your camera settings. The same issue can happen on the dashboard by the way, it is just a different and faster CPU, but vision can bog it down too.

Greg McKaskle

So for the fastest program, I should put a timer in the vision loop that is equal to the value of the camera’s fps? Like if I had a 30fps Image coming through, I should set the timer at 33.3ms?

The vision loop will automatically wait for the next image from the camera, so you don’t need to put in a more visible wait. It won’t necessarily hurt, but it is redundant since one is inside the Get image.

My point is that if you computer takes 60ms to process the image and you run the camera at 20 or 30fps, you are guaranteed to always have the CPU pegged. You want to find out the capacity and run something below that.

And of course it is also worth coming at this from the other direction. How few images can you process and still be successful? If you process an image every 250ms, can you get the robot into scoring position? Can you aim and score? If the objects are moving, then fast frames are a good thing. Ditto to low latency. But sometimes the Red October approach of “One PING only” makes the most sense.

Greg McKaskle