Lesson 1: C++ Basics
This lesson covers fundamental C++ concepts you need to read and write FRC robot code. We'll focus on the essentials: variables, functions, classes, references, and how C++ programs are organized with headers and includes.
Who This Is For
If you're new to programming or coming from another language, this lesson provides a practical foundation. The goal is to help you understand existing FRC code (like state machines, command factories, and subsystem patterns) and start making your own contributions.
Variables and Types
Variables store data in your program. In C++, every variable has a type that determines what kind of data it holds and how much memory it uses.
Basic Types
// Integer types
int robotState = 0; // Whole numbers (-2147483648 to 2147483647)
bool isEnabled = true; // Boolean: true or false
double motorSpeed = 0.5; // Floating-point numbers (decimals)
// Text
std::string teamName = "TEAM1771"; // String of characters
// Auto type deduction (C++11+)
auto currentTime = 2.5; // Compiler figures out it's a double
FRC Context
In robot code, you'll see types like:
intfor counters, state indices, button IDsdoublefor motor speeds, sensor readings, timestampsboolfor flags like "is the mechanism ready?"std::stringfor dashboard labels
Key Point: C++ is statically typed—you declare the type upfront, and it doesn't change. This catches errors early.
Further Reading
Functions
Functions are reusable blocks of code that perform a specific task. They can accept inputs (parameters) and return outputs.
Basic Function Syntax
// Function that takes two integers and returns their sum
int add(int a, int b) {
return a + b;
}
// Function with no return value (void)
void printStatus(std::string message) {
std::cout << message << std::endl;
}
// Function with no parameters
double getCurrentTime() {
return 42.0; // Placeholder
}
FRC Context
In robot code, functions help organize logic:
processState()in subsystems handles state machine transitionssetDesiredStateCmd()creates commands that request state changesPeriodic()runs telemetry callbacks every robot loop
Key Point: Functions let you break down complex robot behavior into manageable, testable pieces.
Further Reading
Classes
Classes bundle data (member variables) and functions (methods) together. They're the foundation of object-oriented programming and WPILib's command-based architecture.
Basic Class Example
class Motor {
private:
double m_speed; // Member variable (m_ prefix is team convention)
bool m_isInverted;
public:
// Constructor: runs when you create a Motor object
Motor() : m_speed(0.0), m_isInverted(false) {}
// Method to set speed
void setSpeed(double speed) {
m_speed = m_isInverted ? -speed : speed;
}
// Method to get speed
double getSpeed() const {
return m_speed;
}
};
// Using the class
Motor leftMotor;
leftMotor.setSpeed(0.5);
FRC Context
In FRC code, classes represent:
- Subsystems:
ExampleSubsystem,Climber,Intake - Commands:
RunOnce,Run, custom command classes - Utilities: Controllers, state machines, telemetry helpers
Each subsystem is a class with:
- Private hardware objects (motors, sensors)
- Public command factories (
setDesiredStateCmd(),runSubsystemCmd()) - State machine logic in
processState()
Key Point: Classes encapsulate robot mechanisms, hiding hardware details and exposing high-level control.
Further Reading
References
References are aliases to existing variables. They let you access or modify a variable without copying it.
Reference Basics
int count = 10;
int& ref = count; // ref is a reference to count
ref = 20; // Changes count to 20
std::cout << count; // Prints: 20
Pass by Reference
// Pass by value (copies the variable)
void incrementCopy(int x) {
x = x + 1; // Only changes local copy
}
// Pass by reference (modifies the original)
void incrementRef(int& x) {
x = x + 1; // Changes the original variable
}
int value = 5;
incrementCopy(value); // value is still 5
incrementRef(value); // value is now 6
Const References
// Pass by const reference (read-only, no copy)
void printMessage(const std::string& message) {
std::cout << message << std::endl;
// Can't modify message here
}
FRC Context
References are everywhere in FRC code:
- Passing large objects efficiently (avoid copying)
- Returning state snapshots:
const StateSnapshot& getState() - Lambda captures:
[&]captures variables by reference
Key Point: Use references to avoid expensive copies and to modify variables in place.
Further Reading
- TEAM1771 Crash Course: References & Pointers
- The Cherno: References in C++
- The Cherno: Pointers in C++ (related topic)
Includes and Header Files
C++ programs are split into header files (.h) and implementation files (.cpp). This separation keeps declarations public and implementation details private.
Header File (.h)
// Motor.h
#pragma once // Prevents multiple inclusion
class Motor {
private:
double m_speed;
public:
Motor();
void setSpeed(double speed);
double getSpeed() const;
};
Implementation File (.cpp)
// Motor.cpp
#include "Motor.h"
Motor::Motor() : m_speed(0.0) {}
void Motor::setSpeed(double speed) {
m_speed = speed;
}
double Motor::getSpeed() const {
return m_speed;
}
Using the Class
// RobotContainer.cpp
#include "subsystems/Motor.h"
Motor myMotor;
myMotor.setSpeed(0.75);
FRC Context
In robot code:
- Headers (
ExampleSubsystem.h) declare the class interface: public methods, state enums, state snapshots - Implementation (
ExampleSubsystem.cpp) contains the actual logic:processState(), command factories, telemetry registration - Includes bring in WPILib classes:
<frc2/command/SubsystemBase.h>,<frc/smartdashboard/SmartDashboard.h>
Key Point: Headers let other files see what a class does without seeing how it does it. This keeps compilation fast and code modular.
Include Guards
// Old style (still works)
#ifndef MOTOR_H
#define MOTOR_H
// ... class definition ...
#endif
// Modern style (preferred)
#pragma once
// ... class definition ...
FRC Note: TEAM1771 uses #pragma once for simplicity.
Further Reading
Reading FRC Code
Now that you know the basics, you can understand patterns in FRC robot code:
State Machine Pattern
// In ExampleSubsystem.h
enum class STATE { OFF, ON, IDLE };
// In ExampleSubsystem.cpp
void ExampleSubsystem::processState() {
switch (m_desiredState) {
case STATE::OFF:
handleOffState();
break;
case STATE::ON:
handleOnState();
break;
case STATE::IDLE:
handleIdleState();
break;
}
}
What's happening?
enum class STATEdeclares possible states (variables with a custom type)processState()is a function that checks the current stateswitchstatement routes to the right function for each state- Each
handle*State()function contains the logic for that state
Command Factories
frc2::CommandPtr ExampleSubsystem::setDesiredStateCmd(STATE state) {
return frc2::cmd::RunOnce([this, state]() { m_desiredState = state; }, {this});
}
What's happening?
- This function returns a command (reusable block of robot logic)
RunOnceruns a lambda function exactly once[this, state]captures the subsystem and state by value- The lambda sets
m_desiredState(member variable reference)
Hold-to-Run Bindings
m_controller.R2().WhileTrue(m_exampleSubsystem.setDesiredStateCmd(STATE::ON))
.OnFalse(m_exampleSubsystem.setDesiredStateCmd(STATE::OFF));
What's happening?
R2()gets a reference to the R2 buttonWhileTrue()runs a command while the button is heldOnFalse()runs a command when the button is released- Commands call functions that change subsystem state variables
Going Deeper
This lesson covers the essentials, but C++ has much more to explore. When you're ready for more depth:
TEAM1771 Crash Course Wiki
The TEAM1771 Crash Course is a comprehensive resource that covers:
- Common C++ features (loops, conditionals, arrays, vectors)
- Advanced topics (smart pointers, templates, lambdas)
- FRC-specific libraries (WPILib, Phoenix, REVLib)
- Best practices for robot code
When to use it: If you see unfamiliar syntax in robot code or want to understand a specific feature in detail.
The Cherno's C++ Playlist
The Cherno's C++ series is a high-quality video course covering C++ from beginner to advanced.
Recommended videos (in addition to those linked above):
- Control Flow in C++ (if/else, switch, loops)
- Const in C++
Tip: You can skip videos about Visual Studio setup—we use VS Code with WPILib extensions instead.
Practice Project
Ready to write some C++? Check out the 01-cpp-basics project in the projects/ folder of the Bootcamp repository to practice these concepts with a hands-on interactive exercise.
The project involves:
- Creating a simple class
- Reading user input from the command line
- Processing data with functions
- Printing results
No WPILib required—run it in any C++ editor or locally with g++.
Next Steps
After completing this lesson and the practice project:
- ✅ Review code in
projects/00-setup-check/with your new C++ knowledge - 📖 Study the Style Guide to see how these concepts apply to team patterns
- 🚀 Move to the next lesson to learn more about WPILib command-based programming
Additional Resources
- WPILib Documentation
- TEAM1771 Crash Course Wiki
- The Cherno C++ Playlist
- C++ Reference - For looking up specific language features