☰
MATLAB反射阵单元相位计算与批量处理全流程实践
2026/10/2 2:57:24 网站建设 项目流程

简介:一份基于MATLAB的反射阵天线单元相位计算代码包,面向无线通信、雷达系统等领域的研究人员与工程师,用于实现反射阵波束赋形中的相位配置与优化。压缩包共4个文件,大小仅14KB,包含2个.m格式的MATLAB脚本(主计算函数与辅助测试脚本)和2个.pm格式的MEX接口辅助文件,完整覆盖了从定义天线参数、计算理想相位、实施相位补偿到结果可视化的主要环节,可直接在MATLAB环境中运行或修改验证。代码逻辑清晰、注释明确,便于理解反射阵单元相位的计算思路,适合用作课程设计、科研入门或工程参考。已有1344人学习下载,适合具备一定天线或电磁场基础、需要快速搭建相位计算仿真环境的中高级用户。通过该资源不仅能够掌握物理光学法或几何传播模型在反射阵设计中的应用,还能结合MEX加速机制处理大规模阵列数据;同时,代码详细展示了每个单元的相位偏移计算与补偿过程,并提供了可视化输出,可帮助读者深入理解波束成形原理,为后续研究阵列互耦、环境干扰等实际因素提供了可扩展的算法框架。

1. 反射阵单元相位计算:为什么这件事值得你用 MATLAB 单独做一套流程

做反射阵天线设计的人,十有八九都被同一个问题卡过:单元相位曲线算不准、对不齐、换一个频点就得重来一遍。反射阵的核心原理并不复杂——每个单元通过改变尺寸或结构,把入射波反射成期望的相位分布,从而等效出一个平面波前。但“原理简单”和“落地顺利”是两回事,真正动手时你会发现,全波仿真软件导出的数据格式五花八门,相位曲线动不动就跳变 ±180°,扫参数据散落在一堆文件里,手动处理一次还可以,做参数优化时几十组数据根本顾不过来。

这个标题所指向的,正是“用 MATLAB 把反射阵单元的反射相位计算做成一条可复用的流水线”。它不是什么高深理论,而是把 HFSS、CST 或 FDTD 这类全波仿真工具的输出结果,用 MATLAB 做系统化的相位提取、归一化、去跳变和曲线拟合。适合谁用?如果你是做反射阵天线、透射阵天线或频率选择表面设计的工程师或研究生,手头已经能跑全波仿真,但被相位数据整理和分析拖慢了进度,这篇文章就是给你写的。网上的相关资源大多只给一个孤立的 .m 文件,注释少、边界条件模糊、换一组参数就翻车;我会把仿真设置到数据后处理的完整链路讲清楚,你照着做就能建立自己的单元相位计算脚本。

2. 反射阵单元相位的基本逻辑:从 S 参数到相位曲线的映射关系

2.1 单元相位到底是什么:反射系数相位与单元尺寸的对应关系

反射阵单元相位,本质上就是单元在周期边界条件下,对垂直入射平面波的反射系数 S11 的相位角。全波仿真软件里,单元通常被建模为一个贴片加上介质基板,放在一个矩形晶胞(unit cell)中,上下左右设成周期边界(主从边界,即 master/slave),端口设在单元上方一定距离处,激励方式是一个 Floquet 端口或波端口。仿真得到的 S11 的相位,就是我们要的单元反射相位。

为什么尺寸变化会带来相位变化?因为贴片尺寸改变时,单元的谐振频率发生偏移。工作频率固定不变的情况下,单元偏离谐振越远,反射相位就越滞后或越超前。在谐振频率附近,相位曲线斜率最陡,这意味着尺寸的微小变化能带来较大的相位变化。常见的做法是通过扫描贴片长度 L(或方环的外边长、圆环的半径),得到一条“相位-尺寸”曲线,也就是反射阵设计里最基础的一条设计曲线。

用 MATLAB 处理这条曲线的意义在于:全波仿真软件只能给你一个个离散频点下的 S11 数据,而单元设计需要从 S11 的相位中剔除传播相位、处理相位缠绕(wrapping)、再插值成连续曲线,最后还要拟合多项式或构建查找表,供阵列综合阶段使用。这些工作在 MATLAB 里可以用几行代码加一个脚本文件全部完成。

2.2 全波仿真导出的数据长什么样:S11 实部虚部 vs 幅度相位

先看你手头会拿到什么数据。HFSS 里导出 S 参数时,默认可以选 dB、幅度、实部虚部三种格式。CST 的 1D 结果导出则一般是极坐标下的幅度和相位,或者实部虚部。我的经验是:不要直接导 dB 和角度,尽量导实部虚部(Re/Im),因为相位角在 ±180° 边界处的跳变本质上是一个反正切函数的象限判断问题,导实部虚部到 MATLAB 里后用angle()函数重新算相位,配合unwrap()去跳变,比直接在仿真软件里导相位数据要稳得多。

% 读取 HFSS 导出的 S11 实部虚部数据(CSV 格式) data = readmatrix('s11_re_im.csv'); freq = data(:, 1); % 频率,单位 GHz s11_re = data(:, 2); % S11 实部 s11_im = data(:, 3); % S11 虚部 % 合成复反射系数并计算相位 s11 = s11_re + 1i * s11_im; phase_rad = angle(s11); % 相位范围 [-pi, pi] phase_deg = rad2deg(phase_rad); % 去除跳变:unwrap 按 2pi 跳变做修正 phase_unwrapped = rad2deg(unwrap(phase_rad));

这里angle()函数返回的是 -π 到 π 之间的相位角,对应 0° 到 360° 的相位映射。unwrap()的机制是检测相邻采样点之间是否有超过 π 的跳变,如果有,就对后面的数据整体加或减 2π 的整数倍,把相位曲线拉成连续曲线。参数上需要注意,unwrap()默认的跳变阈值为 π,如果你的频点间隔取得很大,比如 2 GHz 一个点,相位真值变化可能超过 π,此时建议先加密频点采样,或者把跳变阈值调小。

2.3 为什么要剔除传播相位:晶胞尺寸对相位基准的影响

这是反射阵相位计算里最容易被忽略、也最容易翻车的一步。仿真得到的 S11 相位,包含了电磁波从端口参考面到单元表面这一段路径的传播相位。不同晶胞尺寸周期不同,波从端口到单元表面的距离也不同,导致即使单元结构完全相同,仅仅改变晶胞周期大小,S11 相位也会整体偏移。所以在做“单元尺寸-相位”曲线之前,必须先把传播相位扣掉。

传播相位怎么算?如果端口参考面到单元表面的距离是 h(单位 mm),频率是 f(单位 GHz),则单程传播相位为 2π·f·h/c,其中 c 是真空光速。反射是双程路径,所以总传播相位是两倍的单程相位,也就是 4π·f·h/c。相位的基准通常取单元表面,因此要把 S11 的相位减去这个双程传播相位。

% 剔除传播相位:端口面到单元表面的距离 h,单位 mm h = 5.0; % 根据你的模型实际设置 c = 299.792458; % 光速,单位 mm/GHz freq_ghz = freq; % 频率,单位 GHz % 双程传播相位 phase_prop = 4 * pi * h .* freq_ghz / c; % 扣掉传播相位后重新打包 s11_corrected = s11 .* exp(1i * phase_prop); phase_corrected_rad = angle(s11_corrected); phase_corrected_deg = rad2deg(unwrap(phase_corrected_rad));

这段代码的核心逻辑是用复指数相乘来做相位旋转。exp(1i * phase_prop)产生了单位幅度的相移因子,S11 乘以它之后,等效于把相位参考面从端口搬到了单元表面。注意传播相位是正的还是负的取决于你定义的波传播方向,我这里的写法是端口在上方、波向下入射到单元然后反射回端口,实际使用时先确认一下相位是超前还是滞后,如果方向反了,把phase_prop前的符号换掉即可。

3. 用 MATLAB 写单元相位扫描脚本:从单点计算到参数扫描

3.1 批量读取多组仿真数据:文件命名规范与自动遍历

单元相位曲线的形成,需要扫描单元某个几何参数(贴片长度、方环边长、圆环半径等)。每次扫描一个尺寸值,就需要一次全波仿真,导出一份 S 参数文件。扫描 20 个尺寸,就有 20 个文件。如果手动一个文件一个文件地导入、处理,效率低不说,还容易把文件对应关系搞错。正确做法是建立一个规范的命名规则,然后让 MATLAB 自动遍历文件夹里的所有结果文件。

常见做法是在全波仿真软件里用一个参数扫描任务,批量导出数据时按尺寸值命名文件,比如patch_L_11.0mm.csv、patch_L_11.2mm.csv。MATLAB 端用dir函数列出所有符合模式的文件,然后循环读取。

% 指定结果目录 result_dir = './s11_data/'; file_pattern = 'patch_L_*.csv'; % 文件名包含尺寸信息 files = dir(fullfile(result_dir, file_pattern)); num_files = length(files); % 预分配存储 L_values = zeros(num_files, 1); % 尺寸值数组 phase_at_f0 = zeros(num_files, 1); % 中心频率处的相位 for k = 1:num_files filename = files(k).name; % 从文件名中提取尺寸值 tokens = regexp(filename, 'patch_L_([\d.]+)mm\.csv', 'tokens'); L_values(k) = str2double(tokens{1}{1}); % 读取数据 data = readmatrix(fullfile(result_dir, filename)); freq = data(:, 1); s11_re = data(:, 2); s11_im = data(:, 3); s11 = s11_re + 1i * s11_im; % 剔除传播相位(假设端口面到单元表面距离 h) h = 5.0; c = 299.792458; phase_prop = 4 * pi * h .* freq / c; s11_corrected = s11 .* exp(1i * phase_prop); % 提取中心频率处的相位 f0 = 10.0; % 设计中心频率,单位 GHz [~, idx] = min(abs(freq - f0)); phase_rad = angle(s11_corrected(idx)); phase_at_f0(k) = rad2deg(phase_rad); end % 按尺寸值排序,确保曲线单调对应 [L_sorted, sort_idx] = sort(L_values); phase_sorted = phase_at_f0(sort_idx);

关键参数说明:regexp的正则表达式里的([\d.]+)用来匹配浮点数,如果你的文件名里有多个数字段,用花括号索引指定取第几个匹配项。min(abs(freq - f0))找最接近中心频率的频点索引,这是频点匹配最稳妥的方式,不要用find(freq == f0),因为浮点数比较很可能落空。排序一步容易被忽视,扫描参数不一定按文件名顺序排列,尤其当尺寸超过 10 个时,不排序画出来的曲线是乱的。

3.2 相位去跳变与平滑:unwrap 的边界条件和插值处理

批量提取到的相位值,尺寸相邻的两个单元之间相位差可能超过 180°,尤其是工作在谐振频率附近的单元。此时如果不做相位连续化处理,画出来的“尺寸-相位”曲线会出现断崖式跳变,看起来像是数据错了,实际上只是相位缠绕。unwrap在这里仍然适用,但作用对象从频率轴变成了尺寸轴。

% 对尺寸-相位曲线做 unwrap phase_unwrapped = rad2deg(unwrap(deg2rad(phase_sorted))); % 可选:用 Savitzky-Golay 滤波做平滑,减小仿真噪声影响 window_size = 5; poly_order = 2; phase_smooth = sgolayfilt(phase_unwrapped, poly_order, window_size); % 插值成细密曲线,供后续查表 L_fine = linspace(min(L_sorted), max(L_sorted), 1000); phase_interp = interp1(L_sorted, phase_smooth, L_fine, 'pchip');

unwrap对尺寸轴的相位处理,原理与频率轴完全一致:相邻点相位差超过 π 就补 2π 的整数倍。需要留意的是,如果某个尺寸扫描点恰好落在谐振点附近,相位斜率非常大,相邻点的真实相位变化可能小于 π 但接近 π,加上仿真噪声后可能误判为跳变,此时应优先调整扫描步长而不是依赖 unwrap 硬修。sgolayfilt的窗口宽度和高阶参数是经验值,尺寸扫描点数较少时窗口取 3,点数多取 7 也不会有问题。插值用pchip而不是spline,原因在于 pchip 不产生过冲,单元相位的物理特性约束了曲线不应出现超出仿真范围的振荡。

3.3 相位曲线拟合与多项式逼近:如何从离散点得到可用的解析表达式

有了平滑后的相位曲线,下一步是把它表达成解析形式。反射阵综合阶段,给定一个所需的相位值,要反求单元尺寸。如果相位曲线只有离散点表和线性插值,反求时需要做逆插值。更高效的做法是把“尺寸-相位”关系拟合为多项式函数,或者分段拟合,然后直接解多项式方程。相位曲线的典型形状接近反正切函数,单一多项式拟合在全尺寸范围内误差会比较大,常用技巧是分段拟合,或者先做反正切变换再用低阶多项式。

% 使用 polyfit 拟合相位随尺寸的变化(建议分段拟合) % 先观察曲线形状,手动设置分段边界 segment_breaks = [min(L_sorted), 11.5, 12.5, max(L_sorted)]; coeffs = cell(1, length(segment_breaks)-1); for seg = 1:length(segment_breaks)-1 idx_seg = L_sorted >= segment_breaks(seg) & L_sorted <= segment_breaks(seg+1); if sum(idx_seg) < 3 % 点数不足时跳过,打印警告 warning('第 %d 段数据点不足,无法可靠拟合', seg); continue; end coeffs{seg} = polyfit(L_sorted(idx_seg), phase_unwrapped(idx_seg), 3); end % 生成拟合曲线用于验证 phase_fit = zeros(size(L_fine)); for seg = 1:length(segment_breaks)-1 idx_fine = L_fine >= segment_breaks(seg) & L_fine <= segment_breaks(seg+1); if ~isempty(coeffs{seg}) phase_fit(idx_fine) = polyval(coeffs{seg}, L_fine(idx_fine)); end end % 检查拟合残差 residual = phase_fit - interp1(L_sorted, phase_unwrapped, L_fine, 'pchip'); rms_residual = sqrt(mean(residual.^2)); fprintf('拟合残差 RMS: %.2f deg\n', rms_residual);

分段拟合的边界位置选择不是拍脑袋定的,正确做法是先画曲线,找到斜率最大区间和两个较平坦区间,然后让每一段内的曲线尽量单调且平滑。多项式阶数取 3 通常足够,阶数再高容易过拟合仿真数据的局部噪声,反而不利于后续反演。拟合残差的 RMS 值是一个重要的质量指标,如果超过 3°~5°,说明分段边界或者阶数选择不合理,需要调整。反求尺寸时,对每个多项式段调用roots求实数根,再根据根是否落在该段尺寸范围内来判断用哪个根。

4. 建立单元相位查找表:从单一频点到宽带与多参数插值

4.1 相位-尺寸查找表的数据结构与生成逻辑

单频点的“尺寸-相位”曲线在窄带设计中够用,但如果你做的是宽带反射阵,或者需要评估不同频点下同一组单元的相位误差,就得建立二维查找表:行是尺寸扫描值,列是频点,表内存储对应的反射相位。这要求仿真阶段对每个尺寸都扫频,得到整个频带内的 S11 相位曲线,然后在 MATLAB 里做二维插值。

% 假设已从循环中得到:freq 向量、L_sorted 向量、phase_matrix(尺寸×频率) % 构造网格数据 [Freq_grid, L_grid] = meshgrid(freq, L_sorted); phase_matrix_unwrapped = zeros(size(phase_matrix)); % 对每一行(固定尺寸)沿频率轴做 unwrap for k = 1:size(phase_matrix, 1) phase_row_rad = deg2rad(phase_matrix(k, :)); phase_matrix_unwrapped(k, :) = rad2deg(unwrap(phase_row_rad)); end % 对每一列(固定频率)沿尺寸轴再做 unwrap for f_idx = 1:size(phase_matrix, 2) phase_col_deg = phase_matrix_unwrapped(:, f_idx); phase_matrix_unwrapped(:, f_idx) = rad2deg(unwrap(deg2rad(phase_col_deg))); end % 查表函数:输入尺寸 L 和频率 f,输出相位 L_target = 12.3; f_target = 10.5; phase_value = interp2(Freq_grid, L_grid, phase_matrix_unwrapped, ... f_target, L_target, 'spline');

这段代码里我做了两次 unwrap,先沿频率轴、再沿尺寸轴。原因是相位跳变可能发生在频率维,也可能发生在尺寸维,只做一次无法保证二维曲面的连续性。interp2的网格形式需要注意:第一个参数是 X 坐标网格(频率),第二个是 Y 坐标网格(尺寸),第三个是相位值矩阵,查询点是(f_target, L_target)。spline插值适合相位变化平缓的区域,但如果在谐振点附近,spline 可能产生明显的振荡,安全做法是先用线性插值看看结果是否合理,再决定是否升级插值算法。

4.2 多参数扫描的扩展:双变量单元结构的插值策略

很多反射阵单元不止一个设计自由度。例如双谐振单元,外层方环边长和内层贴片长度同时变化,才能扩展相位范围。这种单元的相位查找表是三维的:两个几何参数加一个频率。三维查找表的数据量增长很快,但处理逻辑与二维没有本质区别,只是把interp2换成interp3或者做两次interp2的嵌套调用。

% 假设两层循环扫描了 outer_L 和 inner_L,得到 phase_3d:outer×inner×freq % 查询时先固定频率,再做二维插值 f_target = 10.0; phase_slice = interp1(freq, squeeze(phase_3d(:, :, :)), f_target); % 在 outer-inner 平面上插值 outer_target = 13.0; inner_target = 8.5; phase_value = interp2(outer_L_vec, inner_L_vec, phase_slice, ... outer_target, inner_target, 'linear');

这里squeeze用来去掉频率维的单一长度维度,interp1沿频率轴取了目标频点的切片。二维插值时的两个尺寸向量必须与该维度在 phase_slice 中的排列方向一致,用meshgrid生成网格来对齐,否则插值结果是错的。多参数扫描的代价是仿真次数呈指数增长,8 个外尺寸 × 8 个内尺寸就是 64 次仿真,所以建议先用一维扫描确认工作频点附近两个参数各自的影响趋势,再决定是否值得做完整二维扫描。

4.3 查找表文件的存储格式:如何让数据可以被阵列综合脚本直接复用

查找表建立起来之后,应该存成独立文件,供阵列综合模块加载。存储格式的选择标准是:MATLAB 原生的.mat文件最方便,但要考虑后续是否与 Python 或其他工具联动,CSV 格式是通用性更好的备份方案。我一般会同时存两种格式,.mat留给 MATLAB 内快速加载,CSV 留给数据可视化或者作为论文附录材料。

% 保存查找表 save('reflectarray_LUT.mat', 'L_sorted', 'freq', 'phase_matrix_unwrapped', ... 'segment_breaks', 'coeffs', 'f0'); % 导出 CSV 便于其他程序读取 csvwrite('reflectarray_LUT.csv', [L_sorted(:), phase_matrix_unwrapped]); % 在阵列综合脚本中加载 loaded_data = load('reflectarray_LUT.mat'); L_table = loaded_data.L_sorted; phase_table = loaded_data.phase_matrix_unwrapped;

保存时把拟合系数也一并存进去,是为了兼顾两种使用方式:查表精确但占用内存,拟合函数速度快但精度略低。阵列综合时如果需要对几万个单元逐个反求尺寸,查表配合二分法比逐个求多项式根更快,预处理一次根的位置表可以进一步提速。CSV 导出时注意把尺寸列放在第一列,这对应大多数数据可视化工具的默认表格格式。

5. 反射阵相位计算避坑指南:5 个高频翻车点与排查方法

5.1 翻车点一:周期边界条件设置不一致导致相位基准漂移

现象:同一单元结构,仅仅改了晶胞周期大小,扫出来的相位曲线整体偏移了一个固定角度,且偏移量与频率成正比。

原因:这是传播相位没有被正确扣掉,或者扣的时候用的端口到单元表面距离 h 与仿真模型实际不符。更隐蔽的情况是 HFSS 主从边界中主边界的坐标原点与从边界的设置不一致,导致参考相位本身就不对。

解决:第一步,在仿真软件里检查 master/slave 边界是否严格对应,特别是两个边界的积分方向是否一致。第二步,确认波端口或 Floquet 端口的参考面位置,测量参考面到单元表面的实际距离,把这个值更新到脚本里的变量 h 中。第三步,用一小组已知结果的单元尺寸做验证,看相位曲线是否与论文或已有设计吻合。

5.2 翻车点二:相位 unwrap 把真实跳变当成噪声处理了

现象:尺寸-相位曲线上出现了不应该出现的大幅度相位“修正”,原本平滑的区域被 unwrap 强行平移了一个周期。

原因:当尺寸扫描步长过大,相邻单元的相位真值差已经超过 180°时,相位差实际上处于缠绕状态,unwrap 无法区分这是真实的快速变化还是需要展开的跳变。这在谐振频率附近尤其常见,因为谐振点附近相位斜率最陡。

解决:减小尺寸扫描步长,在谐振点附近加密采样。如果扫描点数已经很多仍然有问题,可以改用基于相位斜率估计的展开方法,也就是先对原始相位做差分,找出差分值超过阈值的位置,再根据相邻差分的符号判断应该加还是减 2π。我把这套逻辑封装成一个函数,效果比直接调unwrap更稳定。

function phase_out = robust_unwrap(phase_deg) phase_diff = diff(phase_deg); jump_threshold = 180; phase_out = phase_deg; for k = 1:length(phase_diff) if phase_diff(k) > jump_threshold phase_out(k+1:end) = phase_out(k+1:end) - 360; elseif phase_diff(k) < -jump_threshold phase_out(k+1:end) = phase_out(k+1:end) + 360; end end end

这个函数用 180° 作为跳变阈值,与unwrap默认行为一致,但好处是可以逐点检查修正量,方便调试时打印哪些位置发生了跳变修正。

5.3 翻车点三:多频点数据中频点向量不统一

现象:不同尺寸的仿真导出文件里,频点数量不一致或者频点值不是完全对齐的。比如 21 个频点的仿真和 19 个频点的仿真放在一起做二维查找表,矩阵拼接维度不匹配。

原因:全波仿真软件中扫频设置是自适应加密的,某些尺寸下仿真收敛后输出的频点列表可能与另一些尺寸不完全相同。直接readmatrix后假设所有文件频点一致,拼接时就报错。

解决:不直接拼接原始数据,先对每份文件做插值到一个公共频率向量。公共频率向量可取所有文件中频率范围的重叠区间,用linspace生成固定数量的频点,然后逐文件插值对齐。

freq_common = linspace(min_freq, max_freq, 201); for k = 1:num_files % 每份文件插值到公共频点 phase_at_freqs = interp1(freq_k, phase_k, freq_common, 'linear'); phase_interp_matrix(k, :) = phase_at_freqs; end

5.4 翻车点四:相位曲线不平滑但 S11 幅度正常,怀疑数据没问题却拟合失败

现象:相位曲线整体形状正常,但局部有微小的锯齿状波动,多项式拟合出来的曲线在局部出现明显偏差。

原因:全波仿真中的自适应网格剖分在不同尺寸下产生的网格密度不一致,导致 S11 相位的数值精度有细微差异。还有一种可能是在频点接近谐振时 S11 幅度极低,相位对噪声极其敏感。

解决:先用 Savitzky-Golay 滤波做小幅平滑,窗口不要超过 7,然后检查 S11 的幅度是否在工作频点附近低于 -20 dB。如果幅度过低,应调整全波模型的损耗设置或者检查介质基板的损耗正切是否合理。相位计算依赖幅度大于零,谐振点上幅度几乎为零时相位本来就没有物理意义,此时应该把该点剔除而不是硬拟合。

5.5 翻车点五:换了频率点整条曲线形状大变,怀疑脚本有 bug

现象:在中心频率处提取的尺寸-相位曲线形状正常,换到另一个频点后曲线整体变形,相位范围变窄且非线性加剧。

原因:这不是 bug,而是反射阵单元相位随频率变化的正常物理现象。远离中心频率后,单元尺寸达到谐振状态的频率偏移了,尺寸-相位曲线的斜率分布与中心频率处不同。比如 10 GHz 下 12 mm 的贴片恰好接近谐振,相位变化剧烈,但在 9.5 GHz 下这个尺寸可能只是轻微失谐。

解决:明确设计目标是否要求宽带工作。如果只在中心频率单频点工作,窄带查找表足够;如果需要宽带,必须用二维查找表,并且在每个频点下检查相位曲线的平滑度和可反演性。如果某些频点下曲线出现非单调区段,意味着该频点下存在两个尺寸对应同一相位值,此时应更换单元结构或调整单元尺寸范围,而不是继续硬算。

6. 相位补偿与阵列综合的衔接:把单元相位曲线变成波束赋形的输入

到这一步,你的手里应该有一条平滑、连续、去除了传播相位误差的尺寸-相位曲线,以及一份至少覆盖工作频带的二维查找表。但单元相位曲线本身不是终点,反射阵设计的终点是让每个单元上的反射相位与期望的相位分布一致,从而在远场形成预设波束。衔接这一步,需要一个从期望相位到单元尺寸的反演函数。

% 期望相位分布:以阵面中心为参考,计算第 i 行 j 列单元的补偿相位 % 设阵面在 x-y 平面,馈源位于 (xf, yf, zf),单元位于 (xi, yi, 0) xf = 0; yf = 0; zf = 150; % 馈源位置,单位 mm target_angle_theta = 20; % 波束指向仰角,单位度 target_angle_phi = 0; % 波束指向方位角 % 对每个单元计算期望相位 Nx = 20; Ny = 20; dx = 12; dy = 12; % 单元间距,单位 mm x_center = (0:Nx-1) * dx - (Nx-1) * dx / 2; y_center = (0:Ny-1) * dy - (Ny-1) * dy / 2; phase_required = zeros(Ny, Nx); for i = 1:Ny for j = 1:Nx xi = x_center(j); yi = y_center(i); % 馈源到单元的入射波相位 r_inc = sqrt((xi-xf)^2 + (yi-yf)^2 + zf^2); % 期望的反射波出射相位(平面波前),单位角度 phase_out = -2*pi/lam0 * (xi*sind(target_angle_theta)*cosd(target_angle_phi) + ... yi*sind(target_angle_theta)*sind(target_angle_phi)); % 补偿相位 = 出射相位 - 入射相位 phase_required(i, j) = rad2deg(phase_out - (-2*pi*r_inc/lam0)); % 归一化到 [-180, 180] phase_required(i, j) = mod(phase_required(i, j) + 180, 360) - 180; end end

这段代码里lam0是工作频率对应的自由空间波长,mod操作把相位归一化到 ±180° 区间。每个单元的期望补偿相位由两部分组成:一部分补偿馈源到该单元的路径差(入射相位),另一部分建立平面波前(出射相位)。得到每个单元的期望相位之后,调用查表函数反求单元尺寸,算法是二分法或多项式求根,核心逻辑是找到满足|查表相位 - 期望相位| < 容差的尺寸值。

验证这个反演结果的方法是:把反求得到的尺寸作为输入,重新用全波仿真算一遍全部单元的 S11 相位,然后代入阵列因子公式,计算远场方向图,看主瓣指向是否与设定的目标角度一致。这个闭环验证很花时间,但做一次就能确认整条设计链路的正确性。我在实际项目中吃过“查表反演尺寸后直接加工样品”的亏,加工回来测试发现主瓣方向偏了 3°——原因是查找表里插值引入了系统性偏差。从那以后,我无论如何都会先做一轮全波验证再交付加工。

我的习惯是专门写一个verify_phase_design.m脚本,输入是期望相位矩阵和反演出的尺寸矩阵,输出是远场方向图与主瓣指向误差,每次调整单元结构或者换频点时先跑这个脚本再决定是否继续。这套思路虽然朴素,但比反复跑全波仿真效率高得多。希望这篇笔记能帮你少走我走过的弯路,把反射阵单元相位计算这条链路真正变成你设计流程里的稳定一步。

本文还有配套的精品资源,点击获取

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询