Motivation
In 2027 FRC teams will be required to use a new robot controller called SystemCore, and the roboRIO retires. FTC teams start moving to the same controller a season later. The hardware arrives with a long list of software changes: a new field coordinate system, a new driver station, a new way of structuring robot programs, four languages including blocks, and four tools retired in favour of better ones. As an FRC coach and mentor, I wanted one place where students and mentors could see what is changing before the new board is on their bench.
These are my notes on the NEMC 2026 session “SystemCore Software: Preparing for the Transition,” presented by the WPILib team (you can watch the recording here). I have redrawn its main ideas as diagrams, several of which you can click on. The order follows how you will meet the changes: what SystemCore is and who it affects, the hardware, what changes inside your code, what changes in the tools around it, and what you can do to get ready now.
One robot brain for FRC and FTC
SystemCore is a new robot controller built specifically for FIRST, and it is shared across both FRC and FTC. Most of the other changes follow from that. Because both programs run the same hardware, they can now run the same software library, and what a student learns in one program carries directly into the other.
The changeover happens at different speeds in the two programs. FRC gets a hard cutover: SystemCore is required starting in the 2027 season, and the roboRIO stops being competition-legal. FTC moves gradually, starting a season later, and the old control hubs stay legal alongside SystemCore for several years.
Who it affects: mostly Java teams, and now FTC too
In the 2026 season, 93% of FRC teams programmed in Java, and most of the rest used C++ or Python. FTC is far more mixed. Android Studio with Java, browser-based OnBot Java, and blocks all have real populations there. WPILib has been in wide use since the 2009 season, and in 2027 it becomes one library shared by both sets of teams.
What is on the board
SystemCore is built on a Raspberry Pi Compute Module 5, which gives it substantially more processor, memory and onboard storage than either the roboRIO or the REV Control Hub. Many of the ports that used to need add-on hardware are now on the board itself. Click any part of the diagram to see what it does.
Pick a port
Every connector on this board used to need something extra, such as a CAN adapter, an expansion hub, a co-processor or a laptop. Tap any highlighted part of the diagram to see what it replaces.
The diagram is keyboard-navigable too: Tab to a port, then press Enter.
Code on the robot
Tools that used to need a desktop can now be served from the controller itself over Wi-Fi: VS Code and the blocks editor in a browser, plus web versions of AdvantageScope and Elastic. A Chromebook is enough to program the robot.
Vision without a co-processor
AprilTag pipelines run on the controller and are configured through a Limelight-style web interface. Object detection needs the add-on Hailo AI module. As a rough budget, expect about the processing power of one Limelight 4.
Room to be sloppy
With this much headroom, loop overruns, out-of-memory errors and Java garbage-collection pauses all become much harder to hit, so the performance ceiling stops being the thing that shapes how you write code.
MotionCore, for FTC
FTC robots pair SystemCore with a second board. MotionCore is the power and communication hub. It takes the 18 V battery, connects to SystemCore over the bridge port, and hands out combined CAN-and-power connections to the new A301 brushless motor.
The field origin moves to the middle
For years, FRC field coordinates started at the blue alliance wall. In 2027 the origin moves to the center of the field. That sounds like bookkeeping, but it matters as soon as you write an autonomous routine that has to work from both alliances. With the old origin you mirror a pose by subtracting it from the field’s length and width; with the new one you flip a sign.
Numbers that know what they are
Let’s say a method takes a double named angle, and you pass it 90, meaning degrees. It wanted radians. Nothing crashes and nothing warns you. The arm swings somewhere it should not, and you spend an evening reading code that looks perfectly correct. Bugs like this have cost teams real matches.
WPILib’s units library removes that whole category of bug. A distance is not a double but a Distance, and its unit is part of its type, so the compiler knows what you are and are not allowed to do with it. You can try to break it below.
What 2027 changes
Every one of those values is an object. Meters.of(1.5) is not a bare number sitting in a register; it is a small object occupying memory. Every operation makes another one, because a.plus(b) returns a new object rather than changing a.
On the roboRIO that cost mattered enough that WPILib shipped a second, cheaper kind of value: a mutable measure, created once and overwritten in place. It was fast, but it was shared, so anyone holding a reference would see it change underneath them. That is a genuinely nasty class of bug to hand a rookie.
For 2027 the mutable versions are gone. WPILib’s stated reason is that SystemCore has significantly more memory and can run better garbage collection algorithms, so the fast but error-prone option is no longer worth the bugs it invites.
Whether that matters depends on something nobody can measure yet. Your loop has twenty milliseconds, and a garbage collection pause spends some of them. More memory makes collections rarer, but it does not make them free. Collecting short-lived objects is cheap on a modern JVM, since the cost scales with what survives rather than with what you threw away, and the compiler can often skip the allocation entirely for values that never leave the method they were made in. Those optimisations are real, but they are also fragile in ways that are hard to predict from reading code.
So this is the one place in the guide where the honest answer is to go and measure it once you have the hardware. Until then, I would keep units at the edges of your code, where values enter from a sensor and leave toward a motor, and use plain numbers inside any loop you have proven to be hot. That costs you nothing and keeps both options open.
Why not just put the units in a config file?
It is the obvious idea, and it is half right. Naming every constant with its unit in one file, as in armMaxHeightMeters, gets rid of the worst offender, the anonymous magic number, and you should do it regardless. But a name is only a comment, and nothing checks that the value you assigned is really in metres. The numbers that cause the most trouble were never in the file to begin with. They arrive at runtime from an encoder in rotations, get divided by a gear ratio, and meet a gyro reading in degrees. What works is to do both: let the config state each unit explicitly and convert to typed values as it loads. The conversion then lives in one place instead of being scattered through your subsystems.
Getting numbers off the robot
You cannot debug a robot by watching it move. You need its numbers: what angle the arm believed it was at, what the encoder read, whether the camera saw a tag. Two different people want those numbers at two different times.
- The driver, during the match. A few values on a screen, such as the battery, whether the shooter is up to speed, and whether the robot knows where it is.
- You, twenty minutes later. Everything, in a file, so you can scrub back through the match and find the moment the arm stopped.
The old SmartDashboard API made those feel like two separate chores. The telemetry API that replaces it handles both with one line of code, and you write it without deciding which case you are serving:
telemetry.log("arm/angle", 42.7);You give it a name and a value, and it works out how to store it. That covers numbers and booleans, poses and other geometry, unit-typed values, and your own types once you teach it how. Where the value goes is configured separately, and that is the part worth understanding.
Op modes: your autonomous chooser, built in
An op mode is a program option the driver can select, and it is an idea FTC has used for years, now arriving in FRC. Each op mode is its own class with its own lifecycle methods, and the driver station lists them in dropdowns for autonomous, teleop and utility (the old test mode, renamed). One op mode is active at a time.
For FRC teams this replaces the SendableChooser you used to publish to a dashboard. In match mode the driver station picks your autonomous op mode, then switches itself to your selected teleop op mode when autonomous ends. Robot code can also add options programmatically, for example one class registering both a left-side and a right-side variant.
OpModeRobot replaces TimedRobot as the base class, but it is optional: TimedRobot still works if you would rather not change.Why this pairs with Commands V3
Triggers and default commands created inside an op mode are automatically scoped to it. They activate when that op mode is selected and are torn down when you switch away, so a competition teleop and a demo teleop can have entirely different button bindings with no conditional logic. That framework has its own visual guide. It is optional too, and Commands V2 keeps working for the next few seasons.
One driver station, both programs, any operating system
FRC and FTC had separate driver station software, and merging the controller means merging those too. The replacement is written by the WPILib team and runs on Windows, macOS and Linux, with a compact touch layout for driver-hub style tablets. FRC teams on an actual field still need Windows, but that is an FMS requirement rather than a WPILib one.
Your autonomous chooser, no dashboard required.
A few other things change in the driver station:
- Consistent joysticks. Button IDs map identically on every operating system, so plugging into a MacBook instead of a Windows laptop does not change your code. Far more gamepads are supported.
- Modes you already know, renamed. Teleop and autonomous are unchanged. Test mode is now utility mode and practice mode is now match mode. In FTC, match mode is what runs real matches, since there is no FMS.
- AdvantageScope inside. Logs are written in the WPILog format, and a built-in web version of AdvantageScope opens with a button, including joystick visualization of what your drivers actually did.
- Status where drivers can see it. Robot code can publish plain text and alerts to the driver station, next to ping times, battery voltage and console output.
Four tools are being retired
Each of these had low usage and a better-maintained replacement. Retiring them follows the same reasoning as the rest of 2027, which is to make the breaking changes once, in a single season, rather than a few every year.
| Retired | What replaces it |
|---|---|
| SmartDashboard | Elastic and the telemetry API. The publishing API is replaced by the telemetry API, and the display by Elastic, a driver dashboard built for match use and fed by a simpler logging call. |
| Shuffleboard | AdvantageScope. Shuffleboard is aging and largely superseded for both live view and analysis. AdvantageScope is now bundled into the driver station as a web app, one click away. |
| RobotBuilder | No direct replacement named. It generated project scaffolding that no longer matches how teams write code. The talk cited low usage and better alternatives without naming one; project templates and the new blocks editor cover most of what teams used it for. |
| PathWeaver | No direct replacement named. Its path authoring has long since been outgrown by community tools. It was again cited as low-usage with better alternatives available, which in practice means the community trajectory tools most teams already use. |
Blocks that are really Python
WPILib 2027 supports four languages: Java, C++, Python, and a new block-based option built on Google Blockly. It is the same idea as Scratch or the SPIKE Prime editor that many students meet in elementary school, and it matters most for FTC, where a large share of teams start in blocks.
The design goal is stated as “raise the floor, don’t lower the ceiling.” Blocks should get a beginner to a working robot, and every block shows the Python it generates, so moving on to text is a translation rather than a fresh start. Blocks projects can also be split into mechanisms and share code between op modes, so they do not have to be one giant pile.
def start(self): while self.encoder.get_distance() < 2.0: self.drive_motor.set(0.5) self.drive_motor.set(0.0)
Getting ready before the hardware exists
Everything below works today, on a laptop, without a SystemCore in the building.
- Install the 2027 alpha. WPILib 2027 alphas are public and install through the normal installer.
- Run desktop simulation. Full simulation lets you try the new APIs, the coordinate change, op modes and Commands V3 on a laptop.
- Try the new driver station. Alpha builds are downloadable now. Point it at a simulated robot and get familiar with the mode selectors before kickoff.
- FTC teams: start with AdvantageScope. It now reads several FTC SDK log formats, so you can pick up the analysis tooling a full season before switching libraries.
- Follow along, or help. Development happens in public on GitHub, and contributions are not limited to the library. The installer, tools and docs all need people.
Limitations
Please read this guide as a forecast. Everything here comes from a talk given during the alpha period, and the presenters were explicit that details may change in response to testing feedback. Pricing and availability will be announced on the FIRST community blog. Treat the specifics as current intent rather than a promise.
Sources
WPILib team. SystemCore Software: Preparing for the Transition. NEMC 2026 session. Watch the recording.
Companion guides: WPILib Commands V3 and coroutines; From your hands to the wheels, how the whole system connects; Fifteen seconds, autonomous and Choreo for beginners.