Files
ARSS/01. Tx Path/visualize_tx_waveform.m

78 lines
3.8 KiB
Matlab

function fig = visualize_tx_waveform(t, Timing, fc, f_start, Slope, tx_mask, peak_phase_error, f_ripple)
fig = figure('Name', 'FMCW Radar Timing & True RF Frequency', 'Position', [100, 100, 1100, 700]);
t_ramp = t - Timing.IdleTime;
% 주파수 스윕 계산
inst_freq_theoretical = f_start + Slope * t_ramp;
freq_nonlin = peak_phase_error * f_ripple * cos(2 * pi * f_ripple * t_ramp);
inst_freq_theoretical = inst_freq_theoretical + freq_nonlin;
inst_freq_masked = inst_freq_theoretical;
inst_freq_masked(tx_mask == 0) = NaN;
% Y축 동적 스케일링 설정
y_min = (f_start / 1e9) - 0.2;
y_max = (f_start / 1e9) + (Slope * Timing.RampEndTime / 1e9) + 0.1;
% --- [주파수 곡선 플롯] ---
plot(t * 1e6, inst_freq_masked / 1e9, 'b', 'LineWidth', 2.5);
title(sprintf('Mathematical Instantaneous RF Frequency & HW Timing (Center fc = %.2f GHz)', fc/1e9), 'FontSize', 12);
xlabel('Time (\mus)', 'FontSize', 11); ylabel('Absolute Frequency (GHz)', 'FontSize', 11);
ylim([y_min, y_max]);
grid on; hold on;
% --- [좌측 상단: 유효 주파수 및 대역폭 정보 박스 추가] ---
% ADC 샘플링 구간에 해당하는 유효 시작/끝 주파수 및 대역폭 계산
f_valid_start = f_start + (Slope * Timing.AdcStartTime);
f_valid_end = f_start + (Slope * (Timing.AdcStartTime + Timing.AdcSampTime));
valid_bandwidth = f_valid_end - f_valid_start; % 유효 대역폭 추가 계산
info_str = {
sprintf('▶ Valid Start Freq : %.4f GHz', f_valid_start / 1e9), ...
sprintf('▶ Center Freq : %.4f GHz', fc / 1e9), ...
sprintf('▶ Valid End Freq : %.4f GHz', f_valid_end / 1e9), ...
sprintf('▶ Valid Bandwidth : %.4f GHz', valid_bandwidth / 1e9) % 정보 박스에 표시
};
text(0.02, 0.96, info_str, 'Units', 'normalized', ...
'FontSize', 10, 'FontWeight', 'bold', 'BackgroundColor', [1 1 1 0.85], ...
'EdgeColor', 'k', 'VerticalAlignment', 'top', 'Margin', 5);
% --- [가이드 세로선 그리기] ---
y_lims = ylim;
guide_line_args = {'Color', [0 0 0.5], 'LineStyle', '--', 'LineWidth', 1};
x_coords = [0, Timing.IdleTime, ...
(Timing.IdleTime + Timing.TxStartTime), ...
(Timing.IdleTime + Timing.AdcStartTime), ...
(Timing.IdleTime + Timing.AdcStartTime + Timing.AdcSampTime), ...
(Timing.IdleTime + Timing.RampEndTime)];
x_coords_us = x_coords * 1e6;
for i = 1:length(x_coords_us)
plot([x_coords_us(i), x_coords_us(i)], y_lims, guide_line_args{:});
end
% --- [커스텀 다각형 화살표 함수] ---
draw_dim_arrow = @(x1, x2, y, name, val_us) ...
[plot([x1, x2], [y, y], 'k-', 'LineWidth', 1.2), ...
fill([x1, x1 + min(0.6, (x2-x1)*0.35), x1 + min(0.6, (x2-x1)*0.35)], [y, y + 0.015, y - 0.015], 'k', 'EdgeColor', 'none'), ...
fill([x2, x2 - min(0.6, (x2-x1)*0.35), x2 - min(0.6, (x2-x1)*0.35)], [y, y + 0.015, y - 0.015], 'k', 'EdgeColor', 'none'), ...
text((x1+x2)/2, y + 0.03, sprintf('%s\n(%.1f \\mus)', name, val_us), 'HorizontalAlignment', 'center', 'VerticalAlignment', 'bottom', 'FontSize', 9, 'FontWeight', 'bold', 'BackgroundColor', 'w', 'EdgeColor', 'k')];
% 화살표 배치 높이 동적 설정
y1 = y_min + 0.05;
y2 = y_min + 0.18;
y3 = y_min + 0.31;
draw_dim_arrow(x_coords_us(1), x_coords_us(2), y1, 'Idle Time', Timing.IdleTime * 1e6);
draw_dim_arrow(x_coords_us(2), x_coords_us(3), y2, 'TX Start', Timing.TxStartTime * 1e6);
draw_dim_arrow(x_coords_us(2), x_coords_us(4), y3, 'ADC Delay', Timing.AdcStartTime * 1e6);
draw_dim_arrow(x_coords_us(4), x_coords_us(5), y2, 'ADC Sampling (Valid)', Timing.AdcSampTime * 1e6);
draw_dim_arrow(x_coords_us(5), x_coords_us(6), y1, 'Excess', Timing.ExcessTime * 1e6);
hold off;
end