Engee documentation
Notebook

Modelling the microdoppler effect

The example introduces the concept of the microdoppler effect and demonstrates the construction of a radar system capable of extracting a microdoppler from a reflected signal. This feature can be further used to solve the target classification problem.

Connecting libraries and functions

In [ ]:
let
    installed_packages = collect(x.name for (_, x) in Pkg.dependencies() if x.is_direct_dep)
    list_packages = ["DSP","FFTW","LinearAlgebra"]
    for pack in list_packages
        pack in installed_packages || Pkg.add(pack)
    end
end
In [ ]:
using DSP,FFTW,LinearAlgebra  
In [ ]:
gr()
default(titlefontsize=12,top_margin=5Plots.px,guidefont=10,
    fontfamily = "Computer Modern",colorbar_titlefontsize=8,size=(800,400),
    margin = 2Plots.mm
)
function helicopmotion(t,tgtmotion,BladeAng,ArmLength,BladeRate,prf = 2e4, radarpos = [0;0;0])

    Nblades  = size(BladeAng,2)
    tgtpos,tgtvel = tgtmotion(1/prf)

    RotAng = BladeRate*t;
    scatterpos = [0 ArmLength*cos.(RotAng .+ BladeAng);0 ArmLength*sin.(RotAng .+ BladeAng);zeros(1,Nblades+1)].+tgtpos
    scattervel = [0 -BladeRate*ArmLength*sin.(RotAng .+ BladeAng);0 BladeRate*ArmLength*cos.(RotAng .+ BladeAng);zeros(1,Nblades+1)] .+tgtvel

    _,scatterang = rangeangle(scatterpos,radarpos)

    return scatterpos,scattervel,scatterang
end

function spectrogramm_ped(x,t_step;down_lim = -35)

    out,f,t = EngeePhased.Functions.spectrogram(sum(x;dims=1)[:];
        window = DSP.kaiser(128,10),
        noverlap=120,
        nfft=256,fs=1/t_step,
        centered=true,freqloc = "yaxis",out = :data
    )
    out_sig = map(x -> x < down_lim ? down_lim : x,DSP.pow2db.(abs.(out)))
    fig = Plots.heatmap(
        t[:],f,out_sig,color= :jet,
        gridalpha=0.5,
        colorbar_title = "Мощность, дБВт",
        xticks=0:0.5:3,
        yticks=-500:100:500,
    )
    Plots.xlabel!("Время, с")
    Plots.ylabel!("Частота Доплера, Гц")

    return fig
end

function calc_spectrogram_quad(Data,ts,T;limit = -150)
    x = Data./maximum(abs.(Data))
    dT = T/length(x)
    F = 1/dT

    spec_quad = DSP.spectrogram(x,128,120;window=DSP.kaiser(128,3.95),nfft=512,fs=F)
    power_quad = map(x -> x < limit ? limit : x,pow2db.(spec_quad.power))
    power_quad_quad_new = zeros(size(power_quad))

    power_quad_quad_new[1:round(Int64,size(power_quad,1)/2),:] .= power_quad[round(Int64,size(power_quad,1)/2)+1:end,:]
    power_quad_quad_new[round(Int64,size(power_quad,1)/2)+1:end,:] .= power_quad[1:round(Int64,size(power_quad,1)/2),:]
    fig = Plots.heatmap(spec_quad.time*1e3, fftshift(spec_quad.freq)*1e-3, power_quad_quad_new,color= :jet,
        gridalpha=0.5,ylims=(-10,10),xlims=(0,500),colorbar_title = "Мощность, дБВт",
        xticks=0:50:500,yticks=-10:2:10)
    Plots.xlabel!("Время, мс")
    Plots.ylabel!("Частота Доплера, кГц")
    Plots.title!("Спектрограмма отраженного сигнала от вертолета")

    return fig
end


function helperAnnotateSpectrogram(fig)

    Plots.plot!(fig,[20;50],[4;7],linewidth=2,c=:white,lab="",arrow=Plots.Arrow(:close, :tail, 0.5, 1))
    Plots.annotate!(50, 7.5, ("Лопасть 1", 10, :white, :center),annotationfontfamily="Roboto")
    Plots.plot!(fig,[70;120],[4;5.5],linewidth=2,c=:white,lab="",arrow=Plots.Arrow(:close, :tail, 0.5, 1))
    Plots.annotate!(120, 6, ("Лопасть 2", 10, :white, :center),annotationfontfamily="Roboto")

    Plots.plot!(fig,[20;50],[-4;-7],linewidth=2,c=:white,lab="",arrow=Plots.Arrow(:close, :tail, 0.5, 1))
    Plots.annotate!(50, -7.5, ("Лопасть 3", 10, :white, :center),annotationfontfamily="Roboto")
    Plots.plot!(fig,[70;120],[-4;-5.5],linewidth=2,c=:white,lab="",arrow=Plots.Arrow(:close, :tail, 0.5, 1))
    Plots.annotate!(120, -6, ("Лопасть 4", 10, :white, :center),annotationfontfamily="Roboto")

    Plots.plot!(fig,[0;250],[0;-0.1],linewidth=3,c=:white,lab="",arrow=Plots.Arrow(:close, :both, 0.5, 1))
    Plots.annotate!(120, -1, ("Период", 10, :white, :center),annotationfontfamily="Roboto")

    Plots.plot!(fig,[124;125],[0.2;4],linewidth=3,c=:white,lab="",arrow=Plots.Arrow(:close, :both, 0.5, 1))
    Plots.annotate!(137, 2, ("Скорость вращения", 10, :white, :left),annotationfontfamily="Roboto")

end


function plotting_svd(x)
    Plots.plot(10*log10.(x),lab="",ylabel="Сингулярные значения",xlabel="ранг")
    Plots.plot!([55], seriestype="vline", label="",ls=:dashdot,color="red",lw=2)
    Plots.plot!([101], seriestype="vline", label="",ls=:dashdot,color="red",lw=2)
    Plots.plot!([109], seriestype="vline", label="",ls=:dashdot,color="red",lw=2)
    Plots.annotate!(25, -10, ("A", 10, :black, :left),annotationfontfamily="Roboto")
    Plots.annotate!(75, -10, ("B", 10, :black, :left),annotationfontfamily="Roboto")
    Plots.annotate!(102, -10, ("C", 10, :black, :left),annotationfontfamily="Roboto")
    Plots.annotate!(175, -10, ("D", 10, :black, :left),annotationfontfamily="Roboto")
end
Out[0]:
plotting_svd (generic function with 1 method)

1. Concept of microdoppler effect

The concept of micro motion is inextricably linked to the microdoppler effect:

Micro-motion is an insignificant movement or deviation of a constituent part of an object, which is additional to the main volumetric movement of the whole object [1]. The source of micromotion can be a vibrating surface, rotating blades of a helicopter's rotor, a walking person making periodic movements of arms and legs, flapping wings of a bird or other reasons.


Microdoppler effect is a phenomenon associated with enrichment of the spectral composition of the reflected signal, which occurs in the process of radar research as a result of micromovements of objects.


Consider 2 scenarios of object motion: simple translational motion (top figure) and complex translational-rotational motion (bottom figure).

image.png

image_2.png

In 1 case, the object is moving towards us uniformly, so the Doppler frequency has a constant value, independent of time.

In the 2nd case, the situation is different: rotational motion (e.g. rotation of helicopter blades) introduces periodically changing components into the spectrum of the reflected signal, which characterise the microdoppler effect.

A spectrogram of the reflected signal containing microdoppler components in the spectrum is called a microdoppler signature (or abbreviated as MDS). An example of a bird MDS is shown below: image.png

2. Modelling pedestrian MDS

In the following simulation, we consider the development of a car radar based on a continuous LFM signal to identify a crosswalk on the road.

2.1 Model scenario descriptions

The model considers the following scenario:

  • A car with radar is travelling on the inside lane at a speed of 30 km/h from the origin towards a standing car and a pedestrian;
  • The standing car is at a distance of 39.4 metres.
  • The pedestrian is travelling at a speed of 1 m/s.

The visualisation of the scenario is shown below: peshekhod_s_dvumia_avtomobiliami_2.png

2.2 Model parameters

High range and velocity resolution is required for crossing identification. In automotive radars, a continuous linear frequency modulated (FM) signal is used to satisfy the characteristics.

In [ ]:
bw = 250e6 # полоса сигнала, Гц
fs = bw # частота дискретизации, Гц
fc = 24e9 # несущая частота, Гц
tm = 1e-6 # время развертки, с
c = 3e8 # скорость света, м/с

egocar_pos = [0;0;0] # м, вектор положения автомобиля с радаром
egocar_vel = [30*1600/3600;0;0] # м/с, вектор скорости автомобиля с радаром

parkedcar_pos = [39;-4;0] # м, вектор положения впереди стоящего автомобиля
parkedcar_vel = [0;0;0] # м/с, вектор скорости впереди стоящего автомобиля

ped_pos = [40;-3;0] # м, вектор положения пешехода
ped_vel = [0;1;0] # м, вектор скорости пешехода
ped_heading = 90 # град, начальное направление движения пешехода
ped_height = 1.8; # рост пешехода

2.3 System object formation

For the formation of the reflected signal of the object - pedestrian use the system object EngeeRadars.BackscatterPedestrian

In [ ]:
wav_fmcw = EngeePhased.FMCWWaveform(
    SampleRate=fs, # частота дискретизации
    SweepTime=tm, # время развертки
    SweepBandwidth=bw # полоса сигнала
)

# СО автомобиля с радаром
egocar = EngeePhased.Platform(
    InitialPosition=egocar_pos, # начальное положение 
    Velocity=egocar_vel, # вектор скорости
    OrientationAxesOutputPort=true # включение выходного порта ориентации в пространстве
)

# Формирование объекта впереди стоящего автомобиля
parkedcar = EngeePhased.Platform(
    InitialPosition=parkedcar_pos, # начальное положение
    Velocity=parkedcar_vel, # скорость
    OrientationAxesOutputPort=true # включение выходного порта ориентации в пространстве
)
parkedcar_tgt = EngeePhased.RadarTarget(PropagationSpeed=c,OperatingFrequency=fc,MeanRCS=10)

# Формирование объекта - пешеход
ped = EngeeRadars.BackscatterPedestrian(
    InitPosition=ped_pos, # начальное положение
    InitHeading=ped_heading, # начальное направление движения
    PropagationSpeed=c, # скорость распространения сигнала
    OperatingFrequency=fc, #  несущая частота
    Height=ped_height, # рост
    WalkingSpeed=1 # скорость движения 
)

# каналы распространения: до пешехода и ближайшего автомобиля
chan_ped = EngeePhased.FreeSpace(
    PropagationSpeed=c, # скорость распространения
    OperatingFrequency=fc, # несущая частота
    TwoWayPropagation=true, # учет двунаправленного распространения
    SampleRate=fs # частота дискретизации
)
chan_pcar = EngeePhased.FreeSpace(
    PropagationSpeed=c, # скорость распространения
    OperatingFrequency=fc, # несущая частота
    TwoWayPropagation=true, # учет двунаправленного распространения
    SampleRate=fs # частота дискретизации
)

# приемник и передатчик
tx = EngeePhased.Transmitter(PeakPower=1,Gain=25)
rx = EngeePhased.ReceiverPreamp(Gain=25,NoiseFigure=10);

2.4 Simulation of the model

To correctly represent the pedestrian MDS, it is necessary to accumulate the reflected signal during at least one cycle of human movement. The pedestrian's speed is 1 m/s, so a full cycle requires 2 seconds. Let's simulate the pedestrian movement scenario for 2.5 seconds in 1 ms steps:

In [ ]:
Tsim = 2.5 # время симуляции
Tsamp = 0.001 # шаг расчета симуляции, с
npulse = round(Int64,Tsim/Tsamp) # количество импульсов
# Выделение памяти под:
xr = complex(zeros(round(Int64,fs*tm),npulse)) # суммарный отраженный сигнал
xr_ped = complex(zeros(round(Int64,fs*tm),npulse)) # отраженный сигнал от пешехода
@inbounds for m = 1:npulse
    #  расчет  текущего положения, скорости, ориентации и угла визирования 
    # до пешехода и припаркованного автомобиля
    pos_ego,vel_ego,ax_ego = egocar(Tsamp)
    pos_pcar,vel_pcar,ax_pcar = parkedcar(Tsamp)
    pos_ped,vel_ped,ax_ped = move(ped,Tsamp,ped_heading)
    _,angrt_ped = rangeangle(pos_ego,pos_ped,ax_ped)
    _,angrt_pcar = rangeangle(pos_ego,pos_pcar,ax_pcar)

    # расчет отраженного сигнала
    global x = tx(wav_fmcw()) # зондирующий сигнал
    # прохождение сигналов в канале прямого и обратного распространения
    xt_ped = chan_ped(repeat(x,1,size(pos_ped,2)),pos_ego,pos_ped,vel_ego,vel_ped)  
    xt_pcar = chan_pcar(x,pos_ego,pos_pcar,vel_ego,vel_pcar)
    xt_ped = reflect(ped,xt_ped,angrt_ped) # отраженный сигнал от перехода
    xt_pcar = parkedcar_tgt(xt_pcar) # отраженный сигнал от автомобиля
    xr_ped[:,m] = rx(xt_ped) # принятый сигнал от пешехода
    xr[:,m] = rx(xt_ped+xt_pcar) # принятый сигнал от пешехода
end

# перенос сигнала на нулевую частоту
xd_ped = conj(dechirp(xr_ped,x))
xd = conj(dechirp(xr,x));

2.5 Processing the received signal

In the modelled signal, xd_ped contains only the pedestrian response, while xd contains the response of both the pedestrian and the parked car. If we create a spectrogram using only the reflected pedestrian signal, we get the following MDS:

In [ ]:
spectrogramm_ped(xd_ped,Tsamp;down_lim = -35)
title!("Спектрограмма отраженного сигнала от пешехода")
Out[0]:

The spectrogram of the total reflected signal from the pedestrian and the car is as follows:

In [ ]:
spectrogramm_ped(xd,Tsamp;down_lim = -35)
title!("Спектрограмма отраженного сигнала от пешехода и автомобиля")
Out[0]:

It can be seen that the MDS of the car dominates the background MDS of the pedestrian. Therefore, without additional processing the pedestrian cannot be detected.

2.6 Processing with svd decomposition

To detect a weaker signal from a stronger one, we can use singular value decomposition, which allows us to highlight the region of interest.

In [ ]:
out_svd = svd(xd,full=true) # расчет компонента разложения
uxd,sxd,vxd = out_svd.U,out_svd.S,out_svd.V; # считывание матриц S,U,V

Using the function plotting_svd display the main diagonal singular matrix S:

In [ ]:
plotting_svd(sxd)
Out[0]:
A B C D

On the graph of dependence of the singular value on the rank of the matrix we can conventionally distinguish 4 regions:

  • A - includes the main signal making a significant contribution to the spectrogram;
  • B - combination of pedestrian and car signals, with dominance of the second one
  • C - combination of pedestrian and car signals, dominated by the former;
  • D - contribution of noise of the receiving device.

Consequently, to effectively extract the pedestrian MDS it is necessary to extract from the whole spectrogram the C region located within the rank value 103-110:

In [ ]:
rk = 103:110 # диапазон рангов матрицы сигнулярных значений

# расчет обработанной спектрограммы
sxd_new = [sxd;zeros(size(vxd,1)-length(sxd))]
xdr = uxd[:,rk]*Diagonal(sxd_new)[rk,:]*vxd';

Again we plot the pedestrian and car MDS after additional processing (for correct display we reduce the lower limit to -40 dB since the main power is removed):

In [ ]:
spectrogramm_ped(xdr,Tsamp;down_lim = -40)
title!("МДС пешехода и автомобиля после svd преобразования")
Out[0]:

After filtering the car signal, a clear picture of the pedestrian MDS is formed, while the car MDS level has significantly decreased.

Thus, with the help of additional processing (svd decomposition) it was possible to highlight the spectral components of the pedestrian against the background of the interfering signal from the nearby car.

3. helicopter MDS modelling

3.1 Description of the model scenario

Consider the case:

  • a helicopter flies at a distance of [-25,500,500] mesres uniformly in the x-z plane with a speed of 100 m/s along the x-axis.
  • The radar is stationary and located at the origin. In this case, at the beginning of the movement the helicopter approaches the radar, and after the transition to the positive region of the x-axis, will begin to move away. Visualisation of this scenario is shown below: image_2.png

3.2 Model parameters

Let's set the parameters of the scenario of radar and target (helicopter) movement:

In [ ]:
radarpos = [0;0;0] # вектор положения РЛС, м
radarvel = [0;0;0] # вектор скорости РЛС, м/с

tgtinitpos = [-25;500;500] # начальное положение цели, м
tgtvel = [100;0;0]; # скорость цели, м/с

Next, form the helicopter geometry by specifying its main parameters (number of blades, blade length, propeller speed):

In [ ]:
f_rot = 4 # частота вращения винта, c
Nblades   = 4 # количество лопастей
bladeang  = Matrix((0:Nblades-1)')*2*pi/Nblades # вектор углов лопастей
bladelen  = 6.5 # длина лопасти, м
bladerate = deg2rad(360*f_rot);  # скорость вращения винта рад/с
Out[0]:
25.132741228718345

The next stage is the formation of the radar system. Let's set the fundamental parameters of the system:

In [ ]:
c  = 3e8 # скорость распространения сигнала, м/с
fc = 5e9 # несущая частота, Гц
fs = 1e6 # частота дискретизации, Гц
prf = 2e4 # частота следования импульсов, Гц
lambda = c/fc; # длина волны, м

3.3 Creation of system objects

Now, using the parameters of the target scenario and the radar system, let's create the system objects of the model using the library EngeePhased:

In [ ]:
# Формирование цели 
helicop = EngeePhased.RadarTarget(
    MeanRCS=[10 .1 .1 .1 .1], # ЭПР элементов вертолета (фюзеляжа и 4 лопастей)
    PropagationSpeed=c, # скорость распространения
    OperatingFrequency=fc # несущая частота сигнала
)
tgtmotion  = EngeePhased.Platform(InitialPosition=tgtinitpos,Velocity=tgtvel)

# Генератор зондирующего сигнала
wav = EngeePhased.RectangularWaveform(
    SampleRate=fs, # частота дискретизации
    PulseWidth=2/fs, # длительность импульса
    PRF=prf # частота следования импульсов
)
#  Формирование антенной решетки (прямоугольная 4х4)
ura = EngeePhased.URA(
    Size=[4 4], # размер антенной решетки
    ElementSpacing=[lambda/2 lambda/2] # расстояние между элементами
)
tx  = EngeePhased.Transmitter() # передатчик
rx  = EngeePhased.ReceiverPreamp() # предусилитель

# Cреда распространения
env = EngeePhased.FreeSpace(
    PropagationSpeed=c, # скорость распространения, м/с
    OperatingFrequency=fc, # несущая частота, Гц
    TwoWayPropagation=true, # учет двунаправленного распространения
    SampleRate=fs # частота дискретизации
)
# Передающая АР
txant = EngeePhased.Radiator(
    Sensor=ura, # геометрия АР
    PropagationSpeed=c, # скорость распространения, м/с
    OperatingFrequency=fc # несущая частота, Гц
)
# Принимающая АР
rxant = EngeePhased.Collector(
    Sensor=ura, # геометрия АР
    PropagationSpeed=c, # скорость распространения, м/с
    OperatingFrequency=fc # несущая частота, Гц
);

3.4 Running the model simulation

Let's realise the calculation of the radar operation scenario when the helicopter is moving by calling system objects in a loop:

In [ ]:
NSampPerPulse = round(Int64,fs/prf) # количество отсчетов в 1 импульсе
Niter = Int64(1e4) # количество итераций (число излученных импульсов)
y = complex(zeros(NSampPerPulse,Niter)) # выделение памяти для отраженного сигнала

@inbounds for m in 1:Niter
    # обновление положение и скорости вертолета
    t = (m-1)/(prf) # шаг симуляции по времени
    global scatterpos,scattervel,scatterang = helicopmotion(t,tgtmotion,bladeang,bladelen,bladerate,prf,radarpos)

    # расчет отраженного сигнала
    x  = txant(tx(wav()),scatterang)  # зондирующий сигнал        
    xt = env(x,radarpos,scatterpos,radarvel,scattervel) # сигнал, прошедший среду
    xt = helicop(xt) # отраженный сигнал от вертолета                                    
    global xr = rx(rxant(xt,scatterang)) # принятый сигнал    
    y[:,m] = sum(xr;dims=2) # формирование луча                        
end

3.5 Signal processing

Using the system object RangeDopplerResponse we realise range-Doppler processing: matched range filtering and spectral processing based on FFT in velocity.

In [ ]:
rdresp  = EngeePhased.RangeDopplerResponse(
    PropagationSpeed=c, # скорость распространения сигнала
    SampleRate=fs, # частота дискретизации
    DopplerFFTLengthSource="Property", # Cпособ задания БПФ (в параметрах СО)
    DopplerFFTLength=128, # длина БПФ
    DopplerOutput="Speed", # Доплероский выход (скорость)
    OperatingFrequency=fc # несущая частота
)

mfcoeff = getMatchedFilter(wav)
fig1 = plotResponse(rdresp,y[:,1:128],mfcoeff)
Plots.ylims!(0,3000)
Plots.plot!(fig1,title="Дальностно-доплероский портрет",xlabel="Скорость, м/с",
    ylabel="Дальность, м",titlefontsize=12,top_margin=5Plots.px,guidefont=10,
    colorbar_title="Мощность, дБВт",fontfamily = "Computer Modern",colorbar_titlefontsize=8)
Out[0]:

It can be seen that the range-Doppler portrait captures the presence of 3 components: the central component is the fuselage of the helicopter, the side components are the rotation of the blades.

Let us estimate the radial velocity of the helicopter:

In [ ]:
tgtpos = scatterpos[:,1] # положение вертолета на момент окончания симуляции
tgtvel = scattervel[:,1] # скорость вертолета на момент окончания симуляции
tgtvel_truth = radialspeed(tgtpos,tgtvel,radarpos,radarvel)
println("радиальная скорость фюзеляжа вертолета $(round(tgtvel_truth;sigdigits=3)) м/с")
радиальная скорость фюзеляжа вертолета -3.53 м/с

Let's also see the maximum and minimum values of the radial speeds of the propellers:

In [ ]:
maxbladetipvel = [bladelen*bladerate;0;0] # скорость лопастей винта
vtp = radialspeed(tgtpos,-maxbladetipvel+tgtvel,radarpos,radarvel)
vtn = radialspeed(tgtpos,maxbladetipvel+tgtvel,radarpos,radarvel)
println("максимальное значение радиальной скорости $(round(vtp;sigdigits=3)) м/с")
println("минимальное значение радиальной скорости $(round(vtn;sigdigits=3)) м/с")
максимальное значение радиальной скорости 2.24 м/с
минимальное значение радиальной скорости -9.3 м/с

Let's perform matched filtering and plot the spectrogram of the reflected signal:

In [ ]:
# Cогласованная фильтрация
mf  = EngeePhased.MatchedFilter(Coefficients=mfcoeff) # согласованный фильтр
ymf = mf(y) # обработка
ridx = findmax(sum(abs.(ymf);dims=2)[:])[2]; # обнаружение пика по дальности

# Построение МДС
T = Niter/prf # длительность спектрограммы
fig1 = calc_spectrogram_quad(ymf[ridx,:],1/prf,T;limit=-100)
Out[0]:

The central component characterises the reflected signal from the helicopter fuselage, the periodic components characterise the rotation of the blades. Visualise the MDS components using the function helperAnnotateSpectrogram:

In [ ]:
helperAnnotateSpectrogram(fig1)
Out[0]:
Лопасть 1 Лопасть 2 Лопасть 3 Лопасть 4 Период Скорость вращения

From the spectrogram plot we can estimate the oscillation period, which is approximately equal to 250 ms. In this case, the estimate of the number of blades is equal to:

In [ ]:
Tp = 250e-3 # период МДС
bladerate_est = 1/Tp # оценка количества лопастей
println("Оценка числа лопастей $(round(bladerate_est;sigdigits=2))")
Оценка числа лопастей 4.0

The maximum deviation of Doppler frequency is approximately equal to 4 kHz, then the radial velocity of helicopter blades is estimated as:

In [ ]:
f_doppler = 4e3 # амплитуда доплероской частоты, Гц
Vt_detect = dop2speed(f_doppler,lambda)/2
println("Радиальная скорость лопастей $(Vt_detect) м/с")
Радиальная скорость вертолета 120.0 м/с

To estimate the true velocity, we need to determine the solution to the peling angle-of-place problem. Let's use the algorithm "Music" implemented in the system object MUSICEstimator2D:

In [ ]:
doa = EngeePhased.MUSICEstimator2D(
    SensorArray=ura, # 
    OperatingFrequency=fc, # несущая частота
    PropagationSpeed=c, # скорость распространения сигнала
    DOAOutputPort=true, # включение выхода углового направления
    ElevationScanAngles=-90:90 # диапазон сканирования по углу места
)
_,ang_est = doa(xr) # расчет углов визирования
Vt_est = Vt_detect/cosd(ang_est[2]) # оценка скорости движения лопастей
println("Оценка скорости лопастей $(round(Vt_est;sigdigits=3)) м/с")
Оценка скорости лопастей 170.0 м/с

Knowing the estimates of the velocity and the number of blades, let us determine the approximate blade length:

In [ ]:
bladelen_est = Vt_est/(bladerate_est*2*pi)
println("Оценка длины лопасти $(round(bladelen_est;sigdigits=3)) м")
Оценка длины лопасти 6.75 м

The true value of the length is 6.5 m, hence the error is 4%.

Conclusion

In the example the concept of "microdoppler effect" and microdoppler signatures are considered. Using EngeePhased system objects we modelled the MDS of reflected signals for 2 radar scenarios: ground radar in the presence of an air target - a helicopter and car radar in the presence of a pedestrian and a nearby car.