1. SNR 신호처리, Secondary surface 영향 고려하여 SNR 재계산

2. Coverage Figure 개선
3. 윈도우 생성 및 성능 계산 함수 추가
This commit is contained in:
2026-03-06 06:48:07 +09:00
parent e002d08580
commit 3c05d2be09
5 changed files with 270 additions and 123 deletions
@@ -0,0 +1,118 @@
function [windowVector, metrics] = create_window_with_metrics(windowType, windowLength, varargin)
% CREATE_WINDOW_WITH_METRICS - 윈도우 함수 생성 및 성능 지표 계산
%
% 입력:
% windowType - 윈도우 타입 문자열: 'none', 'hann', 'hamming', 'blackman', 'chebwin'
% windowLength - 윈도우 길이 (샘플 수)
% varargin - 추가 파라미터 (예: chebwin의 경우 sidelobe level)
%
% 출력:
% windowVector - 생성된 윈도우 벡터 (1 x windowLength)
% metrics - 윈도우 성능 지표 구조체
% .type : 윈도우 타입
% .length : 윈도우 길이
% .snr_loss_dB : SNR 손실 (dB)
% .scalloping_loss_dB: Scalloping 손실 (dB)
% .coherent_gain : 코히어런트 이득
% .enbw : Equivalent Noise Bandwidth (bins)
% 기본 파라미터 설정
if windowLength <= 0
error('Window length must be positive.');
end
% 윈도우 함수 생성
switch lower(windowType)
case 'none'
windowVector = ones(1, windowLength);
case 'hann'
windowVector = hann(windowLength)';
case 'hamming'
windowVector = hamming(windowLength)';
case 'blackman'
windowVector = blackman(windowLength)';
case 'chebwin'
% Chebyshev 윈도우는 sidelobe level 파라미터 필요 (기본값: 60dB)
if ~isempty(varargin)
sidelobe_dB = varargin{1};
else
sidelobe_dB = 60;
end
windowVector = chebwin(windowLength, sidelobe_dB)';
otherwise
warning('Unknown window type "%s". Using Hann window as default.', windowType);
windowVector = hann(windowLength)';
windowType = 'hann';
end
% 윈도우 성능 지표 계산
metrics = calculate_window_metrics(windowVector, windowType);
end
function metrics = calculate_window_metrics(windowVector, windowType)
% CALCULATE_WINDOW_METRICS - 윈도우 함수의 성능 지표 계산
%
% 계산 항목:
% 1. SNR Loss (dB) : 윈도우 적용으로 인한 SNR 손실
% 2. Scalloping Loss (dB): FFT bin 사이(0.5 bin offset)에서의 최대 손실
% 3. Coherent Gain : 윈도우의 평균 진폭
% 4. ENBW (bins) : Equivalent Noise Bandwidth
w = windowVector(:).'; % Row vector로 변환
N = numel(w);
if N == 0
metrics = struct('type', windowType, 'length', 0, ...
'snr_loss_dB', NaN, 'scalloping_loss_dB', NaN, ...
'coherent_gain', NaN, 'enbw', NaN);
return;
end
% 1. Coherent Gain (코히어런트 이득)
coherent_gain = mean(w);
% 2. Noise Power Gain (잡음 전력 이득)
noise_power_gain = mean(abs(w).^2);
% 3. SNR Loss (dB)
% SNR_loss = (Noise Power Gain) / (Coherent Gain)^2
% 이는 윈도우 적용 시 신호 대 잡음비가 얼마나 감소하는지를 나타냄
if abs(coherent_gain) > eps
snr_loss_linear = noise_power_gain / (abs(coherent_gain)^2);
snr_loss_dB = 10 * log10(snr_loss_linear);
else
snr_loss_dB = NaN;
end
% 4. Equivalent Noise Bandwidth (ENBW)
% ENBW는 윈도우가 얼마나 많은 주파수 bin의 잡음을 통과시키는지 나타냄
enbw = N * noise_power_gain / (sum(w)^2);
% 5. Scalloping Loss (dB)
% FFT bin 중간(0.5 bin offset)에 신호가 위치할 때의 최대 손실
% 이는 가장 나쁜 경우의 신호 손실을 나타냄
sample_index = 0:(N-1);
half_bin_response = abs(sum(w .* exp(-1j * 2 * pi * 0.5 * sample_index / N)));
dc_response = abs(sum(w));
if dc_response > eps
scalloping_loss_dB = -20 * log10(half_bin_response / dc_response);
else
scalloping_loss_dB = NaN;
end
% 결과 구조체 생성
metrics = struct(...
'type', lower(windowType), ...
'length', N, ...
'snr_loss_dB', snr_loss_dB, ...
'scalloping_loss_dB', scalloping_loss_dB, ...
'coherent_gain', coherent_gain, ...
'enbw', enbw);
end
+4 -13
View File
@@ -3,7 +3,6 @@ function [rd_map, doppler_axis] = process_doppler_fft(range_profile, RadarParams
% - range_profile: [NumRx, NumTx, NumChirps, NumRangeBins]
% - RadarParams: 메인 파라미터 구조체
NumChirps = RadarParams.Waveform.NumChirps;
window_type = RadarParams.SP.RDM.window_type_doppler;
[~, ~, ~, ~] = size(range_profile);
% 중심 주파수에서의 파장
@@ -12,18 +11,10 @@ function [rd_map, doppler_axis] = process_doppler_fft(range_profile, RadarParams
% 1. 처프 간 반복 주기 (PRI, Pulse Repetition Interval)
T_pri = RadarParams.Waveform.PRI;
% 2. Doppler-FFT용 윈도우 함수 (사용자 선택 가능)
% 도플러 방향(3번째 차원)으로 사이드로브를 억제합니다.
if strcmpi(window_type, 'none')
win_doppler = ones(1, NumChirps);
elseif strcmpi(window_type, 'hamming')
win_doppler = hamming(NumChirps)';
elseif strcmpi(window_type, 'blackman')
win_doppler = blackman(NumChirps)';
elseif strcmpi(window_type, 'hann')
win_doppler = hann(NumChirps)';
else % default: 'chebwin'
win_doppler = chebwin(NumChirps, 60)'; % 60dB 사이드로브 억제
% 2. Main.m에서 생성된 Doppler-FFT용 윈도우 함수 적용
win_doppler = RadarParams.SP.RDM.window_doppler;
if length(win_doppler) ~= NumChirps
error('Doppler window length mismatch: expected %d, got %d', NumChirps, length(win_doppler));
end
win_data = range_profile .* reshape(win_doppler, [1, 1, NumChirps, 1]);
+4 -12
View File
@@ -5,22 +5,14 @@ function [range_profile, range_axis] = process_range_fft_lpf(adc_raw_data, Radar
fs_adc = RadarParams.Waveform.fs_adc;
Slope = RadarParams.Waveform.Slope;
fc_lpf_Hz = RadarParams.Rxpath.fc_lpf;
window_type = RadarParams.SP.RDM.window_type_range;
[~, ~, ~, N_samples] = size(adc_raw_data);
c = RadarParams.Basic.c;
% 1. 윈도우 함수 적용
if strcmpi(window_type, 'none')
win = ones(1, N_samples);
elseif strcmpi(window_type, 'hamming')
win = hamming(N_samples)';
elseif strcmpi(window_type, 'blackman')
win = blackman(N_samples)';
elseif strcmpi(window_type, 'chebwin')
win = chebwin(N_samples, 60)';
else % default: 'hann'
win = hann(N_samples)';
% 1. Main.m에서 생성된 윈도우 함수 적용
win = RadarParams.SP.RDM.window_range;
if length(win) ~= N_samples
error('Window length mismatch: expected %d, got %d', N_samples, length(win));
end
win_data = adc_raw_data .* reshape(win, [1, 1, 1, N_samples]);