Why do this by hand first#
OPR (Offensive Power Rating) is a linear-algebra estimate of how many points each team contributes to its alliance score on average. Work a tiny case by hand and there is nothing left to take on faith, which makes the spreadsheet version much easier to trust and to debug later.
The toy system#
Take three teams A, B, C and three 2-robot matches. Each match's alliance score is the sum of the two robots' contributions:
Match 1: A + B = 40
Match 2: A + C = 30
Match 3: B + C = 50
Three equations, three unknowns, so the system is exactly determined. Solve it:
- Add all three: 2A + 2B + 2C = 120, so A + B + C = 60.
- Subtract each match: C = 60 - 40 = 20; B = 60 - 30 = 30; A = 60 - 50 = 10.
So OPR(A)=10, OPR(B)=30, OPR(C)=20. Sanity check Match 1: 10 + 30 = 40. Correct.
Why real OPR needs least squares#
At a real event each team plays roughly 6-12 qualification matches, so you get far more equations than teams. That system is overdetermined, and it is usually inconsistent as well, meaning no set of values satisfies every match exactly. OPR takes the values that minimize the sum of squared errors instead. In matrix form, let M be the match-design matrix (rows = alliance-matches, columns = teams, 1 if the team is on that alliance) and let s be the vector of alliance scores. The least-squares OPR vector solves the normal equations:
(Mᵀ M) · opr = Mᵀ s
Doing it in Google Sheets#
You do not need to invert anything manually. Sheets has the matrix functions:
- Build matrix M: one row per alliance-match, one column per team, with 1s for the three teams on that alliance.
- Put the alliance scores in vector s.
- Compute
A = MMULT(TRANSPOSE(M), M)andb = MMULT(TRANSPOSE(M), s). - Solve
opr = MMULT(MINVERSE(A), b).
That one MMULT(MINVERSE(MMULT(TRANSPOSE(M),M)), MMULT(TRANSPOSE(M),s)) block does all of the OPR math. For component OPR (e.g., "coral OPR"), keep M identical but swap s for the coral-points-only column from the TBA score breakdown. That gives you an estimate of each team's coral contribution as well as its total points.
Reality check#
OPR assumes contributions are additive and independent. Defense breaks that assumption: a defender lowers the opponent's score, so a defensive robot shows up with a deceptively low or negative OPR. Cooperative tasks break it too. So OPR is a fast baseline you can build without any scouting, but it is not ground truth, and you should cross-check it against your own observed data. The Blue Alliance publishes OPR/DPR/CCWM per event so you can compare your hand-built numbers against theirs to confirm your matrix is correct.
the part worth keeping
Key takeaways
- OPR is solving alliance-score equations; a 3-team toy case is exactly solvable and proves the concept.
- Real OPR is the least-squares solution of the normal equations (MᵀM)opr = Mᵀs, computable with TRANSPOSE/MMULT/MINVERSE in a spreadsheet.
- Component OPR reuses the same M matrix with a phase-specific score column; OPR misrepresents defense, so cross-check it against scouting.
Scouting & StrategyWorked Examples & Mini-Projectslesson 2 of 5
Keep going
Take the quiz+10 XP with an accountMore in Worked Examples & Mini-Projects
where this came from
Sources and corrections
This lesson is AI-assisted: drafted from primary sources, then reviewed and edited by hand. Errors still get through. When one is reported we fix it and write down what changed, in public, in the corrections log.
sources and further reading
- blog.thebluealliance.comThe Math Behind OPR - An Introduction (TBA Blog)
- statbotics.ioStatbotics — FRC component metrics (OPR/EPA)
- github.comcheer4ftc/OPR - reference OPR/MMSE/Least Squares code
clipped to this lesson
Articles that go further on this
The lesson gets you through the topic. These go wider on it, and they read in one sitting.
- 18 min readThe Blue Alliance (TBA): How to Use FRC's Match & Team DatabaseThe Blue Alliance (TBA) is FRC's free match and team database. Navigate team, event, and match pages, set up myTBA notifications, and use its read API./blogread it
- 18 min readOPR, DPR & CCWM in FRC: What Every Scouting Stat Actually MeansOPR, DPR, and CCWM explained for FRC scouts: how each stat is computed with least squares, what it really measures, where it misleads, and how EPA compares./blogread it
- 6 min readFRC Scouting Sheet Template: Printable Paper Sheet + Google Form to Sheets SetupA ready-to-print FRC scouting sheet plus a Google Form to Sheets setup that auto-averages one row per scout into per-team stats, with a 2026 REBUILT note./blogread it
answer sheet
Lesson quiz
All 3 right completes the lesson. Miss one and only that question comes back, anything you already answered correctly stays banked.
0 of 3 answered
01When computing OPR, what does each entry of the design (schedule) matrix M contain?
02Because there are usually more alliance scores than teams, OPR is found by solving which system?
03What does a single value in the solution vector x (the OPR) represent?
Answer every question to submit.
All 32 lessons in Scouting & Strategyopenclose
01 / prerequisites
02 / scouting-fundamentals
03 / building-a-scouting-system
04 / data-analysis-tba-statbotics
05 / strategy-picklists-and-match-play
06 / worked-examples-and-mini-projects
- Not read yet:Project 1: Configure a QRScout Form for REEFSCAPE
- Not read yet:Project 2: Compute OPR by Hand, Then in a Spreadsheet
- Not read yet:Project 3: Pull Live Data with the TBA and Statbotics APIs
- Not read yet:Project 4: Build an EPA-Component Robot Ranking Sheet
- Not read yet:Project 5: Assemble a One-Page Pre-Match Prep Sheet
07 / common-mistakes-and-troubleshooting
08 / advanced-techniques-and-case-studies