The following maxim summarizes what we hope to teach students on the software team (with examples drawn from controls engineering).
Engineer based on requirements, not an ideology.
Engineering is filled with trade-offs. The tools should fit the job, and not every problem is a nail waiting to be struck by a hammer. Instead, assess the minimum requirements (min specs) for a solution to the task at hand and do only enough work to satisfy them; exceeding your specifications is a waste of time and money. If you require performance or maintainability above the min specs, your min specs were chosen incorrectly by definition.
Controls engineering is pragmatic in a similar respect: solve. the. problem. For control of non-linear systems, plant inversion is elegant on paper but doesn't work with an inaccurate model, yet using a theoretically incorrect solution like linear approximations of the non-linear system works well enough to be used industry-wide. There are more sophisticated controllers than PID, but we use PID anyway for its versatility and simplicity. Sometimes the inferior solutions are more effective or have a more desirable cost-benefit ratio than what the control system designer considers ideal or clean. Choose the tool that is most effective.
Solutions need to be good enough, but do not need to be perfect. We want to avoid integrators as they introduce instability, but we use them anyway because they work well for meeting tracking specifications. One should not blindly defend a design or follow an ideology, because there is always a case where its antithesis is a better option. The engineer should be able to determine when this is the case, set aside their ego, and do what will meet the specifications of their client (e.g., system response characteristics, maintainability, usability). Preferring one solution over another for pragmatic or technical reasons is fine, but the engineer should not care on a personal level which sufficient solution is chosen.
This is egoless engineering.
If you can meet your requirements with a simpler, less comprehensive design, do it. Keep in mind that your requirements can and should include cleanliness, readability, and reusability.
Make your code as simple as possible while still meeting your functionality and cleanliness requirements. You'll thank yourself later when you have to debug it or reuse it.
A lot can be accomplished with no feedback control and a few lines of WPILib. In FRC team 3512's rookie year, their 2011 robot had 100 lines of C++ with fully manual control except for a limit switch for automatically deploying the minibot. It seeded 7th out of 63 teams. Only start writing big, fancy abstractions when it helps attain something that couldn't be done easily otherwise.
There are a lot of difficult problems in robotics and computer science, but most of the ones relevant to FRC were already solved by experts in those fields. That expertise is made available in libraries such as the C++ standard library and WPILib. Learn their APIs well and use them. There's no use in reinventing the wheel (poorly).
PID control isn't a silver bullet, and neither is computer vision. Don't decide to implement something just because it's cool. Implement what gives the highest return on investment first for robot performance. For example, if you want to spend a week on tuning an elevator PID controller, be prepared to show how that will improve the robot's scoring potential compared to manual control of the elevator height.
For FRC-specific C++ software development, we suggest the following minimum laptop specifications.
SSDs are preferred because hard disk drives are slow, are typically a performance bottleneck, and can be damaged by drops at competition.
While Linux is not required, students generally have a nicer development experience in Linux than in Windows. A virtual machine works for this purpose, but it's slower and more resource-intensive than dual-booting. WPILib officially supports Ubuntu, but a mentor uses Arch.
This page serves as a repository of knowledge for topics the software team has explored in the past and topics alumni are learning in college. Students probably won't be able to learn everything in one year, but students are encouraged to learn outside of build sessions to become effective members as soon as possible.
The material here is not a complete guide. It is intended to complement lectures and discussion.
Don't forget that the internet is a valuable resource for software development and engineering. This includes Google, Google Scholar, Stack Overflow, and Wikipedia. The latter two are most easily utilized through an indexing search engine like Google.
See this section for assignment submission instructions. The available modules are listed below.
Introduces the fundamentals of computer programming and software design. Topics include variables, data types, assignment, expressions, basic I/O, control flow, functions and parameters, scope, and data structures.
Introduces version control systems and their uses. This module is taught using Git. Installation of Git, setting up user identification for commits, and basic workflow are covered, with emphasis on the use of branches to manage work between repositories.
Expands on the set of commands and techniques learned from the previous module with a heavy emphasis on the graph theory operations of Git. Topics include tags, rebasing, and managing repository history. These tools will be applied to working with Gerrit, a code review system.
Covers real-time requirements (e.g., determinism) and methods for meeting them.
State machines are presented as a simple yet effective tool for automating complex robot actions.
Introduces FRC students to the broader field of control theory. The end goal is teaching students enough such that they can make informed decisions regarding control system design trade-offs.
Applies the various skills learned in the previous modules to the control of electromechanical systems in FRC. Robot software design patterns are covered as well as features of WPILib and FRC team 3512's custom classes.
Covers more advanced topics such as threading, synchronization, and concurrency, parallelism, asynchronous data passing (i.e. networking). Proper use of C++11 threads, mutexes, and atomics will be taught. SFML is used to instruct students in the proper use of UDP and TCP sockets, as well as when to use each type.
Introduces writing shell scripts using Bash. Shell scripts will be used to automate sequences of commands to optimize parts of one's workflow.
Introduces the scripting language Python. WPILib's wpiformat will be used as a motivating project.
Introduces website design using HTML, CSS and Javascript. Emphasis is placed on writing HTML5 conformant web pages.
Teaches basic image processing using the OpenCV computer vision library.
Introduces the field of machine learning with the perceptron. A basic example in vision processing is presented.
Introduces designing graphical user interfaces with the Qt graphics toolkit.
The Missing Semester of Your CS Education
Document what students have done at the end of each build session (provides external and internal documentation for hand-off and use by other subteams).
Parentheses at end of line have date range. End of range is due date. Due date uses end of day. Can be M, T, W, Th, F, St, or Sn.
The C++ teaching material has weekly assignments the students are expected to work on outside of build sessions and submit via Git. Mentors review their submissions and provide feedback during code review. The student is only done when review is complete and all issues are addressed. While exercises are nominally weekly, they often stretch into three weeks because students don't do them.
The most common issue during review is formatting mistakes. Students can use wpiformat to fix almost all complaints in this area.
Assignment submissions will be made via Git. To start, make an account on GitHub if you don't already have one. See this cheat sheet for an overview of the most commonly used Git commands. Make commits to your repository as often as you feel is necessary.
The following is an example of the desired Git repository structure and naming scheme for the Intro to C++ module. Your source files may have different names from those shown or not exist. This may look confusing so feel free to ask for help!
src
directory while other files
like licenses, makefiles, READMEs and data go outside of itIt's convention to define main()
in a file called
Main.cpp
, but it isn't required and may not make sense for
projects with only one file.
Submissions will have our formatter run on them. After setting it up
according to these instructions,
place .clang-format,
.styleguide, and .styleguide-license in the
root directory of your repository. You may modify
.styleguide-license
to use your name.
File > Open Folder
in the menu barView >
Command Pallete
in the menu barCMake: Quick Start
, choose a name for the
project, and select an executableTo run your code, type CMake: Build
in the command pallete.
You may need to modify the executable and include path.
Include the following in the .gitignore in the root directory of your Git repository:
build/
If you want to use a different IDE such as Vim, provide a Makefile in
each problem folder to compile the executable. "workspaces" and "projects"
aren't relevant here, but follow the directory layout. Here's an example Makefile which recursively finds all the source
files in the src
directory and compiles Debug and Release
versions of them. The NAME
field should be edited before use.
The following entries should be included in the repository's .gitignore
file:
*.d *.o Debug/ Release/