From 7bcf53591353d9a966ebd05d65a0a7bfc8f10bad Mon Sep 17 00:00:00 2001 From: David Protzman Date: Fri, 22 Apr 2022 11:37:05 -0400 Subject: [PATCH] This script was rolled into another --- matlab/find_bursts.m | 93 -------------------------------------------- 1 file changed, 93 deletions(-) delete mode 100644 matlab/find_bursts.m diff --git a/matlab/find_bursts.m b/matlab/find_bursts.m deleted file mode 100644 index e26c218..0000000 --- a/matlab/find_bursts.m +++ /dev/null @@ -1,93 +0,0 @@ -%% Signal parameters -file_path = '/opt/dji/collects/2437MHz_30.72MSPS.fc32'; -file_sample_rate = 30.72e6; % Collected 2x oversampled -rough_frequency_offset = 7.5e6; % The collected signal is 7.5 MHz off center -correlation_threshold = 0.7; % Minimum correlation score to accept (0.0 - 1.0) - -%% LTE parameters -carrier_spacing = 15e3; -signal_bandwidth = 10e6; - -% How many complex samples to read in at a time -chunk_size = 1e6; - -% Pre-calculate the frequency offset rotation -freq_offset_constant = 1j * pi * 2 * (rough_frequency_offset / file_sample_rate); - -% The output of the ZC sequence generator needs to be conjugated to be used in a filter. Also create a variable that -% can hold the filter state between chunks to prevent discontinuities -correlator_taps = conj(create_zc(file_sample_rate / carrier_spacing, 4)); -correlator_state = []; - -% Open the IQ recording -file_handle = fopen(file_path, 'r'); - -% Figure out how many samples there are in the file -fseek(file_handle, 0, 'eof'); -total_samples = ftell(file_handle) / 4 / 2; % 4 bytes per float, 2 floats per complex sample -fseek(file_handle, 0, 'bof'); -fprintf('There are %d samples in "%s"\n', total_samples, file_path); - -% Really large array to store the cross correlation results from *all* samples -zc_scores = zeros(total_samples - length(correlator_taps), 0); - -sample_offset = 0; -while (~ feof(file_handle)) - %% Read in the next buffer - % The `fread` command will return interleaved real, imag values, so pack those into complex samples - floats = fread(file_handle, chunk_size * 2, 'float'); - samples = floats(1:2:end) + 1j * floats(2:2:end); - - %% Frequency shift the input - % This is somewhat optional, but the correlation scores will go down fast if the offset is > 1 MHz - rotation_vector = exp(freq_offset_constant * (sample_offset:(sample_offset+length(samples)-1))); - samples = samples .* reshape(rotation_vector, [], 1); - - %% Correlate for the ZC sequence - % Use a FIR filter to search for the ZC sequence. The resulting values will be normalized to between 0 and 1.0 if - % the abs^2 is taken - % TODO(9April2022): Would be nice to use the fftfilt function, but I don't know if it has issues with keeping state - % as it doesn't have a state input like the filter command. In testing the FFT filter is twice - % as fast - [correlation_values, correlator_state] = filter(correlator_taps, 1, samples, correlator_state); - zc_scores(sample_offset+1:sample_offset+length(correlation_values)) = correlation_values; - - sample_offset = sample_offset + length(samples); -end - -% Get the floating normalized correlation results -abs_scores = abs(zc_scores).^2; - -figure(1); -plot(abs_scores); -title('Correlation Scores (normalized)') - -% Find all places where the correlation result meets the specified threshold -% This is going to find duplicates because there are very likely going to be two points right next to each other that -% meet the required threshold. This will be dealt with later -passing_scores = find(abs_scores > correlation_threshold); - -% Look through each element of the `passing_scores` vector (which is just indicies where the correlation threshold was -% met) and pick just the highest value `search_window` elements around (`search_window/2` to the left and right) of each -% value. The goal here is to only end up with the best score for the starting point of each burst instead of having -% multiple starting points for each burst. -true_peaks = zeros(length(passing_scores), 1); -search_window = 100; -for idx = 1:length(passing_scores) - % Calculate how far to the left and right to look for the highest peak - left_idx = passing_scores(idx) - (search_window / 2); - right_idx = left_idx + search_window - 1; - - % Get the correlation scores for the samples around the current point - window = abs_scores(left_idx:right_idx); - - % Find the peak in the window and use that value as the actual peak - [value, index] = max(window); - true_peaks(idx) = left_idx + index; -end - -% There are going to be duplicates in the vector, so just take the unique elements. What's left should just be the -% actual starting indices for each ZC sequence -true_peaks = unique(true_peaks); - -