matlab读取毫米波雷达数据,并批量转换代码

文章描述了一个MATLAB脚本,用于遍历指定目录下的二进制文件(.bin),通过函数`traverseFolders`和`convert_main`对DCA1000产生的数据进行读取和转换,生成XYZ坐标数据并保存为文本文件。

main文件

负责遍历所有文件,创建文件夹,保存数据

clear;
clc;
close all;

dir_name='res';
  
% 调用函数,遍历名为'dir'的文件夹及其所有子文件夹  
traverseFolders(dir_name);

function traverseFolders(folderPath)  
    % 获取指定文件夹下的所有文件和子文件夹  
    currentDir = dir(fullfile(folderPath, "*"));  
      
    % 遍历当前文件夹下的所有文件和子文件夹  
    for i = 1:length(currentDir)  
        
        if ~isfolder(fullfile(folderPath, currentDir(i).name))
                bin_file = currentDir(i).name(length(currentDir(i).name) - length('.bin')+ 1:length(currentDir(i).name));
                
               
                % 如果不是文件夹,则是文件,可以执行相应的操作  
               if strcmp(bin_file, '.bin')
                   [file_number, ~] = strsplit(currentDir(i).name, '.');
                   file_number = file_number{1};
                   fprintf("%s \n", file_number)
                   file_path = fullfile(folderPath, currentDir(i).name);
                   [X,Y,Z] = convert_main(file_path, 0);
                   dst_path = strrep(file_path, "res", "dots");
                   dst_path = strrep(dst_path, "bin", "txt");
                   fprintf("%s--%d--d:%s\n", bin_file, file_number, dst_path)
                   
                   dlmwrite(strrep(dst_path, file_number, "X" + file_number), X, ' ');
%                    dlmwrite('output_column.txt', Y, ' ');
%                    dlmwrite('output_column.txt', Z, ' ');
               end
%                 fprintf('文件: %s\n', fullfile(folderPath, currentDir(i).name)); 
         
        else  
            % 如果是文件夹,则递归遍历子文件夹  
            if strcmp(currentDir(i).name, '.') || strcmp(currentDir(i).name, '..')  
                % 忽略当前文件夹和父文件夹  
                continue;  
            end  
            % 递归调用traverseFolders函数处理子文件夹  
            if ~exist(fullfile("dots", currentDir(i).name), 'dir')  
                mkdir(fullfile("dots", currentDir(i).name));  
                disp('文件夹已成功创建。');  
            else  
                disp('文件夹已存在。');  
            end
            traverseFolders(fullfile(folderPath, currentDir(i).name));  
        end  
    end  
end  


convert_main

负责转换数据



function [RX, RY, RZ] = convert_main(fileName, show)
% fileName='12.bin';
SampleNum = 128;
ChirpNum = 128;

[retVal] = readDCA1000_convert(fileName,SampleNum);
Frame = 100;
waveLength = 300/61200;
elementDistance = 2.5e-3;
x_range=zeros(1,200);
y_range=zeros(1,200);
z_range=zeros(1,200);
X=zeros(1,200);
Y=zeros(1,200);
Z=zeros(1,200);

for FrameNum = 1:Frame
    data1 = retVal(1,(FrameNum-1)*SampleNum*ChirpNum+1:SampleNum*ChirpNum*(FrameNum));
    data2 = reshape(data1,SampleNum,[]);
    %T1R1 = data2(:,1:3:end);
    T2R1 = data2;
    %T3R1 = data2(:,3:3:end);
    if show
        plot(real(T2R1))
    end
    data1 = retVal(2,(FrameNum-1)*SampleNum*ChirpNum+1:SampleNum*ChirpNum*(FrameNum));
    data2 = reshape(data1,SampleNum,[]);
    %T1R2 = data2(:,1:3:end);
    T2R2 = data2;
    %T3R2 = data2(:,3:3:end);
   data1 = retVal(3,(FrameNum-1)*SampleNum*ChirpNum+1:SampleNum*ChirpNum*(FrameNum)); 
    data2 = reshape(data1,SampleNum,[]);
    %T1R3 = data2(:,1:3:end);
    T2R3 = data2;
    %T3R3 = data2(:,3:3:end);
    data1 = retVal(4,(FrameNum-1)*SampleNum*ChirpNum+1:SampleNum*ChirpNum*(FrameNum)); 
    data2 = reshape(data1,SampleNum,[]);
    %T1R3 = data2(:,1:3:end);
    T2R4 = data2;
    %T3R3 = data2(:,3:3:end);
    %plot(real(T2R4))
    
    
%     ces_T2R1 = T2R1(:,64)-T2R1(:,1);
%     RangeFFTces1 = fft( ces_T2R1.*hann(64) );
%     [cesvalue1,cesloc1] = max(RangeFFTces1(2:20));
%     RangePhaseInRad1ces1 = angle( RangeFFTces1(cesloc1+1) );
%     track(FrameNum,1) = cesloc1;
%     
%     ces_T2R2 = T2R2(:,64)-T2R2(:,1);
%     RangeFFTces2 = fft( ces_T2R2.*hann(64) );
%      [cesvalue2,cesloc2] = max(RangeFFTces2(2:20));
%     RangePhaseInRad1ces2 = angle( RangeFFTces2(cesloc2+1) );
%     track2(FrameNum,1) = cesloc2;
%%    
    for ii=1:128
        if(sum(T2R1(:,ii))==0)
            T2R1(:,ii)=T2R1(:,ii-1);
        end
        RangeFFT1(:,ii) = fft( T2R1(:,ii).*hann(128) );
        RangePhaseInRad1(:,ii) = angle( RangeFFT1(:,ii) );
    end
    RangeFFT1(1,:)=0;   
    for ii=1:128
        VelFFT1(ii,:) = fft( RangeFFT1(ii,:).*hann(128)' );
        VelocityPhaseInRad1(ii,:) = angle( VelFFT1(ii,:) );
    end
    VelFFT1(:,1)=0;
    
    
    for ii=1:128
        if(sum(T2R2(:,ii))==0)
            T2R2(:,ii)=T2R2(:,ii-1);
        end
        RangeFFT2(:,ii) = fft( T2R2(:,ii).*hann(128) );
        RangePhaseInRad2(:,ii) = angle( RangeFFT2(:,ii) );
    end
    RangeFFT2(1,:)=0;
    for ii=1:128
        VelFFT2(ii,:) = fft( RangeFFT2(ii,:).*hann(128)' );
        VelocityPhaseInRad2(ii,:) = angle( VelFFT2(ii,:) );
    end
    VelFFT2(:,1)=0;

    for ii=1:128
        if(sum(T2R3(:,ii))==0)
            T2R3(:,ii)=T2R3(:,ii-1);
        end
        RangeFFT3(:,ii) = fft( T2R3(:,ii).*hann(128) );
    end
    RangeFFT3(1,:)=0;
    for ii=1:128
        VelFFT3(ii,:) = fft( RangeFFT3(ii,:).*hann(128)' );
        VelocityPhaseInRad3(ii,:) = angle( VelFFT3(ii,:) );
    end
    VelFFT3(:,1)=0;
    
    
    for ii=1:128
        if(sum(T2R4(:,ii))==0)
            T2R4(:,ii)=T2R4(:,ii-1);
        end
        RangeFFT4(:,ii) = fft( T2R4(:,ii).*hann(128) );
    end
    RangeFFT4(1,:)=0;
    for ii=1:128
        VelFFT4(ii,:) = fft( RangeFFT4(ii,:).*hann(128)' );
        VelocityPhaseInRad4(ii,:) = angle( VelFFT4(ii,:) );
    end
    VelFFT4(:,1)=0;
%     if(FrameNum>25)
%         FrameNum
%     figure(2)
%     %mesh(abs(VelFFT1(2:50,3:127)));
%     mesh(abs(VelFFT1))
%     axis([3 127 0 50 0 1e5]);
%     pause(0.5);
%     end
%     figure(2)
%     plot(abs(RangeFFT(2:50,:)))
%     axis([0 50 0 0.8e5]);
%     pause(0.5);
%     if (FrameNum==120)
%         pause(0.1);
%     end
    %%
    TargetRange=[];
    TargetVelocity=[];
    TargetAmp=[];
    LoopTargetNumber=0;
%     maxvelvalue = max(max(abs(VelFFT1(2:20,3:31))));
%     [maxrow , maxcol] = find(abs(VelFFT1(2:20,3:31)) == maxvelvalue);
%     rowlast = maxrow+1;
%     collast = maxcol+2;
%     
%     maxvelvalue1 = max(max(abs(VelFFT2(2:20,3:31))));
%     [maxrow1 , maxcol1] = find(abs(VelFFT2(2:20,3:31)) == maxvelvalue1);
%     rowlast1 = maxrow1+1;
%     collast1 = maxcol1+2;
%     
%     ZhaoYaobuniubidejiaodu(FrameNum,1) = AngleProcess(VelocityPhaseInRad3(rowlast,collast),VelocityPhaseInRad3(rowlast1,collast1),elementDistance, waveLength);
    for p=3:127%15
        [pks2,locs2] = findpeaks(abs(VelFFT1(7:15,p)));%20
        for z=1:length(pks2)
            if(   pks2(z)>20000 ) %(locs2(z)+1)<10 &&13
                LoopTargetNumber = LoopTargetNumber+1;
                TargetRange(LoopTargetNumber)=locs2(z)+5;
                TargetVelocity(LoopTargetNumber)=p;
                TargetAmp(LoopTargetNumber)=pks2(z);
            end
        end
    end
%     for p=3:127%15
%         [pks2,locs2] = findpeaks(abs(VelFFT2(6:20,p)));%20
%         for z=1:length(pks2)
%             if(   pks2(z)>40000 ) %(locs2(z)+1)<10 &&13
%                 LoopTargetNumber = LoopTargetNumber+1;
%                 TargetRange(LoopTargetNumber)=locs2(z)+5;
%                 TargetVelocity(LoopTargetNumber)=p;
%                 TargetAmp(LoopTargetNumber)=pks2(z);
%             end
%         end
%     end
    
    if(FrameNum==25)
        pause(0.1);
    end
    
    if ( length(TargetRange) > 0 )
        
        for r=1:length(TargetRange)

             PitchAngle(r,FrameNum) = AngleProcess( VelocityPhaseInRad2(TargetRange(r),TargetVelocity(r)), VelocityPhaseInRad1(TargetRange(r),TargetVelocity(r)), elementDistance, waveLength );
             AzimuthAngle(r,FrameNum) = AngleProcess( VelocityPhaseInRad3(TargetRange(r),TargetVelocity(r)), VelocityPhaseInRad1(TargetRange(r),TargetVelocity(r)), elementDistance, waveLength );
            if( abs(PitchAngle(r,FrameNum))<60 && abs(AzimuthAngle(r,FrameNum))<60  )
                Y(r,FrameNum)=cos( AzimuthAngle(r,FrameNum) *pi/180)*TargetRange(r)*0.085;%Y(r,ii)
                X(r,FrameNum)=sin( AzimuthAngle(r,FrameNum) *pi/180)*TargetRange(r)*0.085;%cos( PitchAngle(r,ii) *pi/180)*% X(r,ii) Z( round(X(r,ii)) +20, round(Y(r,ii))+20 )
                Z(r,FrameNum)=sin( PitchAngle(r,FrameNum) *pi/180)*TargetRange(r)*0.085;
            end
        end
        
        %         Y(Y<5)=0;
        %         X(X<5)=0;
        %         Z(Z<5)=0;
        x_range(FrameNum)=sum( X(:,FrameNum))/length(nonzeros(X(:,FrameNum)));
        y_range(FrameNum)=sum( Y(:,FrameNum))/length(nonzeros(Y(:,FrameNum)));
        z_range(FrameNum)=sum( Z(:,FrameNum))/length(nonzeros(Z(:,FrameNum)));
%                  figure(3)
%                  plot3(X(:,FrameNum), Y(:,FrameNum),Z(:,FrameNum),'.')
%                  hold on
%                  grid on
%                  axis([-2 2 -2 2 0 3])
%                  pause(0.1)
         if show
                 figure(4);
                 plot(X(:,FrameNum), Y(:,FrameNum),'*');
                  axis([-2 2 -2 2])
                  hold on
                  pause(0.01);
                  figure(5);
                 plot(X(:,FrameNum), Z(:,FrameNum),'*');
                 axis([-2 2 -2 2]);
                 hold on
                 pause(0.01);
         end
        
    else
        RangeOut(ii)=0;
        VelOut(ii)=0;
%         PitchAngle(1,ii) =0;
%         AzimuthAngle(1,ii)=0;
    
    end
    
end
RX = X;
RY = Y;
RZ = Z;
end

readDCA1000_convert

负责转换DCA数据


%%% This script is used to read the binary file produced by the DCA1000 and Mmwave Studio
%%% Command to run in Matlab GUI -
function [retVal] = readDCA1000_convert(fileName,SampleNum)
%% global variables
% change based on sensor config
numADCSamples = SampleNum; % number of ADC samples per chirp
numADCBits = 16; % number of ADC bits per sample
numRX = 4; % number of receivers
numLanes = 2; % do not change. number of lanes is always 2
isReal = 0; % set to 1 if real only data, 0 if complex data0
%% read file
% read .bin file
fid = fopen(fileName,'r');
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);
fileSize = size(adcData, 1);
% real data reshape, filesize = numADCSamples*numChirps
if isReal
	numChirps = fileSize/numADCSamples/numRX;
	LVDS = zeros(1, fileSize);
	%create column for each chirp
	LVDS = reshape(adcData, numADCSamples*numRX, numChirps);
	%each row is data from one chirp
	LVDS = LVDS.';
else
	% for complex data
	% filesize = 2 * numADCSamples*numChirps
	numChirps = fileSize/2/numADCSamples/numRX;
	LVDS = zeros(1, fileSize/2);
	%combine real and imaginary part into complex data
	%read in file: 2I is followed by 2Q
	counter = 1;
	for i=1:4:fileSize-1
		LVDS(1,counter) = adcData(i) + sqrt(-1)*adcData(i+2); 
		LVDS(1,counter+1) = adcData(i+1)+sqrt(-1)*adcData(i+3);
		counter = counter + 2;
	end
	% create column for each chirp
	LVDS = reshape(LVDS, numADCSamples*numRX, numChirps);
	%each row is data from one chirp
	LVDS = LVDS.';
end
%organize data per RX
adcData = zeros(numRX,numChirps*numADCSamples);
for row = 1:numRX
	for i = 1: numChirps
		adcData(row, (i-1)*numADCSamples+1:i*numADCSamples) = LVDS(i, (row-1)*numADCSamples+1:row*numADCSamples);
	end
end
% return receiver data
retVal = adcData;

在这里插入图片描述

<think>我们正在讨论如何使用Python读取毫米波雷达的ADC数据。用户之前提到过DCA1000和相关的MATLAB函数,但现在用户明确要求使用Python方法。根据引用[1]中给出的代码片段,我们可以推断用户可能已经通过某种方式获取了IQ数据(可能是从DCA1000采集的二进制文件),现在需要解析这些数据。 另外,根据之前的对话,我们知道DCA1000采集的数据是以二进制格式存储的,每个采样点由两个16位整数(分别代表I和Q)组成,小端字节序。 因此,我们需要做以下几步: 1. 读取二进制文件。 2. 将二进制数据解析为整数(有符号16位整数)。 3. 将整数转换为浮点数(可选,但通常用于信号处理)。 4. 组合成复数(I + jQ)。 同时,引用[1]中的代码片段展示了一个特征提取函数,它接受一个一维复数数组(即一个帧的IQ数据提取特征。但是,我们首先需要将原始的二进制数据转换成这样的复数数组。 此外,用户之前的问题中提到了DCA1000_Read_Data函数,该函数在MATLAB中用于解析数据,现在我们需要用Python实现类似功能。 根据以上分析,我们可以给出以下步骤: 步骤1:读取二进制文件,得到字节流。 步骤2:将字节流解析为有符号16位整数数组。 步骤3:将整数数组重新整形为[num_frames, num_chirps, num_channels, num_samples](注意维度顺序可能有所不同,但通常采样点在最内层)。 步骤4:将I和Q数据组合成复数。注意,在二进制数据中,通常是I0, Q0, I1, Q1, ... 这样的顺序。 但是,我们还需要知道雷达的参数设置(帧数、每帧啁啾数、通道数、每个啁啾的采样点数)。这些参数必须与采集时设置的参数一致,否则无法正确解析。 下面是一个示例代码,用于解析DCA1000采集的二进制数据: 注意:DCA1000采集的数据存储格式为小端字节序(little-endian),每个采样点由两个16位整数组成(I和Q),按顺序交替存储。 假设我们有一个二进制文件'adc_data.bin',采集参数如下: num_frames: 帧数 num_chirps: 每帧的啁啾数 num_channels: 接收天线通道数(例如4个接收天线) num_samples: 每个啁啾的采样点数 那么,总的数据点数为:num_frames * num_chirps * num_channels * num_samples * 2(因为每个采样点有I和Q两个值) 因此,读取的整数数组长度应为上述总数据点数,然后我们将其重新整形为4维数组(帧,啁啾,通道,采样点),然后再组合成复数。 具体代码实现如下: </think>以下是使用 Python 读取毫米波雷达 ADC 数据的完整方法说明,结合 DCA1000 采集卡的操作流程: ### 一、Python 读取 ADC 数据核心步骤 #### 1. **硬件连接配置** ```mermaid graph LR A[毫米波雷达传感器] -- LVDS --> B(DCA1000) B -- 千兆以太网 --> C[PC] C -- USB --> B ``` - **关键设置**: - PC 静态 IP: `192.168.33.30`,子网掩码 `255.255.255.0` - 雷达配置参数:需与代码参数严格一致(帧数/啁啾数/通道数/采样点) #### 2. **Python 数据解析代码** ```python import numpy as np def read_dca1000_bin(file_path, num_frames, num_chirps, num_channels, num_samples): """ 解析DCA1000采集的原始ADC数据 参数说明: file_path: .bin文件路径 num_frames: 帧数 num_chirps: 每帧啁啾数 num_channels: RX通道数 num_samples: 每个啁啾的采样点数 """ # 读取二进制文件 raw_data = np.fromfile(file_path, dtype=np.int16) # 计算总采样点数 total_samples = num_frames * num_chirps * num_channels * num_samples * 2 # ×2(I/Q分离) # 数据校验 if len(raw_data) != total_samples: raise ValueError(f"数据量不匹配! 预期:{total_samples}, 实际:{len(raw_data)}") # 转换为复数数据 (I + jQ) complex_data = raw_data[::2] + 1j * raw_data[1::2] # 重塑为4D数组 [帧, 啁啾, 通道, 采样点] reshaped_data = complex_data.reshape( num_frames, num_chirps, num_channels, num_samples ) return reshaped_data # 示例调用(AWR1243参数) adc_data = read_dca1000_bin( file_path="adc_data.bin", num_frames=50, # 50帧 num_chirps=128, # 每帧128个啁啾 num_channels=4, # 4个接收通道 num_samples=256 # 每个啁啾256个采样点 ) ``` #### 3. **数据格式说明** DCA1000 输出的二进制文件格式: - **数据类型**:16位有符号整数(`int16`) - **字节顺序**:小端序(Little-Endian) - **排列顺序**: ``` I0, Q0, I1, Q1, ..., In, Qn ``` - **复数转换公式**: $$ \text{ADC}_{complex}[k] = I_k + jQ_k $$ ### 二、实时数据采集方案 使用 TI 官方 `DCA1000EVM` Python 包实时获取数据: ```python from DCA1000 import DCA1000 # 配置雷达参数 config = { 'num_frames': 50, 'num_chirps': 128, 'num_channels': 4, 'num_samples': 256 } # 初始化采集卡 dca = DCA1000() dca.configure(config) # 开始实时采集 dca.start_capture() # 获取当前帧数据(非阻塞模式) while True: frame_data = dca.get_frame() if frame_data is not None: process_frame(frame_data) # 自定义处理函数 # 停止采集 dca.stop_capture() ``` ### 三、关键注意事项 1. **参数一致性** 代码中的雷达参数必须与硬件配置**完全匹配**,否则会导致数据维度错误(常见报错:`ValueError: cannot reshape array`)[^1] 2. **数据验证方法** 可通过能量检测验证数据有效性: ```python frame_energy = np.sum(np.abs(adc_data[0,0,0,:])**2) print(f"首帧首啁啾能量: {frame_energy:.2f}") # 正常应 > 1000 ``` 3. **性能优化技巧** - 使用内存映射文件处理大文件: ```python raw_data = np.memmap("adc_data.bin", dtype=np.int16, mode='r') ``` - 行处理帧数据(结合 `multiprocessing` 模块) ### 四、典型应用场景 1. **人体姿态识别** ```python # 提取微多普勒特征 range_fft = np.fft.fft(adc_data, axis=3) doppler_fft = np.fft.fft(range_fft, axis=1) ``` 2. **手势识别系统** ```python # 生成距离-多普勒图(RD图) rd_map = 20*np.log10(np.abs(doppler_fft.mean(axis=2))) ``` 3. **呼吸心跳监测** ```python # 提取相位变化 phase_data = np.angle(adc_data[0,0,0,:]) respiratory_wave = np.unwrap(phase_data) ``` > ⚠️ **注意**:不同雷达型号(IWR6843/AWR1843等)需调整`num_channels`参数,需查阅对应数据手册[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

东哥aigc

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值