I am currently working on characterizing the noise sources of a Global Navigation Satellite System (GNSS) sensor using an Allan Variance plot, which is commonly employed to analyze frequency stability in atomic clocks, but has since been extended to other applications such as Inertial Measurement Units (IMUs) and sensors.
A typical (modified) Allan Deviation plot exhibits a distinctive "bowl" shape where different noise contributors are distinctly represented (see Wikipedia and Example).
In order to characterize the diverse noise sources affecting each component of the GNSS sensor, I collected data at a fixed location for five consecutive days with samples recorded every 0.05 seconds (20 Hz), under two separate configurations:
- Antenna facing upward
- Antenna facing sideways
Below is an extract from the obtained data (antenna up):
Assuming precise knowledge of the receiver's position, I computed the errors and plotted their respective Allan deviations for both configurations, depicted as follows:
For the antenna facing up, I get the following Allan curve (in meters [m]):
For the antenna facing sideways, I get the following curve (in meters [m]):
As observed, these Allan deviations hint towards a dominant presence of random walk noise, which contradicts expectations of boundedness. Specifically, I expect a GNSS estimate to fluctuate around the true value, due to factors like atmospheric conditions, satellite constellation geometry, clock biases, etc.
Thus, the assumption about noise interpretation must be incorrect as random walk is by definition unbounded. I would appreciate suggestions for accurately interpreting these results.
Additionally, I provide Fast Fourier Transform (FFT) representations of the errors, here and here.
These FFT outputs seem consistent with the random walk conjecture when compared against canonical noises examples (see this document, top of page 6 for an example of different noises FFT).
My analysis of the noise in the signal based on the Allan variance curves is therefore wrong. Would you have a suggestion for reading these curves correctly?
Any help is greatly appreciated. Thank you very much.
[EDIT] - The Allan Variance function used to perform the above analysis is the below. It is derived from the paper Bridging the gap between sensor noise modeling and sensor characterization:
def allanDeviation2(signal: np.ndarray, dt: float):
"""
Implementation of allan deviation computation from the paper
https://www.sciencedirect.com/science/article/abs/pii/S026322411730578X?via%3Dihub
"""
# Size tau vector
N = len(signal)
orderMax = int(np.log10(N * dt) + 1) - 2 # Number of digits in final time (minus two for some reason...)
order = int(np.log10(dt))
# Generate tau vector
base = np.array([2, 3, 4, 5, 6, 7, 8, 9])
tauVec = np.array([])
while order < orderMax:
tauVec = np.concatenate((tauVec, 10 ** order * base))
order += 0.5
tauVec = np.sort(tauVec)
allanDev = np.zeros(len(tauVec))
# For each tau, calculate the Allan Deviation
for i, tau in enumerate(tauVec):
t = round(tau / dt) # Number of measurements in this tau bin
nDivisions = int(N // t)
# Calculate the average for each block of data
avg = np.average(signal[: nDivisions * t].reshape(-1, t), axis=1) # Very fast thanks to Jon
# Calculate the Allan Variance on the difference of two successive averages
diff = np.diff(avg)
allanDev[i] = np.sqrt(1 / 2 * np.average(diff ** 2))
error = allanDev / np.sqrt(N * dt / tauVec + 1)
return tauVec, allanDev, error
You can find the test of this function to different noise sources in this pdf document.
[EDIT 2]: You can find the dataset here (numpy and CSV format). Order is ENU.