View Single Post
  #2   Spotlight this post!  
Unread 15-07-2012, 08:20
shawnz shawnz is offline
Flamewar Initiator
FRC #0907 (E. Y. Cybernetics)
Team Role: Programmer
 
Join Date: Apr 2007
Rookie Year: 2007
Location: Toronto
Posts: 36
shawnz will become famous soon enough
Re: Lessons to be learned from Einstein reports

Quote:
Originally Posted by Todd View Post
Excessive ethernet communications:
Transmitting too large images, at too high a framerate, as well as sending too much data far faster than it can possibly actually be required at (did you know the default labview code sends driver station updates as fast as it receives instruction packets?)
The LabVIEW default code actually sends driver station updates 1/25th as often as it recieves instruction packets, AFAIK. We've modified ours to have this factor be 1/5th instead, but haven't actually tested the change on a real field yet. Either way, networking technology is pretty good. We should be able to stream 1080p video over the air easily in this day and age. This kind of data should be inconsequential.

Quote:
Originally Posted by Todd View Post
Excessive 'useless' CPU utilization:
Some tasks have to run fast, all tasks are not equal, and they do not all have to run fast. Particularly, many teams put time consuming I/O instructions into code segments that are expected to run very often, resulting in full CPU utilization just in the processor trying to keep up.
I noticed that, more than once, the problem was using "yield" instead of "sleep" (For the uninformed, the "yield" function is basically like a sleep for 0 milliseconds. It doesn't actually wait any minimum amount of time, but if other things are scheduled, it will go process them.) This should be just as good IMO -- In this case, if you're hitting 100% CPU but still executing all of your code regularly, all that means is that you're being 100% efficient with the hardware.

If you weren't yielding OR sleeping in your secondary threads, or just not doing either often enough, that would be a different story. The only thing executing would be your heavy block of code.

Quote:
Originally Posted by Todd View Post
Ignorance of the potential for 'partial' failures:
Things happen, wires get cut, parts of your CAN bus fail, that gorgeous IC2 chip you have gets smashed by a basketball. Software should be architected so that the failure of one system does not mean the failure of the whole system. This is particularly dangerous in the case where a failure with an I/O device causes excessive timeout delays, which lead to the 'useless' CPU utilization problem mentioned above.
I love this advice. On our team this year we tried to intentionally make the bare functionality of the robot sensorless, as a strict policy. Also, the driver should never be overridden by a faulty sensor. It wasn't perfect, since we did actually have sensor failures that costed us a match at GTR west, but perhaps next year we can implement this idea more rigorously.

Quote:
Originally Posted by Todd View Post
Segregation of 'I/O' jobs, vs 'Processing' jobs:
This one isn't entirely necessary, per say, but something that in my opinion is good practice. Too many a PID loop running in threads driven by instruction packet receipt, alongside I/O tasks that could throttle the control system loop into running in a totally unexpected timestep. The more that your system can seperate I/O tasks from Processing tasks, and from each other, the likely better off you are. (Certainly not in all cases, and only to a certain degree, but in general, in my opinion)
We still don't do this, but we really should. I mean, I don't think we've ever caused ourselved to miss a teleop packet because we took so long to process the last one, but there are many other good reasons to be doing this anyway.

In fact I think this is one area where the default template could be improved -- it could be friendlier to the idea of offloading whatever you can into other threads. Maybe this will be coming next year, along with the "more thorough documentation regarding threading".