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.
Why I mentor
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.
Even in college, hands-on engineering projects like FRC are rare. I'm on an FSAE team at UCSC. We don't receive any support from the engineering department (and not for lack of trying) because they are more focused on research. Students should make the most of their FRC experience while they can.
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.
Minimum laptop specifications
For FRC-specific C++ software development, we suggest the following minimum laptop specifications.
- Intel i3 (i5 is preferred)
- 4GB of RAM
- 64GB SSD
- Capable of running Linux
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.
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.
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.
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
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
Teaches basic image processing using the OpenCV computer vision library.
Perceptrons and Artificial Neural Networks
Introduces the field of machine learning with the perceptron. A basic example in vision processing is presented.
Introduces writing applications using the Android SDK. Instruction in the Java programming language is provided as needed.
Graphical User Interfaces
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.
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
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
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
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
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 are presented as a simple yet effective tool for automating complex robot actions.
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.
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.
- cs01-assignments (Git repository root)
- chapter01 (workspace)
- drill02 (project)
- exercise13 (project)
- chapter11 (workspace)
- drill14 (project)
- cool-lab (workspace)
- first-section-name (project)
- Folders use lowercase and files use camel case
- Source code goes in the
srcdirectory while other files like licenses, makefiles, READMEs and data go outside of it
- 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
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:
*.d *.o .metadata/ .settings/ Debug/ Release/ RemoteSystemsTempFiles/
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,
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
*.d *.o Debug/ Release/