Curriculum and Instruction

The Mindset of an 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.

Why I Mentor

Tyler Veness

My time as a student in FRC was basically one giant R&D experience for me. By always being on the cutting edge of 3512, I learned a lot along the way (successes and failures included). This exercise in independent learning made a big impact on my future and I want to give students here the same opportunity. I tell college students this often: "Don't let schooling interfere with your education.". Seek out projects that you're interested in and learn everything you can. It opens a lot of avenues for you later. With that...


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.

Computer Science

Intro to C++

Computer Science 1 (70% complete)

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.

Program Design

Computer Science 2 (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++

Computer Science 3 (30% complete)

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

Computer Science 4 (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

Computer Science 5 (0% complete)

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

Computer Science 7 (0% complete)

Teaches basic image processing using the OpenCV computer vision library.

Perceptrons and Artificial Neural Networks

Computer Science 8 (0% complete)

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

Android Development

Computer Science 9 (0% complete)

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

Graphical User Interfaces

Computer Science 10 (20% complete)

Introduces designing graphical user interfaces with the Qt graphics toolkit.


Intro to 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. 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

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

Control Theory

PID Controllers

Control Theory 1 (90% complete)

Introduces the topic of control systems and how they can improve the performance of a robot. PID controllers are introduced as a versatile tool for control applications in FRC. The dynamics of PID controllers, their types, and procedures for tuning them effectively are also discussed.

Intro to Feedback Control Systems

Control Theory 2 (25% complete)

Develops a more rigorous understanding of control systems through the analysis and design of continuous linear feedback control systems commonly used in FRC. Feedforwards and motion profiles will also be discussed.

Classical Control Theory

Control Theory 3 (20% complete)

Provides an introduction to methods of classical control theory. Frequency domain analysis will be used to characterize systems using their step response. Single input, single output (SISO) systems will be discussed.

Modern Control Theory

Control Theory 4 (30% complete)

Provides an introduction to methods of modern control theory. Design, analysis, and control of multiple input, multiple output (MIMO) systems will be performed using their state-space representations. State estimators such as the Kalman filter are also covered.

Filters and State Estimation

Control Theory 5 (15% complete)

Covers why filters are necessary, how to represent them with transfer functions and state-space models, and how to discretize them for use in digital signal processing. A few common ones will be discussed using WPILib's LinearDigitalFilter class for examples.


State Machines

FRC 1 (90% complete)

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

Robot Software

Applies the various skills learned in RT 1, CS 1, and CT 1 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.

Scouting Application

FRC 2 (25% complete)

Focuses on writing a software application for scouting during FRC competitions. This has typically been written in conjunction with a spreadsheet which receives the scouting data. HTML web pages and Android applications have been used in the past.


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: