AWR1243+DCA100——数据读取(基于mmWave Studio GUI)
一、 DCA1000读取AWR1243的ADC数据的格式
- DCA1000通过4个LVDS线读取对应AWR1243的4个接收天线Rx的回波数据;
- 使能LVDS的数量要和使能接收天线Rx的数量相等,且由大到小依次对应。例如使能了RX1,RX2和Lane2,Lane3,则Lane2读取RX1数据,Lane3读取RX2数据,其他数据线(Lane1和Lane4填充零);
- 每个数据单元大小为2Bytes(=16bits)
参考:Mmwave Radar Device ADC Raw Data Capture
以下分别是读取的512个ADC采样数据的实部和复数数据:
实部数据:RX1-Lane1 (共256行):
复数数据:RX1-Lane1 (共512行):
使用Notepad++编辑器查看二进制bin文件 右键"view in"-->"16-Bit"以16位(4个16进制数)形式查看。
二、 在Matlab中解译Bin文件
1. 数据获取
a) 依次按下"DAC1000"和"Trigger Frame"后可获得原始数据"adc_data_RAW_0.bin"。但以为数据是基于以太网协议传输,此时获得数据可能存在丢包等问题。
b) 按下"PostProc"后会对"adc_data_RAW_0.bin"进行数据包重排序和丢失数据的零填充,生成新文件"adc_data.bin"。
此后的操作,均是对"adc_data.bin"进行的。
参考:Mmwave Radar Device ADC Raw Data Capture
2. Matlab脚本(用于读取"adc_data.bin")
自定义函数"readDCA1000.m"用于读取"adc_data.bin"
%%% This script is used to read the binary file produced by the DCA1000
%%% and Mmwave Studio
%%% Command to run in Matlab GUI - readDCA1000('<ADC capture bin file>')
function [retVal] = readDCA1000(fileName)
%% global variables
% change based on sensor config
numADCBits = 16; % number of ADC bits per sample
numLanes = 4; % do not change. number of lanes is always 4 even if only 1 lane is used. unused lanes
isReal = 0; % set to 1 if real only data, 0 if complex data are populated with 0
%% read file and convert to signed number
% read .bin file
fid = fopen(fileName,'r');
% DCA1000 should read in two's complement data
adcData = fread(fid, 'int16');
% if 12 or 14 bits ADC per sample compensate for sign extension
if numADCBits ~= 16
l_max = 2^(numADCBits-1)-1;
adcData(adcData > l_max) = adcData(adcData > l_max) - 2^numADCBits;
end
fclose(fid);
%% organize data by LVDS lane
% for real only data
if isReal
% reshape data based on one samples per LVDS lane
adcData = reshape(adcData, numLanes, []);
%for complex data
else
% reshape and combine real and imaginary parts of complex number
adcData = reshape(adcData, numLanes*2, []);
adcData = adcData([1,2,3,4],:) + 1j*adcData([5,6,7,8],:);
end
%% return receiver data
retVal = adcData;
参考:Mmwave Radar Device ADC Raw Data Capture
通过程序读出的数据如下图所示:
设置每个chirp信号ADC采样数为512,帧数为1帧,1帧中有1个chirp信号,使能1个发射天线Tx0,4个接收天线
设置每个chirp信号ADC采样数为512,帧数为1帧,1帧中有128个chirp信号 (128*512=65536),使能1个发射天线Tx0,4个接收天线
3. 实例程序
这里设置的是单发多收(SIMO),可用于测距和测速。
利用AWR1243+DCA1000进行了场景实测:
场景1 :位于2m左右的墙体目标
场景2 :利用mmWave Studio设置的两个仿真点目标 ([x,y,z],Velocity) ([4,4,0],5) ([0,8,0],-3)
AWR1243雷达参数设置如下图所示:
数据处理代码:
clc;clear;close all
%% 读取数据
%%% adc_data_wall.bin
% 测量目标是位于2m左右的墙 由AWR1243+DCA1000获取回波数据
% Nadc = 512 Nframe = 1 Nchirp = 128 一帧中128个chirp信号 每个chirp信号采样512个点
%%% adc_data_sim.bin
% 由mmWave Studio中设置的仿真点目标
% Nadc = 512 Nframe = 1 Nchirp = 128 一帧中128个chirp信号 每个chirp信号采样512个点
filename = 'adc_data_wall.bin';
rawData = readDCA1000(filename);
%% 雷达参数设置
c = physconst('lightspeed');
f0 = 77E9;
ADCStartTime = 6E-6;
IdleTime = 10E-6;
RampEndTime = 63.14E-6;
K = 63.343E12; % 调频率 (Hz/sec)
fStart = f0+K*ADCStartTime; % 起始频率
fS = 9121e3; % ADC采样频率 (sps)
Ts = 1/fS; % ADC采样间隔
Nchirp = 128; % 一个帧的chirp数
Nadc = 512; % 一个chirp的adc采样点数
%% 雷达系统参数
Tchirp = Ts*Nadc; % ADC采样时间
B = K*Tchirp; % 采样信号带宽
rangeRes = c/(2*B); % 距离分辨率
fc = f0+B/2; % 中间频率
Tc = RampEndTime+IdleTime; % 总的chirp信号时长,包含空闲时间
lambda = c/fc;
velRes = lambda/(2*Tc*Nchirp); % 速度分辨率
%% Take Range-FFT
nFFT = 1024;
rawData = squeeze(rawData(1,:)); % 取Rx0的回波采样信号
rawData = reshape(rawData,Nadc,Nchirp);
% 1D-FFT
rawDataFFT1 = fft(rawData,nFFT);
% 2D-FFT
rawDataFFT2 = fft(rawDataFFT1,nFFT,2);
rawDataFFT2 = fftshift(rawDataFFT2,2);
% 绘制距离FFT图
rangeAxis = rangeRes*(0:nFFT-1)*(Nadc/nFFT);
chirpAxis = 1:Nchirp;
figure('name','距离FFT')
mesh(chirpAxis,rangeAxis,mag2db(abs(rawDataFFT1)));
view(2)
xlabel('Chirp脉冲数');
xlim([1,Nchirp]);
ylabel('距离(m)');
ylim([0,rangeAxis(end)]);
title('距离FFT');
% 绘制R-D图
dopplerAxis = velRes*((-nFFT/2:nFFT/2-1))*(Nchirp/nFFT);
figure('name','R-D图')
mesh(dopplerAxis,rangeAxis,mag2db(abs(rawDataFFT2)));
view(2);
xlabel('速度(m/s)');
xlim([dopplerAxis(1),dopplerAxis(end)]);
ylabel('距离(m)');
ylim([0,rangeAxis(end)]);
title('R-D图');
场景1的处理效果:
场景2的处理效果:
4. 测角
这里使用AWR1243的2根发射天线Tx0,Tx2和4根接收天线Rx0,Rx1,Rx2,Rx3,等效位于同一水平位置上的8个阵元用以测量目标方位角。
注意:这里使用TDM-MIMO,要注意接收回波中每个发射天线的Chirp信号是交错的,对于同一个发射天线来说在一个帧中其发射脉冲间隔增大了!
-示例代码:
%%% adc_data_simAngleFFT
% 由mmWave Studio中设置的仿真点目标 [(x,y,z),Velocity,SignalLevel]
% 目标1:[(4,4,0),5,-2.5] 目标2:[(0,8,0),-3,-15]
% Nadc = 512 Nframe = 1 Nchirp = 128 使能发射天线Tx0,Tx2 接收天线Rx0,Rx1,Rx2,Rx3
% filename = 'adc_data_simAngleFFT.bin';
%-------------------------------------------------------------------------------------------
% 触发雷达信号并接受回波
run('CaptrueData.m');
% 等待ADC数据读取
pause(2);
% ADC数据地址
filename = 'D:\Radar\AWR1243\ReadData\RawData_0\adc_data_Raw_0.bin';
% 读取数据
adcData = readDCA1000(filename);
%% 雷达参数设置
c = physconst('lightspeed');
f0 = 77E9;
ADCStartTime = 6E-6;
IdleTime = 10E-6;
RampEndTime = 63.14E-6;
K = 63.343E12; % 调频率 (Hz/sec)
fStart = f0+K*ADCStartTime; % 起始频率
fS = 9121e3; % ADC采样频率 (sps)
Ts = 1/fS; % ADC采样间隔
Nchirp = 128; % 一个帧的chirp数
Nadc = 512; % 一个chirp的adc采样点数
Nrx = 4; % 接收天线Rx数量
Ntx = 2; % 发射天线Tx数量
Nant = Nrx*Ntx;
%% 雷达系统参数
Tchirp = Ts*Nadc; % ADC采样时间
B = K*Tchirp; % 采样信号带宽
rangeRes = c/(2*B); % 距离分辨率
fc = f0+B/2; % 中间频率
Tc = (RampEndTime+IdleTime)*Ntx;
% Tc = 总的chirp信号时长,包含空闲时间
% 在使用TDM-MIMO时要注意,Tc是对于同1个Tx的相邻两个Chirp信号之间的间隔 所以要Tc×Ntx => 速度分辨率减小
% 当然也可以将不同Tx的Chirp信号合并处理,则原有的Tc不变,Nchirp增大Ntx倍(Nchirp×Ntx)=>速度分辨率增大
lambda = c/fc;
velRes = lambda/(2*Tc*Nchirp); % 速度分辨率
d = lambda/2; % 等效阵元的间距
angleRes = (lambda/(Nant*d))*180/pi; % 角度分辨率
% --------------------------------------------------------------------------------
%% 重排回波数据
rawDataTx = zeros(Nrx*Ntx,Nadc,Nchirp);
% format: [Nrx*Ntx,Nadc,Nchirp]
% [Rx0Tx0 Rx0Tx1 | Rx1Tx0 Rx1Tx1 | Rx2Tx0 Rx2Tx1 | Rx3Tx0 Rx3Tx1]
channal = 0; %初始化通道数
for ii = 1:Nrx
tempData = squeeze(adcData(ii,:));
tempData = reshape(tempData,Nadc,[]);
for jj = 1:Ntx
channal = channal + 1; % 通道数递增1 最大通道数channalMax = Nrx*Ntx
rawDataTx(channal,:,:) = tempData(:,jj:Ntx:end);
end
end
% [Rx0Tx0 Rx1Tx0 Rx2Tx0 Rx3Tx0 | Rx0Tx1 Rx1Tx1 Rx2Tx1 Rx3Tx1]
rawDataRx = zeros(Nrx*Ntx,Nadc,Nchirp);
for jj = 1:Ntx
rawDataRx(1+Nrx*(jj-1):Nrx*jj,:,:) = rawDataTx(jj:Ntx:end,:,:);
end
% --------------------------------------------------------------------------------
% 虚拟 阵元设置 根据Rx和Tx的位置关系设置
% [Rx3Tx0 Rx2Tx0 Rx1Tx0 Rx0Tx0 | Rx3Tx1 Rx2Tx1 Rx1Tx1 Rx0Tx1]
rawDataVx = zeros(Nrx*Ntx,Nadc,Nchirp);
for jj = 1:Ntx
rawDataVx(1+Nrx*(jj-1):Nrx*jj,:,:) = rawDataTx(flip(jj:Ntx:end),:,:);
end
%% Take Range-FFT
nFFT = 1024;
rawData = rawDataVx.*hanning(Nadc).'; % 加窗,抑制频谱泄露
% 1D-FFT
rawDataFFT1 = fft(rawData,nFFT,2);
% 2D-FFT
rawDataFFT2 = fft(rawDataFFT1,nFFT,3);
rawDataFFT2 = fftshift(rawDataFFT2,3);
% 3D-FFT
% 通过RD图找到目标峰值对应的索引并沿通道维做FFT
angleFFTargetOne = fftshift(fft(rawDataFFT2(:,270,792),nFFT)); % 目标1位置 强度(-2.5dBFS)
angleFFTargetTwo = fftshift(fft(rawDataFFT2(:,380,280),nFFT)); % 目标2位置 强度( -15dBFS)
% ----绘制距离FFT图---------------------------------------------------------------
rangeAxis = rangeRes*(0:nFFT-1)*(Nadc/nFFT);
chirpAxis = 1:Nchirp;
rangeFFT = squeeze(rawDataFFT1(1,:,:));
figure('name','距离FFT')
mesh(chirpAxis,rangeAxis,mag2db(abs(rangeFFT)/max(abs(rangeFFT),[],'all')))
colorbar;
view(2)
colorbar;
caxis([-120,0])
xlabel('Chirp脉冲数');
xlim([1,Nchirp]);
ylabel('距离(m)');
ylim([0,rangeAxis(end)]);
title('距离FFT');
% ----------------------------------------------------------------------------------------
% 绘制R-D图
dopplerAxis = velRes*((-nFFT/2:nFFT/2-1))*(Nchirp/nFFT);
dopplerFFT = squeeze(rawDataFFT2(1,:,:));
figure('name','R-D图')
mesh(abs(dopplerFFT)/max(abs(dopplerFFT),[],'all'));
mesh(dopplerAxis,rangeAxis,mag2db(abs(dopplerFFT)/max(abs(dopplerFFT),[],'all')));
view(2);
colorbar;
caxis([-120,0])
xlabel('速度(m/s)');
xlim([dopplerAxis(1),dopplerAxis(end)]);
ylabel('距离(m)');
ylim([0,rangeAxis(end)]);
title('R-D图');
%------------------------------------------------------------------------------------------
% 绘制角度FFT图
angleAxis = angleRes*(-nFFT/2:nFFT/2-1)*(Nant/nFFT);
angleAxis = angleAxis./cosd(angleAxis);
figure('name','角度FFT')
plot(angleAxis,abs(angleFFTargetOne/max(angleFFTargetOne)));hold on
plot(angleAxis,abs(angleFFTargetTwo/max(angleFFTargetTwo)));
legend('目标1','目标2');
xlabel('角度(°)');
xlim([-90,90]);
ylabel('幅值');
title('角度FFT');
- 场景一:
- 场景二:
代码以及相关文件可访问: https://github.com/fangrxkami/AWR1243