Sources & confidence: EZ-Template installation and chassis API verified at ez-robotics.github.io/EZ-Template. LemLib chassis constructor and OdomSensors API verified at the official LemLib documentation and GitHub. PROS template architecture (one chassis library = one PROS template) verified against PROS documentation. RECF EN4 student-centred policy on libraries verified against the LemLib FAQ — teams using a library must understand its algorithms at a high level.
// Section 01

Toolchain Onboarding for V5RC 🛠️

Four tools, one stack. Visual Studio Code is your editor. PROS is your runtime. EZ-Template (or LemLib) is your chassis library. This guide walks new team members through each, what they do, and how they fit together.
🎓 New-Team Friendly 🎯 Spartan Design Stack 📚 Good Practice

The Stack at a Glance

VS CodeThe editor where you write your C++ code. Free, cross-platform, Microsoft-maintained. Has a PROS extension that integrates the build/upload workflow.
PROSThe operating system / runtime that runs on the V5 Brain. Provides the C++ API for motors, sensors, tasks, etc. Open-source, maintained by Purdue SIGBots. Underneath: FreeRTOS.
EZ-TemplateA PROS template (library) for chassis movement. Wraps drivetrain motors and the IMU into a chassis object. Provides PID drive, turn, swing, odometry, auton selector. Spartan Design's primary chassis library.
LemLibA PROS template that competes with EZ-Template. Similar feature set, different API style. Inspired by EZ-Template and OkapiLib. Alternative to EZ-Template, not a complement.

The Three Big Questions This Guide Answers

  1. How do I install all four? — Sections 02–05.
  2. Can I use EZ-Template AND LemLib in the same project? — Section 06. Short answer: technically yes, practically no, and we recommend against it.
  3. What does good practice look like? — Section 07. Project structure, naming, version control, code review.

Why This Stack Specifically

Spartan Design uses VS Code + PROS + EZ-Template because:

This guide doesn't try to talk you out of any of these choices. It teaches you how to use them well.

Related Guides

// Section 02
Visual Studio Code 💻
Your editor. Free. Cross-platform (Windows, macOS, Linux, Chromebook with Linux container). The same VS Code that professional engineers use daily.

What VS Code Does

What VS Code does NOT do: compile or upload your code by itself. The PROS toolchain handles that, invoked through VS Code commands.

Installation Steps

  1. Download VS Code from code.visualstudio.com. Install with default settings.
  2. Open VS Code. Go to the Extensions panel (left sidebar, blocks icon).
  3. Search for "PROS". Install the official PROS extension (published by purduesigbots).
  4. The PROS extension will prompt you to install the PROS CLI and the toolchain (the C++ compiler and tools targeting the V5 Brain). Accept the prompts.
  5. On first install, this can take 10–30 minutes depending on your network. The toolchain is large.

Recommended VS Code Extensions

PROSThe official PROS extension. Required for V5RC work in this stack.
C/C++ (Microsoft)Adds IntelliSense, debugging support, and proper C++ syntax handling. Required for autocomplete to work on PROS APIs.
GitLensOptional but highly useful. Shows git blame inline (who wrote which line, when). Speeds up code review.
Better CommentsOptional. Highlights TODO, FIXME, and other comment markers in distinct colors. Great for shared codebases.
Live ShareOptional. Lets multiple team members edit the same file in real time. Useful for pair programming.

Day-One Setup Tips

What Goes Wrong

⚠️ Common First-Day Issues
  • PROS CLI not in PATH. The PROS extension installs the CLI but sometimes doesn't add it to your shell's PATH. Reopen VS Code, or restart your terminal.
  • IntelliSense red squiggles everywhere. Usually means C/C++ extension hasn't found the PROS includes. Run PROS > Conductor > Apply Template to refresh.
  • Build fails immediately. Check that you're inside an actual PROS project (there should be a project.pros file in the root). VS Code can be opened without a project — PROS commands then fail.
  • USB-C cable doesn't connect. Some USB-C cables are charge-only and lack data lines. Use the cable that came with your V5 Brain, or known-good data cables.
// Section 03
PROS ⚙️
Purdue Robotics Operating System. Open-source firmware/runtime for the V5 Brain, plus a CLI and a C++ API. Maintained by Purdue SIGBots. The base layer of everything else in this stack.

What PROS Provides

Project Structure

A standard PROS project looks like this:

my-project/ src/ main.cpp // your code: initialize(), opcontrol(), autonomous() subsystems.cpp // your sensor and motor definitions autons.cpp // your auton routines include/ main.h // includes pros/api.h and EZ-Template subsystems.hpp // extern declarations of your motors/sensors firmware/ EZ-Template@x.x.x.zip // installed PROS templates project.pros // PROS project metadata Makefile // build script (rarely edited)

The Three PROS Lifecycle Functions

Every PROS project defines three functions. The runtime calls them at the right time:

1

initialize()

Runs once at brain power-on, before anything else. Use for: sensor calibration (IMU especially), display initialization, starting background tasks. Blocking calls here are OK — the brain is not in a match yet.

2

autonomous()

Runs once when the autonomous period starts (15 seconds in match, 60 seconds in skills). Your auton routine goes here. Returns when the routine finishes; runtime stops calling it.

3

opcontrol()

Runs in a loop during the driver-controlled period. Reads controller input, sets motor power, runs driver-assist macros. Should NOT block — structure as a while(true) { ... pros::delay(20); } loop.

Common PROS CLI Commands

prosv5 conduct new my-project # create a new project prosv5 build # compile your code prosv5 upload # upload to V5 Brain (must be plugged in) prosv5 mu # build + upload + run terminal in one command prosv5 terminal # open serial terminal to brain (printf output) prosv5 conduct apply EZ-Template # add EZ-Template to project

VS Code's PROS extension provides GUI buttons for build/upload, but the CLI is faster once you're comfortable with it.

Why PROS Over VEXcode

The trade: PROS is harder for absolute beginners. VEXcode's drag-and-drop blocks make "make the robot move forward" trivial. PROS makes "coordinate three subsystems with sensor feedback" tractable. Different tools for different stages.

// Section 04
EZ-Template 🏌
Spartan Design's primary chassis library. A PROS template that wraps drivetrain motors + IMU into a chassis object with PID drive, turn, swing, and async motion. Created by EZ-Robotics, MIT-licensed, actively maintained.

What EZ-Template Provides

Installation

  1. Open your PROS project in VS Code.
  2. Open VS Code's integrated terminal.
  3. Run: prosv5 conduct fetch https://github.com/EZ-Robotics/EZ-Template/releases/latest/download/EZ-Template@latest.zip (URL pattern; check ez-robotics.github.io/EZ-Template for the current release URL).
  4. Run: prosv5 conduct apply EZ-Template to apply the template to your project.
  5. EZ-Template publishes a complete example project at github.com/EZ-Robotics/EZ-Template-Example. Easier path: clone that repo and rename it for your project.

The Chassis Constructor

From EZ-Template's installation tutorial:

// EZ-Template chassis constructor
// EN4: rewrite in your own words for your notebook. ez::Drive chassis( // Drive motors. The first motor is used as the "sensing" motor. {1, 2, 3}, // Left chassis ports (negative port = reversed) {-4, -5, -6}, // Right chassis ports (negative port = reversed) 7, // IMU port 4.125, // Wheel diameter (4" wheels w/o screw holes are actually 4.125) 343.0 // Wheel RPM = motor cartridge * (motor gear / wheel gear) );

That's it — you've declared a chassis with 6 drive motors and an IMU. The chassis object now has dozens of methods (chassis.pid_drive_set, chassis.opcontrol_tank, etc.).

Common EZ-Template Patterns

// Driver control in opcontrol
void opcontrol() { chassis.drive_brake_set(MOTOR_BRAKE_COAST); while (true) { ez_template_extras(); // EZ-Template housekeeping chassis.opcontrol_tank(); // tank drive // ...other driver code (mechanisms, macros)... pros::delay(ez::util::DELAY_TIME); } }
// Auton routine
void my_auton() { chassis.pid_drive_set(24_in, DRIVE_SPEED, true); chassis.pid_wait(); chassis.pid_turn_set(90_deg, TURN_SPEED); chassis.pid_wait(); chassis.pid_drive_set(-12_in, DRIVE_SPEED); chassis.pid_wait(); }
// Auton selector setup
void initialize() { ez_template_print(); pros::lcd::register_btn0_cb(ez::as::page_down); pros::lcd::register_btn2_cb(ez::as::page_up); ez::as::auton_selector.autons_add({ Auton("Red Left", red_left_auton), Auton("Red Right", red_right_auton), Auton("Skills", skills_auton), }); } void autonomous() { chassis.drive_imu_reset(); chassis.drive_sensor_reset(); chassis.drive_brake_set(MOTOR_BRAKE_HOLD); ez::as::auton_selector.selected_auton_call(); }

Why EZ-Template for Spartan Design

What EZ-Template Does NOT Do

Same as we've said in the sensor guides: EZ-Template wraps the chassis only. It does NOT wrap:

For all of those you use the standard PROS API (pros::Optical, etc.) and compose them with EZ-Template chassis calls in your auton code. See the sensor onboarding roadmap.

// Section 05
LemLib 🌿
An alternative chassis library to EZ-Template. Same problem space, different API. Inspired by EZ-Template and OkapiLib. Worth knowing about even if you stay on EZ-Template.

What LemLib Provides

Per the LemLib README: it's an open-source PROS template "inspired by EZ-Template and OkapiLib."

Installation

  1. Same PROS project structure as EZ-Template.
  2. Run: prosv5 conduct fetch [LemLib release URL] — check the LemLib GitHub for the current latest release URL.
  3. Run: prosv5 conduct apply LemLib.
  4. Follow the LemLib chassis setup tutorial (currently at the LemLib documentation).

The LemLib Chassis Constructor

LemLib uses a more decomposed setup than EZ-Template. From the LemLib docs:

// LemLib drivetrain definition
// EN4: rewrite in your own words for your notebook. pros::MotorGroup left_motors({1, 2, 3}, pros::MotorGearset::blue); pros::MotorGroup right_motors({-4, -5, -6}, pros::MotorGearset::blue); lemlib::Drivetrain drivetrain( &left_motors, &right_motors, 11.0, // track width (inches) lemlib::Omniwheel::NEW_4, // wheel diameter 360, // drivetrain rpm 8 // horizontal drift ); pros::Imu imu(7); lemlib::OdomSensors sensors( nullptr, // vertical tracking wheel 1 nullptr, // vertical tracking wheel 2 nullptr, // horizontal tracking wheel 1 nullptr, // horizontal tracking wheel 2 &imu // IMU ); // PID controllers (you tune these) lemlib::ControllerSettings linearSettings(/* kP, kI, kD, ... */); lemlib::ControllerSettings angularSettings(/* kP, kI, kD, ... */); lemlib::Chassis chassis(drivetrain, linearSettings, angularSettings, sensors);

LemLib Auton Pattern

// LemLib auton
void my_auton() { chassis.setPose(0, 0, 0); // X, Y, theta in inches/degrees chassis.moveToPoint(24, 0, 4000); // X, Y, timeout in ms chassis.waitUntilDone(); chassis.turnToHeading(90, 2000); chassis.waitUntilDone(); chassis.moveToPose(24, 24, 90, 4000); // move to pose AND face heading chassis.waitUntilDone(); }

EZ-Template vs LemLib — A Fair Comparison

Beginner FriendlinessEZ-Template wins. Simpler chassis constructor, plug-and-play example.
Odometry & Path FollowingLemLib wins for advanced motion. Pure Pursuit with imported paths is first-class. EZ-Template has Pure Pursuit too but more recently added.
Auton SelectorEZ-Template ships one. LemLib doesn't — you write your own.
Live PID TuningEZ-Template ships a controller-based tuner. LemLib doesn't.
API StyleEZ-Template: command-pattern (pid_drive_set + pid_wait). LemLib: more modern, methods like moveToPoint, moveToPose, follow.
DocumentationBoth good. EZ-Template's tutorials are more linear; LemLib's are more reference-style.
RECF LegalityBoth are V5RC legal per RECF student-centred policy. You must understand how the algorithms work at a high level if asked by a judge.

When to Pick LemLib Over EZ-Template

Pick LemLib if:

Stay on EZ-Template if:

Spartan Design's recommendation: stay on EZ-Template through your first season at minimum. Re-evaluate after.

// Section 06
Can You Use EZ-Template AND LemLib Together? 🤔
The honest answer: technically yes. Practically no. Recommended: never. Here's why.
Spartan Design recommendation: do NOT use both libraries in the same project. Pick one. The reasons are technical, organizational, and pedagogical. All three matter.

Why It's Technically Possible

EZ-Template and LemLib are both PROS templates. PROS allows multiple templates in one project. There's no compiler error from including both. You could write code that creates both an ez::Drive chassis_ez and a lemlib::Chassis chassis_lem in the same file.

Why It's Practically Bad

⚙ Reason 1: Both Libraries Want to Own the Drivetrain

EZ-Template's chassis object holds references to the drive motors. LemLib's Chassis object holds MotorGroup references to the same motors. If both try to drive the same motors at the same time, the last write wins — you get jitter, opposing forces, or completely unpredictable behavior. You'd have to manually arbitrate which library "owns" the drive at each moment, defeating the purpose of using a library.

⚙ Reason 2: Both Calibrate the IMU

EZ-Template calls imu.reset() at chassis construction. LemLib calls imu.calibrate() via chassis.calibrate(). If both try to calibrate the IMU at startup, you'll get a calibration race — one finishes, the other starts a new one, and your "ready" signal lies. Per the LemLib chassis header: "this should only be necessary if you are using a different library that calibrates the IMU" — the project authors are aware of this exact conflict.

⚙ Reason 3: Two Odometry Estimates That Disagree

If both libraries are tracking position from the same wheel encoders + IMU, they'll produce two slightly different estimates due to differences in their integration math, sample timing, and filter implementations. Your code now has to choose which one to trust at any given moment — an unsolvable problem for new programmers.

⚙ Reason 4: Confused Code Reviews and Onboarding

A new team member reading chassis_ez.pid_drive_set(24_in) on one line and chassis_lem.moveToPoint(24, 0, 4000) on the next has to learn both APIs to understand the auton. That doubles the onboarding burden. For RECF EN4 reviews, you have to explain to judges why both exist — with no good answer.

⚙ Reason 5: Larger Binary & Slower Builds

Including both adds compile time and binary size. Not catastrophic on the V5 Brain (it has plenty of flash), but unnecessary.

The Only Defensible "Both" Pattern

There is one narrow case where having both installed (but not actively running) might be acceptable: a temporary migration. Example: your team is moving from EZ-Template to LemLib. For a few weeks, you have both installed while you port one auton routine at a time. Even then:

This is the only pattern Spartan Design considers acceptable. Any longer coexistence is a sign of indecision, not engineering.

What If We Want Features From Both?

Look for those features somewhere else:

How to Actually Decide

  1. Pick one library based on the comparison in Section 05.
  2. Use it for an entire season.
  3. At end-of-season, in your post-season retrospective, evaluate whether the other library would have served better.
  4. Migrate before the next season if you decide to switch.

Don't mix them mid-season. Don't maintain a compromise project that uses bits of each. Pick. Commit. Reassess later.

// Section 07
What Good Practice Looks Like 🏆
Concrete patterns that separate teams who win from teams who debug. None of these are unique to V5RC — they're standard software engineering practice scaled to the season.

1. Project Layout

Spread your code across files by responsibility, not by season:

src/ main.cpp # initialize(), opcontrol(), autonomous() — thin subsystems.cpp # motor / sensor instance definitions autons/ red_left.cpp # one auton per file red_right.cpp blue_left.cpp blue_right.cpp skills.cpp mechanisms/ arm.cpp # arm subsystem (with its sensor task) intake.cpp # intake subsystem climb.cpp # climb subsystem utilities/ calibration.cpp # brain screen calibration prints color_classify.cpp # Optical Sensor color classification include/ subsystems.hpp # extern declarations matching subsystems.cpp autons.hpp mechanisms/ arm.hpp intake.hpp climb.hpp

This means every file has a single, obvious purpose. New team members can find "the arm code" without reading main.cpp.

2. Naming & Constants

3. Version Control (Git)

For full setup and workflow details — including the team-mentor pull-request flow, conflict resolution, recovery patterns, and competition-day Git checklist — see the dedicated Git & GitHub Workflow Deep Dive. The bullets below are the high-level rules; the deep dive is what your programming mentor and team should read first.

Every team should use Git, even small teams. Reasons:

The minimum useful workflow:

  1. Create a private GitHub repo for your team's code.
  2. Every programmer commits their changes at the end of every session, with a meaningful commit message.
  3. Before competition, tag the working version (e.g., v1.0-statefair) so you can return to it.
  4. Don't commit binaries or compiled output. Add a .gitignore for bin/ and similar.

4. Code Reviews

5. Sensor Discipline

From the sensor onboarding roadmap:

6. Test Discipline

7. Engineering Notebook Integration

8. Pre-Match Checklist Discipline

Per the sensor roadmap checklist: every match should follow the same power-on, sensor-test, auton-selection sequence. Discipline beats heroics.

The Single Most Important Principle

🎯
Reliability beats sophistication. A simple, well-tuned auton that works 95% of the time wins more matches than a vision-corrected, GPS-resetted, AI-classified auton that works 60% of the time. Build robust before you build clever. Most of the practices in this section are about making your robot boring — in the best way.
← ALL GUIDES