【2243】module_param.m_caso cfar-程序员宅基地

技术标签: matlab  AWR2243  开发语言  

cascade_MIMO_signalProcessing

% 处理原始ADC数据的顶级主测试链。处理链包括adc数据校准模块、量程FFT模块、多普勒FFT
模块,CFAR模块,DOA模块。每个模块在链中实际使用之前都首先初始化。

%  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/
%
%
%   Redistribution and use in source and binary forms, with or without
%   modification, are permitted provided that the following conditions
%   are met:
%
%     Redistributions of source code must retain the above copyright
%     notice, this list of conditions and the following disclaimer.
%
%     Redistributions in binary form must reproduce the above copyright
%     notice, this list of conditions and the following disclaimer in the
%     documentation and/or other materials provided with the
%     distribution.
%
%     Neither the name of Texas Instruments Incorporated nor the names of
%     its contributors may be used to endorse or promote products derived
%     from this software without specific prior written permission.
%
%   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
%   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
%   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
%   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
%   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
%   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
%   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
%   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
%   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
%   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
%   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%
%

% cascade_MIMO_signalProcessing.m
%
% Top level main test chain to process the raw ADC data. The processing chain including adc data calibration module, range FFT module, DopplerFFT
% module, CFAR module, DOA module. Each module is first initialized before actually used in the chain.
% 处理原始ADC数据的顶级主测试链。处理链包括adc数据校准模块、量程FFT模块、多普勒FFT
% 模块,CFAR模块,DOA模块。每个模块在链中实际使用之前都首先初始化。

clearvars
close all

PLOT_ON = 1;              % 1: turn plot on; 0: turn plot off   1:开启;0:关闭
LOG_ON = 1;               % 1: log10 scale; 0: linear scale     1: log10刻度;0:线性范围
% numFrames_toRun = 10;   %要运行的帧数,可以少于保存在原始数据中的帧数 number of frame to run, can be less than the frame saved in the raw data
SAVEOUTPUT_ON = 0;
PARAM_FILE_GEN_ON = 1;
DISPLAY_RANGE_AZIMUTH_DYNAMIC_HEATMAP = 1 ;     % Will make things slower   显示范围方位动态热图 0不显示、1显示
dataPlatform = 'TDA2'

%% get the input path and testList 获取输入路径和testList   
pro_path = getenv('CASCADE_SIGNAL_PROCESSING_CHAIN_MIMO'); % getenv的这个调用返回一个空字符数组;getenv会返回一些环境变量
% input_path = strcat(pro_path,'\main\cascade\input\');      % strcat 横向连接字符串
input_path = strcat(pro_path,'input\');      % strcat 横向连接字符串
testList = strcat(input_path,'testList.txt');
%path for input folder 输入文件夹路径
fidList = fopen(testList,'r');
testID = 1;

while ~feof(fidList)                                        % 表示若未读到文件末尾,则继续循环
    
    %% get each test vectors within the test list     获取测试列表中的每个测试向量
    % test data file name 测试数据文件名  采集的数据
    dataFolder_test = fgetl(fidList);    % fgetl()读取每一行
   
    %calibration file name 校准文件名称
    dataFolder_calib = fgetl(fidList);
    
    %module_param_file 定义初始化每个信号处理的参数
    %module
    module_param_file = fgetl(fidList);
    
    %parameter file name for the test测试的参数文件名
    %生成测试参数的.m文件,放入 input_path 路径下
    pathGenParaFile = [input_path,'test',num2str(testID), '_param.m'];  % num2str()把数值转换成字符串
    %important to clear the same.m file, since Matlab does not clear cache automatically
    %清除同样的文件,因为Matlab不会自动清除缓存
    clear(pathGenParaFile);
    
    %generate parameter file for the test to run 生成运行测试的参数文件
    if PARAM_FILE_GEN_ON == 1    
        parameter_file_gen_json(dataFolder_test, dataFolder_calib, module_param_file, pathGenParaFile, dataPlatform);
        
    end
    
    %load calibration parameters  校准参数
    load(dataFolder_calib)        %load将文件变量加载到工作区中
    
    % simTopObj is used for top level parameter parsing and data loading and saving 
    % 用于顶级参数解析以及数据加载和保存
    simTopObj           = simTopCascade('pfile', pathGenParaFile);
    % 校准级联
    calibrationObj      = calibrationCascade('pfile', pathGenParaFile, 'calibrationfilePath', dataFolder_calib);
    rangeFFTObj         = rangeProcCascade('pfile', pathGenParaFile);
    DopplerFFTObj       = DopplerProcClutterRemove('pfile', pathGenParaFile);
    detectionObj        = CFAR_CASO('pfile', pathGenParaFile);
    DOAObj              = DOACascade('pfile', pathGenParaFile);
    
    % get system level variables
    %获取系统级变量
    platform            = simTopObj.platform;
    numValidFrames      = simTopObj.totNumFrames;
    
    cnt = 1;
    frameCountGlobal = 0;
    
    
   % Get Unique File Idxs in the "dataFolder_test"    在“dataFolder_test”中获取唯一的文件Idxs
   [fileIdx_unique] = getUniqueFileIdx(dataFolder_test);
    
    for i_file = 1:(length(fileIdx_unique))
        
       % Get File Names for the Master, Slave1, Slave2, Slave3   
      [fileNameStruct]= getBinFileNames_withIdx(dataFolder_test, fileIdx_unique{i_file});        
       
      %pass the Data File to the calibration Object 将数据文件传递给校准对象
      calibrationObj.binfilePath = fileNameStruct;
        
      %检测结果
      detection_results = [];  
        
       % Get Valid Number of Frames 获取有效的帧数
       [numValidFrames dataFileSize] = getValidNumFrames(fullfile(dataFolder_test, fileNameStruct.masterIdxFile));
        %intentionally skip the first frame due to TDA2  故意跳过第一帧,因为TDA2
       
        for frameIdx = 2:1:numValidFrames;                      % numFrames_toRun运行的帧数
            tic                                                 % ic表示计时的开始,toc表示计时的结束。    
            %read and calibrate raw ADC data    
            %读取并校准原始ADC数据
            calibrationObj.frameIdx = frameIdx;
            frameCountGlobal = frameCountGlobal+1
            adcData = datapath(calibrationObj);  % calibrationCascade模块的datapath功能,该功能使用校准来校准ADC数据
            
            % RX Channel re-ordering  RX通道重新排序
                adcData = adcData(:,:,calibrationObj.RxForMIMOProcess,:);            
            
            %only take TX and RXs required for MIMO data analysis  只接收MIMO数据分析所需的TX和RXs
            % adcData = adcData
            
            if mod(frameIdx, 10)==1         % b = mod(a,m) 返回用 m 除 a 后的余数
                fprintf('Processing %3d frame...\n', frameIdx);
            end
            
            
            %perform 2D FFT  进行二维FFT
            rangeFFTOut = [];
            DopplerFFTOut = [];
            
            for i_tx = 1: size(adcData,4)
                % range FFT
                rangeFFTOut(:,:,:,i_tx)     = datapath(rangeFFTObj, adcData(:,:,:,i_tx));
                
                % Doppler FFT
                DopplerFFTOut(:,:,:,i_tx)   = datapath(DopplerFFTObj, rangeFFTOut(:,:,:,i_tx));
                
            end
            
  
            % CFAR done along only TX and RX used in MIMO array 
            %仅沿MIMO阵列中使用的TX和RX执行恒虚警
            DopplerFFTOut = reshape(DopplerFFTOut,size(DopplerFFTOut,1), size(DopplerFFTOut,2), size(DopplerFFTOut,3)*size(DopplerFFTOut,4));
            
            %detection检测
            sig_integrate = 10*log10(sum((abs(DopplerFFTOut)).^2,3) + 1);
                        % .*表示两个矩阵对应元素相乘
            detection_results = datapath(detectionObj, DopplerFFTOut);
            detection_results_all{cnt} =  detection_results;
            
            detect_all_points = [];
            for iobj = 1:length(detection_results)
                detect_all_points (iobj,1)=detection_results(iobj).rangeInd+1;
                detect_all_points (iobj,2)=detection_results(iobj).dopplerInd_org+1;
                detect_all_points (iobj,4)=detection_results(iobj).estSNR;
            end
            
            if PLOT_ON
                figure(1);
                set(gcf,'units','normalized','outerposition',[0 0 1 1])     % gcf 返回当前Figure 对象的句柄值           
                subplot(2,2,1)               
                plot((1:size(sig_integrate,1))*detectionObj.rangeBinSize, sig_integrate(:,size(sig_integrate,2)/2+1),'g','LineWidth',4);
                hold on; 
                grid on
                for ii=1:size(sig_integrate,2)
                    plot((1:size(sig_integrate,1))*detectionObj.rangeBinSize, sig_integrate(:,ii));
                    hold on; 
                    grid on
                    if ~isempty(detection_results)
                        ind = find(detect_all_points(:,2)==ii);  %find查找非零元素的索引和值
                        if (~isempty(ind))
                            rangeInd = detect_all_points(ind,1);
                            plot(rangeInd*detectionObj.rangeBinSize, sig_integrate(rangeInd,ii),'o','LineWidth',2,...
                                'MarkerEdgeColor','k',...
                                'MarkerFaceColor',[.49 1 .63],...
                                'MarkerSize',6);
                        end
                    end
                end
                
                %title(['FrameID: ' num2str(cnt)]);
                xlabel('Range(m)');
                ylabel('Receive Power (dB)')
                title(['Range Profile(zero Doppler - thick green line): frameID ' num2str(frameIdx)]);
                hold off;
                subplot(2,2,2);
                %subplot_tight(2,2,2,0.1)
                imagesc((sig_integrate))
                c = colorbar;
                c.Label.String = 'Relative Power(dB)';
                title(' Range/Velocity Plot');
                pause(0.01)
            end
            
            angles_all_points = [];
            xyz = [];
            %if 0
            if ~isempty(detection_results)
                % DOA, the results include detection results + angle estimation results.
                % access data with angleEst{frame}(objectIdx).fieldName
                angleEst = datapath(DOAObj, detection_results);
                
                if length(angleEst) > 0
                    for iobj = 1:length(angleEst)
                        angles_all_points (iobj,1:2)=angleEst(iobj).angles(1:2);
                        angles_all_points (iobj,3)=angleEst(iobj).estSNR;
                        angles_all_points (iobj,4)=angleEst(iobj).rangeInd;
                        angles_all_points (iobj,5)=angleEst(iobj).doppler_corr;
                        angles_all_points (iobj,6)=angleEst(iobj).range;
                        %switch left and right, the azimuth angle is flipped左右切换,方位角翻转
                        xyz(iobj,1) = angles_all_points (iobj,6)*sind(angles_all_points (iobj,1)*-1)*cosd(angles_all_points (iobj,2));
                        xyz(iobj,2) = angles_all_points (iobj,6)*cosd(angles_all_points (iobj,1)*-1)*cosd(angles_all_points (iobj,2));
                        %switch upside and down, the elevation angle is flipped
                        xyz(iobj,3) = angles_all_points (iobj,6)*sind(angles_all_points (iobj,2)*-1);
                        xyz(iobj,4) = angleEst(iobj).doppler_corr;
                        xyz(iobj,9) = angleEst(iobj).dopplerInd_org;
                        xyz(iobj,5) = angleEst(iobj).range;
                        xyz(iobj,6) = angleEst(iobj).estSNR;
                        xyz(iobj,7) = angleEst(iobj).doppler_corr_overlap;
                        xyz(iobj,8) = angleEst(iobj).doppler_corr_FFT;
                        
                    end
                    angles_all_all{cnt} = angles_all_points;
                    xyz_all{cnt}  = xyz;
                    maxRangeShow = detectionObj.rangeBinSize*rangeFFTObj.rangeFFTSize;
                    %tic
                    if PLOT_ON
                        moveID = find(abs(xyz(:,4))>=0);
                        subplot(2,2,4);                        
                        
                         if cnt==1
                             scatter3(xyz(moveID,1),xyz(moveID,2),xyz(moveID,3),45,(xyz(moveID,4)),'filled');% 填充图
                        else
%                              yz = [xyz_all{cnt}; xyz_all{cnt-1}];
%                              scatter3(xyz(moveID,1),xyz(moveID,2),xyz(moveID,3),45,(xyz(moveID,4)),'filled');
                        end
                        
                        c = colorbar;
                        c.Label.String = 'velocity (m/s)';                        
                        grid on;
                        
                        xlim([-20 20])
                        ylim([1 maxRangeShow])
                        %zlim([-4 4])
                        zlim([-5 5])
                        xlabel('X (m)')
                        ylabel('y (m)')
                        zlabel('Z (m)')                        
                        
                        view([-9 15])                        
                        title(' 3D point cloud');
                        
                        %plot range and azimuth heatmap绘图范围和方位热图
                        subplot(2,2,3)
                        STATIC_ONLY = 1;
                        minRangeBinKeep =  5;
                        rightRangeBinDiscard =  20;
                        [mag_data_static(:,:,frameCountGlobal) mag_data_dynamic(:,:,frameCountGlobal) y_axis x_axis]= plot_range_azimuth_2D(detectionObj.rangeBinSize, DopplerFFTOut,...
                            length(calibrationObj.IdTxForMIMOProcess),length(calibrationObj.RxForMIMOProcess), ...
                            detectionObj.antenna_azimuthonly, LOG_ON, STATIC_ONLY, PLOT_ON, minRangeBinKeep, rightRangeBinDiscard);
                        title('range/azimuth heat map static objects')
                       
                        
    if (DISPLAY_RANGE_AZIMUTH_DYNAMIC_HEATMAP)                   
    figure(2)
    subplot(121);
    surf(y_axis, x_axis, (mag_data_static(:,:,frameCountGlobal)).^0.4,'EdgeColor','none');
    view(2);
    xlabel('meters');    ylabel('meters')
    title({'Static Range-Azimuth Heatmap',strcat('Current Frame Number = ', num2str(frameCountGlobal))})
    
    subplot(122);
    surf(y_axis, x_axis, (mag_data_dynamic(:,:,frameCountGlobal)).^0.4,'EdgeColor','none');
    view(2);    
    xlabel('meters');    ylabel('meters')
    title('Dynamic HeatMap')
    end
    pause(0.1) 

     
                    end
                    
                end
                
            end
                             
            cnt = cnt + 1;    
       toc    
        end
        
        
    end
    
    ind = strfind(dataFolder_test, '\');
    testName = dataFolder_test(ind(end-1)+1:(ind(end)-1));
    if SAVEOUTPUT_ON == 1
        save(['.\main\cascade\output\newOutput_',testName,'.mat'],'angles_all_all', 'detection_results_all','xyz_all');
    end
    testID = testID + 1;
    
end

module_param.m

%包含用于信号处理的每个模块的初始参数列表,包括simTopCascade、calibration、rangeFFT、DopplerFFT、CFAR、DOA模块。重要的是要知道,每个参数都需要定义为moudleName\u parameterName,parameterName在相应的模块中定义。在更改此文件之前,用户需要知道每个模块具有哪些参数。

%  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 
%  
%  
%   Redistribution and use in source and binary forms, with or without 
%   modification, are permitted provided that the following conditions 
%   are met:
%  
%     Redistributions of source code must retain the above copyright 
%     notice, this list of conditions and the following disclaimer.
%  
%     Redistributions in binary form must reproduce the above copyright
%     notice, this list of conditions and the following disclaimer in the 
%     documentation and/or other materials provided with the   
%     distribution.
%  
%     Neither the name of Texas Instruments Incorporated nor the names of
%     its contributors may be used to endorse or promote products derived
%     from this software without specific prior written permission.
%  
%   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
%   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
%   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
%   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
%   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
%   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
%   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
%   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
%   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
%   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
%   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%  
% 

% module_param.m
%  
% Contains a list of inital parameters for each modules used for signal
% processing, including modules of simTopCascade, calibration, rangeFFT, DopplerFFT, CFAR, DOA
% it is important to know that each parameter needs to be defined as
% moudleName_parameterName, the parameterName is defined in the
% corresponding module. Users need to know what parameters each module have
% before change this file.
%包含用于信号处理的每个模块的初始参数列表,包括simTopCascade、calibration、rangeFFT、DopplerFFT、CFAR、DOA模块。
%重要的是要知道,每个参数都需要定义为moudleName\u parameterName,parameterName在相应的模块中定义。
%在更改此文件之前,用户需要知道每个模块具有哪些参数。

platform = 'TI_4Chip_CASCADE';

%% fixed antenna ID and postion values for TI 4-chip cascade board. Should not be changed if user is based on TI board
%%TI 4芯片级联板的固定天线ID和位置值。如果用户基于TI板,则不应更改
% % Legacy Format TDA
%传统格式TDA
% TI_Cascade_TX_position_azi = [0 4 8 12 16 20 24 28 32 9 10 11];%12 TX antenna azimuth position on TI 4-chip cascade EVM
% TI_Cascade_TX_position_ele = [0 0 0 0 0 0 0 0 0 1 4 6];%12 TX antenna elevation position on TI 4-chip cascade EVM

% New Format TDA
% 新格式 TDA
% TI 4芯片级联EVM上的TX天线方位角位置
TI_Cascade_TX_position_azi = [11 10 9 32 28 24 20 16 12 8 4 0 ];%12 TX antenna azimuth position on TI 4-chip cascade EVM
%TI 4芯片级联EVM上的12 TX天线仰角位置
TI_Cascade_TX_position_ele = [6 4 1 0 0 0 0 0 0 0 0 0];%12 TX antenna elevation position on TI 4-chip cascade EVM

% Legacy RX channel mapping  传统RX信道映射
%TI_Cascade_RX_position_azi = [42:-1:39 3:-1:0 7:-1:4 53:-1:50 ];%16 RX antenna azimuth position on TI 4-chip cascade EVM
% TI_Cascade_RX_position_azi = [0:3 11:14 50:53 46:49 ];
TI_Cascade_RX_position_ele = zeros(1,16);%16 RX antenna elevation position on TI 4-chip cascade EVM
% TI_Cascade_RX_ID = [1 2 3 4 5 6 7 8 13 14 15 16 9 10 11 12]; %RX channel order on TI 4-chip cascade EVM

% Changed for the new Data format  更改为新的数据格式
TI_Cascade_RX_position_azi = [ 11:14 50:53 46:49 0:3  ];
%TI 4芯片级联EVM上的RX信道顺序
TI_Cascade_RX_ID = [13 14 15 16 1 2 3 4 9 10 11 12 5 6 7 8 ]; %RX channel order on TI 4-chip cascade EVM
%天线距离就是为这个频率设计的
TI_Cascade_Antenna_DesignFreq = 76.8; % antenna distance is designed for this frequency

%% constants   常数
speedOfLight        = 3e8;
% 比例因子
scaleFactor         = [0.0625, 0.03125, 0.015625, 0.0078125, 0.00390625, 0.001953125, 0.0009765625, 0.00048828125]*4;

%% define TX/RX antennas used for virtual array analysis. It can be a subset of the antennas enabled in data capture phase
%TxForMIMOProcess defines antenna TD used for TDM MIMO processing, can
%be a sub set of TxToEnable; CANNOT be channels that not enabled in TxToEnable
%%定义用于虚拟阵列分析的收发天线。它可以是在数据捕获阶段启用的天线的子集
%TXformoProcess定义了用于TDM MIMO处理的天线TD,可以是TxToEnable的子集;不能是未在TxToEnable中启用的通道
TxForMIMOProcess = TxToEnable;  
%TxForMIMOProcess = [1:9  ];
[IdTxForMIMOProcess ia ib] = intersect(TxForMIMOProcess, TxToEnable,'stable' );
if length(IdTxForMIMOProcess)~= length(TxForMIMOProcess)
    error('TX channel used for processing is not valid')
    
end
%使用所有16个RX,用户还可以选择RX的子集进行MIMO数据分析
RxForMIMOProcess = TI_Cascade_RX_ID; %using all 16 RXs, user can also choose subset of RXs for MIMO data analysis
%RxForMIMOProcess = [1:8];
%TX方位天线坐标
D_TX = TI_Cascade_TX_position_azi(TxToEnable(ib)); %TX azimuth antenna coordinates 
%TX仰角天线坐标
D_TX_ele = TI_Cascade_TX_position_ele(TxToEnable(ib));%TX elevation antenna coordinates
%RX方位天线坐标
D_RX = TI_Cascade_RX_position_azi(RxForMIMOProcess); %RX azimuth antenna coordinate
%RX仰角天线坐标
D_RX_ele = TI_Cascade_RX_position_ele(RxForMIMOProcess);%RX elevation antenna coordinate

%draw the virtual array
%绘制虚拟阵列
plotArray = 0;
RX_id_tot = [];
RX_id_tot_ele = [];
if plotArray == 1
    figure(1);
end
for ii = 1:length(D_TX)
    RX_id_new = D_RX + sum(D_TX(ii));
    RX_id_tot = [RX_id_tot RX_id_new];
    
    RX_id_new_ele = D_RX_ele + D_TX_ele(ii);
    RX_id_tot_ele = [RX_id_tot_ele RX_id_new_ele];
    if plotArray == 1
        plot(RX_id_new,RX_id_new_ele,'o');grid on; hold on
        ylim([-8 8])
    end
end
D(:,1) = RX_id_tot;
D(:,2) = RX_id_tot_ele;


%% derived parameters
%%导出参数
DopplerFFTSize = 2^(ceil(log2(nchirp_loops)));
numChirpsPerFrame = nchirp_loops*numChirpsInLoop;%nchirp_loops*numTxAnt;
chirpRampTime       = numADCSample/adcSampleRate;
chirpBandwidth      = chirpSlope * chirpRampTime; % Hz
chirpInterval       = chirpRampEndTime + chirpIdleTime;
carrierFrequency    = startFreqConst +  (adcStartTimeConst + chirpRampTime/2)*chirpSlope; % Hz center frequency
lambda              = speedOfLight/carrierFrequency;
maximumVelocity     = lambda / (chirpInterval*4) ; % m/s
maxRange            = speedOfLight*adcSampleRate*chirpRampTime/(2*chirpBandwidth);
numSamplePerChirp   = round(chirpRampTime*adcSampleRate);
rangeFFTSize        = 2^(ceil(log2(numSamplePerChirp)));
numChirpsPerVirAnt  = nchirp_loops;
numVirtualRxAnt     = length(TxForMIMOProcess) * length(RxForMIMOProcess) ;
rangeResolution     = speedOfLight/2/chirpBandwidth;
rangeBinSize        = rangeResolution*numSamplePerChirp/rangeFFTSize;
velocityResolution  = lambda / (2*nchirp_loops * chirpInterval*numTxAnt);
velocityBinSize     = velocityResolution*numChirpsPerVirAnt/DopplerFFTSize;


%% simTopCascade parameters
simTopCascade_inputDataSource          = 'bin'; % choose from 'mat','bin','gen'
simTopCascade_enable      = 1;
simTopCascade_outputDataSavingEnable   = 0;
simTopCascade_outputDataFileName       = [];
simTopCascade_totNumFrames = frameCount;
simTopCascade_platform                 = platform;


%% calibration cascade parameters
%用于频率校准的范围FFT的插值因子,在校准阶段确定
calibrationInterp              = 5;     %interpolation factor used for range FFT for frequency calibration, determined at calibration stage
calibrationCascade_enable      = 1;
calibrationCascade_binfilePath = [];
calibrationCascade_calibrationfilePath = [];
calibrationCascade_frameIdx = 1;
calibrationCascade_numSamplePerChirp = numSamplePerChirp;
calibrationCascade_nchirp_loops = nchirp_loops;
calibrationCascade_numChirpsPerFrame = numChirpsPerFrame;
calibrationCascade_TxToEnable = TxToEnable;
calibrationCascade_Slope_calib = Slope_calib;
calibrationCascade_Sampling_Rate_sps = adcSampleRate;
calibrationCascade_fs_calib = fs_calib;
calibrationCascade_chirpSlope = chirpSlope;
calibrationCascade_calibrationInterp = calibrationInterp;
calibrationCascade_TI_Cascade_RX_ID = TI_Cascade_RX_ID;
calibrationCascade_RxForMIMOProcess = RxForMIMOProcess;
calibrationCascade_IdTxForMIMOProcess = IdTxForMIMOProcess;
calibrationCascade_numRxToEnable = numRxToEnable;
%1:仅相位校准;0:相位和幅度校准
calibrationCascade_phaseCalibOnly = 1; % 1: only phase calibration; 0: phase and amplitude calibration
%1: adc数据校准开启;0校准关闭
calibrationCascade_adcCalibrationOn = 1; %1: adc data calibration on; 0 calibration off
%1:表示高级帧配置,该值从顶部主文件传递
calibrationCascade_ADVANCED_FRAME_CONFIG = ADVANCED_FRAME_CONFIG; %1 : indicate advance frame config, this value is passed from top main file
calibrationCascade_dataPlatform = dataPlatform;
calibrationCascade_RxOrder = TI_Cascade_RX_ID;
calibrationCascade_NumDevices = NumDevices;

if ADVANCED_FRAME_CONFIG == 1
    %用于在高级帧配置中读取原始adc数据
    calibrationCascade_N_TXForMIMO = N_TXForMIMO; % used for read raw adc data in advanced frame config
    calibrationCascade_NumAnglesToSweep = NumAnglesToSweep;% used for read raw adc data in advanced frame config
end

%% range FFT parameters
rangeProcCascade_enable                = 1;
rangeProcCascade_numAntenna            = numVirtualRxAnt;      % number of antennas
rangeProcCascade_numAdcSamplePerChirp  = numSamplePerChirp;    % number of samples per chirp
rangeProcCascade_rangeFFTSize          = rangeFFTSize;         % FFT size
rangeProcCascade_dcOffsetCompEnable    = 1;
%在范围FFT之前启用或禁用窗口的标志
rangeProcCascade_rangeWindowEnable     = 1;                    % flag to enable or disable windowing before range FFT
% rangeProcCascade_rangeWindowCoeff      = [0.0800, 0.0894, 0.1173, 0.1624, 0.2231, 0.2967, 0.3802, 0.4703, 0.5633...
%                                     0.6553, 0.7426, 0.8216, 0.8890 0.9422, 0.9789, 0.9976]; % range FFT window coefficients
%windowCoeff = hann_local(numSamplePerChirp);
windowCoeff = hanning(numSamplePerChirp);
rangeProcCascade_rangeWindowCoeff      = windowCoeff(1:(numSamplePerChirp/2));
rangeProcCascade_scaleFactorRange      = scaleFactor(log2(rangeFFTSize) - 3);
%1: 应用scaleFactorRange;0:未应用比例因子
rangeProcCascade_FFTOutScaleOn = 0; %1: apply scaleFactorRange; 0: scaling factor not applied

%% Doppler FFT parameters
DopplerProcClutterRemove_enable              = 1;
DopplerProcClutterRemove_numAntenna          = numVirtualRxAnt;      % number of antennas
DopplerProcClutterRemove_numDopplerLines     = rangeFFTSize;         % number of Doppler lines  多普勒线数
DopplerProcClutterRemove_dopplerFFTSize      = DopplerFFTSize;       % Doppler FFT size
DopplerProcClutterRemove_numChirpsPerVirAnt  = numChirpsPerVirAnt;
%多普勒FFT前启用或禁用窗口的标志
DopplerProcClutterRemove_dopplerWindowEnable = 0;                    % flag to enable or disable windowing before Doppler FFT
windowCoeff = hanning(numChirpsPerVirAnt);
DopplerProcClutterRemove_dopplerWindowCoeff = windowCoeff(1:(numChirpsPerVirAnt/2));
DopplerProcClutterRemove_scaleFactorDoppler  = scaleFactor(log2(DopplerFFTSize) - 3);
%1: 应用scaleFactorRange;0:未应用比例因子
DopplerProcClutterRemove_FFTOutScaleOn       = 0; %1: apply scaleFactorRange; 0: scaling factor not applied
%1=启用杂波消除;0=否
DopplerProcClutterRemove_clutterRemove       = 0;                        %1=enable clutter removal; 0=no


%% detection parameters
ind = find(D(:,2)==0);
[val ID_unique] = unique(D(ind,1));
%仅用于唯一方位ID的虚拟通道ID
antenna_azimuthonly = ind(ID_unique); %virtual channel ID only for unique azimuth ID

CFAR_CASO_enable             = 1;
%(CASO-CFAR)双通道rng/dop;仅支持一种恒虚警方法
CFAR_CASO_detectMethod       = 1;                %(CASO-CFAR)dualpass rng/dop; only support one CFAR method
CFAR_CASO_numAntenna         = numVirtualRxAnt; %number of antennas
%估计噪声方差的参考单元数
CFAR_CASO_refWinSize         = [8, 4];          % number of reference cells to estimate noise variance
%防止泄漏被检测为信号的间隙单元数量
CFAR_CASO_guardWinSize       = [8, 0];           % number of gap cells to prevent leakage being detected as signal
%阈值比例因子——6.3对应于8dB的SNR
CFAR_CASO_K0                 = [5 3];       % Threshold scaling factor -- 6.3 corresponds to SNR of 8dB
%1: 仅在窗口内最大时检测;0:否则
CFAR_CASO_maxEnable          = 0;                %1: detect only if it is the maximum within window; 0: otherwise
%用于确定用于检测的噪声级的百分比
CFAR_CASO_ratio_OS           = 0.65;             % percentage used to determine noise level used for detection
CFAR_CASO_rangeBinSize    = rangeBinSize;
CFAR_CASO_velocityBinSize  = velocityBinSize;
CFAR_CASO_dopplerFFTSize     = DopplerFFTSize;   % Doppler FFT size
%如果检测到的信号功率低于该水平,则丢弃该目标。
CFAR_CASO_powerThre          = 0;                % if power of detected signal is less than this level, drop off this object.
%由于DC周围的失真(正频率)而丢弃的范围盒数
CFAR_CASO_discardCellLeft    = 10;                % Number of range bins to discard due to distortions around DC (positive frequencies)
%由于DC周围的失真(负频率)而丢弃的范围箱数量
CFAR_CASO_discardCellRight   = 20;               % Number of range bins to discard due to distortions around DC (negative frequencies)
CFAR_CASO_numRxAnt           = length(RxForMIMOProcess);
CFAR_CASO_TDM_MIMO_numTX     = length(TxForMIMOProcess);
%仅用于唯一方位ID的虚拟通道ID
CFAR_CASO_antenna_azimuthonly = antenna_azimuthonly; %virtual channel ID only for unique azimuth ID
%在该范围内,流量计不应用最大速度扩展
CFAR_CASO_minDisApplyVmaxExtend = 10; % meter, within this range, do not apply max velocity extension
CFAR_CASO_applyVmaxExtend = 0;

%find the overlap antenna ID that can be used for phase compensation
%查找可用于相位补偿的重叠天线ID
TX_ID_MIMO = repmat(1:length(TxForMIMOProcess),length(RxForMIMOProcess),1);
TX_ID_MIMO = TX_ID_MIMO(:);
sumTwo = D(:,1)*10 + D(:,2);
[val id] = unique(sumTwo);
id_repeat = setxor(id, 1:length(sumTwo));

overlapAntenna_ID = [];   % 重叠天线ID
%found the overlap antenna ID
%找到重叠天线ID
for ii = 1:length(id_repeat)
    %ID of pair
    %配对ID
    overlapAntenna_ID(ii,1:2) = find(sumTwo == sumTwo(id_repeat(ii)));
    %associated TX of each pair
    %每对的相关发送
    overlapAntenna_ID(ii,3:4) =TX_ID_MIMO(overlapAntenna_ID(ii,1:2));
end

if length(overlapAntenna_ID) > 0
    %find the pairs offset only by 1 chirp/TX in time
    %在时间上仅查找1个啁啾/TX的对偏移
    dif_TX = abs(overlapAntenna_ID(:,3) - overlapAntenna_ID(:,4));
    ID_dif_1TX = find((dif_TX) == 1 );
    CFAR_CASO_overlapAntenna_ID = overlapAntenna_ID(ID_dif_1TX,:);
    ID_dif_2TX = find(dif_TX == 2);
    CFAR_CASO_overlapAntenna_ID_2TX = overlapAntenna_ID(ID_dif_2TX,:);
    ID_dif_3TX = find(dif_TX == 3);
    CFAR_CASO_overlapAntenna_ID_3TX = overlapAntenna_ID(ID_dif_3TX,:);
else
    CFAR_CASO_overlapAntenna_ID = [];
    CFAR_CASO_overlapAntenna_ID_2TX = [];
    CFAR_CASO_overlapAntenna_ID_3TX = [];
    
end


%% DOA parameters
% optimal d value used of for RF frequency of 76G 77G 78G 79G 80G
%用于76G 77G 78G 79G 80G射频频率的最佳d值
%d_optimal_calib = [0.495 0.504 0.51 0.516 0.522];
% switch centerFreq
%     case 76
%         d_optimal = d_optimal_calib(1);
%     case 77
%         d_optimal = d_optimal_calib(2);
%     case 78
%         d_optimal = d_optimal_calib(3);
%     case 79
%         d_optimal = d_optimal_calib(4);
%     case 80
%         d_optimal = d_optimal_calib(5);
% end

d_optimal = 0.5 * centerFreq / TI_Cascade_Antenna_DesignFreq;

DOACascade_enable                = 1;
DOACascade_D = D;
DOACascade_DOAFFTSize = 256;
DOACascade_numAntenna          = numVirtualRxAnt;
DOACascade_antPos          = [0:numVirtualRxAnt-1];
DOACascade_antDis              = d_optimal;              % in terms of lamda   就lamda而言
%1:2D多目标波束形成,2:2D多目标波束形成和azi/ele FFT后的峰值搜索
DOACascade_method              = 1;                % 1: 2D  muli-object beamforming, 2: 2D  muli-object beamforming and peak search after azi/ele FFT
%在方位角上运行2D DOA的视野
DOACascade_angles_DOA_az=[-80 80]; %field of view to run 2D DOA in azimuth
%在仰角中运行二维DOA的视野
DOACascade_angles_DOA_ele = [-20 20];%field of view to run 2D DOA in elevation
%用于峰值检测
DOACascade_gamma  = 10^(0.2/10);      % Used in peak detection
%用于在方位扫描2D DOA中抑制旁瓣
DOACascade_sidelobeLevel_dB_azim = 1; % used to reject sidelobe in azimuth run 2D DOA
%用于抑制仰角运行2D DOA中的旁瓣
DOACascade_sidelobeLevel_dB_elev = 0;% used to reject sidelobe in elevation run 2D DOA
DOACascade_dopplerFFTSize      = DopplerFFTSize;




simTopCascade.m

%  Copyright (C) 2018 Texas Instruments Incorporated - http://www.ti.com/ 
%  
%  
%   Redistribution and use in source and binary forms, with or without 
%   modification, are permitted provided that the following conditions 
%   are met:
%  
%     Redistributions of source code must retain the above copyright 
%     notice, this list of conditions and the following disclaimer.
%  
%     Redistributions in binary form must reproduce the above copyright
%     notice, this list of conditions and the following disclaimer in the 
%     documentation and/or other materials provided with the   
%     distribution.
%  
%     Neither the name of Texas Instruments Incorporated nor the names of
%     its contributors may be used to endorse or promote products derived
%     from this software without specific prior written permission.
%  
%   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 
%   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 
%   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
%   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 
%   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
%   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
%   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
%   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
%   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
%   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
%   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
%  
% 

%simTopCascade.m
%
%simTopCascade module definition. Contains some top level parameters. 
%simTopCascade模块定义。包含一些顶级参数。

classdef simTopCascade < Module
    %% properties
    % 属性
    properties (Access = public)
        inputDataSource          = 'bin'; % choose from 'mat','bin','gen'
        outputDataSavingEnable   = 0;
        outputDataFileName       = [];        
        platform = [];
        totNumFrames = 0;
    end
    
    methods
        %% constructor
         %构造函数
        function obj = simTopCascade(varargin)      % varargin = ['pfile'] {'input\test1_param.m'}
            if(isempty(find(strcmp(varargin,'name'), 1)))   % strcmp比较字符串
               varargin = [varargin, 'name','simTopCascade']; % varargin = ['pfile'] {'input\test1_param.m'}  'name','simTopCascade'
            end 
            obj@Module(varargin{:});
            
            obj.enable = getParameter(obj, 'enable');    %获取参数
            obj.inputDataSource = getParameter(obj, 'inputDataSource');  
            obj.outputDataSavingEnable = getParameter(obj, 'outputDataSavingEnable');             
            obj.outputDataFileName = getParameter(obj, 'outputDataFileName');             
            obj.platform = getParameter(obj, 'platform');             
            obj.totNumFrames = getParameter(obj, 'totNumFrames');  
          
            
            % overwritten the property value inside parameter file
            %setProperties(obj, nargin, varargin{:});
            obj = set(obj, varargin{:});            

 
        end
        
        
        
        

    end        
end

getParameter.m

function par = getParameter(obj, varargin)


try
    str = fullfile(obj.name, varargin{:});
    str = strrep(str, filesep, '_');

    %eval(obj.pfile);
    run(obj.pfile);
    par = eval(str);
    
catch
    error(['MODULE:' obj.name], 'Invalid parameter');
end

calibrationCascade.m

 

rangeProcCascade.m

 

DopplerProcClutterRemove.m

 

CFAR_CASO.m

 

DOACascade.m

 

getUniqueFileIdx.m



function [binId_unique]= getUniqueFileIdx(dataFolder_test)

currentFolder = pwd;   % pwd确定当前文件夹
cd(dataFolder_test);
listing = dir('*_data.bin');
cd(currentFolder);

% (a) Find all the binaryFile Id numbers
% Search for '_' and extract the numerical value
%(a)查找所有二进制文件Id号
%搜索‘_’并提取数值
binFileId = [];
for jj=1:length(listing)
fileName = listing(jj).name;
[ind]=find(fileName == '_');
binIdnumSearch = str2num(fileName(ind(1)+1:ind(2)-1));
binFileId = [binFileId; binIdnumSearch];
end
binFileId = unique(binFileId);
binId_unique = {};
for jj=1:length(binFileId)
binId_unique{jj} = num2str(binFileId(jj),'%04d');
end


getBinFileNames_withIdx.m

 % 获取Master、Slave1、Slave2、Slave3的文件名    带‘0000’的文件

getValidNumFrames.m

 % Get Valid Number of Frames 获取有效的帧数

% get number of valid frames in the associated *_data.bin file captured
% with TDA2 platform

% File header in *_idx.bin:
%     struct Info
%     {
%         uint32_t tag;
%         uint32_t version;
%         uint32_t flags;
%         uint32_t numIdx;       // number of frames 
%         uint64_t dataFileSize; // total data size written into file
%     };
% 
% Index for every frame from each radar:
%     struct BuffIdx
%     {
%         uint16_t tag;
%         uint16_t version; /*same as Info.version*/
%         uint32_t flags;
%         uint16_t width;
%         uint16_t height;
%         uint32_t pitchOrMetaSize[4]; /*For image data, this is pitch.
%                                                        For raw data, this is size in bytes per metadata plane.*/
%         uint32_t size; /*total size in bytes of the data in the buffer (sum of all planes)*/
%         uint64_t timestamp;
%         uint64_t offset;
%     };


function [numIdx dataFileSize] = getValidNumFrames(adcIdxFileName)

idxFile = fopen(adcIdxFileName,'r');
heaferInfoSize = 6;     
heaferInfo = fread(idxFile, heaferInfoSize,'uint32');
%有效帧数
numIdx = heaferInfo(4); % number of effective frame  
fclose(idxFile);
idxFile = fopen(adcIdxFileName,'r');
heaferInfoSize = 3;
heaferInfo = fread(idxFile, heaferInfoSize,'uint64');
%有效帧数的数据大小
dataFileSize = heaferInfo(3); % data size for the effective number of frames
fclose(idxFile);

end

 

 

 

 

 

 

datapath.m

%数据路径.m
%
%calibrationCascade模块的datapath功能,该功能使用安装有calibrationfilePath给定路径名的校准矩阵校准ADC数据。在进一步处理之前,直接对原始ADC数据进行校准。在时域中应用频率和相位校准;振幅校准是可选的,可以打开或关闭
%输入
%obj:calibrationCascade的对象实例

%datapath.m
%
% datapath function of calibrationCascade module, this function calibrates the ADC data with the calibration
% matrix installed with the path name given by calibrationfilePath.
% Calibration is done directly on the raw ADC data before any further
% processing. Apply frequency and phase calibration in time domain; amplitude
% calibration is optional, can be turned on or off
%
%input
%   obj: object instance of calibrationCascade


function outData = datapath(obj)

%load calibration file
load(obj.calibrationfilePath);
RangeMat = calibResult.RangeMat;
PeakValMat = calibResult.PeakValMat;

fileFolder = obj.binfilePath;
frameIdx = obj.frameIdx;

numSamplePerChirp = obj.numSamplePerChirp;
nchirp_loops = obj.nchirp_loops;
numChirpsPerFrame = obj.numChirpsPerFrame;
TxToEnable = obj.TxToEnable;
Slope_calib = obj.Slope_calib;
fs_calib = obj.fs_calib;
Sampling_Rate_sps = obj.Sampling_Rate_sps;

chirpSlope = obj.chirpSlope;
calibrationInterp = obj.calibrationInterp;
TI_Cascade_RX_ID = obj.TI_Cascade_RX_ID;
RxForMIMOProcess = obj.RxForMIMOProcess;
IdTxForMIMOProcess = obj.IdTxForMIMOProcess;
numRX = obj.numRxToEnable;
phaseCalibOnly = obj.phaseCalibOnly;
adcCalibrationOn = obj.adcCalibrationOn;
N_TXForMIMO = obj.N_TXForMIMO;
NumAnglesToSweep =  obj.NumAnglesToSweep ;
RxOrder = obj.RxOrder;
NumDevices = obj.NumDevices;

numTX = length(TxToEnable);
outData = [];


fileName=[fileFolder];
switch obj.dataPlatform

    case 'TDA2'
        numChirpPerLoop = obj.numChirpsPerFrame/obj.nchirp_loops; 
        numLoops = obj.nchirp_loops;  
        %固定数量
        numRXPerDevice = 4; % Fixed number    每个设备的接收数  
        [radar_data_Rxchain] = read_ADC_bin_TDA2_separateFiles(fileName,frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, 1);
    otherwise
        error('Not supported data capture platform!');       
end


%use the first TX as reference by default
TX_ref = TxToEnable(1);

if adcCalibrationOn == 0
    outData = radar_data_Rxchain;
else
    
    for iTX = 1: numTX
        
        %use first enabled TX1/RX1 as reference for calibration
        %使用第一个启用的TX1/RX1作为校准参考
        TXind = TxToEnable(iTX);
%         TXind = iTX;
        %construct the frequency compensation matrix        
        %构建频率补偿矩阵
        freq_calib = (RangeMat(TXind,:)-RangeMat(TX_ref,1))*fs_calib/Sampling_Rate_sps *chirpSlope/Slope_calib;       
        freq_calib = 2*pi*(freq_calib)/(numSamplePerChirp * calibrationInterp);
        correction_vec = (exp(1i*((0:numSamplePerChirp-1)'*freq_calib))');
        
        
        freq_correction_mat = repmat(correction_vec, 1, 1, nchirp_loops);
        freq_correction_mat = permute(freq_correction_mat, [2 3 1]);
        outData1TX = radar_data_Rxchain(:,:,:,iTX).*freq_correction_mat;
        
        
        %construct the phase compensation matrix
        %构造相位补偿矩阵
        phase_calib = PeakValMat(TX_ref,1)./PeakValMat(TXind,:);
        %remove amplitude calibration
        %删除振幅校准
        if phaseCalibOnly == 1
            phase_calib = phase_calib./abs(phase_calib);
        end
        phase_correction_mat = repmat(phase_calib.', 1,numSamplePerChirp, nchirp_loops);
        phase_correction_mat = permute(phase_correction_mat, [2 3 1]);
        outData(:,:,:,iTX) = outData1TX.*phase_correction_mat;
        
    end
end

%re-order the RX channels so that it correspond to the channels of
% ********   16_lamda     ****   4_lamda    ****
% and only maintain RX/TX data used for requred MIMO analysis.
% outData = outData(:,:,RxForMIMOProcess,IdTxForMIMOProcess);
% outData = outData(:,:,RxForMIMOProcess,:);

'E:\MMWAVE STUDIO\mmwave_studio_03_00_00_14\mmWaveStudio\MatlabExamples\4chip_cascade_MIMO_example\main\cascade\input\calibrateResults_high.mat'

read_ADC_bin_TDA2_separateFiles

%% read raw adc data with MIMO 
%%使用MIMO读取原始adc数据
function [radar_data_Rxchain] = read_ADC_bin_TDA2_separateFiles(fileNameCascade,frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices)


  dataFolder =fileNameCascade.dataFolderName;
  fileFullPath_master = fullfile(dataFolder,fileNameCascade.master);
  fileFullPath_slave1 = fullfile(dataFolder,fileNameCascade.slave1);
  fileFullPath_slave2 = fullfile(dataFolder,fileNameCascade.slave2);
  fileFullPath_slave3 = fullfile(dataFolder,fileNameCascade.slave3);

 [radar_data_Rxchain_master] = readBinFile(fileFullPath_master, frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices);
 [radar_data_Rxchain_slave1] = readBinFile(fileFullPath_slave1, frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices);
 [radar_data_Rxchain_slave2] = readBinFile(fileFullPath_slave2, frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices);
 [radar_data_Rxchain_slave3] = readBinFile(fileFullPath_slave3, frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices);

% Arranged based on Master RxChannels, Slave1 RxChannels, slave2 RxChannels, slave3 RxChannels 
% The RX channels are re-ordered according to "TI_Cascade_RX_ID" defined in
% "module_params.m"
%基于主RX通道、从1 RX通道、从2 RX通道、从3 RX通道排列
%根据中定义的“TI\u Cascade\u RX\u ID”对RX信道进行重新排序
%“模块参数m”
 radar_data_Rxchain(:,:,1:4,:) = radar_data_Rxchain_master;
 radar_data_Rxchain(:,:,5:8,:) = radar_data_Rxchain_slave1;
 radar_data_Rxchain(:,:,9:12,:) = radar_data_Rxchain_slave2;
 radar_data_Rxchain(:,:,13:16,:) = radar_data_Rxchain_slave3;
        
end


function [adcData1Complex] = readBinFile(fileFullPath, frameIdx,numSamplePerChirp,numChirpPerLoop,numLoops, numRXPerDevice, numDevices)
% 每帧预期的采样数
Expected_Num_SamplesPerFrame = numSamplePerChirp*numChirpPerLoop*numLoops*numRXPerDevice*2; 
fp = fopen(fileFullPath, 'r');
fseek(fp,(frameIdx-1)*Expected_Num_SamplesPerFrame*2, 'bof'); % fseek()移至文件中的指定位置
adcData1 = fread(fp,Expected_Num_SamplesPerFrame,'uint16');
neg             = logical(bitget(adcData1, 16));
adcData1(neg)    = adcData1(neg) - 2^16;
%% 
adcData1 = adcData1(1:2:end) + sqrt(-1)*adcData1(2:2:end);   % 实部加虚部  
adcData1Complex = reshape(adcData1, numRXPerDevice, numSamplePerChirp, numChirpPerLoop, numLoops);
adcData1Complex = permute(adcData1Complex, [2 4 1 3]);  % 置换数组维度
fclose(fp);
end

 

 

 

 

 datapath function == rangeFFTOut

        %% datapath function
        % input: adc data, assuming size(input) = [numSamplePerChirp, numChirpsPerFrame numAntenna]
        function [out] = datapath(obj, input)
            
            numLines  = size(input,2);
            numAnt    = size(input,3);
            % dopplerWinLen  = length(obj.dopplerWindowCoeff);
            
            if obj.enable           
                
                % initialize
                out = zeros(obj.rangeFFTSize, numLines, numAnt);
                
                for i_an = 1:numAnt  
                   
                    % vectorized version  %矢量化版本
                    inputMat    = squeeze(input(:,:,i_an));   % squeeze删除长度为 1 的维度
                    
                    % DC offset compensation  直流偏移补偿
                    inputMat    = bsxfun(@minus, inputMat, mean(inputMat));   % 对两个数组应用按元素运算(启用隐式扩展)
                    
                    % apply range-domain windowing  应用范围域窗口
                    inputMat    = bsxfun(@times, inputMat, obj.rangeWindowCoeffVec);
                    
                    % Range FFT
                    fftOutput   = fft(inputMat, obj.rangeFFTSize);
                    
                    % apply Doppler windowing and scaling to the output. Doppler windowing moved to DopplerProc.m (5/24)
                    % fftOutput   = bsxfun(@times, fftOutput, obj.scaleFactorRange*obj.dopplerWindowCoeffVec.');
                    % 对输出应用多普勒窗口和缩放。多普勒窗口移到DopplerProc.m(5/24)
                    if  obj.FFTOutScaleOn == 1      % FFT输出比例开启
                        fftOutput   = fftOutput * obj.scaleFactorRange;
                    end
                    
                    % populate in the data cube
                    %在数据立方体中填充
                    out(:,:,i_an) = fftOutput;
                    
                end            
                
            else
                out     = input;
                
            end
            
        end

datapath function == DopplerFFTObj

        % datapath function
        % input: adc data, assuming size(input) = [numSamplePerChipr numChirpsPerFrame numAntenna]
        function [out] = datapath(obj, input)
            
            numLines  = size(input,1);
            numAnt    = size(input,3);
            
            if obj.enable                  
                
                % initialize
                out = zeros(numLines, obj.dopplerFFTSize, numAnt);
                
                for i_an = 1:numAnt                  
                   
                    %% vectorized version
                    inputMat    = squeeze(input(:,:,i_an));
                    inputMat    = bsxfun(@times, inputMat, obj.dopplerWindowCoeffVec.');
                    if obj.clutterRemove ==1   % 杂波消除
                        inputMat = inputMat - (repmat(mean(inputMat'),size(inputMat,2),1))';
                    end
                    fftOutput   = fft(inputMat, obj.dopplerFFTSize, 2);                         
                    
                    if obj.FFTOutScaleOn ==1  %FFT输出比例开启
                        fftOutput   = fftshift(fftOutput, 2) * obj.scaleFactorDoppler;
                    else
                        fftOutput   = fftshift(fftOutput, 2);
                    end
                    % populate in the data cube
                    %在数据立方体中填充
                    out(:,:,i_an) = fftOutput;
                    
                end
                
            else
                out     = input;
                
            end
            
        end

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_42046837/article/details/125960239

智能推荐

SSD1306显示屏--躲避类游戏_proteus躲避游戏-程序员宅基地

文章浏览阅读654次。SSD1306显示屏–躲避类游戏要求:​ 使用Arduino控制OLED显示屏SSD1306(proteus中搜索UG-2864HSWEG01),再连接几个按钮。观察下面视频中的游戏,在Arduino上编程实现相同效果:效果视频注:题目来自HBUE的硬件编程考题,本代码仍有缺陷,显示器闪动较严重,且不够简洁。此代码电路仅供学习交流使用,转载使用时请注明来处。/*SOFTWARE: Proteus 8 ProfessionalCSDN: 空白之子公众号:硬核开发(正在建设中)*/#i_proteus躲避游戏

Intellij IEAD上创建java web项目并且部署到tomcat上_如何把iead中的web配置到tomcat服务器的目录下-程序员宅基地

文章浏览阅读411次。具体操作步骤:打开idea,创建一个java web项目输入项目名称,指定项目路径在src文件下面创java文件导入Tomcat的两个jar包Artifacts 操作配置web.xml文件配置Tomcat开启tomcat*本次教程用idea2019版的创建的 *打开idea,创建一个java web项目必须勾选Web Application输入项目名称,指定项目路径在src文件下面创..._如何把iead中的web配置到tomcat服务器的目录下

volatile关键字 C++与Java的区别_c++ 和 java volatile-程序员宅基地

文章浏览阅读2.5k次。volatilevolatile这个单词在英文之中的意思是:易变的,不稳定的的含义。在Java中也有volatile关键字,Java之中volatile的作用是:确保内存可见性:读写变量具有全局有序性,保证当前线程读到的值是内存中最新的,而不是缓存中的值。但是volatile关键字并不保证线程读写变量的相对顺序,所以适用场景有限。禁止指令重排序:指令重排序是JVM为了提高运行程序的效率,..._c++ 和 java volatile

Python 命令行工具 argparse 模块使用详解_parser = argparse.argumentparser()-程序员宅基地

文章浏览阅读822次。先来介绍一把最基本的用法import argparseparser = argparse.ArgumentParser()parser.parse_args()在执行 parse_args() 之前,所有追加到命令行的参数都不会生效,生效了之后的默认情况类似于这样:设置默认参数函数:import argparseparser = argparse.Argum..._parser = argparse.argumentparser()

iOS 调用相机,获取相册,截取头像_ios 调用相机 截图-程序员宅基地

文章浏览阅读1.7k次。iOS 调用相机,获取相册,截取头像前言应用经常需要使用到用户提供的图像。iOS提供了两种方式:UIImagePickerController和资产库:(asset library)。UIImagePickerController提供了导航相册和照片的模态用户界面,适合在应用没有特殊的照片浏览和选择需求(即Apple提供的风格就能满足要求)时使用;资产库提供了全面的照片和相册访问功能,适合在图像导航_ios 调用相机 截图

使用Bootstrap制作简单的旅游主页-程序员宅基地

文章浏览阅读464次。页面效果代码:需要导入bootstrapt文件,解压至项目中。下载地址:https://v3.bootcss.com/getting-started/#download<!DOCTYPE html><html lang="zh-CN"> <head> <meta charset="utf-8"> <..._使用bootstrap制作旅游网站

随便推点

使用Java操作PDF文档-程序员宅基地

文章浏览阅读553次。1.文档内容的基本格式设置 示例代码:package com.yan.exc;import java.awt.Color;import java.io.FileNotFoundException;import java.io.FileOutputStream;import java.io.IOException;import javax.swing.JO..._java com.lowagie.text.pdf.pdfreader 第三张第四章的时候方向反了

SpringBoot系列一:入门_:spring boot可以把web应用程 序变为可自执行的jar文件这句话正确吗-程序员宅基地

文章浏览阅读358次。SpringBoot提供了一种新的编程范式,能在最小的阻力下开发Spring应用程序,有了它你可以敏捷地开发Spring应用程序,专注于应用程序的功能,不用在Spring的配置上多花功夫,甚至完全不用配置。_:spring boot可以把web应用程 序变为可自执行的jar文件这句话正确吗

让我们来认识一下信号与系统的关系_身边信号作用于系统的例子-程序员宅基地

文章浏览阅读2.2k次。第一课什么是卷积卷积有什么用什么是傅利叶变换什么是拉普拉斯变换引子很多朋友和我一样,工科电子类专业,学了一堆信号方面的课,什么都没学懂,背了公式考了试,然后毕业了。先说"卷积有什么用"这个问题。(有人抢答,"卷积"是为了学习"信号与系统"这门课的后续章节而存在的。我大吼一声,把他拖出去枪毙!)讲一个故事:张三刚刚应聘到了一个电子产品公司做测试人员,他没有学过"信号与系统"这门课程。一天,他拿到了一个产品,开发人员告诉他,产品有一个输入端,有一个输出端,有限的输入信号只会产生有_身边信号作用于系统的例子

云计算和虚拟化技术_云计算与虚拟化技术-程序员宅基地

文章浏览阅读6.3k次,点赞8次,收藏58次。# 写于2021.04.10# 本文为学习笔记,用的ppt是陈羽中教授版,侵删# 笔记只为交流,入门小白,有错望留言纠正# 总结不易 望赞鼓励1. 大数据和云计算1.1 大数据现象是怎么形成的?形成 人用的多了 产生数据设备多了大数据时代导致数据有以下特点:1.2 云计算有哪些特点?超大规模虚拟化高可靠性通用性高可伸缩性按需服务极其廉价1.3 云计算你找服务类型可分为哪几类?1.4 云计算技术体系结构可分为哪几层?资源池和管理中间件层为云计算技术的_云计算与虚拟化技术

《3D数学基础:图形与游戏开发 》_3d数学基础图形与游戏开发 博客-程序员宅基地

文章浏览阅读2.7k次。1,什么是欧拉角?2,万向锁是一种什么现象?3,游戏动画中遇到万向锁时会发生什么?4,怎样解决万向锁这个问题? 一,什么是欧拉角? 用一句话说,欧拉角就是物体绕坐标系三个坐标轴(x,y,z轴)的旋转角度。在这里,坐标系可以是世界坐标系,也可以是物体坐标系,旋转顺序也是任意的,可以是xyz,xzy,yxz,zxy,yzx,zyx中的任何一种,_3d数学基础图形与游戏开发 博客

推流工具_link.hostname.av_len 0-程序员宅基地

文章浏览阅读1.4k次。一 大家有用过librtmp可曾遇到一个比较头疼的问题向某家视频云推送视频的时候,需要指定域名,但是又想指定接入服务器ip。librtmp里面自己给解析了域名,看看源码实现。RTMP_Connect(RTMP *r, RTMPPacket *cp, unsigned int *outip, unsigned int *selfPort){//fix the problem of when rtmp..._link.hostname.av_len 0

推荐文章

热门文章

相关标签