Diagnosing Roll and Pitch Oscillations in ArduPilot RATE and ATT Logs
ardupilottuningoscillationlog-analysispid

Diagnosing Roll and Pitch Oscillations in ArduPilot RATE and ATT Logs

LogHat Engineering TeamMarch 27, 20265 min read

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_D is 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

  1. 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, drop ATC_RAT_RLL_D in 25% steps and re-fly.
  2. Visible roll wobble in hover. 5–10 Hz. Drop ATC_RAT_RLL_P in 10% steps and confirm the wobble decreases. If the wobble persists with low P, the airframe likely has structural flex.
  3. Slow wallowing in Loiter or PosHold. Below 1 Hz, often with RATE.ROut not saturating. Reduce ATC_ANG_RLL_P, or if you also see PSCN.PN oscillating against PSCN.DPN, tune the position controller (PSC_VEL_XY_P).
  4. 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 = 4 and INS_LOG_BAT_MASK = 1 for 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, and INS_HNTCH_MODE = 1 (throttle-based) or 4 (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.C1 shows the same period as ATT.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/IVE are 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

LE

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

ardupilottuningoscillationlog-analysispid

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