kopia lustrzana https://github.com/proto17/dji_droneid
Create ifo_test.m
rodzic
ca5fada2d0
commit
95863425aa
|
@ -0,0 +1,93 @@
|
||||||
|
% This script is for testing how to detect integer frequeny offsets (IFO) in OFDM
|
||||||
|
|
||||||
|
clear all;
|
||||||
|
|
||||||
|
%% Parameters
|
||||||
|
sample_rate = 15.36e6;
|
||||||
|
fft_size = get_fft_size(sample_rate);
|
||||||
|
carrier_spacing = sample_rate / fft_size;
|
||||||
|
data_carriers = 600;
|
||||||
|
starting_zeros = 100;
|
||||||
|
cp_len = 80;
|
||||||
|
frac_frequency_offset = 0e3;
|
||||||
|
carrier_offset = -1;
|
||||||
|
freq_offset = carrier_spacing * carrier_offset;
|
||||||
|
cp_backoff = 0;
|
||||||
|
max_allowed_int_offset = 5;
|
||||||
|
enable_plots = 0;
|
||||||
|
snr = 15;
|
||||||
|
|
||||||
|
if (abs(carrier_offset) > max_allowed_int_offset)
|
||||||
|
warning("TEST WILL FAIL!! OFFSET TOO HIGH");
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Get Data Carrier Indices
|
||||||
|
left_carriers = (fft_size / 2) - (data_carriers / 2);
|
||||||
|
right_carriers = left_carriers - 1;
|
||||||
|
carrier_indices = (left_carriers + 1):(left_carriers + 1 + data_carriers);
|
||||||
|
|
||||||
|
%% Create OFDM Symbol
|
||||||
|
|
||||||
|
% Generate ZC sequence and zero the middle sample (will become FFT DC)
|
||||||
|
zc_seq = zadoffChuSeq(600, 601);
|
||||||
|
zc_seq((data_carriers / 2) + 1) = 0;
|
||||||
|
|
||||||
|
% Build the FFT freq domain by placing the ZC sequence in the middle with
|
||||||
|
% the nulled out ZC sample at DC
|
||||||
|
golden_freq_domain = reshape([zeros(left_carriers, 1); zc_seq; zeros(right_carriers, 1)], 1, []);
|
||||||
|
|
||||||
|
% Convert to time domain
|
||||||
|
golden_time_domain = ifft(golden_freq_domain);
|
||||||
|
|
||||||
|
% Create and prepend the cyclic prefix
|
||||||
|
cp = golden_time_domain(end-cp_len+1:end);
|
||||||
|
ofdm_symbol = [cp, golden_time_domain];
|
||||||
|
|
||||||
|
%% Create Sample Vector with Burst
|
||||||
|
|
||||||
|
% Create a "burst" with zeros on either side
|
||||||
|
samples = [zeros(1, starting_zeros), ofdm_symbol, zeros(1, starting_zeros)];
|
||||||
|
|
||||||
|
% Add some noise
|
||||||
|
samples = awgn(samples, snr, 'measured');
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(3);
|
||||||
|
plot(10 * log10(abs(samples).^2));
|
||||||
|
end
|
||||||
|
|
||||||
|
%% Apply Integer Frequency Offset
|
||||||
|
|
||||||
|
% Generate the vector that will be used to rotate each sample
|
||||||
|
freq_offset_vector = exp(1j * 2 * pi * freq_offset / sample_rate * [1:length(samples)]);
|
||||||
|
samples = samples .* freq_offset_vector;
|
||||||
|
|
||||||
|
%% Apply Fractional Frequency Offset
|
||||||
|
frac_offset_vector = exp(1j * 2 * pi * frac_frequency_offset / sample_rate * [1:length(samples)]);
|
||||||
|
samples = samples .* frac_offset_vector;
|
||||||
|
|
||||||
|
%% Find Starting Sample Index
|
||||||
|
|
||||||
|
% Use autocorrelation to search for the start of the ZC sequence. This
|
||||||
|
% takes advantage of the fact that the ZC sequence is symmetrical about the
|
||||||
|
% center in both the time and frequency domains. Each iteration of the
|
||||||
|
% loop below will look at one `fft_size` window of samples sliding to the
|
||||||
|
% right by one sample on each iteration. The window is then split in two
|
||||||
|
% with the second half fliped so that it's backwards. These two windows
|
||||||
|
% are then correlated with each other, and the score saved off
|
||||||
|
sto_search_window = fft_size;
|
||||||
|
sto_scores = zeros(1, starting_zeros * 2);
|
||||||
|
for td_idx=1:length(sto_scores)
|
||||||
|
sto_window = samples(td_idx:td_idx + fft_size - 1);
|
||||||
|
sto_left_window = sto_window(1:(fft_size / 2));
|
||||||
|
sto_right_window = sto_window((fft_size / 2) + 1:end);
|
||||||
|
sto_scores(td_idx) = xcorr(sto_left_window, fliplr(sto_right_window), 0, 'normalized');
|
||||||
|
end
|
||||||
|
|
||||||
|
if (enable_plots)
|
||||||
|
figure(1);
|
||||||
|
plot(abs(sto_scores)); title('STO Scores');
|
||||||
|
end
|
||||||
|
|
||||||
|
% Find the index of the maximum value from the autocorrelation above
|
||||||
|
[~, sto_est] = max(abs(sto_scores));
|
Ładowanie…
Reference in New Issue