The "Toilet Bowl" Effect
Diagnosis
You switch to Loiter. The drone holds for a moment, then starts to circle. The circle gets wider and faster with every revolution. This is the Toilet Bowl Effect (TBE). It is a classic instability in the position control loop.
The Mechanics of Failure
TBE is caused by a disagreement between the drone's Heading (where it thinks it is pointing) and its Track (where the GPS says it is moving).
The Vector Rotation
The flight controller calculates a position error vector ($\vec{E}$) to correct drift.
$$ \vec{E} = \vec{P}{target} - \vec{P}{current} $$
It then attempts to apply a correction acceleration ($\vec{A}$) by rotating this error vector into the body frame using the Compass Heading ($\psi$).
$$ \vec{A}{body} = R(\psi) \cdot \vec{E}{NED} $$
The Error
If your Compass is rotated by $\theta = 90^\circ$ (due to magnetic interference):
- Drift: The drone drifts North.
- GPS: Reports "Moving North".
- FC Logic: "To stop moving North, I must lean South."
- Reality: Because $\psi$ is wrong, "South" in the body frame is actually West.
- Result: The drone leans West. It accelerates sideways.
- Loop: The GPS now sees Westward drift. The FC tries to correct... and pushes South. The error vector rotates continuously, driving the drone into a widening spiral.
Virtual GPS Specifics
Indoor environments are notoriously bad for compasses. Steel beams, reinforced concrete, and electrical wiring create magnetic fields that warp the Earth's field, changing $\psi$ dynamically as you fly past pillars.
The Solution: Mag-Less Flight
If you have a solid Virtual GPS fix, you might not need a compass at all.
- GPS Heading: If the drone is moving, the EKF can infer heading from the velocity vector (EK3_MAG_CAL options).
- External Yaw: If your positioning system provides Yaw (e.g., Visual Odometry or Dual Antenna GPS), you can inject this via the
yawfield inGPS_INPUT(centidegrees) and disable the internal compass.
Source Code Reference
- State Prediction:
libraries/AP_NavEKF3/AP_NavEKF3_core.cpp- SeeUpdateStrapdownEquationsNEDwhere the attitude quaternion rotates accelerations. - Fusion Logic:
libraries/AP_NavEKF3/AP_NavEKF3_PosVelFusion.cpp- SeeFuseVelPosNED.