kopia lustrzana https://github.com/proto17/dji_droneid
Create cyclic_prefix_sto_test.m
rodzic
95863425aa
commit
ec1ca41c6b
|
@ -0,0 +1,125 @@
|
||||||
|
clear all;
|
||||||
|
|
||||||
|
% This script is meant to test using the cyclic prefix to find the starting time offset (STO) of a
|
||||||
|
% DroneID burst
|
||||||
|
|
||||||
|
%% Parameters
|
||||||
|
sample_rate = 15.36e6;
|
||||||
|
fft_size = get_fft_size(sample_rate);
|
||||||
|
[long_cp_len, short_cp_len] = get_cyclic_prefix_lengths(sample_rate);
|
||||||
|
cyclic_prefix_length_schedule = [...
|
||||||
|
long_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
short_cp_len, ...
|
||||||
|
long_cp_len];
|
||||||
|
num_data_carriers = 600;
|
||||||
|
left_guards = (fft_size / 2) - (num_data_carriers / 2);
|
||||||
|
right_guards = left_guards - 1;
|
||||||
|
num_ofdm_symbols = 9;
|
||||||
|
carrier_spacing = sample_rate / fft_size;
|
||||||
|
zero_padding_count = 100;
|
||||||
|
modulation_order = 4;
|
||||||
|
|
||||||
|
% User definable parameters
|
||||||
|
integer_freq_offset = -58;
|
||||||
|
snr = 0;
|
||||||
|
enable_plots = 1;
|
||||||
|
|
||||||
|
%% Create Time Domain Samples
|
||||||
|
modulator = comm.OFDMModulator( ...
|
||||||
|
"FFTLength", fft_size, ...
|
||||||
|
"NumGuardBandCarriers", [left_guards; right_guards], ...
|
||||||
|
"CyclicPrefixLength", cyclic_prefix_length_schedule, ...
|
||||||
|
"NumSymbols", num_ofdm_symbols, ...
|
||||||
|
"InsertDCNull", true);
|
||||||
|
|
||||||
|
% Generate the PSK that will be used in the data carriers of each OFDM sym
|
||||||
|
data_carriers = pskmod(...
|
||||||
|
randi([0, log2(modulation_order)], num_data_carriers, num_ofdm_symbols), ...
|
||||||
|
modulation_order);
|
||||||
|
|
||||||
|
% Create the time domain samples and convert to a row vector
|
||||||
|
samples = modulator(data_carriers);
|
||||||
|
samples = reshape(samples, 1, []);
|
||||||
|
|
||||||
|
% Add in zeros to the left and right
|
||||||
|
samples = [zeros(1, zero_padding_count), samples, zeros(1, zero_padding_count)];
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(1);
|
||||||
|
plot(10 * log10(abs(samples).^2));
|
||||||
|
title('Original Time Domain');
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Apply Integer Frequency Offset
|
||||||
|
int_freq_offset_hz = integer_freq_offset * carrier_spacing;
|
||||||
|
int_offset_vec = exp(1j * 2 * pi * int_freq_offset_hz / sample_rate * [0:(length(samples)-1)]);
|
||||||
|
|
||||||
|
samples = samples .* int_offset_vec;
|
||||||
|
|
||||||
|
%% Add Noise
|
||||||
|
samples = awgn(samples, snr, 'measured');
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(2);
|
||||||
|
plot(10 * log10(abs(samples).^2));
|
||||||
|
title('Samples With Noise & Int Freq Offset');
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Find STO with Cyclic Prefix
|
||||||
|
|
||||||
|
% How far from the first sample to search for the STO
|
||||||
|
num_offsets = zero_padding_count * 1.5;
|
||||||
|
scores_cp_sto = zeros(1, num_offsets);
|
||||||
|
|
||||||
|
for idx=1:length(scores_cp_sto)
|
||||||
|
offset = idx;
|
||||||
|
scores = zeros(1, num_ofdm_symbols);
|
||||||
|
|
||||||
|
% Extract and correlate the samples that each cyclic prefix is expected
|
||||||
|
% to be at
|
||||||
|
for cp_idx=1:num_ofdm_symbols
|
||||||
|
cp_len = cyclic_prefix_length_schedule(cp_idx);
|
||||||
|
|
||||||
|
% Extract the full OFDM symbol including cyclic prefix
|
||||||
|
window = samples(offset:offset + fft_size + cp_len - 1);
|
||||||
|
|
||||||
|
% Extract the cyclic prefix and the final samples of the symbol
|
||||||
|
left = window(1:cp_len);
|
||||||
|
right = window(end - cp_len + 1:end);
|
||||||
|
|
||||||
|
% Correlate the two windows
|
||||||
|
scores(cp_idx) = abs(xcorr(left, right, 0, 'normalized'));
|
||||||
|
|
||||||
|
% Move the sample pointer forward by the full symbol size
|
||||||
|
offset = offset + cp_len + fft_size;
|
||||||
|
end
|
||||||
|
|
||||||
|
% In the real DroneID the first OFDM symbol needs to be ignored since
|
||||||
|
% it isn't always present. So, just average the correlation scores of
|
||||||
|
% all but the first element
|
||||||
|
scores_cp_sto(idx) = sum(scores(2:end)) / (length(scores) - 1);
|
||||||
|
end
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(3);
|
||||||
|
plot(scores_cp_sto);
|
||||||
|
title('STO Scores (Cyclic Prefix)')
|
||||||
|
end
|
||||||
|
|
||||||
|
% Find the index of the highest score
|
||||||
|
[~, sto_est_cp] = max(scores_cp_sto);
|
||||||
|
fprintf("True offset: %d, estimated offset: %d\n", zero_padding_count + 1, sto_est_cp);
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(4);
|
||||||
|
plot(10 * log10(abs(fftshift(fft(samples))).^2));
|
||||||
|
title('FFT of Noisy Signal');
|
||||||
|
end
|
||||||
|
|
||||||
|
% XCorr for ZC -> Extract Burst -> CP STO -> Coarse CFO -> Integer CFO -> Equalization
|
Ładowanie…
Reference in New Issue