🎦 Driver-Focused · Control Schemes

Curvature (Cheesy) Drive

A third control scheme between arcade and tank. Originally invented by FRC Team 254, Cheesy Drive gives beginners the straight-line simplicity of arcade while giving experienced drivers the arc control that rivals tank — in a single joystick.

1
What It Is
2
How It Works
3
The Code
4
Tuning
// Section 01
What Curvature Drive Is
Curvature Drive — nicknamed “Cheesy Drive” after FRC Team 254, The Cheesy Poofs, who popularized it — is a split arcade variant where the turning behavior changes based on how fast the robot is moving.
🏎
The key insight: in normal split arcade, the turn stick adds and subtracts a fixed amount from each drive side regardless of speed. In Cheesy Drive, the turn stick controls the curvature of the robot’s path — meaning the turn output scales with forward speed. Faster speed = wider turns. Slower speed = tighter turns. This is how real vehicles steer.

The Problem With Standard Split Arcade at High Speed

In standard split arcade at high forward speed, pushing the turn stick even slightly causes the robot to veer aggressively. The driver has to be very delicate with the turn input to go roughly straight — which is cognitively expensive at full speed.

Cheesy Drive solves this: when moving fast, the turn response is naturally gentler. The driver can hold a moderate turn input and the robot follows a wide, predictable arc rather than jerking sideways.

The Three Things Cheesy Drive Does

  1. Speed control from throttle stick — same as standard split arcade. Left stick Y = forward/back.
  2. Turn rate scales with speed — when moving fast, the turn input affects curvature (arc radius) rather than adding directly to wheel differential. High speed + turn input = wide arc. Low speed + turn input = tighter turn.
  3. Quick-turn mode at zero speed — when the throttle is at zero, turn input switches to a direct spin-in-place mode. This recovers tank-style spot-turn precision when the robot is not moving.
ℹ️
The SigBots wiki credits this algorithm to FRC Team 254’s 2015 Java code. It has since been adopted widely in VRC because it solves a real driver problem: high-speed turn sensitivity that arcade drive suffers from. Many experienced teams that previously used tank drive find Cheesy Drive easier to adapt to than standard arcade.
// Section 02
How the Math Works
You do not need to understand the math to use Cheesy Drive — but understanding it helps you tune it intelligently for your driver.

Standard Arcade Math (for comparison)

In standard split arcade:

The turn value is added linearly regardless of speed. At max speed (throttle=127, turn=40): left=127, right=87 — a significant difference that causes a sharp turn.

Curvature Drive Math

Cheesy Drive instead calculates:

Live Response Visualizer

⚙️ Cheesy Drive Response Preview
Throttle: 80
Turn: 40
// Section 03
Implementing Cheesy Drive in PROS
Cheesy Drive is a custom control function — it is not built into EZ Template, but it replaces the EZ Template drive call in your opcontrol loop. About 30 lines of code.

Complete Implementation

include/main.h — function declaration
// Add this declaration so opcontrol() can call it void cheesyDrive(double throttle, double turn, bool quickTurn);
src/main.cpp — the Cheesy Drive function
// ── Cheesy Drive Implementation ──────────────────────────────────────── // Based on Team 254's 2015 algorithm, adapted for PROS / VEX V5 // throttle: -127 to 127 (forward/back) // turn: -127 to 127 (left/right) // quickTurn: true when throttle is near zero → spin-in-place mode static double oldTurn = 0; // smoothing memory const double QUICK_STOP_THRESHOLD = 0.2; const double QUICK_STOP_ALPHA = 0.1; const double TURN_SENSITIVITY = 1.0; // increase = more responsive turns void cheesyDrive(double throttle, double turn, bool quickTurn) { double angularPower; double overPower = 0; if (quickTurn) { // Pure spin-in-place — linear turn input if (abs(throttle) < QUICK_STOP_THRESHOLD) { oldTurn = (1 - QUICK_STOP_ALPHA) * oldTurn + QUICK_STOP_ALPHA * turn * 2; } overPower = 1; angularPower = turn; } else { // Curvature mode — turn scales with throttle oldTurn = 0; angularPower = abs(throttle) * turn * TURN_SENSITIVITY - oldTurn; } double left = throttle + angularPower; double right = throttle - angularPower; // Clamp to [-127, 127] if (left > 127) { right -= overPower * (left - 127); left = 127; } if (right > 127) { left -= overPower * (right - 127); right = 127; } if (left < -127) { right += overPower * (-127 - left); left = -127; } if (right < -127) { left += overPower * (-127 - right); right = -127; } // Send to chassis — use EZ Template's direct tank set chassis.opcontrol_tank_set((int)left, (int)right); }
src/main.cpp — inside opcontrol() while loop
// Read inputs int throttle = master.get_analog(ANALOG_LEFT_Y); int turn = master.get_analog(ANALOG_RIGHT_X); // right stick for turning // Apply deadband const int DEAD = 10; if (abs(throttle) < DEAD) throttle = 0; if (abs(turn) < DEAD) turn = 0; // Quick-turn when throttle is near zero bool quickTurn = (abs(throttle) < 15); // Replace chassis.opcontrol_tank() or arcade with this: cheesyDrive(throttle / 127.0, turn / 127.0, quickTurn);
⚠️
Do not use this alongside chassis.opcontrol_tank() or EZ Template’s arcade functions. Replace the EZ Template drive call entirely with cheesyDrive(). EZ Template’s joystick curves and active brake still work — call cheesyDrive() instead of the normal drive function, and set curves/brake in initialize() as usual.
// Section 04
Tuning Cheesy Drive & Who It Suits
Cheesy Drive has two tunable constants that directly control the driving feel. Adjust them based on your driver’s feedback, not by guessing.

The Two Tuning Constants

💡
The driver interview question for Cheesy Drive: “At full speed, do the turns feel too sharp, about right, or too gentle?” Too sharp → decrease TURN_SENSITIVITY. Too gentle → increase it. Run 5 match simulations after each adjustment and ask again.

Who Cheesy Drive Suits Best

Driver ProfileCheesy Drive FitRecommendation
New driver, video game background Excellent More intuitive than standard arcade at high speed. Easier to drive straight. Good starting point for season 1.
Experienced arcade driver Very Good Familiar stick layout with better high-speed feel. Adaptation takes 1–2 weeks. Worth the switch.
Experienced tank driver Moderate Tank drivers find quick-turn intuitive but miss independent side control at slow speeds. Try it during off-season.
Robot with many buttons to operate Good Split arcade layout frees right hand for mechanisms — same benefit as standard split arcade.

Cheesy Drive vs the Other Options — One-Page Summary

FeatureTankSplit ArcadeCheesy Drive
Straight-line easeHard — sync both sticksEasy — one stickEasy — one stick
High-speed turningPreciseToo sensitiveNatural arc
Spot turn (stopped)ExcellentGoodExcellent (quick-turn)
Mechanism accessBoth thumbs on sticksRight hand freeRight hand free
Learning curveSteepGentleGentle
Mechanical failure recoveryBest — independent sidesLimitedLimited
⚙ STEM Highlight Mathematics: Nonlinear Functions & Input Mapping
Cheesy Drive applies a nonlinear function to joystick input. A linear mapping (speed = joystick) gives equal sensitivity everywhere. A cubic or exponential curve compresses sensitivity near zero (fine control when slow) and expands it near maximum (fast response at full stick). Mathematically: output = sign(x) × x² maps −1…1 to −1…1 but concentrates values near zero. The turn-scaling by forward speed (turn × |forward|) is a bilinear interpolation — the turn response depends on two inputs simultaneously.
🎤 Interview line: “Cheesy Drive applies a nonlinear mapping to joystick inputs. We scale turn response proportionally to forward speed using multiplication — which is a bilinear function of two variables. The result is intuitive control: tight turns when slow, gentle arcs at speed, which matches how human drivers naturally think about robot movement.”
🔬 Check for Understanding
In Cheesy Drive, when the robot is moving at full forward speed, what happens to the turn response compared to when it is stationary?
Turn response is the same — the joystick still controls turn rate directly
Turn response is scaled by the forward speed, so it is reduced — you need more stick input to turn at the same rate
The robot cannot turn at full forward speed
Turn response is increased to compensate for forward momentum
Related Guides
🏎 Driver Tuning →🎮 Driver Practice →🤖 Full Robot Code →
← ALL GUIDES