Chapter 1
Getting Started
Install the toolchain, create your first PROS project, and add the LemLib motion-control library.
Why PROS?
VEX robots run on a V5 Brainโa 32-bit ARM processor running at 400 MHz. You can program it with VEXcode (a beginner-friendly IDE), but for competition-level code teams use PROS (Purdue Robotics Operating System).
PROS gives you:
- A full real-time operating system with true multitasking (FreeRTOS under the hood)
- A standard C++ toolchain (GCC), so you can use templates, lambdas, STL containers, etc.
- A rich API mirroring the official VEX SDK
- A package manager (
pros conductor) for community libraries like LemLib
Why LemLib?
LemLib is an open-source motion-control library built on top of PROS. It provides:
- Odometry โ tracks your robot's X, Y, and heading on the field
- PID movement โ
moveToPoint,turnToHeading,swingToHeading - Path following โ smooth curves via Bรฉzier paths
- Chassis abstraction โ configure once, call motion functions everywhere
In this codebase, the Chassis class extends lemlib::Chassis
to add custom distance-reset methods (covered in depth later).
Installation
-
Install PROS CLI.
Download the installer for your OS from pros.cs.purdue.edu or install via pip:pip install pros-cli -
Install the VS Code extension.
Search for "PROS" in the VS Code Extensions marketplace and install it. It wraps the CLI and gives you one-click upload. -
Create a new project.
This scaffolds:pros conduct new-project my-robot --target v5 --version latestmy-robot/ โโโ include/ โ โโโ main.h โ PROS entry-point header โ โโโ api.h โ full PROS API โโโ src/ โ โโโ main.cpp โ initialize, autonomous, opcontrol stubs โโโ Makefile โโโ project.pros -
Add the LemLib template.
This downloads LemLib headers intocd my-robot pros conduct add-depot https://lemlib.github.io/LemLib/depot.json pros conduct apply LemLibinclude/lemlib/and the library binary intofirmware/. -
Build and upload.
Or use the PROS VS Code extension's toolbar buttons.pros make # compile pros upload # send to Brain over USB
Project Entry Points
PROS defines four callback functions that you fill in:
| Function | When it runs | Typical use |
|---|---|---|
initialize() | Immediately on power-on | Calibrate sensors, start background tasks, show LCD |
disabled() | Robot disabled by FMS/switch | Usually empty |
competition_initialize() | Connected to FMS, before auton | Auton selector |
autonomous() | 15-second auton period | Run the selected auton routine |
opcontrol() | 1:45 driver control period | Read controller, drive motors |
Here is the minimal initialize() from this robot:
src/main.cppvoid initialize() { pros::lcd::initialize(); // Start brain LCD display chassis.calibrate(); // Zero IMU + tracking wheels pros::delay(100); // GPS sensor physical offset from robot center (converted m โ inches) gps.set_offset(.75/39.37008, 4.5/39.37008); chassis.setPose(0, 0, 0); // Starting position is the origin optical.set_integration_time(20); // Fast color sampling (ms) optical.set_led_pwm(100); // Background task: print robot state to LCD every 50 ms pros::Task screen_task([&]() { while (true) { pros::lcd::print(2, selectedAuton.c_str()); pros::lcd::print(5, "X: %f", chassis.getPose().x); pros::lcd::print(6, "Y: %f", chassis.getPose().y); pros::lcd::print(7, "Theta: %f", chassis.getPose().theta); pros::delay(50); } }); pros::lcd::register_btn1_cb(on_center_button); // Auton selector button }
Always call
chassis.calibrate() in initialize().
This zeros the inertial sensor and tracking wheel encoders. Skipping it means your
heading will be wrong from the very first movement.