% Run an acquisition test, returning vectors of estimation errors
-function [delta_ct delta_foff] = acquisition_test(Ntests=10, EbNodB=100, foff_hz=0, hf_en=0, fine_en=0)
+function [delta_ct delta_foff timing_mx_log] = acquisition_test(Ntests=10, EbNodB=100, foff_hz=0, hf_en=0, fine_en=0)
Ts = 0.018;
sim_in.Tcp = 0.002;
rate_fs_pilot_samples = states.rate_fs_pilot_samples;
% test fine or acquisition over test signal
- #{
- fine: - start with coarse timing instant
- - on each frame est timing a few samples about that point
- - update timing instant
- corr: - where is best plcase to sample
- - just before end of symbol?
- - how long should sequence be?
- - add extra?
- - aim for last possible moment?
- - man I hope IL isn't too big.....
- #}
-
- delta_ct = []; delta_foff = [];
+ delta_ct = []; delta_foff = []; timing_mx_log = [];
% a fine simulation is a bit like what ofsd_demod() does, just searches a few samples
% either side of current coarse est
delta_t = [delta_ft ft_est - ceil(window_width/2)];
end
else
- % for coarse simulation we just use constant window shifts
+ % coarse is like initial acquiistion - we have no idea of timing or freq offset
+ % for coarse we just use constant window shifts to simulate a bunch of trials
st = 0.5*Nsamperframe;
en = 2.5*Nsamperframe - 1; % note this gives Nsamperframe possibilities for coarse timing
ct_target = Nsamperframe/2; % actual known position of correct coarse timing
for w=1:Nsamperframe:length(rx)-4*Nsamperframe
- %for w=1:M+Ncp:length(rx)-4*Nsamperframe
- [ct_est foff_est] = coarse_sync(states, rx(w+st:w+en), rate_fs_pilot_samples);
+ [ct_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(states, rx(w+st:w+en), rate_fs_pilot_samples);
if states.verbose
printf("w: %d ct_est: %4d foff_est: %3.1f\n", w, ct_est, foff_est);
end
delta_ct = [delta_ct ct_est-ct_target];
delta_foff = [delta_foff (foff_est-foff_hz)];
+ timing_mx_log = [timing_mx_log; timing_mx1 timing_mx2];
end
end
endfunction
+% Used to develop sync state machine - in particular metric to show we
+% are out of sync of have lost nodem signal
+
+function sync_metrics()
+ Fs = 8000;
+ Ntests = 10;
+ f_offHz = [0 0.5 1 2 5 10];
+ EbNodB = [0 2 4 6 10 20];
+
+ figure(1); clf;
+
+ for f = 1:length(f_offHz)
+ af_offHz = f_offHz(f);
+ mean_mx1_log = mean_mx2_log = [];
+ for e = 1:length(EbNodB)
+ aEbNodB = EbNodB(e);
+ [dct dfoff timing_mx_log] = acquisition_test(Ntests, aEbNodB, af_offHz);
+ mean_mx1 = mean(timing_mx_log(:,1));
+ mean_mx2 = mean(timing_mx_log(:,2));
+ printf("f_offHz: %3.2f EbNodB: %3.2f mx1: %3.2f mx2: %3.2f\n", af_offHz, aEbNodB, mean_mx1, mean_mx2);
+ mean_mx1_log = [mean_mx1_log mean_mx1]; mean_mx2_log = [mean_mx2_log mean_mx2];
+ end
+ if f == 2, hold on, end;
+ leg1 = sprintf("b+-;mx1 f_offHz %3.2f;", af_offHz);
+ leg2 = sprintf("g*-;mx2 f_offHz %3.2f;", af_offHz);
+ plot(EbNodB, mean_mx1_log, leg1)
+ plot(EbNodB, mean_mx2_log, leg2)
+ end
+ hold off;
+ xlabel('Eb/No (dB');
+ ylabel('Coefficient')
+endfunction
+
+
% ---------------------------------------------------------
% choose simulation to run here
% ---------------------------------------------------------
format;
more off;
-init_cml('/home/david/Desktop/cml/');
+%init_cml('/home/david/Desktop/cml/');
-run_single
+%run_single
%run_curves
%run_curves_estimators
%acquisition_histograms(0, 0)
%acquisition_test(10, 4, 5)
+sync_metrics
% samples to determine the most likely timing offset. Combines two
% frames pilots so we need at least Nsamperframe+M+Ncp samples in rx.
% Also determines frequency offset at maximimum correlation. Can be
-% used for acquisition (coarse timing a freq offset), and fine timing
+% used for acquisition (coarse timing and freq offset), and fine
+% timing
-#{
- TODO:
- [ ] attempt to speed up sync
- + tis rather stateless, this current demod, which is nice
- [ ] 0.5Hz grid and measure BER
- + so run demod a bunch of times at different offsets
- + Hmm cld also try +/- 20Hz multiples as it's aliased?
- + might to use
- + need metric for sync, could be callback.
- [ ] or refine freq offset using pilots
- [ ] different error measure that 10% maybe soft dec
- + 10% very high BER
- [ ] simpler CPU/DFT for freq offset estimation
- + more suitable for real time implementation
-#}
-
-function [t_est foff_est timing_valid timing_mx] = coarse_sync(states, rx, rate_fs_pilot_samples)
+function [t_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(states, rx, rate_fs_pilot_samples)
ofdm_load_const;
Npsam = length(rate_fs_pilot_samples);
for i=1:Ncorr
rx1 = rx(i:i+Npsam-1); rx2 = rx(i+Nsamperframe:i+Nsamperframe+Npsam-1);
- corr(i) = abs(rx1 * rate_fs_pilot_samples' + rx2 * rate_fs_pilot_samples')/av_level;
+ corr_st = rx1 * rate_fs_pilot_samples'; corr_en = rx2 * rate_fs_pilot_samples';
+ corr1(i) = abs(corr_st + corr_en)/av_level;
+ corr2(i) = (abs(corr_st) + abs(corr_en))/av_level;
end
- [timing_mx t_est] = max(corr);
- timing_valid = timing_mx > timing_mx_thresh;
+ [timing_mx1 t_est] = max(corr1);
+ timing_mx2 = max(corr2);
+ timing_valid = timing_mx1 > timing_mx_thresh;
if verbose > 1
- printf(" max: %f timing_est: %d timing_valid: %d\n", timing_mx, timing_est, timing_valid);
+ printf(" mx1: %f mx2: %f timing_est: %d timing_valid: %d\n", timing_mx1, timing_mx2, timing_est, timing_valid);
end
#{
% Attempt coarse timing estimate (i.e. detect start of frame)
st = M+Ncp + Nsamperframe + 1; en = st + 2*Nsamperframe;
- [ct_est foff_est timing_valid timing_mx] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
+ [ct_est foff_est timing_valid timing_mx1 timing_mx2] = coarse_sync(states, states.rxbuf(st:en), states.rate_fs_pilot_samples);
if states.verbose
- printf(" ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx: %d\n", ct_est, foff_est, timing_valid, timing_mx);
+ printf(" ct_est: %4d foff_est: %3.1f timing_valid: %d timing_mx1: %f timing_mx2: %f\\n", ct_est, foff_est, timing_valid, timing_mx1, timing_mx2);
end
if timing_valid
states.nin = Nsamperframe;
end
states.timing_valid = timing_valid;
- states.timing_mx = timing_mx;
+ states.timing_mx1 = timing_mx1;
+ states.timing_mx2 = timing_mx2;
states.coarse_foff_est_hz = foff_est;
endfunction
st = M+Ncp + Nsamperframe + 1 - floor(ftwindow_width/2) + (timing_est-1);
en = st + Nsamperframe-1 + M+Ncp + ftwindow_width-1;
- [ft_est coarse_foff_est_hz timing_valid timing_mx] = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
+ [ft_est coarse_foff_est_hz timing_valid timing_mx1 timing_mx2] = coarse_sync(states, rxbuf(st:en) .* exp(-j*woff_est*(st:en)), rate_fs_pilot_samples);
if timing_valid
timing_est = timing_est + ft_est - ceil(ftwindow_width/2);
end
if verbose > 1
- printf(" ft_est: %2d timing_est: %2d mx: %3.2f sample_point: %2d\n", ft_est, timing_est, timing_mx, sample_point);
+ printf(" ft_est: %2d timing_est: %2d mx1: %3.2f mx2: %3.2f sample_point: %2d\n", ft_est, timing_est, timing_mx1, timing_mx2, sample_point);
end
end