Three constants, three failure modes each. Once you can name the symptom, the cause is usually obvious.
flowchart TD
Start([Run pid_drive_set
and observe behavior]) --> Q1{What did
it do?}
Q1 -->|"Stopped short of target"| Short[kP too low
OR exit_condition triggered early
FIX: increase kP 10-20%
OR loosen exit_condition]
Q1 -->|"Overshot past target"| Over[kP too high
OR kD too low
FIX: decrease kP
OR add kD around 10x kP]
Q1 -->|"Wobbled/oscillated"| Wob[kP way too high
OR system has lag
FIX: cut kP in half
add small kD]
Q1 -->|"Settled slowly near target"| Slow[Steady-state error
kI needed
FIX: add small kI 0.05-0.1]
Q1 -->|"Worked correctly"| Done([Tuned])
style Start fill:#1e293b,stroke:#22d3ee,stroke-width:2px,color:#e2e8f0
style Done fill:#1e293b,stroke:#22c55e,stroke-width:2px,color:#e2e8f0
style Q1 fill:#fbbf24,color:#0f172a,stroke:#fbbf24
style Short fill:#7c2d12,color:#fef3c7,stroke:#fbbf24
style Over fill:#7c2d12,color:#fef3c7,stroke:#fbbf24
style Wob fill:#7f1d1d,color:#fecaca,stroke:#ef4444
style Slow fill:#7c2d12,color:#fef3c7,stroke:#fbbf24
Identify exactly what's wrong with your robot's movement — and know exactly which constant to change. Symptom → diagnosis → fix.
The robot creeps toward the target with very little force. It might time out before reaching it, or crawl in at less than walking speed.
The robot reaches the target but continues past it by several inches before stopping (or coming back).
The robot reaches the approximate target but keeps rocking back and forth, over-correcting, unable to settle.
The robot reliably stops just short of the target — always the same distance short. It's not oscillating, just slightly under.
pid_exit_condition_set() so the robot doesn't exit too early.
When commanded to drive straight, the robot arcs to the left or right instead of going in a straight line.
pid_heading_constants_set() kP. Default is around 11.0 — try 13–15 if drifting. The heading PID runs in the background during drives to keep the robot pointed correctly.
Robot spins past the target angle by 10–30° or more. Sometimes comes back, sometimes just keeps going.
The robot creeps to the target angle or gets very close but then takes 2–3 seconds of tiny adjustments to finally settle.
pid_turn_exit_condition_set() might be too strict, causing it to wait unnecessarily.
Tuned on your practice field but doesn't hit the same angles at the competition venue.
default_constants() function in autons.cpp. The tuner does NOT save automatically — you must copy the numbers into code manually.You can add your own subsystem PIDs (arm, lift, etc.) to the tuner so you can tune them the same way:
Always tune with a repeatable test — don't use your actual autonomous. Write a dedicated tuning routine:
(0.0, 0.0, 0.0). Run test — robot does nothing (expected).(0.0, 0.0, 0.0).Swing turns pivot using only one side of the drive. EZ Template supports these with pid_swing_set(). They need their own constants: