Sharing is caring. Please find attached a RobotC competition program structure that my team uses (the proposed template is a cleaned-up structural extract of the code they have converged to).
The central idea is a layered structure with a well-defined HAL (Hardware Abstraction Layer) at the bottom. Let’s look at the layers:
- HAL (a C file with motor/sensor definitions and some defines/functions) abstracts out the hardware parts using mostly trivial, yet abstract accessors. It can hide how many motors you have on the drivebase and, thinking of it, a well-implemented HAL could even hide the fact that you’re sharing half of them with a “passive” MOGO lift. HAL is also the only file allowed to directly address the ports.
- function-library contains the higher-level functions built on top of the HAL. Think of stuff like “drive this distance”, “turn 90deg left”,
“lift the mogo asynchronously”. The idea is that the library should be generic enough to work the same way on different robot builds, as long as it gets well implemented HAL for each of them. - teleop contains the driver controls implementation, using the HAL and/or the function library as needed. Thanks to this structure, you can easily migrate your teleop implementation (which channel drives what) between different robots, hopefully with no or minimal modifications.
- A set of auton-helper includes (more on these later)
- a number of anton implementations (each, or a subset of them in a separate file). Parametrized if possible.
- The main file that ties everything together.
Success story:
The team (experienced roboteers, but 1st year in VRC) started the season building a simple 4-bar and also had a clawbot to get some headstart in programming. Over the time they built up their library of functions, testing them both on the clawbot and the real robot
and then spent long grumpy hours refactoring. It took them time to retrofit the growing codebase into the HAL-based structure, while the builders progressed on RD4B design. Then, when the RD4B was field-ready (not finished yet, but good enough for some programming) , it only took writing new HAL (and commenting out the so-far unfinished mechanisms) and voila! The new robot immediately listened to the same joystick commands and better yet, the auton routines (like 22pt scoring) still worked!
All of that despite the fact that the new robot has the gyro mounted upside-down (intentionally for a few reasons) and the MoGo lift potentiometer on the other side (turning backwards and with a different working range), all easy to abstract in the HAL.
Part of the template assumes you have some form of an LCD program selection implemented that takes a list of strings and returns the selected index. It uses auto-generated dispatch code based on my discussion with @jpearman (all bugs are mine, all wits is James)
It also has a built-in helper for running a single auton (the one you’re currently working on) directly, skipping the above mentioned (but tedious during debugging) selection on LCD.
Implementation notes - auton files are .c, so you can directly run them with the auton helper.
Other files are .h so RobotC disables the run button (as you don’t want to run, say, a library, right?) - a lousy workaround for the lack of RobotC’s lack of the notion of a project.
HAL needs to be a .c file, unfortunately, as RobotC would also disable the Motor/Sensor setup button - also, whenever you need to edit the port setup, do it from the HAL file, not from the main.
Possible further extension: Testing - imagine you could easily simulate your drivebase having more friction on one side. How would your library routines behave? Would “drive straight” still drive straight? That’s now trivial to test - you have one single entry point to inject your “fault” into.