去年年底我在跑一版高铁路测数据的时候,发现一个特别典型的现场:列车速度一上300km/h,传统OFDM系统的误码率曲线就开始肉眼可见地抬起来,解调星座图上的点也不再聚拢,旋转、拖尾、糊成一片。当时组里在论证新一代波形方案,OTFS和ODDM这两个词被反复提起。OTFS的全称是正交时频空间调制,ODDM是正交时延多普勒复用,这俩都不是什么新概念,但在面向高速移动通信的6G、车联网、低轨卫星场景里,它们几乎成了绕不开的备选方案。
这篇内容不是什么标准文档复读,而是我自己从零开始啃OTFS和ODDM的学习笔记,加上后来用Python做链路仿真踩坑的实录。我会尽量把“为什么OFDM在高速场景会翻车”“OTFS到底改了什么”“ODDM和OTFS又差在哪”这些核心问题讲清楚,同时给出一套可以直接跑起来的教学级仿真骨架。适合正在看论文但被公式劝退、或者刚入通信物理层想找方向的读者。如果你已经对OFDM那套很熟,只是想快速理解DD域波形,那这篇应该能帮你省很多翻资料的时间。
1. 先从直觉上理解:为什么OFDM在高速场景会“翻车”
1.1 OFDM的老毛病:子载波正交性失效
OFDM之所以能抗多径,靠的是把宽带信道切成很多个窄带子载波,然后利用循环前缀把多径时延带来的符号间干扰转成每个子载波上的一个复乘系数。这个逻辑成立的前提是“每个子载波在符号周期内保持近似平坦衰落”。
一旦终端高速移动,事情就变了。你想象一辆高铁,时速350km/h,载频如果取2.4GHz,多普勒频移大概是700多Hz。这个数字和子载波间隔一比较就很尴尬:5G的常规子载波间隔是15kHz,700Hz相当于把每个子载波旁边的主瓣偏移了大约1/20个子载波宽度。听起来不大,但多普勒不再是单频,而是随散射路径连续分布,每条路径产生的频偏叠加在一起,子载波之间就会产生严重的载波间干扰。
循环前缀能救符号间干扰,但它救不了载波间干扰。因为ICI是频域上的泄漏,你加再长的CP也不会把泄漏重新收回去。OFDM接收机通常要做频域均衡,默认子载波之间的正交性仍然保持,一旦这个前提碎了,均衡器就会越算越乱,最终反映在高误码率上。
1.2 OTFS的思路转变:换一个“坐标系”看信道
OTFS的核心点子其实不复杂:物理信道是时变的,它会带来多径时延和时间选择性衰落。OFDM习惯把信号放在“时间-频率”这张网格上看,而OTFS把信息放在“延迟-多普勒”这张网格上看。
延迟就是回波到达的早晚,多普勒就是每个回波经历的频移。对绝大多数无线信道来说,可分辨的路径数量不多,而且每条路径的延迟和多普勒在几十毫秒内都变化很慢。换句话说,信道在DD域是稀疏的、近似时不变的。这就像你用相机拍一个动态场景,在像素域每一帧都在变,但如果你把视频转到某种变换域,运动目标就变成了少数几个聚焦点,处理起来自然简单。
OTFS做的事情就是把调制符号直接放到延迟-多普勒网格上,然后通过二维辛傅里叶变换(ISFFT)把它搬到时频域,再像OFDM那样调制发射。接收端做逆操作,拿到DD域的接收符号,这时候你会发现,时变多径信道对每个符号的干扰变成了一个相对稀疏的矩阵,检测器的压力小很多。
1.3 ODDM的出场:更轻量地实现DD域复用
ODDM的全称是正交时延-多普勒复用。你可以把它理解成OTFS家族中的一种“更硬件友好”的实现方式。OTFS在教科书里通常被描述为“DD域符号 + ISFFT + 时频域脉冲整形”,而ODDM绕开了时频域这个中间站,直接在DD域构造一组双正交的基函数,每个数据符号通过对应的基波发送。
这个区别带来的直接好处是:发射机不需要显式地做二维FFT那一大套操作,减少了调制过程的处理时延和部分实现开销。同时ODDM如果配合矩形窗和特定脉冲整形,峰均比会比典型的OTFS实现更温和,对功放的线性度要求也会友好一些。对高铁终端、低轨卫星这类功耗和实现复杂度敏感的节点来说,这一点很实在。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 从信号模型看ODDM与OTFS的“血缘关系”
2.1 先搞清楚延迟-多普勒域里的信道长什么样
假设一个时变信道,某个时刻t,存在P条路径,每条路径对应延迟τ_i和多普勒ν_i,那么接收信号可以写成多条衰减、时延、频移信号的叠加。虽然时域信道响应是随时间跳的,但把每个散射体映射到(τ_i, ν_i)平面上的一个点,就会得到一张非常稀疏的脉冲图。
举个例子,城市环境下典型能看到6到12条主要路径,每一条都有一个固定延迟和相对速度产生的频移。用DD域表示信道时,每条路径就是网格上的一个尖峰,尖峰周围会有少量拖尾,那是因为信道在观测窗口内并不是完全静止。这种“稀疏性”是OTFS检测算法的基石。你在做仿真时,如果用一个P=3的多径信道,加上每径不同的多普勒偏移,在DD域接收矩阵上看,能量就集中在少数几个索引上,比在时频域看漂亮得多。
2.2 OTFS的经典实现:ISFFT加Heisenberg变换
OTFS发射端流程可以拆成三步。第一步:把要发送的QPSK/QAM符号填进一个N×M的DD域矩阵Xdd,其中N对应多普勒维,M对应延迟维。第二步:用逆辛傅里叶变换(ISFFT)把Xdd变成时频域矩阵Xtf,这一步相当于在二维网格上做一次联合变换,把调制符号“打散”到整个时频平面上,从而获得全分集。第三步:对Xtf做Heisenberg变换,也就是把每一行的频域数据当成一个OFDM符号,经过IFFT和加循环前缀之后发射出去。
接收端是逆流程:先Wigner变换,也就是去掉CP并做FFT得到Ytf,再对Ytf做SFFT得到Ydd。最后在DD域做信道估计和符号检测。看到这里你应该能感觉到,OTFS并不是神秘得脱离OFDM的另一种东西,它更像是“前置了一个二维变换的OFDM”。
2.3 ODDM与OTFS的核心差别
ODDM的出发点是直接构造时域发射波形。把DD域符号矩阵Xdd通过逆Zak变换映射到时域,生成一个连续时间信号。Zak变换相当于在DD域和时域之间建立了一种直接联系,省掉了ISFFT和Heisenberg变换的显式拆分。学术界普遍认为ODDM是OTFS的一种广义实现特例,当OTFS选择理想脉冲整形时,两者在误码性能上等价,但ODDM的基函数构造更加直观,实现上也能降低部分计算量。
我整理了一个对比表格,方便你快速抓住差异:
| 维度 | OTFS(经典形式) | ODDM |
|---|---|---|
| 数据映射域 | 延迟-多普勒域 | 延迟-多普勒域 |
| 时频域显式转换 | 需要ISFFT/SFFT | 不需要,利用Zak变换直接生成时域波 |
| 脉冲整形 | 灵活,可选用矩形/升余弦等 | 常用矩形脉冲,双正交约束更直观 |
| 实现复杂度 | 中等,二维FFT加OFDM调制 | 略低,适合硬件流水线 |
| 峰均比 | 与脉冲整形相关,可能较高 | 通过脉冲设计可进一步抑制 |
| 兼容OFDM | 改动较大 | 部分结构可复用OFDM收发链路 |
如果你在论文里看到“OTFS与ODDM性能趋于一致”的结论,没必要惊讶。两者在DD域承载信息这个核心思想上是相通的,差别主要在于工程化路径。
3. 从零搭一个OTFS/ODDM仿真:参数与代码
3.1 仿真参数怎么定:从信道反推网格尺寸
刚开始学的时候,我犯过一个很容易犯的错:随便选了N和M,结果多普勒分辨率不够,DD域能量直接混叠。正确做法是先从信道特性反推参数。
先说延迟维M,它要能覆盖信道的最大时延扩展。假设系统带宽是B=1.92MHz,OFDM子载波间隔Δf=15kHz,子载波数Nc=128,采样间隔T_s≈1/B≈0.52μs。如果信道最大时延扩展τ_max=2μs,你大概需要覆盖4个采样点,所以M可以取8或16,留一点余量。
再说多普勒维N,它取决于最大多普勒频移f_d_max和符号时间T。一个OFDM符号时间T=1/Δf≈66.7μs。在DD域里,多普勒分辨率是1/(NT)。如果速度350km/h、载频2.4GHz,f_d≈777Hz,要让777Hz不出混叠,NT至少需要大于1/777≈1.29ms。N=128时,观测时间NT≈8.53ms,分辨率约117Hz,足够。实际仿真里我常用N=128,M=64,总符号数NM=8192,对QPSK来说一个帧能传16384比特,链路开销不大。
3.2 可运行的教学级发射接收骨架
下面这个Python骨架为了简洁,用二维FFT近似了OTFS的ISFFT/SFFT变换对,并复用了OFDM调制。它不包含信道编码和复杂检测,但能帮你直观理解信号流动过程。
python复制import numpy as np
# 参数
M = 64 # 延迟维(可理解为子载波数)
N = 128 # 多普勒维(可理解为OFDM符号数)
cp_len = 16 # 循环前缀长度
# 发射端
def otfs_tx(bits):
# QPSK调制:每2个比特映射为1个QPSK符号
symbols = 2 * (bits[0::2].astype(np.float32) - 0.5) \
+ 1j * 2 * (bits[1::2].astype(np.float32) - 0.5)
x_dd = symbols.reshape(N, M)
# 逆辛傅里叶变换:DD域 -> 时频域
# 先沿多普勒维做IDFT,再沿延迟维做DFT
x_tf = np.fft.ifft(x_dd, axis=0, norm='ortho')
x_tf = np.fft.fft(x_tf, axis=1, norm='ortho')
# OFDM调制:对每个时频块的行做IFFT,加上循环前缀
tx_time = np.fft.ifft(x_tf, axis=1, norm='ortho')
tx_cp = np.hstack([tx_time[:, -cp_len:], tx_time])
return tx_cp.flatten()
# 接收端
def otfs_rx(rx_time):
frames = rx_time.reshape(N, M + cp_len)
rx_time_cp_removed = frames[:, cp_len:]
# OFDM解调
y_tf = np.fft.fft(rx_time_cp_removed, axis=1, norm='ortho')
# SFFT:时频域 -> DD域
y_dd = np.fft.fft(y_tf, axis=0, norm='ortho')
y_dd = np.fft.ifft(y_dd, axis=1, norm='ortho')
return y_dd.flatten()
这段代码里,变换方向的正反不关键,关键是收发两端要保持对称。实际系统里还需要插入导频、做信道估计和均衡。你可以在x_dd矩阵里预留几个位置的导频符号,然后在接收端y_dd对应位置估计信道矩阵,再用最小均方误差或消息传递检测恢复数据。
3.3 加信道时最容易忽略的细节
把上面的发端信号送入信道时,很多人直接写一个多径衰落函数,逐样本叠加多普勒频移。这样做没错,但要注意采样率匹配。OTFS时域信号是连续OFDM符号串成的,如果你想在时域精确模拟多普勒,需要先上采样,或者用信号处理上的数值积分方法。否则频率偏移在离散采样点上的相位增量可能算错。
一个实用做法是:把每个OFDM符号看成一个整体,在第n个符号上给每条路径乘一个相位旋转exp(j2πν_i nT),同时按延迟τ_i落在不同采样点进行叠加。这相当于只在符号级建模多普勒,在采样级保持简单。虽然精度略低,但足以用来验证DD域检测算法。
4. 我在学习和仿真中踩过的坑
4.1 循环前缀不够:错把多径延迟当保护间隔
我最初按照OFDM的习惯,把循环前缀大小取成最大时延对应的采样点数,以为这样就没问题。但OTFS的帧是多符号联合处理的,延迟维上的覆盖范围M要能容纳所有路径延迟,如果M取得太小,即使CP够长,DD域上依然会发生延迟混叠,等于把不同路径的能量叠在同一个网格里,信道估计一塌糊涂。后来我把M从16改成64,卷积效果立刻正常了。这里的关键是:CP是保护符号间干扰的,M是承载延迟分辨能力的,两者不能互相替代。
4.2 多普勒分辨率没算够:DD域出现混叠
有一次我为了压缩帧长,把N设成32,结果误码率一直在0.1附近下不去。排查了半天,发现是归一化多普勒超出了多普勒域能表示的范围。N=32时,多普勒分辨率是1/(3266.7μs)≈468Hz,而高速信道的最大多普勒将近800Hz,已经超过奈奎斯特极限了,DD域发生折叠。这里教训是:N要满足最大多普勒频率小于1/(2NT)?严格说是小于1/(NT)的一半?在OFDM符号级观测下,多普勒频移最大不超过1/T才不会混叠到符号间;而DD域多普勒维度能覆盖的范围是±1/(2T)。对于N个符号,多普勒分辨率=1/(NT),可表示范围是±N/(2NT)=±1/(2T)。所以只要多普勒小于1/(2T)≈7.5kHz,N具体多少只影响分辨率,不影响是否混叠。我当时的真正问题其实是路径多普勒超出了1/(2T),N只是背锅侠。不过N太小会导致分辨率不够,多条路径的多普勒频率靠得太近而无法分辨,同样会让信道估计矩阵病态。所以N还是要留足。
4.3 忽略了窗函数和脉冲整形的影响
OTFS理想模型假设矩形脉冲,也就是时域信号连续、频域是sinc函数。实际仿真中如果直接截断,会产生频谱泄漏,DD域信道响应也会出现额外的“旁瓣”扩散。后来我在收发两端加入根升余弦窗函数,误码率进一步下降。这说明ODDM论文里反复强调“双正交脉冲设计”不是玄学,它直接影响检测矩阵的稀疏程度。
4.4 常见问题速查表
| 现象 | 可能原因 | 排查与解决 |
|---|---|---|
| DD域导频位置能量扩散 | 窗函数不合适、CP/帧边界错位 | 检查加窗处理,修正符号同步偏移 |
| 误码率平台极高 | 多普勒分辨率不足或多普勒混叠 | 增大N,检查最大多普勒 |
| 信道估计矩阵病态 | 路径延迟接近整数倍采样点 | 加大M,或用分数延迟插值 |
| 峰均比过高 | 未做脉冲整形或超帧结构连续发射 | 采用升余弦窗,或改用ODDM的矩形脉冲设计 |
| 接收端星座旋转 | 载波频偏未补偿 | 在DD域完成信道估计后做残余频偏校正 |
5. 高速场景之外的扩展思考
5.1 从高铁到低轨卫星:同一个“快”但更极端
低轨卫星相对地面终端的速度可以到7km/s以上,载频如果用Ka波段,多普勒频移能到几百kHz。OFDM在这种场景下几乎要完全重新设计子载波间隔,而OTFS/ODDM在DD域处理天然对极大多普勒更从容。这里有一个前提:你需要更密的DD域网格来支撑大动态范围的多普勒,N可能需要上千,导频开销和检测复杂度会上升。所以“OTFS一统高速场景”这个说法太绝对,实际还得看具体参数和硬件约束。
5.2 和感知一体化结合:DD域天生适合雷达
通感一体化是6G的一个热门方向,基站既要通信又要感知目标。雷达测量本质上就是在估计目标的延迟和多普勒,这和OTFS的DD域信道表示高度契合。一个很自然的方案是:利用OTFS导频域同时做数据解调的目标探测,雷达得到的目标点迹直接映射到DD域的散射点,省掉了传统雷达的二维FFT处理。我后续打算在这个方向上做一轮仿真,先解决波形的模糊函数设计问题。
5.3 后续学习路线建议
如果你刚开始学,建议按这个顺序推进:先吃透OFDM的数学模型,再理解时变信道对OFDM的影响,然后推导OTFS的ISFFT公式,之后再转ODDM的Zak变换会比较顺。论文方面,建议从Delay-Doppler domain的原始概念入手,再找OTFS和ODDM对比类文献。仿真方面,不要急着搭完整链路,先跑通AWGN下的收发端,再加单径多普勒,最后加多径和多普勒联合,每一步都确认DD域星座图变化,这样能避免最后一锅粥。
最后再分享一个调试小技巧:在DD域接收矩阵里可视化能量分布。当时我有一版信道模型写错了,多普勒符号方向反了,满屏星座图看不出来,但是打印出Ydd矩阵的幅度热力图后,异常路径的斜纹一眼就暴露了问题。做DD域波形调试,别总盯着误码率曲线,多看看域内的能量图,比什么都直观。
