1
0
mirror of https://github.com/gnss-sdr/gnss-sdr synced 2026-07-03 09:50:46 +00:00

Fix and refactor GPS L1 C/A KF tracking dump reader and plotter.

The KF tracking dump reader now follows the parameters dumped by kf_tracking.cc

lib/gps_l1_ca_kf_read_tracking_dump.py:
- Rewrite using the same _RECORD_FORMAT / _FIELD_NAMES architecture as
  dll_pll_veml_read_tracking_dump.py: one struct.unpack per record and
  EOF handling, dropping the v1..v22 / bytes_shift / seek.

gps_l1_ca_kf_plot_sample.py:
- map innovation -> carr_error; drop r_noise_cov

lib/plotKalman.py, lib/plotTracking.py:
- Skip the "Estimated Noise Variance" panel when r_noise_cov is absent.
- Replace fig.canvas.set_window_title() with
  fig.canvas.manager.set_window_title(). The canvas method was deprecated
  in matplotlib 3.4 and is gone in current matplotlib (3.6.3 here), where
  it raised AttributeError. Ref: https://github.com/raysect/source/issues/383

Signed-off-by: minhaj <minhaj.sixbyte@gmail.com>
This commit is contained in:
minhaj
2026-06-19 23:01:57 -05:00
parent ec718c6e64
commit 43bceb52ff
4 changed files with 130 additions and 254 deletions
+47 -38
View File
@@ -1,17 +1,21 @@
"""
gps_l1_ca_kf_plot_sample.py
Reads GNSS-SDR Tracking dump binary file using the provided
function and plots some internal variables
Reads a GPS L1 C/A Kalman-filter tracking dump binary file
(GPS_L1_CA_KF_Tracking) and plots some internal tracking and Kalman-filter
variables.
Irene Pérez Riega, 2023. iperrie@inta.es
Minhaj Uddin Ahmad, 2026. mahmad12@crimson.ua.edu
Modifiable in the file:
sampling_freq - Sampling frequency [Hz]
channels - Number of channels to check if they exist
samplingFreq - Sampling frequency [Hz]
channels - Number of channels
first_channel - Number of the first channel
path - Path to folder which contains raw file
'trk_dump_ch' - Fixed part in tracking dump files names
code_period - Code period [s]
path - Path to folder which contains the tracking dump files
fig_path - Path where the plots will be saved
file_prefix - Fixed part of the tracking dump file names
-----------------------------------------------------------------------------
@@ -35,52 +39,55 @@ trackResults = []
kalmanResults = []
# ---------- CHANGE HERE:
# Signal parameters:
samplingFreq = 6625000
samplingFreq = 4000000 # must match SignalSource.sampling_frequency in the .conf
channels = 5
first_channel = 0
code_period = 0.001
path = '/home/labnav/Desktop/TEST_IRENE/tracking'
path = '../../../out/'
fig_path = '../../../PLOTS/KF_Tracking'
file_prefix = 'track_ch'
for N in range(1, channels + 1):
tracking_log_path = os.path.join(path,
f'trk_dump_ch{N-1+first_channel}.dat')
f'{file_prefix}{N-1+first_channel}.dat')
GNSS_tracking.append(gps_l1_ca_kf_read_tracking_dump(tracking_log_path))
# todo lee lo mismo que dll_pll_velm_plot_sample y guarda diferente v13 y v14
# GNSS-SDR format conversion to Python GPS receiver
for N in range(1, channels + 1):
trackResult= {
trackResult = {
'status': 'T', # fake track
'codeFreq': np.copy(GNSS_tracking[N - 1]["code_freq_hz"]),
'carrFreq': np.copy(GNSS_tracking[N - 1]["carrier_doppler_hz"]),
'codeFreq': np.copy(GNSS_tracking[N-1]["code_freq_hz"]),
'carrFreq': np.copy(GNSS_tracking[N-1]["carrier_doppler_hz"]),
'carrFreqRate':
np.copy(GNSS_tracking[N - 1]["carrier_doppler_rate_hz2"]),#todo no se usa en dll, carrier_doppler_rate_hz_s segun dll
'dllDiscr': np.copy(GNSS_tracking[N - 1]["code_error"]),
'dllDiscrFilt': np.copy(GNSS_tracking[N - 1]["code_nco"]),
'pllDiscr': np.copy(GNSS_tracking[N - 1]["carr_error"]),#todo code_freq_rate_hz_s segun dll
'pllDiscrFilt': np.copy(GNSS_tracking[N - 1]["carr_nco"]),
np.copy(GNSS_tracking[N-1]["carrier_doppler_rate_hz2"]),
'dllDiscr': np.copy(GNSS_tracking[N-1]["code_error"]),
'dllDiscrFilt': np.copy(GNSS_tracking[N-1]["code_nco"]),
'pllDiscr': np.copy(GNSS_tracking[N-1]["carr_error"]),
'pllDiscrFilt': np.copy(GNSS_tracking[N-1]["carr_nco"]),
'I_P': np.copy(GNSS_tracking[N - 1]["prompt_I"]),#todo distinto de dll
'Q_P': np.copy(GNSS_tracking[N - 1]["prompt_Q"]),#todo distinto de dll
'I_P': np.copy(GNSS_tracking[N-1]["prompt_I"]),
'Q_P': np.copy(GNSS_tracking[N-1]["prompt_Q"]),
'I_E': np.copy(GNSS_tracking[N - 1]["E"]),
'I_L': np.copy(GNSS_tracking[N - 1]["L"]),
'Q_E': np.zeros(len(GNSS_tracking[N - 1]["E"])),
'Q_L': np.zeros(len(GNSS_tracking[N - 1]["L"])),
'PRN': np.copy(GNSS_tracking[N - 1]["PRN"]),
'CNo': np.copy(GNSS_tracking[N - 1]["CN0_SNV_dB_Hz"])
'I_E': np.copy(GNSS_tracking[N-1]["E"]),
'I_L': np.copy(GNSS_tracking[N-1]["L"]),
'Q_E': np.zeros(len(GNSS_tracking[N-1]["E"])),
'Q_L': np.zeros(len(GNSS_tracking[N-1]["L"])),
'PRN': np.copy(GNSS_tracking[N-1]["PRN"]),
'CNo': np.copy(GNSS_tracking[N-1]["CN0_SNV_dB_Hz"]),
'prn_start_time_s':
np.copy(GNSS_tracking[N-1]["PRN_start_sample"]) / samplingFreq
}
kalmanResult= {
'PRN': np.copy(GNSS_tracking[N - 1]["PRN"]),
'innovation': np.copy(GNSS_tracking[N - 1]["carr_error"]),#todo code_freq_rate_hz_s segun dll
'state1': np.copy(GNSS_tracking[N - 1]["carr_nco"]),
'state2': np.copy(GNSS_tracking[N - 1]["carrier_doppler_hz"]),
'state3': GNSS_tracking[N - 1]["carrier_doppler_rate_hz2"],#todo segun el dll es carrier_doppler_rate_hz_s
'r_noise_cov': np.copy(GNSS_tracking[N - 1]["carr_noise_sigma2"]),#todo carr_error segun dll
'CNo': np.copy(GNSS_tracking[N - 1]["CN0_SNV_dB_Hz"])
# Kalman-filter internals. The KF dump stores the carrier discriminator
# (carr_error -> innovation) and the filter states, but no measurement
# noise covariance, so 'r_noise_cov' is intentionally left out (plotKalman
# skips that panel when it is absent).
kalmanResult = {
'PRN': np.copy(GNSS_tracking[N-1]["PRN"]),
'innovation': np.copy(GNSS_tracking[N-1]["carr_error"]),
'state1': np.copy(GNSS_tracking[N-1]["carr_nco"]),
'state2': np.copy(GNSS_tracking[N-1]["carrier_doppler_hz"]),
'state3': np.copy(GNSS_tracking[N-1]["carrier_doppler_rate_hz2"]),
'CNo': np.copy(GNSS_tracking[N-1]["CN0_SNV_dB_Hz"])
}
trackResults.append(trackResult)
@@ -90,7 +97,9 @@ for N in range(1, channels + 1):
'numberOfChannels': channels,
'msToProcess': len(GNSS_tracking[N-1]['E']),
'codePeriod': code_period,
'timeStartInSeconds': 20
'timeStartInSeconds': 0,
'fig_path': fig_path,
'show': False # set True to display the figures interactively
}
# Create and save graphics as PNG