Curriculum and instruction

The mindset of an egoless engineer

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.

Advice for FRC software teams

Engineering is about meeting requirements

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

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.

Know the standard library and WPILib

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).

Be pragmatic in design and implementation

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.

Minimum laptop specifications

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.

Software engineering / robotics

Intro to C++

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.

Intro to Git

Presentation: Git

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.

Intro to real-time software

Presentation: Real-time software

Covers real-time requirements (e.g., determinism) and methods for meeting them.

State machines

Module (90% complete)
Lab: State machine
Lab: Event framework

State machines are presented as a simple yet effective tool for automating complex robot actions.

Control theory

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.

Robot software

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.

Miscellaneous computer science

Program design

Module (0% complete)

Teaches students a systematic approach to program design using the Racket programming language (a derivative of Scheme). Selected topics include data structures such as arrays, lists, and trees; recursion; and binary search.

Advanced C++

Module (30% complete)
Submodule: High performance and embedded
Submodule: Concurrency and atomics
Submodule: Parallelism
Submodule: Networking

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.

Intro to Shell Scripting

Module (20% complete)

Introduces writing shell scripts using Bash. Shell scripts will be used to automate sequences of commands to optimize parts of one's workflow.

Intro to Python

Introduces the scripting language Python. WPILib's wpiformat will be used as a motivating project.

Intro to HTML

Introduces website design using HTML, CSS and Javascript. Emphasis is placed on writing HTML5 conformant web pages.

Computer vision

Module (0% complete)

Teaches basic image processing using the OpenCV computer vision library.

Artificial neural networks

Module (0% complete)

Introduces the field of machine learning with the perceptron. A basic example in vision processing is presented.

Android development

Module (0% complete)

Introduces writing applications using the Android SDK. Instruction in the Java programming language is provided as needed.

Graphical user interfaces

Module (20% complete)

Introduces designing graphical user interfaces with the Qt graphics toolkit.

Lesson plan


Build season

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.

Week 1

Week 2

Week 3

Week 4

Week 5

Week 6

Instruction notes

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 CS 1 module. Your source files may have different names from those shown or not exist.

  1. Folders use lowercase and files use camel case
  2. Source code goes in the src directory while other files like licenses, makefiles, READMEs and data go outside of it
  3. For labs, submit all files used according to this format unless otherwise stated in the lab.

It'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.

Option 1: Eclipse workspaces

The directory tree above provides an example of which folders should be an Eclipse workspace or project within a workspace (parentheses are not part of the name). This ensures the Eclipse projects and their metadata are backed up via Git. If you do this, you'll need to include the following entries in a .gitignore in the root directory of your Git repository:


If you need to clone your repository to a different computer to work projects in what was an existing chapter workspace, choose the chapter folder as a workspace when Eclipse starts up like usual. You can import the problem projects into the workspace by right-clicking on the Project Explorer and selecting Import.... In the resulting dialog, choose General > Existing Projects into Workspace.

Option 2: Alternate editor

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: