├── ESPRITforOFDMsensing.m ├── MUSICforOFDMsensing.m ├── cccSensing.m ├── fig ├── figure1.fig ├── figure2.fig └── figure3.fig ├── ofdm_radar_main.m └── sensingSignalGen.m /ESPRITforOFDMsensing.m: -------------------------------------------------------------------------------- 1 | %% ESPRIT for OFDM sensing 2 | % CIM: Input channel information matrix(pre-processed by known transmitted symbols) 3 | % k:target number 4 | % Author: Yunbo HU(SIMIT, UCAS) 5 | % GitHub: https://github.com/edenhu1111 6 | function [range,velocity] = ESPRITforOFDMsensing(CIM,k) 7 | global lambda delta_f c0 Ts 8 | [M,N] = size(CIM); 9 | %% range estimation 10 | z = [CIM(1:M-1,:);CIM(2:M ,:)]; 11 | R_zz = z*z'/N; 12 | [U,~,~] = svd(R_zz); 13 | Es = U(:,1:k); 14 | Esx = Es(1:M-1,:); 15 | Esy = Es(M:end,:); 16 | 17 | EE = [Esx,Esy]; 18 | [F,~,~] = svd(EE'*EE); 19 | F = F(:,end-k+1:end); 20 | F1 = F(1:k,:); 21 | F2 = F(k+1:2*k,:); 22 | psi = -F1*inv(F2); 23 | [~,D] = eig(psi); 24 | 25 | 26 | phi = angle(diag(D)); 27 | phi(phi>0) = phi(phi>0) - 2*pi; 28 | tau = -phi/(2*pi*delta_f); 29 | range = tau*c0/2; 30 | 31 | %% doppler estimation 32 | z = [CIM(:,1:N-1),CIM(:,2:N)]; 33 | R_zz = z.'*conj(z)/M; 34 | [U,~,~] = svd(R_zz); 35 | Es = U(:,1:k); 36 | Esx = Es(1:N-1,:); 37 | Esy = Es(N:end,:); 38 | 39 | EE = [Esx,Esy]; 40 | [F,~,~] = svd(EE'*EE); 41 | F = F(:,end-k+1:end); 42 | F1 = F(1:k,:); 43 | F2 = F(k+1:2*k,:); 44 | psi = -F1*inv(F2); 45 | [~,D] = eig(psi); 46 | 47 | phi = angle(diag(D)); 48 | phi(phi<0) = phi(phi<0) + 2*pi; 49 | doppler = phi/(2*pi*Ts); 50 | velocity = doppler*lambda/2; 51 | 52 | end 53 | 54 | -------------------------------------------------------------------------------- /MUSICforOFDMsensing.m: -------------------------------------------------------------------------------- 1 | %% MUSIC for OFDM sensing 2 | % CIM: Input channel information matrix(pre-processed by known transmitted symbols) 3 | % k:target number 4 | % Author: Yunbo HU(SIMIT, UCAS) 5 | % GitHub: https://github.com/edenhu1111 6 | function [P_music_range,P_music_velo] = MUSICforOFDMsensing(CIM,k) 7 | global M N c0 delta_f lambda Ts 8 | %% range estimation 9 | R_range = CIM*CIM'/N; 10 | [V,D]=eig(R_range); 11 | [~,ind_D] = sort(diag(D),'descend'); 12 | U_n = V(:,ind_D(k+1:end)); 13 | 14 | delay = linspace(0,2*100/c0*delta_f,M); 15 | ii = 0:M-1; 16 | A = exp(-1j*2*pi*kron(ii',delay)); 17 | P_music_range = zeros(size(A,2),1); 18 | for jj = 1:size(A,2) 19 | P_music_range(jj) = 1/(A(:,jj)'*(U_n*U_n')*A(:,jj)); 20 | end 21 | 22 | 23 | %% Velocity Estimation 24 | R_dop = CIM.'*conj(CIM)/M; 25 | [V,D]=eig(R_dop); 26 | [~,ind_D] = sort(diag(D),'descend'); 27 | U_n = V(:,ind_D(k+1:end)); 28 | 29 | doppler = linspace(0,2*100/lambda*Ts,M); 30 | ii = 0:N-1; 31 | A = exp(1j*2*pi*kron(ii',doppler)); 32 | P_music_velo = zeros(size(A,2),1); 33 | for jj = 1:size(A,2) 34 | P_music_velo(jj) = 1/(A(:,jj)'*(U_n*U_n')*A(:,jj)); 35 | end 36 | 37 | 38 | end 39 | 40 | -------------------------------------------------------------------------------- /cccSensing.m: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edenhu1111/OFDM-Sensing-Algorithms/26b6ddf24c58c86e4d2eae8bc39901659397b295/cccSensing.m -------------------------------------------------------------------------------- /fig/figure1.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edenhu1111/OFDM-Sensing-Algorithms/26b6ddf24c58c86e4d2eae8bc39901659397b295/fig/figure1.fig -------------------------------------------------------------------------------- /fig/figure2.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edenhu1111/OFDM-Sensing-Algorithms/26b6ddf24c58c86e4d2eae8bc39901659397b295/fig/figure2.fig -------------------------------------------------------------------------------- /fig/figure3.fig: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edenhu1111/OFDM-Sensing-Algorithms/26b6ddf24c58c86e4d2eae8bc39901659397b295/fig/figure3.fig -------------------------------------------------------------------------------- /ofdm_radar_main.m: -------------------------------------------------------------------------------- 1 | %% A comparison of OFDM Radar signal processing methods 2 | % Description: This project compares some classical sensing algorithm. 3 | % Algorithms in this project: 4 | % 5 | % 1. 2DFFT 6 | % 2. Cyclic Cross Correlation 7 | % 3. Super Resolution Estimation: MUSIC and TLS-ESPRIT 8 | % 9 | % Author: Yunbo HU (SIMIT, UCAS) 10 | % GitHub: https://github.com/edenhu1111 11 | clc; 12 | clear; 13 | addpath('fig'); 14 | global c0 fc lambda M N delta_f Ts CPsize 15 | %% ISAC Transmitter 16 | % System parameters 17 | c0 = 3e+8; % velocity of light 18 | fc = 30e+9; % carrier frequency 19 | lambda = c0 / fc; % wavelength 20 | M = 1024; % number of subcarriers 21 | N = 15; % number of symbols per subframe 22 | delta_f = 120e+3; % subcarrier spacing 23 | T = 1 / delta_f; % symbol duration 24 | Tcp = T / 4; % cyclic prefix duration 25 | Ts = T + Tcp; % total symbol duration 26 | CPsize = M / 4; % cyclic prefix length 27 | bitsPerSymbol = 2; % bits per symbol 28 | qam = 2^(bitsPerSymbol); % 16-QAM modulation 29 | 30 | % Transmit data 31 | data = randi([0 qam - 1], M, N); 32 | TxData = qammod(data, qam, 'gray'); 33 | 34 | % OFDM modulator 35 | TxSignal = ifft(TxData, M); % IFFT 36 | TxSignal_cp = [TxSignal(M - CPsize + 1: M, :); TxSignal]; % add CP 37 | TxSignal_cp = reshape(TxSignal_cp, [], 1); % time-domain transmit signal 38 | 39 | %% Channel 40 | % Sensing Data Generation 41 | SNR = 30; 42 | r = [30]; % range.(it can be a row vector) 43 | v = [20]; %velocity 44 | RxSignal = sensingSignalGen(TxSignal_cp, r,v,SNR); 45 | k = length(r); 46 | 47 | %% OFDM Radar Receivers 48 | 49 | % 1. 2DFFT based (classical method, reference is omitted here) 50 | 51 | Rx = RxSignal(1:size(TxSignal_cp,1),:); 52 | 53 | Rx = reshape(Rx,[],N); 54 | Rx = Rx(CPsize + 1 : M + CPsize,:); % remove CP and reshape it into a matrix 55 | Rx_dem = fft(Rx,M); 56 | CIM_2dfft = Rx_dem .* conj(TxData); %elementwise-multiply(equals to match filtering) 57 | 58 | RDM_2dfft = fft(ifft(CIM_2dfft,M).',10*N); 59 | 60 | % plot the range doppler map 61 | figure(1); 62 | range_2dfft = linspace(0,c0/(2*delta_f),M+1); 63 | range_2dfft = range_2dfft(1:M); 64 | 65 | velocity_2dfft = linspace(0,lambda/2/Ts,10*N+1); 66 | velocity_2dfft = velocity_2dfft(1:10*N); 67 | 68 | [X,Y] = meshgrid(range_2dfft,velocity_2dfft); 69 | 70 | RDM_2dfft_norm = 10*log10( abs(RDM_2dfft)/max(abs(RDM_2dfft),[],'all')); 71 | % Maximized Likelihood Estimation(In theory) 72 | 73 | mesh(X,Y,(RDM_2dfft_norm)); 74 | title('2D-FFT based method'); 75 | xlabel('range(m)'); 76 | ylabel('velocity(m/s)'); 77 | savefig('fig/figure1.fig'); 78 | 79 | 80 | % 2. CCC-based (Method proposed by Kai Wu et al.) 81 | figure(2); 82 | % setting parameters for CCC-based sensing method 83 | % please refer to the paper for the meaning of these paramaters 84 | mildM = 512; 85 | Qbar = 64; 86 | mildQ = 128; 87 | % CCC 88 | [r_cc,RDM] = cccSensing(RxSignal,TxSignal_cp,mildM,Qbar,mildQ); % ccc sensing 89 | 90 | %plot the range doppler map 91 | Tsa = 1/delta_f/M; 92 | mildN = floor((length(TxSignal_cp)-Qbar-mildQ)/(mildM - Qbar)); 93 | range_ccc = linspace(0,c0/2*Tsa*mildM, mildM+1); 94 | doppler_ccc = linspace(0,lambda/(mildM-Qbar)/Tsa/2,10*mildN+1); 95 | range_ccc = range_ccc(1:mildM); 96 | doppler_ccc = doppler_ccc(1:10*mildN); 97 | 98 | RDM_norm = 10*log10(abs(RDM)/max(abs(RDM),[],'all')); 99 | [X,Y] = meshgrid(range_ccc,doppler_ccc); 100 | mesh(X,Y,(RDM_norm)); % plot the range-doppler map 101 | title('CCC based method'); 102 | xlabel('range(m)'); 103 | ylabel('velocity(m/s)'); 104 | savefig('fig/figure2.fig'); 105 | 106 | % 3. Super resolution sensing method 107 | % 3.1 MUSIC based (a time consuming but precise method) 108 | CIM = Rx_dem .*conj(TxData); 109 | 110 | [P_music_range,P_music_velo] = MUSICforOFDMsensing(CIM,k); 111 | 112 | 113 | % plot the MUSIC power spectrum 114 | figure(3); 115 | title('MUSIC for OFDM sensing'); 116 | subplot(1,2,1); 117 | plot(linspace(0,100,length(P_music_range)),abs(P_music_range)/max(abs(P_music_range))); 118 | ylabel('Pmusic'); 119 | xlabel('range(m)'); 120 | ylim([10^-3,1]); 121 | title('MUSIC for range estimation'); 122 | subplot(1,2,2); 123 | plot(linspace(0,100,M),abs(P_music_velo)/max(abs(P_music_velo))); 124 | ylabel('Pmusic'); 125 | xlabel('velocity(m/s)'); 126 | ylim([10^-3,1]); 127 | title('MUSIC for velocity estimation'); 128 | 129 | savefig('fig/figure3.fig'); 130 | 131 | % 3.2 ESPRIT based method 132 | [range,velocity] = ESPRITforOFDMsensing(CIM,k); 133 | fprintf('The estimation result of TLS-ESPRIT is :\n'); 134 | fprintf('Range = %f\n',range); 135 | fprintf('Velocity = %f\n',velocity); 136 | 137 | -------------------------------------------------------------------------------- /sensingSignalGen.m: -------------------------------------------------------------------------------- 1 | %% Sensing Channel Generation 2 | % Description: Generating a simulated time shifted and doppler modulaed 3 | % signal. 4 | % TxSignal_cp: transmit signal 5 | % 6 | % range: target range. When it is a row vector, it indicated that there are 7 | % more than one target; 8 | % 9 | % velocity:target relative velocity. Its size should be the same as "range" 10 | % 11 | % SNR: Signal-to-noise Ratio 12 | % 13 | % Author: Yunbo HU (SIMIT, UCAS) 14 | % GitHub: https://github.com/edenhu1111 15 | %% Code 16 | function RxSignal = sensingSignalGen(TxSignal_cp,range,velocity,SNR) 17 | global c0 lambda M delta_f 18 | delay = 2 * range / c0; 19 | h_gain = exp(1j*2*pi*rand(size(delay))); 20 | doppler = 2*velocity/lambda; 21 | % max_delay = max(delay,[],'all'); 22 | % RxSignal = zeros(size(TxSignal_cp,1) + max_delay,1); 23 | RxSignal = zeros(size(TxSignal_cp,1) ,1); 24 | d = zeros(size(TxSignal_cp)); 25 | for p = 1:length(delay) 26 | ii = 0:length(d)-1; 27 | d = exp(1j*2*pi*doppler(p)*ii'/(delta_f*M)); 28 | tau = exp(-1j*2*pi*delay(p)*delta_f*M/length(d)*ii'); 29 | % RxSignal = RxSignal + h_gain(p) * ... 30 | % [zeros(delay(p),1);... 31 | % TxSignal_cp .* d... 32 | % ;zeros(max_delay-delay(p),1)]; 33 | RxSignal = RxSignal + h_gain(p)*ifft(fft(TxSignal_cp.*d).*tau); 34 | end 35 | RxSignal = RxSignal + 10^(-SNR/10)*(randn(size(RxSignal)) + 1j*randn(size(RxSignal)))/sqrt(2); 36 | end 37 | 38 | --------------------------------------------------------------------------------