
Diagnosing Roll and Pitch Oscillations in ArduPilot RATE and ATT Logs
Key Takeaway
ArduPilot roll/pitch oscillations show up as RATE.R deviating from RATE.RDes or ATT.Roll deviating from ATT.DesRoll. The fix depends on frequency: above 10 Hz means D gain too high or harmonic notch not configured; below 5 Hz means P gain too high. Identify the frequency from an FFT plot before touching any gain — the wrong fix makes the wrong band worse.
TL;DR: Roll/pitch oscillations show up in ArduPilot logs as the achieved attitude rate (RATE.R) or angle (ATT.Roll) tracking a desired value with periodic error. The diagnosis depends on frequency: above ~10 Hz the cause is almost always rate-loop D gain too high or motor noise leaking through; below ~5 Hz the cause is rate-loop P too high, structural flex, or saturation. Identify the frequency, then apply the matching fix — the wrong fix for the wrong band makes things worse.
What the log carries
Two messages do most of the work. ATT records the attitude controller's desired vs achieved angle:
ATT TimeUS DesRoll Roll DesPitch Pitch DesYaw Yaw ErrRP ErrYaw AEKF
RATE records the rate-loop equivalent — the layer that actually drives the motor mix:
RATE TimeUS RDes R ROut PDes P POut YDes Y YOut ADes A AOut AOutSlew
RATE.R follows RATE.RDes with under 50 ms of lag in a healthy tune. ATT.Roll follows ATT.DesRoll with a similar relationship at the angle layer. Sustained oscillation appears as a sinusoidal error between the two.
Reading the frequency
The fix depends on the oscillation frequency, so identify it first. In Mission Planner, plot RATE.R versus RATE.RDes for the affected axis, zoom into a few seconds of oscillation, and count peaks per second. In MAVExplorer:
MAV> graph RATE.RDes RATE.R
MAV> graph ATT.DesRoll ATT.Roll
MAV> fft RATE.R
The FFT plot tells you the dominant frequency directly. Three bands matter:
- Above 30 Hz — almost always motor noise leaking through the gyro filter. The harmonic notch isn't configured or isn't tracking. See ArduPilot's harmonic notch setup.
- 10–30 Hz — rate-loop D gain too high.
ATC_RAT_RLL_Dis amplifying gyro noise into motor commands. - Below 10 Hz — rate-loop P gain too high (very fast) or structural / payload coupling (slower).
- Below 1 Hz — angle-loop P (
ATC_ANG_RLL_P) is over-aggressive, or the position controller is fighting itself in Loiter.
The decision tree
- High-frequency whine, motors audibly humming. Look at
VIBE.VibeX/Y/Z. If they're above 30 m/s², the problem is mechanical — balance props, check motor mounts, foam the FC, and re-fly before touching gains. If VIBE is clean, dropATC_RAT_RLL_Din 25% steps and re-fly. - Visible roll wobble in hover. 5–10 Hz. Drop
ATC_RAT_RLL_Pin 10% steps and confirm the wobble decreases. If the wobble persists with low P, the airframe likely has structural flex. - Slow wallowing in Loiter or PosHold. Below 1 Hz, often with
RATE.ROutnot saturating. ReduceATC_ANG_RLL_P, or if you also seePSCN.PNoscillating againstPSCN.DPN, tune the position controller (PSC_VEL_XY_P). - Oscillation only on one axis. Check the motor balance on that side. Strap into a hover stand and measure RPM per motor at hover throttle — one motor delivering less thrust than the others produces a single-axis wobble.
The harmonic notch comes before any gain tweak
Modern Copter builds rely on INS_HNTCH_* to suppress motor noise before the rate loop sees it. If the notch isn't tuned:
- Set
INS_LOG_BAT_OPT = 4andINS_LOG_BAT_MASK = 1for one tuning flight. - Hover for at least 30 seconds.
- Open Mission Planner → Setup → Advanced → FFT → IMU Batch Sample — load the .bin.
- Read the peak frequency from the pre-filter gyro spectrum.
- Set
INS_HNTCH_ENABLE = 1,INS_HNTCH_FREQ = peak_freq,INS_HNTCH_BW = peak_freq / 2, andINS_HNTCH_MODE = 1(throttle-based) or4(in-flight FFT, F7/H7 only).
With the notch in place, raising ATC_RAT_RLL_D doesn't amplify motor noise — that's the gain you need to get a tight tune. AutoTune almost always succeeds after this.
What ATT.ErrRP tells you
The ErrRP field is a smoothed combined roll/pitch error magnitude in radians. A healthy hover has ErrRP below 0.05 (about 3 degrees). Sustained above 0.1 with motors not saturated means the airframe can't keep up with what the controller is asking — the loop is fighting itself. Anything above 0.5 for sustained periods is what the crash check uses to declare loss of control (ERR Subsys=12 ECode=2).
When it's not really an oscillation
- Pilot-induced oscillation. The pilot oscillates the sticks and the airframe responds.
RCIN.C1shows the same period asATT.Roll. Not a tune problem. - Wind gusts. Disturbance enters from outside, the controller reacts, oscillation damps within a second or two. Sustained gust patterns at low frequency can look like a tune problem but are airframe authority limits.
- EKF noise. If
XKF3.IVN/IVEare spiky, the position controller is chasing a noisy estimate. Fix the EKF before tuning. See our EKF innovation post.
When LogHat helps — and when it doesn't
LogHat runs the FFT for you on every flight log and flags axes where the dominant frequency falls in the noise-amplification or P-gain-overshoot bands. We also surface the parameter snapshot at takeoff so you can correlate a tune change with the resulting behaviour. What we can't tell you is whether your customer's heavy payload variation is the real cause — that needs the payload mass logged alongside the flight, which the autopilot doesn't capture.
About the author
LogHat Engineering Team
The LogHat engineering team — drone-systems engineers who build and operate the LogHat flight analytics platform. Posts in this byline are written and reviewed by team members working on the parsers, analysis engine, and Vector AI that the post describes.
Tagged
Try LogHat
Analyze your flight logs in seconds
Upload a .bin, .tlog, .log, or .ulg file. Get AI crash analysis, 3D replay, and forensic PDF reports instantly.
Try LogHat Free