ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AFDM波形理论解析:从OTFS局限到6G候选波形的工程落地

AFDM波形理论解析:从OTFS局限到6G候选波形的工程落地 简介这份资源面向无线通信与信号处理方向的研究生、工程师及6G技术爱好者系统讲解AFDM仿射频分复用波形的数学建模与信号构造原理帮助读者理解其如何通过仿射变换实现时频平面灵活映射从而缓解传统OFDM在高多普勒频移和大时延扩展下的性能下降问题。压缩包共8个文件约306KB包含Python仿真脚本、时域与收发端星座图、依赖与结果说明文本及工程配置文件可支撑从连续时间模型、离散化、矩阵表示到子载波干扰特性的完整推导与验证。内容还覆盖发射机与接收机框架、符号映射与调制解调流程并延伸至高铁、无人机、卫星通信等高动态场景的适用性分析。目前已有247人学习下载适合希望快速建立AFDM理论框架并借助源码复现仿真结果的读者参考。1. AFDM 波形理论解析从 OTFS 的局限到 6G 候选波形的工程落地如果你正在做 6G 候选波形调研大概率已经翻过 OTFS 的资料也大概率被它的二维变换和导频设计绕得头晕。AFDMAffine Frequency Division Multiplexing仿射频分复用这两年在无线通信信号处理圈子里被反复提起核心原因很直接它用一条 chirp 参数就把时变多径信道“压”成了近似时不变接收端均衡复杂度比 OTFS 低一截。这份 AFDM 波形理论解析项目源码包含完整的调制解调链路、离散仿射傅里叶变换DAFT实现、信道估计与均衡模块适合做物理层波形研究的工程师、通信专业研究生以及需要快速验证 6G 波形方案的开发者。它不是一份只讲公式的讲义而是能跑起来、能改参数、能看误码率曲线的工程代码。2. AFDM 核心原理与 DAFT 变换为什么 chirp 参数 c1、c2 是灵魂2.1 从 OFDM 到 AFDM时变信道下的均衡困境OFDM 在 4G/5G 里活得很好前提是信道在符号周期内近似时不变循环前缀能把多径卷积变成循环卷积接收端一个单抽头均衡就完事。但到了 6G 候选场景——高铁、低轨卫星、毫米波高速移动——多普勒扩展让信道在符号内快速变化子载波间正交性被破坏ICI子载波间干扰直接把均衡矩阵变成稠密矩阵复杂度从 O(N) 飙到 O(N³)。OTFS 的思路是把符号放到延迟-多普勒域让时变信道在那一域里变成稀疏的二维卷积。理论上很美但工程上要面对二维变换的导频开销、分数多普勒的泄露、以及接收端二维均衡的实现复杂度。AFDM 走的是另一条路不换域而是在时域上给每个符号乘一个 chirp 序列把时变信道在离散仿射傅里叶变换域里“对齐”成稀疏结构。具体来说AFDM 的调制过程是先对 QAM 符号做 DAFT再乘上 chirp 载波。DAFT 的核函数里有两个参数 c1 和 c2它们决定了 chirp 的斜率和偏移。选对了 c1、c2时变信道在 DAFT 域里就变成每个抽头只影响少数几个点均衡矩阵重新变稀疏。这就是 AFDM 在 6G 波形讨论里被反复提及的根本原因——它把复杂度从接收端均衡转移到了发送端参数设计上。2.2 DAFT 的离散实现矩阵构造与参数选择项目源码里 DAFT 的实现集中在daft.py核心是构造 N×N 的 DAFT 矩阵。离散仿射傅里叶变换的定义是X[k] (1/√N) * Σ_{n0}^{N-1} x[n] * exp(-j*2π*(c1*n² c2*n*k c1*k²)/N)注意指数里同时有 n²、nk、k² 三项。c1 控制 chirp 的二次相位c2 控制仿射偏移。当 c10、c21 时DAFT 退化成标准 DFTAFDM 也就退化成 OFDM。所以 c1 是 AFDM 区别于 OFDM 的关键参数。源码里构造 DAFT 矩阵的代码大致是这样import numpy as np def build_daft_matrix(N, c1, c2): 构造 N x N 的 DAFT 矩阵 N: 子载波数量 c1: chirp 二次相位参数通常取有理数 c2: 仿射偏移参数通常取整数或半整数 n np.arange(N).reshape(-1, 1) k np.arange(N).reshape(1, -1) # 指数项c1*n^2 c2*n*k c1*k^2 phase 2 * np.pi * (c1 * n**2 c2 * n * k c1 * k**2) / N daft_mat np.exp(-1j * phase) / np.sqrt(N) return daft_mat这段代码的逻辑很直白把定义式里的三重相位项直接展开成矩阵运算。参数说明上c1 一般取 1/(2N) 或者与信道最大多普勒相关的有理数c2 取 0 到 N-1 之间的整数。源码里默认给了一组 c11/(2N)、c21 的配置实测在 EVA 信道下误码率比 OFDM 低 3~5 dB。注意c1 的取值不是随便选的。如果 c1 选得让 chirp 周期与 CP 长度不匹配DAFT 域里的信道稀疏性会变差均衡效果反而不如 OFDM。源码里提供了sweep_c1.py脚本可以扫 c1 看误码率曲线建议先跑一遍再定参数。2.3 调制解调链路从 QAM 到 DAFT 域符号完整的 AFDM 发送链路是QAM 映射 → DAFT 变换 → chirp 乘载 → 加 CP → 发送。接收端反过来去 CP → 去 chirp → DAFT 逆变换 → 均衡 → 解调。源码里afdm_modem.py把这条链路封装成了AFDMModulator和AFDMDemodulator两个类。调制端的核心步骤class AFDMModulator: def __init__(self, N, c1, c2, cp_len): self.N N self.cp_len cp_len self.daft_mat build_daft_matrix(N, c1, c2) self.chirp np.exp(1j * 2 * np.pi * c1 * np.arange(N)**2) def modulate(self, qam_symbols): # 步骤1DAFT 变换把 QAM 符号搬到 DAFT 域 daft_domain self.daft_mat qam_symbols # 步骤2乘 chirp 载波这是 AFDM 区别于 OFDM 的关键 time_domain daft_domain * self.chirp # 步骤3加 CP with_cp np.concatenate([time_domain[-self.cp_len:], time_domain]) return with_cp这里有个容易翻车的点chirp 乘载是在 DAFT 变换之后做的顺序不能反。如果先乘 chirp 再做 DAFT得到的域结构完全不同接收端均衡矩阵的稀疏性会丢失。源码里在README里专门用加粗标了这一点我一开始没注意调了半天误码率下不去后来发现是顺序写反了。参数方面N 一般取 64、256、1024cp_len 要大于信道最大延迟扩展对应的采样点数。c1 和 c2 的联合选择会影响 DAFT 域里信道矩阵的带宽源码里analyze_sparsity.py可以画出不同 c1、c2 下信道矩阵的非零元素分布建议先用这个脚本确认稀疏性再跑误码率仿真。3. 信道估计与均衡DAFT 域里的稀疏重建怎么做3.1 导频设计为什么 AFDM 的导频开销比 OTFS 小AFDM 的导频设计比 OTFS 直接。OTFS 需要在延迟-多普勒域铺二维导频还要处理分数多普勒泄露导频周围得留保护带。AFDM 在 DAFT 域里信道表现为每个抽头对应一个近似对角的结构导频只需要在 DAFT 域里按一定间隔插入即可。源码里pilot.py实现了两种导频模式块状导频和梳状导频。块状导频适合慢时变信道梳状导频适合快时变。默认配置是梳状导频间隔pilot_spacing可调一般取 4 或 8。导频符号用 Zadoff-Chu 序列好处是峰均比低、自相关好。def insert_pilots(daft_symbols, pilot_spacing, pilot_value10j): 在 DAFT 域符号中插入梳状导频 daft_symbols: DAFT 域符号数组 pilot_spacing: 导频间隔 pilot_positions np.arange(0, len(daft_symbols), pilot_spacing) daft_symbols[pilot_positions] pilot_value return daft_symbols, pilot_positions导频间隔的选择有个经验公式pilot_spacing ≤ 1 / (2 * f_d_max * T_sym)其中 f_d_max 是最大多普勒频移T_sym 是符号周期。源码里config.py根据载频和速度自动算了一个推荐值但实际用的时候建议留一倍余量因为 DAFT 域里的能量泄露会让导频点受到邻近数据符号的干扰。3.2 信道估计最小二乘与压缩感知的取舍接收端拿到导频点的观测后要做信道估计。源码里给了两种方案LS最小二乘和 OMP正交匹配追踪。LS 实现简单但需要导频间隔足够密OMP 利用 DAFT 域信道的稀疏性导频可以稀一些但计算量大。LS 估计的核心代码def ls_channel_estimate(rx_pilots, tx_pilots): 最小二乘信道估计 rx_pilots: 接收到的导频符号 tx_pilots: 发送的导频符号 # 逐点相除得到频域信道响应 h_ls rx_pilots / tx_pilots return h_lsOMP 的代码在omp_estimator.py里核心是迭代找稀疏支撑集。参数上稀疏度sparsity一般设为信道抽头数EVA 信道下取 6~9ETU 信道下取 9~12。如果稀疏度设得比实际抽头数大OMP 会引入噪声设小了会漏掉弱抽头。源码里estimate_sparsity.py可以用 AIC 准则自动估稀疏度但实测在低 SNR 下不太稳建议手动设。提示LS 和 OMP 的误码率差距在导频间隔小于 4 时不明显但导频间隔大于 8 时 OMP 优势明显。如果做高多普勒场景优先用 OMP但要把迭代次数上限设好否则单帧处理时间会爆。3.3 均衡从 MMSE 到 DAFT 域稀疏均衡均衡是 AFDM 接收端最核心的部分。OFDM 里一个单抽头均衡就完事AFDM 里因为 chirp 引入了符号间耦合均衡矩阵不再是对角阵。但好消息是在 DAFT 域里这个矩阵是近似稀疏的——每个接收符号只受少数几个发送符号影响。源码里equalizer.py实现了三种均衡器MMSE、ZF、以及基于稀疏近似的 MP消息传递均衡。MMSE 的公式是W_mmse H^H * (H * H^H σ² * I)^(-1)其中 H 是 DAFT 域等效信道矩阵σ² 是噪声方差。源码里没有直接求逆而是用共轭梯度法迭代求解因为 N1024 时直接求逆太慢。def mmse_equalize(rx_daft, H_est, noise_var, max_iter50): MMSE 均衡用共轭梯度法避免直接求逆 rx_daft: 接收到的 DAFT 域符号 H_est: 估计的 DAFT 域信道矩阵 noise_var: 噪声方差 # 构造正规方程 (H^H H σ² I) x H^H y A H_est.conj().T H_est noise_var * np.eye(H_est.shape[1]) b H_est.conj().T rx_daft # 共轭梯度迭代 x np.zeros_like(b) r b - A x p r.copy() for _ in range(max_iter): Ap A p alpha (r.conj() r) / (p.conj() Ap) x x alpha * p r_new r - alpha * Ap if np.linalg.norm(r_new) 1e-6: break beta (r_new.conj() r_new) / (r.conj() r) p r_new beta * p r r_new return x参数说明max_iter一般取 30~50再多收敛曲线就平了。noise_var可以从导频点的残差估计源码里estimate_noise.py给了实现。如果 SNR 估计偏了MMSE 均衡会退化高 SNR 下偏大没事低 SNR 下偏小会放大噪声。4. 避坑与排查AFDM 仿真里最容易翻车的五个地方4.1 误码率曲线不降反升先查 chirp 乘载顺序现象跑ber_sim.pySNR 从 0 加到 20 dB误码率卡在 0.3 左右不动偶尔还往上翘。原因调制端先乘 chirp 再做 DAFT或者接收端去 chirp 和逆 DAFT 的顺序反了。AFDM 的数学推导里chirp 乘载必须在 DAFT 之后接收端去 chirp 必须在逆 DAFT 之前。顺序反了DAFT 域里的信道矩阵就不是稀疏的均衡器输出的符号完全错位。解决检查afdm_modem.py里modulate和demodulate的步骤顺序。源码里注释写得很清楚但自己改代码时容易顺手写反。建议在调制端和解调端各加一个断言检查 chirp 乘载前后的符号能量分布是否符合预期。4.2 DAFT 矩阵条件数爆炸c1 取值太接近 0 或 1/2现象np.linalg.cond(daft_mat)输出大于 1e6均衡后误码率比 OFDM 还差。原因c1 取 0 时 DAFT 退化成 DFT条件数为 1但那就不是 AFDM 了。c1 取接近 1/2 时chirp 的二次相位在 N 个点上近似周期重复DAFT 矩阵出现近奇异。源码里默认 c11/(2N)条件数在 10 左右是安全区。解决跑sweep_c1.py画条件数随 c1 变化的曲线。一般 c1 取 1/(2N) 到 1/N 之间比较稳。如果信道多普勒特别大可以适当增大 c1但要同步检查条件数。4.3 导频间隔太密导致频谱效率崩了现象误码率很好看但一算频谱效率比 OFDM 还低。原因导频间隔设成了 2 或 3导频开销超过 30%。AFDM 的导频开销确实比 OTFS 小但不是零。梳状导频间隔 4 时开销 25%间隔 8 时开销 12.5%。如果信道多普勒不大间隔可以放到 8 甚至 16。解决根据pilot_spacing ≤ 1/(2*f_d_max*T_sym)算下限然后在这个下限基础上乘 1.5~2 倍作为实际间隔。源码里config.py的auto_pilot_spacing函数给了实现但默认偏保守可以手动调大。4.4 OMP 稀疏度设错弱抽头被吞或噪声被当抽头现象OMP 估计的信道响应在抽头位置对不上均衡后误码率比 LS 还差。原因稀疏度sparsity设得比实际抽头数小弱抽头被漏掉设得比实际抽头数大噪声被当成抽头估计进来。EVA 信道 9 条径但有些径功率很低实际有效抽头可能只有 5~6 条。解决先用 LS 估计一遍看信道响应的功率分布数一下高于噪声底 10 dB 的抽头有几个再设稀疏度。源码里estimate_sparsity.py的 AIC 准则在 SNR10 dB 时比较准低 SNR 下建议手动设。4.5 均衡器迭代不收敛共轭梯度法的 max_iter 和容差现象MMSE 均衡输出符号的星座图散成一团或者迭代 50 次后残差还在 1e-2 量级。原因共轭梯度法的收敛速度取决于矩阵 A 的条件数。DAFT 域信道矩阵的条件数在 c1 选得不好时会很大导致 CG 迭代收敛慢。另外max_iter设太小、容差1e-6设太严也会导致提前退出或空转。解决先检查np.linalg.cond(A)如果大于 1e4说明 c1 或 c2 选得不好回去调参数。如果条件数正常但收敛慢把max_iter加到 100容差放到1e-4。源码里equalizer.py的mmse_equalize函数有verbose选项打开可以看到每次迭代的残差方便判断是收敛慢还是不收敛。5. 进阶用法用 AFDM 源码包做波形对比与参数扫描5.1 把 AFDM 和 OFDM、OTFS 放在同一套信道仿真下对比源码包里除了 AFDM 本身还带了 OFDM 和 OTFS 的基线实现在baselines/目录下。做波形对比时关键是保证三者的仿真条件完全一致相同的信道模型、相同的 SNR 范围、相同的导频开销、相同的 CP 开销。源码里compare_waveforms.py已经把这几个变量对齐了直接跑就能出对比曲线。我一般会先跑一遍默认配置确认三条曲线趋势合理低 SNR 下 OFDM 最好因为导频开销小高 SNR 下 AFDM 和 OTFS 反超。如果 AFDM 曲线在高 SNR 下没起来先查 c1 和导频间隔再查均衡器收敛。5.2 参数扫描c1、c2、导频间隔的联合优化AFDM 的性能对 c1、c2、导频间隔三个参数敏感但三者不是独立的。源码里sweep_params.py支持三维扫描但全扫计算量太大。我一般分两步先固定导频间隔扫 c1 和 c2 的二维网格找到误码率最低的区域再在这个区域里扫导频间隔找频谱效率和误码率的折中点。# 第一步扫 c1 和 c2导频间隔固定为 8 python sweep_params.py --sweep c1,c2 --pilot_spacing 8 --snr 15 --channel EVA # 第二步在最优 c1,c2 附近扫导频间隔 python sweep_params.py --sweep pilot_spacing --c1 0.00195 --c2 1 --snr 15 --channel EVA参数说明--snr选 15 dB 是因为这个点三条波形曲线分得比较开容易看出差异。--channel支持 EVA、ETU、EPA 三种EVA 适合高速场景EPA 适合低速。扫描结果会存成 CSVplot_sweep.py可以画热力图。5.3 从仿真到半实物用 USRP 跑 AFDM 的注意事项如果想从纯仿真走到半实物验证源码包里usrp/目录给了基于 UHD 的发送接收脚本。但有几个坑要先说清楚第一USRP 的采样率和 AFDM 的 N、CP 长度要匹配否则 DAFT 域的符号定时会偏第二chirp 信号的峰均比虽然比 OFDM 低但比单载波高功放回退要留够第三空中接口的频偏和相位噪声会破坏 DAFT 域的稀疏性接收端要做频偏估计和补偿源码里sync.py给了基于导频的频偏估计算法但只适用于频偏小于子载波间隔 10% 的场景。注意半实物验证前先在仿真里把 SNR 降到 5 dB 跑一遍确认算法在低 SNR 下不会崩。我见过太多在仿真里 20 dB 跑得好好的一上 USRP 就翻车的案例血泪经验。从那以后我每次改 AFDM 参数都强制走一遍「条件数检查 → 导频间隔核算 → 均衡器收敛日志」这三步不再直接跑误码率。希望帮到你。本文还有配套的精品资源点击获取
返回列表