Add files via upload
This commit is contained in:
parent
d91f202e2b
commit
31171fa508
19
基于点云的人体定位demo/RAfftMatrix.m
Normal file
19
基于点云的人体定位demo/RAfftMatrix.m
Normal file
@ -0,0 +1,19 @@
|
||||
%% 2DFFT得到距离-角度热力图
|
||||
|
||||
function fft2dData = RAfftMatrix(rawData)
|
||||
|
||||
rawData = squeeze(rawData);
|
||||
[angleBin,rangeBin] = size(rawData);
|
||||
|
||||
angleWin = hanning(angleBin);
|
||||
angleWin2D = repmat(angleWin,1,rangeBin);
|
||||
|
||||
rangeWin = hanning(rangeBin)';
|
||||
rangeWin2D = repmat(rangeWin,angleBin,1);
|
||||
|
||||
rawDataWin = rawData .* angleWin2D;
|
||||
fft1dData = fftshift(fft(rawDataWin,angleBin,1));
|
||||
|
||||
fft1dDataWin = fft1dData .* rangeWin2D;
|
||||
fft2dData = fft(fft1dDataWin,rangeBin,2);
|
||||
end
|
14
基于点云的人体定位demo/RDfftMatrix.m
Normal file
14
基于点云的人体定位demo/RDfftMatrix.m
Normal file
@ -0,0 +1,14 @@
|
||||
%% 2DFFT得到距离-速度热力图
|
||||
|
||||
function fft2dData = RDfftMatrix(rawData)
|
||||
rawData = squeeze(rawData);
|
||||
[rangeBin,dopplerBin] = size(rawData);
|
||||
rangeWin = hanning(rangeBin);
|
||||
rangeWin2D = repmat(rangeWin,1,dopplerBin);
|
||||
dopplerWin = hanning(dopplerBin)';
|
||||
dopplerWin2D = repmat(dopplerWin,rangeBin,1);
|
||||
rawDataWin = rawData .* rangeWin2D;
|
||||
fft1dData = fft(rawDataWin,rangeBin,1);
|
||||
fft1dDataWin = fft1dData .* dopplerWin2D;
|
||||
fft2dData = fftshift(fft(fft1dDataWin,dopplerBin,2),2);
|
||||
end
|
67
基于点云的人体定位demo/cfar.m
Normal file
67
基于点云的人体定位demo/cfar.m
Normal file
@ -0,0 +1,67 @@
|
||||
%% 请了解:什么是CFAR,以及什么是2D-CFAR
|
||||
|
||||
function [pointList,cfarRD] = cfar(parameter,accumulateRD)
|
||||
|
||||
[rangeLen,dopplerLen] = size(accumulateRD);
|
||||
%% doppler维度搜索
|
||||
dopplerMethod = parameter.dopplerMethod;
|
||||
dopplerSNR = parameter.dopplerSNR;
|
||||
dopplerWinGuardLen = parameter.dopplerWinGuardLen;
|
||||
dopplerWinTrainLen = parameter.dopplerWinTrainLen;
|
||||
|
||||
dopplerLeft = accumulateRD(:,dopplerLen - dopplerWinGuardLen - dopplerWinTrainLen + 1:dopplerLen);
|
||||
dopplerRight = accumulateRD(:,1:dopplerWinGuardLen+dopplerWinTrainLen);
|
||||
dopplercfar = [dopplerLeft accumulateRD dopplerRight];
|
||||
dopplerCfarList = [];
|
||||
for rangeIdx = 1:rangeLen
|
||||
for dopplerIdx = 1:dopplerLen
|
||||
dopplerCfarIdx = dopplerIdx + dopplerWinGuardLen + dopplerWinTrainLen;
|
||||
leftCell = dopplercfar(rangeIdx,dopplerIdx:dopplerIdx+dopplerWinTrainLen-1);
|
||||
rightCell = dopplercfar(rangeIdx,dopplerCfarIdx+dopplerWinGuardLen:dopplerCfarIdx+dopplerWinGuardLen+dopplerWinTrainLen-1);
|
||||
leftNoise = mean(leftCell);
|
||||
rightNoise = mean(rightCell);
|
||||
noise = (leftNoise + rightNoise) / 2;
|
||||
indexdb = dopplercfar(rangeIdx,dopplerCfarIdx);
|
||||
targetSnr = indexdb - noise;
|
||||
if targetSnr > dopplerSNR
|
||||
dopplerCfarList = [dopplerCfarList dopplerIdx];
|
||||
cfarRDdoppler(rangeIdx,dopplerIdx) = indexdb;
|
||||
end
|
||||
end
|
||||
end
|
||||
dopplerCfarList = unique(dopplerCfarList);
|
||||
%% range维度搜索
|
||||
rangeMethod = parameter.rangeMethod;
|
||||
rangeSNR = parameter.rangeSNR;
|
||||
rangeWinGuardLen = parameter.rangeWinGuardLen;
|
||||
rangeWinTrainLen = parameter.rangeWinTrainLen;
|
||||
|
||||
rangeUp = accumulateRD(rangeLen - rangeWinGuardLen - rangeWinTrainLen + 1:rangeLen,:);
|
||||
rangeDown = accumulateRD(1:rangeWinGuardLen+rangeWinTrainLen,:);
|
||||
rangecfar = [rangeUp;accumulateRD;rangeDown];
|
||||
rangeCfarList = [];
|
||||
cfarRD = zeros(rangeLen,dopplerLen);
|
||||
for dopplerIdx = dopplerCfarList
|
||||
for rangeIdx = 1:rangeLen
|
||||
|
||||
rangeCfarIdx = rangeIdx + rangeWinGuardLen + rangeWinTrainLen;
|
||||
upCell = rangecfar(rangeIdx:rangeIdx+rangeWinTrainLen-1,dopplerIdx);
|
||||
downCell = rangecfar(rangeCfarIdx+rangeWinGuardLen:rangeCfarIdx+rangeWinGuardLen+rangeWinTrainLen-1,dopplerIdx);
|
||||
upNoise = mean(upCell);
|
||||
downNoise = mean(downCell);
|
||||
if rangeMethod == 1
|
||||
noise = (upNoise + downNoise) / 2;
|
||||
indexdb = rangecfar(rangeCfarIdx,dopplerIdx);
|
||||
targetSnr = indexdb - noise;
|
||||
if targetSnr > rangeSNR
|
||||
rangeCfarList = [rangeCfarList [rangeIdx;dopplerIdx]];
|
||||
cfarRD(rangeIdx,dopplerIdx) = indexdb;
|
||||
end
|
||||
elseif dopplerMethod == 2
|
||||
elseif dopplerMethod == 3
|
||||
else
|
||||
end
|
||||
end
|
||||
end
|
||||
pointList = rangeCfarList;
|
||||
end
|
10
基于点云的人体定位demo/chan_Accumulate.m
Normal file
10
基于点云的人体定位demo/chan_Accumulate.m
Normal file
@ -0,0 +1,10 @@
|
||||
%% 通道间的非相干累计
|
||||
|
||||
function accumulateRD = chan_Accumulate(fft2dDataDB)
|
||||
[channelNum,rangeBin,dopplerBin] = size(fft2dDataDB);
|
||||
accumulateRD = zeros(rangeBin,dopplerBin);
|
||||
|
||||
for channelId = 1:channelNum
|
||||
accumulateRD = accumulateRD + (abs(squeeze(fft2dDataDB(channelId,:,:))));
|
||||
end
|
||||
end
|
83
基于点云的人体定位demo/doa.m
Normal file
83
基于点云的人体定位demo/doa.m
Normal file
@ -0,0 +1,83 @@
|
||||
%% 三种角度估计的方法
|
||||
|
||||
function [angle,doa_abs] = doa(parameter,antVec)
|
||||
|
||||
doaMethod = parameter.doaMethod;
|
||||
if doaMethod == 1
|
||||
[angle,doa_abs] = dbfMethod(parameter,antVec);
|
||||
elseif doaMethod == 2
|
||||
[angle,doa_abs] = fftMethod(parameter,antVec);
|
||||
elseif doaMethod == 3
|
||||
[angle,doa_abs] = caponMethod(parameter,antVec);
|
||||
else
|
||||
end
|
||||
end
|
||||
|
||||
function [angle,doa_abs] = dbfMethod(parameter,antVec)
|
||||
|
||||
txAntenna = parameter.txAntenna;
|
||||
rxAntenna = parameter.rxAntenna;
|
||||
virtualAntenna = parameter.virtualAntenna;
|
||||
lambda = parameter.lambda;
|
||||
txNum = length(txAntenna);
|
||||
rxNum = length(rxAntenna);
|
||||
dx = parameter.dx;
|
||||
deg = -90:0.1:90;
|
||||
weightVec = zeros(virtualAntenna,1);
|
||||
doa_dbf = zeros(length(deg),1);
|
||||
kk = 1;
|
||||
for degscan = deg
|
||||
for txId = 1:txNum
|
||||
for rxId = 1:rxNum
|
||||
dphi = ((txId-1) * rxNum + rxId - 1) * 2 * pi / lambda * dx * sind(degscan);
|
||||
weightVec((txId-1) * rxNum + rxId) = exp(-1i * dphi);
|
||||
end
|
||||
end
|
||||
doa_dbf(kk) = antVec'*weightVec;
|
||||
kk = kk + 1;
|
||||
end
|
||||
doa_abs = abs(doa_dbf);
|
||||
[pk,loc]=max(doa_abs);
|
||||
angle = deg(loc);
|
||||
end
|
||||
|
||||
function [angle,doa_abs] = fftMethod(parameter,antVec)
|
||||
angleIndex = asin((-512:1:512-1)/512) * 180 / pi;
|
||||
doa_fft=fftshift(fft(antVec,1024));
|
||||
doa_abs=abs(doa_fft);
|
||||
[pk,loc]=max(doa_abs);
|
||||
angle = angleIndex(loc);
|
||||
end
|
||||
|
||||
function [angle,doa_abs] = caponMethod(parameter,antVec)
|
||||
|
||||
txAntenna = parameter.txAntenna;
|
||||
rxAntenna = parameter.rxAntenna;
|
||||
txNum = length(txAntenna);
|
||||
rxNum = length(rxAntenna);
|
||||
lambda = parameter.lambda;
|
||||
dx = parameter.dx;
|
||||
virtualAntenna = parameter.virtualAntenna;
|
||||
Rx = antVec * antVec' / virtualAntenna;
|
||||
deg = -90:0.1:90;
|
||||
a = zeros(virtualAntenna,1);
|
||||
% a = zeros(1,virtualAntenna);
|
||||
kk = 1;
|
||||
for degscan = deg
|
||||
for txId = 1:txNum
|
||||
for rxId = 1:rxNum
|
||||
virtualAntennaId = (txId-1) * rxNum + rxId - 1;
|
||||
dphi = 2 * pi / lambda * dx * virtualAntennaId * sind(degscan);
|
||||
a((txId-1) * rxNum + rxId) = exp(-1i * dphi);
|
||||
end
|
||||
end
|
||||
RxInv = inv(Rx);
|
||||
P_out(kk) = 1/(a'*RxInv*a);
|
||||
kk = kk + 1;
|
||||
end
|
||||
doa_abs = abs(P_out);
|
||||
[pk,loc]=max(doa_abs);
|
||||
angle = deg(loc);
|
||||
figure;
|
||||
plot(deg,20*log10(abs(P_out)));
|
||||
end
|
14
基于点云的人体定位demo/generateCfarParameter.m
Normal file
14
基于点云的人体定位demo/generateCfarParameter.m
Normal file
@ -0,0 +1,14 @@
|
||||
%% 生成CFAR所需的参数
|
||||
|
||||
function parameter = generateCfarParameter()
|
||||
|
||||
parameter.dopplerMethod = 1; %1:ca-cfar 2:so-cfar 3:go-cfar
|
||||
parameter.dopplerSNR = 10;
|
||||
parameter.dopplerWinGuardLen = 2;
|
||||
parameter.dopplerWinTrainLen = 8;
|
||||
|
||||
parameter.rangeMethod = 1; %1:ca-cfar 2:so-cfar 3:go-cfar
|
||||
parameter.rangeSNR = 10;
|
||||
parameter.rangeWinGuardLen = 2;
|
||||
parameter.rangeWinTrainLen = 4;
|
||||
end
|
36
基于点云的人体定位demo/generateParameter.m
Normal file
36
基于点云的人体定位demo/generateParameter.m
Normal file
@ -0,0 +1,36 @@
|
||||
% 参数设置
|
||||
function parameter = generateParameter()
|
||||
|
||||
parameter.c = 3e8; %光速
|
||||
parameter.stratFreq = 76.5e9; %起始频率
|
||||
|
||||
|
||||
parameter.Tr = 10e-6; %扫频时间 也就是周期
|
||||
parameter.Samples = 256; %采样点
|
||||
parameter.Fs = 25.6e6; %采样率
|
||||
|
||||
parameter.rangeBin = parameter.Samples ; %rangebin
|
||||
parameter.Chirps = 512; %chirp数
|
||||
parameter.dopplerBin = parameter.Chirps; %dopplerbin
|
||||
|
||||
parameter.Slope = 30e12; %chirp斜率
|
||||
parameter.Bandwidth = parameter.Slope * parameter.Tr ; %发射信号有效带宽
|
||||
parameter.BandwidthValid = parameter.Samples/parameter.Fs*parameter.Slope; %发射信号带宽
|
||||
parameter.centerFreq = parameter.stratFreq + parameter.Bandwidth / 2; %中心频率
|
||||
parameter.lambda = parameter.c / parameter.centerFreq; %波长
|
||||
|
||||
parameter.txAntenna = ones(1,3); %发射天线个数
|
||||
parameter.rxAntenna = ones(1,4); %接收天线个数
|
||||
parameter.txNum = length(parameter.txAntenna);
|
||||
parameter.rxNum = length(parameter.rxAntenna);
|
||||
parameter.virtualAntenna = length(parameter.txAntenna) * length(parameter.rxAntenna);
|
||||
|
||||
parameter.dz = parameter.lambda / 2; %接收天线俯仰间距
|
||||
parameter.dx = parameter.lambda / 2; %接收天线水平间距
|
||||
parameter.doaMethod = 2; %测角方法选择 1-dbf 2-fft 3-capon
|
||||
parameter.target = [
|
||||
100 -20 0; %target1 range speed angle
|
||||
0 10 -30; %target2 range speed angle
|
||||
0 20 30; %target2 range speed angle
|
||||
];
|
||||
end
|
67
基于点云的人体定位demo/generateSignal.m
Normal file
67
基于点云的人体定位demo/generateSignal.m
Normal file
@ -0,0 +1,67 @@
|
||||
%% 生成混频信号
|
||||
|
||||
function rawData = generateSignal(Parameter)
|
||||
|
||||
c = Parameter.c; %光速
|
||||
stratFreq = Parameter.stratFreq; %起始频率
|
||||
|
||||
Tr = Parameter.Tr; %扫频时间
|
||||
samples = Parameter.Samples; %采样点
|
||||
fs = Parameter.Fs; %采样率
|
||||
|
||||
rangeBin = Parameter.rangeBin; %rangeBin
|
||||
chirps = Parameter.Chirps; %chirp数
|
||||
dopplerBin = Parameter.dopplerBin; %dopplerBin
|
||||
|
||||
slope = Parameter.Slope; %chirp斜率
|
||||
bandwidth = Parameter.Bandwidth; %发射信号带宽
|
||||
centerFreq = Parameter.centerFreq; %中心频率
|
||||
lambda = Parameter.lambda;
|
||||
txAntenna = Parameter.txAntenna; %发射天线
|
||||
txNum = length(txAntenna); %发射天线数
|
||||
rxAntenna = Parameter.rxAntenna; %接收天线
|
||||
rxNum = length(rxAntenna); %接收天线数
|
||||
dz = Parameter.dz; %俯仰间距
|
||||
dx = Parameter.dx; %水平间距
|
||||
|
||||
target = Parameter.target; %目标
|
||||
targetNum = size(target,1); %目标数
|
||||
rawData = zeros(txNum*rxNum,rangeBin,dopplerBin);
|
||||
|
||||
t = 0:1/fs:Tr-(1/fs); %chirp采样的时间序列
|
||||
for chirpId = 1:chirps
|
||||
for txId = 1:txNum
|
||||
St = exp((1i*2*pi)*(centerFreq*(t+(chirpId-1)*Tr)+slope/2*t.^2)); %发射信号
|
||||
|
||||
for rxId = 1:rxNum
|
||||
Sif = zeros(1,rangeBin);
|
||||
for targetId = 1:targetNum
|
||||
|
||||
%%连续帧 目标设置,如果不需要连续帧,令Parameter.frame=0,即可。
|
||||
if targetId==1
|
||||
targetRange = target(targetId,1)-Parameter.frame;
|
||||
targetSpeed = target(targetId,2);
|
||||
targetAngle = target(targetId,3);
|
||||
elseif targetId==2
|
||||
targetRange = target(targetId,1)+0.5*Parameter.frame;
|
||||
targetSpeed = target(targetId,2);
|
||||
targetAngle = target(targetId,3);
|
||||
elseif targetId==3
|
||||
targetRange = target(targetId,1)+Parameter.frame;
|
||||
targetSpeed = target(targetId,2);
|
||||
targetAngle = target(targetId,3);
|
||||
end
|
||||
|
||||
tau = 2 * (targetRange + targetSpeed * (txId - 1) * Tr) / c;
|
||||
fd = 2 * targetSpeed / lambda;
|
||||
wx = ((txId-1) * rxNum + rxId) / lambda * dx * sind(targetAngle);
|
||||
Sr = 10*exp((1i*2*pi)*((centerFreq-fd)*(t-tau+(chirpId-1) * Tr)+slope/2*(t-tau).^2 -wx)); %回波信号
|
||||
Sif = Sif + St .* conj(Sr);
|
||||
%叠加20dB高斯白噪声
|
||||
Sif = awgn(Sif,20);
|
||||
end
|
||||
rawData((txId-1) * rxNum + rxId,:,chirpId) = Sif;
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
30
基于点云的人体定位demo/peakSearch.m
Normal file
30
基于点云的人体定位demo/peakSearch.m
Normal file
@ -0,0 +1,30 @@
|
||||
%% 寻找峰值
|
||||
|
||||
function [RD_pearkSearch,peakSearchList] = peakSearch(RD_cfar,cfarTargetList)
|
||||
|
||||
peakSearchList = [];
|
||||
[rangeLen, dopplerLen] = size(RD_cfar);
|
||||
RD_pearkSearch = zeros(rangeLen, dopplerLen);
|
||||
length = size(cfarTargetList,2);
|
||||
|
||||
for targetIdx = 1:length
|
||||
|
||||
rangeIdx = cfarTargetList(1,targetIdx);
|
||||
dopplerIdx = cfarTargetList(2,targetIdx); %坐标
|
||||
|
||||
if rangeIdx > 1 && rangeIdx < rangeLen && dopplerIdx > 1 && dopplerIdx < dopplerLen %边界点不考虑
|
||||
|
||||
if RD_cfar(rangeIdx,dopplerIdx) > RD_cfar(rangeIdx - 1,dopplerIdx) && ...
|
||||
RD_cfar(rangeIdx,dopplerIdx) > RD_cfar(rangeIdx + 1,dopplerIdx) && ...
|
||||
RD_cfar(rangeIdx,dopplerIdx) > RD_cfar(rangeIdx,dopplerIdx - 1) && ...
|
||||
RD_cfar(rangeIdx,dopplerIdx) > RD_cfar(rangeIdx,dopplerIdx + 1)
|
||||
|
||||
RD_pearkSearch(rangeIdx,dopplerIdx) = RD_cfar(rangeIdx,dopplerIdx);
|
||||
|
||||
cfarTarget = [rangeIdx ; dopplerIdx];
|
||||
|
||||
peakSearchList = [peakSearchList cfarTarget];
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user