Copter4.0: yaw/compass unreliable (ekf3)

Hello,
I’m running into a problem where the compass_heading reported by the AP has a lot of variance, and quite likely carries some offset throughout. My setup has a camera that observes a stationary external target/object (in the camera frame) and reprojects its position into the world frame using the vehicle’s reported pose. The camera’s extrinsic transform is correct, and its intrinsics are also verified. I have the ‘ground truth’ position of this target.

The x-y values of the reprojection are usually off by a constant value, and change based on the distance. They also sometimes agree well while the vehicle is yawing, but usually a drift is visible. The z-component is fine (falls within ~10cm). All of this indicates a compass problem … and here’s a graph that captures the compass data over 1000s on the ground without moving:
compass_weirdness3

I have two questions:

  1. Any insight on whether this is normal/expected? I have an onboard computer and some other electronics, but the AP is well shielded (I believe). Also, this is a Pixhawk Cube from Hex/ProfiCNC. I’ve done compass cal, with a “strict” fit. I’ve tried setting magnetometer fusion models to “in-flight after yaw reset” and “always”, and there isn’t a perceptible difference.
  2. The vehicle usually flies well in Position modes. Is it possible for the compass to have a constant offset of, say, up to 3~4 degrees and still have stable flights? In a very stable position hold, under low wind, the compass data usually looks like so:
    compass_weirdness2

Insights appreciated.
Thanks!

Are you using the cubes internal compass? Or an external, most likely mounted on the GPS?

Performing the Compass/Motor calibration might help too - dangerous if not performed as per instructions.
https://ardupilot.org/copter/docs/common-compass-setup-advanced.html#common-compass-setup-advanced-compassmot-compensation-for-interference-from-the-power-wires-escs-and-motors

We might be able to tell more from a .bin log file too.