Классификация Радиолокационных сигналов
Author
function randOverInterval(interval)
a, b = interval
a + (b - a)*rand()
end
function awgn(x, snr_db)
ps = mean(abs2, x)
pn = ps / 10.0^(snr_db/10)
n = sqrt(pn/2) * (randn(length(x)) + 1im*randn(length(x)))
x + n
end
function freq_offset(x, Fs, Fc)
N = length(x)
t = (0:N-1) ./ Fs
x .* exp.(1im .* (2π .* Fc .* t))
end
function frac_delay(x, d)
N = length(x)
n0 = floor(Int, d)
frac = d - n0
y = zeros(eltype(x), N)
for i in 1:N
k = i - n0
if frac == 0
if 1 <= k <= N
y[i] = x[k]
end
else
k0 = k
k1 = k - 1
v0 = (1 <= k0 <= N) ? x[k0] : zero(eltype(x))
v1 = (1 <= k1 <= N) ? x[k1] : zero(eltype(x))
y[i] = (1 - frac)*v0 + frac*v1
end
end
y
end
function rician_channel(x; Fs, delays_samp, avg_gains_db, K=4.0, max_doppler=4.0)
N = length(x)
t = (0:N-1) ./ Fs
y = zeros(ComplexF64, N)
for (τs, gdb) in zip(delays_samp, avg_gains_db)
p = 10.0^(gdb/10)
a_los = sqrt(p) * sqrt(K/(K+1)) * exp(1im*2π*rand())
a_nlos = sqrt(p) * sqrt(1/(K+1)) * (randn() + 1im*randn())/sqrt(2)
a = a_los + a_nlos
fD = rand()*(2*max_doppler) - max_doppler
xd = frac_delay(x, τs)
y .+= a .* (xd .* exp.(1im .* (2π .* fD .* t)))
end
y
end
function rect_wave(Ncc, Fs; N=1024)
period = Ncc
base = ones(Float64, Ncc)
seq = collect(Iterators.take(Iterators.flatten(Iterators.repeated(base, ceil(Int, N/period))), N))
ComplexF64.(seq)
end
function lfm_wave(B, Ncc, Fs, direction; N=1024)
t = (0:Ncc-1) ./ Fs
k = (direction == :Up ? 1.0 : -1.0) * B / (Ncc/Fs)
f0 = -B/2
ϕ = 2π .* (f0 .* t .+ 0.5 .* k .* t.^2)
chirp = exp.(1im .* ϕ)
base = chirp
seq = ComplexF64[]
while length(seq) < N
append!(seq, base)
end
seq[1:N]
end
function barker_code(N)
N == 3 && return [1,1,-1]
N == 4 && return [1,1,-1,1]
N == 5 && return [1,1,1,-1,1]
N == 7 && return [1,1,1,-1,-1,1,-1]
N == 11 && return [1,1,1,-1,-1,-1,1,-1,-1,1,-1]
error("Unsupported Barker length")
end
function barker_wave(Nchips, chipWidthSamples, N; amp=1.0)
code = barker_code(Nchips)
chip = fill(amp, chipWidthSamples)
pulse = ComplexF64[]
for c in code
append!(pulse, ComplexF64.(c .* chip))
end
seq = ComplexF64[]
while length(seq) < N
append!(seq, pulse)
push!(seq, 0.0 + 0.0im)
end
seq[1:N]
end
function helperGenerateRadarWaveforms(;Fs=1e8, nSignalsPerMod=3000, seed=0)
Random.seed!(seed)
Ts = 1/Fs
modTypes = ["LFM","Rect","Barker"]
rangeFc = (Fs/6, Fs/5)
rangeN = (512.0, 1920.0)
snrVector = collect(-6:5:30)
rangeB = (Fs/20, Fs/16)
rangeNChip = [3,4,5,7,11]
rangeNcc = [1,5]
data = Vector{Vector{ComplexF64}}()
truth = String[]
for modType in modTypes
for iS in 1:nSignalsPerMod
Fc = randOverInterval(rangeFc)
if modType == "Rect"
Ncc = round(Int, randOverInterval(rangeN))
wav = rect_wave(Ncc, Fs; N=1024)
elseif modType == "LFM"
B = randOverInterval(rangeB)
Ncc = round(Int, randOverInterval(rangeN))
dir = rand(Bool) ? :Up : :Down
wav = lfm_wave(B, Ncc, Fs, dir; N=1024)
elseif modType == "Barker"
Nchips = rand(rangeNChip)
Nccv = rand(rangeNcc)
chipWidth = Nccv/Fc
chipWidthSamples = max(1, round(Int, chipWidth*Fs) - 1)
wav = barker_wave(Nchips, chipWidthSamples, 1024)
end
SNR = rand(snrVector)
wav = awgn(wav, SNR)
wav = freq_offset(wav, Fs, Fc)
wav = rician_channel(wav; Fs=Fs, delays_samp=[0.0,1.8,3.4], avg_gains_db=[0.0,-2.0,-10.0], K=4.0, max_doppler=4.0)
push!(data, wav)
push!(truth, modType)
end
end
data, truth
end
function tfd_image_gray(x, Fs; nwin=256, nover=192)
sp = DSP.spectrogram(real.(x), nwin, nover; fs=Fs, window=hanning(nwin))
P = sp.power .+ eps()
I = log10.(P)
I .-= minimum(I)
I ./= maximum(I) + eps()
Gray.(I)
end
function save_dataset_as_tfd_images_splits(data, truth; Fs, outdir="tfd_png", img_sz=(224,224), nwin=256, nover=192, ratios=(0.8,0.1,0.1), seed=42)
Random.seed!(seed)
labs = unique(truth)
for s in ("train","val","test"), c in labs
mkpath(joinpath(outdir, s, String(c)))
end
assign = fill("", length(truth))
for c in labs
idx = findall(t->t==c, truth)
idx = Random.shuffle(idx)
n = length(idx)
ntr = round(Int, ratios[1]*n)
nval = round(Int, ratios[2]*n)
nte = n - ntr - nval
for i in idx[1:ntr]; assign[i] = "train"; end
for i in idx[ntr+1:ntr+nval]; assign[i] = "val"; end
for i in idx[ntr+nval+1:end]; assign[i] = "test"; end
end
for (i,(x,y)) in enumerate(zip(data, truth))
I = tfd_image_gray(x, Fs; nwin=nwin, nover=nover)
I2 = imresize(I, img_sz)
fname = string(rand(UInt32)) * ".png"
save(joinpath(outdir, assign[i], String(y), fname), I2)
end
end