View Single Post
  #3   Spotlight this post!  
Unread 25-03-2012, 19:11
Ziv Ziv is offline
Has code to be writing...
FRC #0125 (Nutrons)
Team Role: Alumni
 
Join Date: Mar 2010
Rookie Year: 2009
Location: Boston
Posts: 39
Ziv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of lightZiv is a glorious beacon of light
Re: How does your team architect its codebase?

This is a nontrivial problem for which there are several correct answers. First, here is Team 125's code from this year. It used to be organized according to the structure I outline below, but two back-to-back competitions led to some unfortunately hacky fixes under time pressure. C'este le code.

For the past two years 125 has used some sort of command-subsystem model*, with a significant amount of WPILib support provided it this year. I covered it in my Java presentation at this year's kickoff; for more detail, check out the WPILib Cookbook or the FRC Java API. In brief summary:
  • Subsystems represent actual parts of your robot. Their methods represent the lowest level actions that you will ever want to use them for. While there can be some extra logic inside the methods—such as an elevator not going beyond minimum and maximum positions, doing some math to turn a real world value into a sensor value, or even a PID loop—you generally want subsystems to be "stupid". A corollary of this is that the subsystems are never aware of whether it is autonomous or teleop, because you should use the same set of methods for both. It also means that subsystems almost never talk to each other. (We have one exception in our code that I'll eliminate if I ever rewrite it.)
  • Commands are objects that tell subsystems what to do. This is where you combine all of your subsystem's methods in clever ways that make them do useful game actions, such as score. Make these apply to both autonomous and teleop as much as possible, but there are some commands that will naturally only be used in one mode. For instance, "spin 180 degrees" isn't useful in teleop, and "manual tank drive" has no place in autonomous, but "auto-align to target" could be written so that it can be used in either.
  • Command groups perform a group of commands. (Duh .) They are themselves commands and can be nested inside other command groups. These combine simple commands to make an even more complicated game action, such as waiting until a shooter wheel is at the correct speed and then firing a ball. Autonomous modes are generally command groups.
  • Obviously, some things (perhaps the dashboard or camera) don't necessarily fit exactly into the above structure. Be flexible.
That, in retrospect, was not very brief. Hopefully it or one of the links is at least a little enlightening. It sounds like you're doing something like this already, but a slightly more strictly hierarchal organization could help you avoid the messiness of interacting subsystems.

Last year I wrote a scripting language for autonomous mode, but we never had time to test it. If you do something of this degree of complexity, start in the offseason.

*This was originally inspired by 254's autonomous code from 2010; a common mentor between our teams brought the idea to the opposite coast, where we made it more object-oriented and applied in teleop. In 2011, we wrote our own system for running commands, but thanks to the WPILib update this is no longer an obstacle to using this intuitive architecture.