Compare commits
3
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a70aa68053 | ||
|
|
9595d68526 | ||
|
|
855c3d1d55 |
@@ -22,8 +22,10 @@ function [adc_raw_data, adc_combined] = apply_lna_and_mixer(RxOut, TxOut, RadarP
|
||||
phase_noise_cfg = struct();
|
||||
if isfield(RadarParams.Waveform.nonideal, 'phaseNoise')
|
||||
phase_noise_cfg = RadarParams.Waveform.nonideal.phaseNoise;
|
||||
if isfield(phase_noise_cfg,'enabled') && phase_noise_cfg.enabled && ...
|
||||
isfield(phase_noise_cfg,'offset_Hz') && isfield(phase_noise_cfg,'level_dBc_Hz')
|
||||
has_offset = isfield(phase_noise_cfg,'offset_Hz') && ~isempty(phase_noise_cfg.offset_Hz);
|
||||
has_level = isfield(phase_noise_cfg,'level_dBc_Hz') && ~isempty(phase_noise_cfg.level_dBc_Hz);
|
||||
same_length = has_offset && has_level && (numel(phase_noise_cfg.offset_Hz) == numel(phase_noise_cfg.level_dBc_Hz));
|
||||
if same_length
|
||||
use_datasheet_phase_noise = true;
|
||||
end
|
||||
end
|
||||
@@ -31,6 +33,7 @@ function [adc_raw_data, adc_combined] = apply_lna_and_mixer(RxOut, TxOut, RadarP
|
||||
NumTx = RadarParams.Antenna.NumTx;
|
||||
rxPathGain_dB = RadarParams.Rxpath.rxPathGain_dB;
|
||||
system_NF_dB = RadarParams.Rxpath.system_NF_dB;
|
||||
impedance_ohm = 50; % 임피던스 기준 (일반적으로 50옴)
|
||||
PA_Profile = RadarParams.RFOutput.PA_Profile;
|
||||
SpurParams = RadarParams.SpurParams;
|
||||
enable_spur = true;
|
||||
@@ -57,8 +60,8 @@ function [adc_raw_data, adc_combined] = apply_lna_and_mixer(RxOut, TxOut, RadarP
|
||||
P_inst_dBm = interp1(PA_Profile(:,1), PA_Profile(:,2), f_inst, 'linear', 'extrap');
|
||||
end
|
||||
|
||||
% dBm -> Watt -> 전압 진폭(V) 변환 (50옴 시스템 기준)
|
||||
Vtx_inst = sqrt(10.^((P_inst_dBm - 30) / 10) * 50);
|
||||
% dBm -> Watt -> 전압 진폭(V) 변환 (임피던스 기준)
|
||||
Vtx_inst = sqrt(10.^((P_inst_dBm - 30) / 10) * impedance_ohm);
|
||||
|
||||
% --- 2. 수신단 시스템 잡음 계산 ---
|
||||
T_ref = RadarParams.Basic.T0;
|
||||
@@ -69,7 +72,7 @@ function [adc_raw_data, adc_combined] = apply_lna_and_mixer(RxOut, TxOut, RadarP
|
||||
|
||||
% ADC 입력단 기준 최종 잡음 전력 및 전압 표준편차
|
||||
P_noise_total_W = P_noise_floor_W * system_NF_lin * rxPathGain_lin;
|
||||
sigma_n = sqrt(P_noise_total_W * 50);
|
||||
sigma_n = sqrt(P_noise_total_W * impedance_ohm);
|
||||
|
||||
% --- MIMO 모드에 따른 TX 활성화 패턴 계산 ---
|
||||
% TDM: 처프마다 다른 TX만 활성화
|
||||
|
||||
@@ -13,13 +13,34 @@ function fig = visualize_rd_map_with_spurs(target_rd_map, r_axis, v_axis, Target
|
||||
% 출력:
|
||||
% - fig: 생성된 figure 핸들
|
||||
|
||||
if ~isfield(RadarParams, 'SP') || ~isfield(RadarParams.SP, 'RDM') || ...
|
||||
~isfield(RadarParams.SP.RDM, 'window_range') || ~isfield(RadarParams.SP.RDM, 'window_doppler')
|
||||
error('RadarParams.SP.RDM.window_range / window_doppler 정보가 필요합니다.');
|
||||
end
|
||||
|
||||
win_r = RadarParams.SP.RDM.window_range;
|
||||
win_d = RadarParams.SP.RDM.window_doppler;
|
||||
|
||||
normal_factor = RadarParams.Rxpath.fc_lpf * RadarParams.Waveform.PRF * sum(win_r.^2) * sum(win_d.^2);
|
||||
|
||||
if ~isfield(RadarParams, 'Rxpath') || ~isfield(RadarParams.Rxpath, 'load_impedance_ohm')
|
||||
error('RadarParams.Rxpath.load_impedance_ohm 값이 필요합니다.');
|
||||
end
|
||||
load_impedance_ohm = RadarParams.Rxpath.load_impedance_ohm;
|
||||
|
||||
psd2d_w_hz2 = (abs(target_rd_map).^2) / (load_impedance_ohm * max(normal_factor, eps));
|
||||
rbw_range_hz = RadarParams.Waveform.fs_adc * sum(win_r.^2) / max(eps, (sum(win_r)^2));
|
||||
rbw_doppler_hz = RadarParams.Waveform.PRF * sum(win_d.^2) / max(eps, (sum(win_d)^2));
|
||||
rd_map_dbm_bin = 10*log10(max(psd2d_w_hz2, realmin) / 1e-3) + 10*log10(max(rbw_range_hz * rbw_doppler_hz, eps));
|
||||
|
||||
fig = figure('Name', '2D Range-Doppler Map');
|
||||
imagesc(r_axis, v_axis, 20*log10(abs(target_rd_map)));
|
||||
imagesc(r_axis, v_axis, rd_map_dbm_bin);
|
||||
axis xy; % y축 방향(속도)을 위로 정렬
|
||||
colorbar;
|
||||
cb = colorbar;
|
||||
cb.Label.String = 'Power (dBm/bin)';
|
||||
xlabel('Range (m)');
|
||||
ylabel('Velocity (m/s)');
|
||||
title('Range-Doppler Map (Single Channel)');
|
||||
title('Range-Doppler Map (dBm/bin)');
|
||||
colormap(jet);
|
||||
|
||||
% 범례용 핸들 및 레이블 수집
|
||||
@@ -61,7 +82,6 @@ function fig = visualize_rd_map_with_spurs(target_rd_map, r_axis, v_axis, Target
|
||||
ni = RadarParams.Waveform.nonideal;
|
||||
enable_phase_noise = false;
|
||||
enable_nonlinearity = false;
|
||||
enable_datasheet_phase_noise = false;
|
||||
|
||||
if isfield(ni,'enable_phase_noise')
|
||||
enable_phase_noise = logical(ni.enable_phase_noise);
|
||||
@@ -69,12 +89,8 @@ function fig = visualize_rd_map_with_spurs(target_rd_map, r_axis, v_axis, Target
|
||||
if isfield(ni,'enable_nonlinearity')
|
||||
enable_nonlinearity = logical(ni.enable_nonlinearity);
|
||||
end
|
||||
if isfield(ni,'phaseNoise') && isstruct(ni.phaseNoise) && isfield(ni.phaseNoise,'enabled')
|
||||
enable_datasheet_phase_noise = logical(ni.phaseNoise.enabled);
|
||||
end
|
||||
|
||||
show_nonideal_overlay = show_nonideal_overlay && ...
|
||||
(enable_phase_noise || enable_nonlinearity || enable_datasheet_phase_noise);
|
||||
(enable_phase_noise || enable_nonlinearity);
|
||||
end
|
||||
|
||||
% --- 2. LO/ADC 톤 스퍼 표시 ---
|
||||
|
||||
@@ -42,12 +42,11 @@ RadarParams.Waveform.nonideal.pn_level = 0.05; % 위상노이즈
|
||||
RadarParams.Waveform.nonideal.f_ripple = 300e3; % 위상 리플 주파수
|
||||
RadarParams.Waveform.nonideal.peak_phase_error = 0.1; % 최대 위상오차
|
||||
RadarParams.Waveform.nonideal.power_drop_edge = 0.8; % 엣지 파워 드롭
|
||||
RadarParams.Waveform.nonideal.enable_phase_noise = false; % phase noise on/off
|
||||
RadarParams.Waveform.nonideal.enable_phase_noise = true; % phase noise on/off
|
||||
RadarParams.Waveform.nonideal.enable_nonlinearity = false; % nonlinearity on/off
|
||||
% Datasheet 기반 phase noise 설정 (예: -89 dBc/Hz @ 1 MHz)
|
||||
RadarParams.Waveform.nonideal.phaseNoise.offset_Hz = [1e6];
|
||||
RadarParams.Waveform.nonideal.phaseNoise.level_dBc_Hz = [-89];
|
||||
RadarParams.Waveform.nonideal.phaseNoise.enabled = false;
|
||||
|
||||
% 2-3) MIMO 모드 설정
|
||||
RadarParams.Waveform.mimoMode = 'TDM'; % 'TDM' 또는 'DDMA'
|
||||
@@ -71,11 +70,11 @@ RadarParams.Antenna.TxPattern = build_antenna_patterns(RadarParams.Antenna.NumTx
|
||||
RadarParams.Antenna.RxPattern = build_antenna_patterns(RadarParams.Antenna.NumRx, '2D', 14, 2, 40, 15, RadarParams.Antenna.rx_files);
|
||||
|
||||
% 5) 타겟 모델링
|
||||
RadarParams.Target.R = [12, 80, 120]; % 타겟 거리 (m)
|
||||
RadarParams.Target.v = [7, -5, 0]; % 타겟 속도 (m/s)
|
||||
RadarParams.Target.rcs = [10, 5, 20]; % 타겟 RCS (dBsm)
|
||||
RadarParams.Target.az = [10, -10, 0]; % 방위각 (deg)
|
||||
RadarParams.Target.el = [0, 0, 5]; % 고각 (deg)
|
||||
RadarParams.Target.R = [12]; % 타겟 거리 (m)
|
||||
RadarParams.Target.v = [7]; % 타겟 속도 (m/s)
|
||||
RadarParams.Target.rcs = [-10000]; % 타겟 RCS (dBsm)
|
||||
RadarParams.Target.az = [10]; % 방위각 (deg)
|
||||
RadarParams.Target.el = [0]; % 고각 (deg)
|
||||
RadarParams.Target.NumTargets = length(RadarParams.Target.R);
|
||||
|
||||
% 6) 수신단 파라미터
|
||||
@@ -84,6 +83,7 @@ RadarParams.Rxpath.fc_lpf = 0.8*RadarParams.Waveform.fs_adc/2; % L
|
||||
RadarParams.Rxpath.adc_bits = 12; % ADC 비트수
|
||||
RadarParams.Rxpath.adc_v_full_scale = 2.0; % full-scale 전압 (Vp-p)
|
||||
RadarParams.Rxpath.receiver_mode = 'Real'; % 'IQ' 또는 'Real'
|
||||
RadarParams.Rxpath.load_impedance_ohm = 50; % 임피던스 (Ohm)
|
||||
RadarParams.Rxpath.rxPathGain_dB = 50; % RX 경로 이득 (dB)
|
||||
RadarParams.Rxpath.system_NF_dB = 15; % 시스템 잡음지수 (dB)
|
||||
|
||||
@@ -104,6 +104,34 @@ RadarParams.SpurParams.enabled = false; % spur on/of
|
||||
% 7) 신호처리 파라미터
|
||||
RadarParams.SP.RDM.window_type_range = 'hann'; % Range FFT용 윈도우
|
||||
RadarParams.SP.RDM.window_type_doppler = 'chebwin'; % Doppler FFT용 윈도우
|
||||
|
||||
num_samples_range = round(RadarParams.Waveform.fs_adc * RadarParams.Waveform.Timing.AdcSampTime);
|
||||
num_chirps_doppler = RadarParams.Waveform.NumChirps;
|
||||
|
||||
if strcmpi(RadarParams.SP.RDM.window_type_range, 'none')
|
||||
RadarParams.SP.RDM.window_range = ones(1, num_samples_range);
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_range, 'hamming')
|
||||
RadarParams.SP.RDM.window_range = hamming(num_samples_range)';
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_range, 'blackman')
|
||||
RadarParams.SP.RDM.window_range = blackman(num_samples_range)';
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_range, 'chebwin')
|
||||
RadarParams.SP.RDM.window_range = chebwin(num_samples_range, 60)';
|
||||
else
|
||||
RadarParams.SP.RDM.window_range = hann(num_samples_range)';
|
||||
end
|
||||
|
||||
if strcmpi(RadarParams.SP.RDM.window_type_doppler, 'none')
|
||||
RadarParams.SP.RDM.window_doppler = ones(1, num_chirps_doppler);
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_doppler, 'hamming')
|
||||
RadarParams.SP.RDM.window_doppler = hamming(num_chirps_doppler)';
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_doppler, 'blackman')
|
||||
RadarParams.SP.RDM.window_doppler = blackman(num_chirps_doppler)';
|
||||
elseif strcmpi(RadarParams.SP.RDM.window_type_doppler, 'hann')
|
||||
RadarParams.SP.RDM.window_doppler = hann(num_chirps_doppler)';
|
||||
else
|
||||
RadarParams.SP.RDM.window_doppler = chebwin(num_chirps_doppler, 60)';
|
||||
end
|
||||
|
||||
RadarParams.SP.CFAR.method = 'OS'; % 'CA' 또는 'OS'
|
||||
RadarParams.SP.CFAR.dimension = '2D'; % '1D' 또는 '2D'
|
||||
RadarParams.SP.CFAR.axis = 'doppler'; % 1D일 때만 사용: 'range' 또는 'doppler'
|
||||
|
||||
Reference in New Issue
Block a user