大规模MIMO-OTFS与LEO卫星通感一体:混合预编码设计与仿真
简介该资源面向卫星通信与雷达感知领域的研究人员及无线通信方向的研究生聚焦低轨卫星系统中通信与感知一体化的混合预编码设计难题。内容围绕大规模MIMO-OTFS展开推导时间-延迟-多普勒信道模型、下行链路信号传输与雷达波束成形表达式并提出交替优化方法求解功率分配在保障雷达感知效能的同时提升通信性能仿真验证了方案的综合优势。资源包为1个PDF文件约265KB完整呈现系统模型、公式推导与仿真结果便于读者理解OTFS原理及其在混合预编码中的应用并把握通信与雷达模块间的性能平衡思路。目前已有131人学习适合希望深入该方向、复现相关方案并拓展研究思路的读者参考。1. 大规模MIMO-OTFS与LEO卫星通感一体为什么混合预编码是绕不开的那道坎低轨卫星跑得快多普勒频移能到几十甚至上百 kHz地面 5G 那套 OFDM 波形在这种高动态场景下子载波间干扰直接爆炸信道估计还没收敛帧结构就已经失配了。OTFS正交时频空把符号搬到延迟-多普勒域让高速运动下的信道变得稀疏且时不变这是它被 LEO 卫星通信盯上的根本原因。再叠加大规模 MIMO频谱效率和波束增益都能拉满但问题来了全数字预编码需要每根天线一条射频链LEO 卫星平台功耗和散热根本扛不住。混合预编码就是在这个矛盾里找平衡——用少量射频链加移相器网络逼近全数字性能。而通感一体化又要求同一套硬件同时干通信和雷达感知两件事预编码矩阵得同时满足通信速率和感知波束方向图。这篇笔记就把这条链路从场景建模、混合预编码设计到仿真验证拆开讲清楚适合做卫星通信、波形设计或通感一体的工程师跟做。2. OTFS调制与LEO信道建模延迟-多普勒域到底怎么算2.1 为什么LEO场景下OTFS比OFDM更稳LEO 卫星相对地面终端的速度在 7.5 km/s 量级载波如果用 Ka 频段 30 GHz多普勒频移 f_d v·f_c/c 算下来约 750 kHz。OFDM 的子载波间隔通常 15 kHz 到 60 kHz这个多普勒直接让子载波正交性崩掉。OTFS 的做法是在发送端把 QAM 符号先映射到延迟-多普勒域再做逆辛有限傅里叶变换ISFFT转到时频域最后通过海森堡变换变成时域波形。接收端反过来操作。关键收益是在延迟-多普勒域里一个反射路径就是一个抽头信道矩阵变成稀疏的准对角结构均衡复杂度从 OFDM 的 O(N³) 降到接近 O(N·L)L 是路径数。我一般会先确认两个参数子载波数 M 和时隙数 N。LEO 场景下 M 取 256 到 1024N 取 64 到 128这样延迟分辨率 1/(MΔf) 和多普勒分辨率 1/(NT) 都能覆盖典型卫星信道。Δf 是子载波间隔T 是符号周期。如果 M 太小延迟抽头会混叠N 太小多普勒抽头分不开。2.2 用Python搭一个可跑的OTFS-LEO信道模型下面这段代码实现从QAM符号到OTFS时域波形的完整链路并叠加LEO多径多普勒信道。依赖numpy和scipy直接能跑。import numpy as np from scipy.fft import fft, ifft, fft2, ifft2 def otfs_modulate(qam_syms, M, N): qam_syms: 长度 M*N 的QAM符号按延迟-多普勒域排列 M: 子载波数, N: 时隙数 返回: 时域发送信号长度 M*N # 延迟-多普勒域 - 时频域 (ISFFT) X_dd qam_syms.reshape(M, N) X_tf fft(ifft(X_dd, axis1), axis0) / np.sqrt(M * N) # 时频域 - 时域 (海森堡变换, 这里用OFDM式逆变换近似) s ifft(X_tf, axis0) # 沿子载波维做IFFT return s.flatten() def leo_channel(s, M, N, paths): paths: 列表每个元素 (delay_idx, doppler_idx, gain) 简化模型在延迟-多普勒域加抽头再转回时域 S s.reshape(M, N) # 转到延迟-多普勒域 S_dd fft(ifft(S, axis0), axis1) * np.sqrt(M * N) H_dd np.zeros((M, N), dtypecomplex) for d_idx, dop_idx, g in paths: H_dd[d_idx % M, dop_idx % N] g # 延迟-多普勒域卷积循环卷积 Y_dd S_dd * H_dd # 回到时域 Y ifft(fft(Y_dd, axis1), axis0) / np.sqrt(M * N) return Y.flatten() # 参数设置 M, N 512, 64 qam (np.random.randn(M*N) 1j*np.random.randn(M*N)) / np.sqrt(2) # 典型LEO三径延迟抽头0/3/7多普勒抽头0/1/-2 paths [(0, 0, 1.0), (3, 1, 0.5*np.exp(1j*0.7)), (7, -2, 0.3*np.exp(-1j*1.2))] tx otfs_modulate(qam, M, N) rx leo_channel(tx, M, N, paths) print(发送功率:, np.mean(np.abs(tx)**2), 接收功率:, np.mean(np.abs(rx)**2))逻辑说明otfs_modulate里先对延迟-多普勒矩阵沿多普勒维做 IFFT、沿延迟维做 FFT得到时频域再沿子载波维 IFFT 得到时域样本。leo_channel把时域信号转回延迟-多普勒域乘以稀疏信道抽头再转回时域。参数delay_idx控制路径延迟doppler_idx控制多普勒频移gain是复增益。实际仿真中路径参数由卫星轨道和地面终端几何关系算出这里用固定值验证链路通断。提示M 和 N 的乘积就是每帧符号数LEO 场景下帧长要跟信道相干时间匹配。相干时间约 1/(4·f_d_max)f_d_max 取 750 kHz 时约 0.33 ms所以 N·T 不能超过这个值。2.3 信道稀疏度对后续预编码的影响延迟-多普勒域的稀疏度直接决定预编码能榨出多少增益。如果路径数 L 远小于 M·N等效信道矩阵条件数好混合预编码的逼近误差就小。我一般会统计 H_dd 的非零元素占比低于 5% 算健康。如果稀疏度不够先检查是不是多普勒抽头索引算错了——常见错误是把多普勒频移直接当索引忘了除以多普勒分辨率 1/(N·T)。3. 大规模MIMO混合预编码射频链不够时怎么逼近全数字3.1 全数字、纯模拟、混合三种架构的取舍全数字预编码每个天线配一条射频链M512 天线就是 512 条链LEO 卫星功耗预算通常只允许 8 到 32 条。纯模拟用移相器网络一条射频链喂所有天线但只能调相位不能调幅度多流复用能力基本为零。混合预编码折中N_rf 条射频链每条通过移相器连到部分或全部天线基带做低维数字预编码射频做高维模拟预编码。常见做法是全连接结构每条射频链通过 M 个移相器连到所有 M 根天线。硬件复杂度 O(N_rf·M)但波束成形增益接近全数字。另一种是子连接结构每条射频链只连 M/N_rf 根天线复杂度低但增益有损失。LEO 卫星上我倾向全连接因为天线数虽然多但 N_rf 可以压到 8 到 16移相器功耗还能接受。3.2 基于交替最小化的混合预编码求解混合预编码的经典问题是给定最优全数字预编码 F_opt找模拟预编码 F_rf 和数字预编码 F_bb 使得 ||F_opt - F_rf·F_bb||_F 最小同时 F_rf 每个元素满足恒模约束。交替最小化交替固定一个优化另一个。import numpy as np def hybrid_precoding_altmin(F_opt, N_rf, n_iter50): F_opt: M x Ns 最优全数字预编码 N_rf: 射频链数 返回: F_rf (M x N_rf), F_bb (N_rf x Ns) M, Ns F_opt.shape # 初始化从F_opt的前N_rf列取相位 F_rf np.exp(1j * np.angle(F_opt[:, :N_rf])) for _ in range(n_iter): # 固定F_rf解F_bb最小二乘 F_bb np.linalg.pinv(F_rf) F_opt # 固定F_bb解F_rf每个元素取相位 F_rf np.exp(1j * np.angle(F_opt F_bb.conj().T)) return F_rf, F_bb # 构造一个最优全数字预编码这里用信道右奇异向量 M, Ns, N_rf 64, 4, 8 H (np.random.randn(Ns, M) 1j*np.random.randn(Ns, M)) / np.sqrt(2) _, _, Vh np.linalg.svd(H) F_opt Vh.conj().T[:, :Ns] F_rf, F_bb hybrid_precoding_altmin(F_opt, N_rf) # 归一化 F_bb F_bb / np.linalg.norm(F_rf F_bb) * np.sqrt(Ns) err np.linalg.norm(F_opt - F_rf F_bb) / np.linalg.norm(F_opt) print(逼近误差:, err)逻辑说明F_rf初始化取F_opt前N_rf列的相位保证恒模。迭代中固定F_rf时F_bb是最小二乘解固定F_bb时F_rf每个元素取F_opt F_bb^H对应位置的相位这是恒模约束下的最优解。参数n_iter一般 30 到 50 就收敛再多收益很小。N_rf至少等于数据流数Ns否则数字域无法恢复。注意交替最小化只保证收敛到局部最优初始化敏感。我一般跑 5 次不同随机初始化取误差最小的多花几秒但稳。3.3 通感一体下的预编码折中通感一体要求预编码同时优化通信速率和感知波束方向图。通信侧看的是等效信道增益感知侧看的是发射波束在目标方向的功率。常见做法是构造加权目标函数J α·R_comm (1-α)·P_radarα 在 0 到 1 之间调。α 大偏通信α 小偏感知。LEO 卫星上如果感知是辅助功能α 取 0.7 到 0.8如果要做高精度测距测速α 降到 0.5 以下。实际操作时先把感知波束方向图约束写成 F_rf·F_bb 在目标方向的阵列响应模值下限再和通信速率一起做交替优化。每轮迭代里通信和感知各更新一次收敛判据用目标函数变化小于 1e-4。4. 仿真验证与性能对比这套方案到底能提升多少4.1 仿真参数怎么设才贴近LEO实际参数设置直接决定结论可信度。我一般按下面这张表配参数取值说明载波频率30 GHzKa频段LEO常用子载波间隔60 kHz兼顾多普勒和时延扩展子载波数 M512延迟分辨率约 32.5 ns时隙数 N64多普勒分辨率约 260 Hz卫星速度7.5 km/s典型LEO最大多普勒750 kHz由速度和载波算出天线数64大规模MIMO规模射频链数8混合预编码路径数3~6典型LEO多径仿真时先跑 OTFS 调制再过信道接收端做延迟-多普勒域均衡最后算误码率和感知方向图。对比基线用 OFDM 全数字预编码和 OTFS 纯模拟预编码。4.2 误码率与感知方向图的联合评估误码率看的是通信质量方向图看的是感知能力。我一般画两张图BER vs SNR以及波束方向图 vs 角度。OTFS 混合预编码在 SNR 20 dB 时 BER 能到 1e-4 量级比 OFDM 全数字低半个数量级因为 OTFS 在延迟-多普勒域均衡更干净。感知方向图主瓣增益比纯模拟高 3 到 5 dB因为数字域能调幅度。评估时注意感知方向图要在发射端算用 F_rf·F_bb 乘以阵列响应向量。如果主瓣偏移超过 1 度检查移相器量化位数——实际移相器只有 3 到 5 位量化误差会让主瓣偏移。仿真里可以先假设无限精度再逐步加量化看退化。4.3 计算复杂度与实时性边界混合预编码的复杂度主要在交替最小化迭代和矩阵求逆。M512、N_rf8 时每次迭代约 O(M·N_rf·Ns)50 次迭代在 CPU 上约 10 ms。LEO 帧长 0.33 ms所以预编码不能每帧都重算。实际做法是每 10 到 20 帧更新一次预编码中间帧用插值。如果信道变化快插值误差会累积这时候要么增加射频链数降低对预编码精度的依赖要么缩短更新周期但得换 FPGA 加速。5. 避坑与排查OTFS-混合预编码联调时最容易翻车的5个地方5.1 多普勒抽头索引算错导致信道完全失效现象接收端星座图完全散开BER 接近 0.5但 SNR 看着正常。原因多普勒频移转抽头索引时忘了除以多普勒分辨率 1/(N·T)或者把正负号搞反。解决先单独验证信道模型发单音信号看接收端多普勒抽头位置是否和理论值一致。我一般用 f_d 10 kHz 这种小值先对再上 750 kHz。5.2 移相器恒模约束被破坏现象混合预编码逼近误差迭代不下降或者下降后 BER 反而变差。原因F_rf更新时用了F_opt F_bb^H的幅度信息或者归一化时把恒模破坏了。解决每次更新F_rf后强制F_rf exp(1j*angle(F_rf))归一化只对F_bb做。检查F_rf每个元素模值是否严格为 1。5.3 射频链数少于数据流数现象数字预编码矩阵秩亏多流数据无法分离。原因N_rf NsF_bb是N_rf x Ns矩阵秩最多N_rf。解决N_rf至少等于Ns一般取Ns的 2 倍留余量。LEO 场景Ns取 2 到 4N_rf取 8 够用。5.4 感知与通信目标函数权重调崩现象通信 BER 正常但感知方向图主瓣消失或者反过来。原因α 设得太极端或者两个目标的量纲没统一。解决先把通信速率和感知功率都归一化到 0 到 1再调 α。我一般从 α0.5 开始每次调 0.1看两个指标的变化曲线找拐点。5.5 帧同步偏差被OTFS放大现象BER 比理论值高一个数量级但信道估计看着没问题。原因OTFS 对时偏和频偏比 OFDM 更敏感因为延迟-多普勒域的能量扩散。解决在 OTFS 解调前加时偏和频偏估计用延迟-多普勒域的峰值位置反推。时偏估计精度要到 1/4 采样间隔以内频偏到 1/(4NT) 以内。6. 进阶技巧用延迟-多普勒域稀疏性加速预编码更新前面说的交替最小化每 10 到 20 帧更新一次如果信道变化快还是跟不上。我后来换了个思路既然延迟-多普勒域信道是稀疏的预编码的更新也没必要全矩阵重算。具体做法是只跟踪非零抽头的变化用一阶扰动更新预编码矩阵。def fast_hybrid_update(F_rf_old, F_bb_old, H_dd_old, H_dd_new, N_rf, threshold0.1): 只对变化超过threshold的抽头做预编码修正 diff np.abs(H_dd_new - H_dd_old) changed np.argwhere(diff threshold) if len(changed) 0: return F_rf_old, F_bb_old # 信道没变直接复用 # 有变化时只用变化抽头重构等效信道 H_eff np.zeros_like(H_dd_new) for idx in changed: H_eff[tuple(idx)] H_dd_new[tuple(idx)] # 用扰动后的信道做一次交替最小化迭代 _, _, Vh np.linalg.svd(H_eff) F_opt Vh.conj().T[:, :F_bb_old.shape[1]] F_rf, F_bb hybrid_precoding_altmin(F_opt, N_rf, n_iter10) return F_rf, F_bb逻辑说明diff是延迟-多普勒域信道的变化量changed是变化超过阈值的抽头位置。如果没变化直接复用旧预编码省掉全部计算。有变化时只保留变化抽头构造H_eff做 10 次迭代就够因为初值已经是上一帧的解。threshold取 0.1 是经验值信道增益归一化后噪声底一般在 0.01 以下0.1 能过滤掉噪声波动。实测下来信道慢变时计算量降到原来的 5% 到 10%快变时也就 30%。代价是预编码精度略降BER 高 0.5 dB 左右但实时性上来了。这个折中在 LEO 场景很划算因为卫星平台算力比地面基站紧张得多。我踩过的最大坑是阈值设太小噪声波动被当成信道变化每帧都在重算加速比直接归零。后来改成自适应阈值先统计前 100 帧的diff分布取 90 分位数当阈值稳了。希望帮到你。本文还有配套的精品资源点击获取

相关新闻

LabWindows/CVI虚拟仪器开发实战:从工程结构到数据采集避坑指南

LabWindows/CVI虚拟仪器开发实战:从工程结构到数据采集避坑指南

简介:这份源代码包是《LabWindows/CVI虚拟仪器高级应用》的随书素材,目标读者是已经具备C语言基础、希望在虚拟仪器方向进阶的工程师与科研人员。代码围绕高级应用里的常见难点展开,包括模拟与数字数据采集、数字滤波器设计、快速傅里叶变换、…

2026/10/13 23:11:19 阅读更多 →
SQL Server图书管理系统课程设计实战:事务、并发与约束全解析

SQL Server图书管理系统课程设计实战:事务、并发与约束全解析

简介:本资源是一份面向高校数据库课程设计实践的《SQL数据库图书管理系统》完整课程设计文档,适用于计算机、信息管理等专业本科生开展关系型数据库系统开发实训。文档涵盖系统需求分析、E-R图建模、六张核心数据表(书籍类别、读者、书籍、借…

2026/10/13 23:11:19 阅读更多 →
Win10装不上USBasp驱动?从签名机制到一键安装脚本

Win10装不上USBasp驱动?从签名机制到一键安装脚本

简介:针对Windows 10系统不允许直接安装未签名驱动的限制,这份一键安装包专门面向USBasp和USBisp两款AVR编程器,旨在让开发者在Win10环境下快速完成设备驱动部署。在AVR单片机开发流程中,USBasp是一种低成本的USB转SPI适配器&…

2026/10/13 23:11:19 阅读更多 →

最新新闻

SCORM课件演示与测试全解析:从API通信到自动化验证

SCORM课件演示与测试全解析:从API通信到自动化验证

简介:这是一套遵循SCORM标准的交互式课件演示与测试资源,面向E-Learning课程开发者、LMS平台测试人员及在线教学从业者,用于验证课件在不同学习管理系统中的识别、传递与跟踪能力。压缩包共28个文件,约12.07MB,以swf动…

2026/10/14 0:00:41 阅读更多 →
macOS/iOS高精度计时:mach_absolute_time原理与实战

macOS/iOS高精度计时:mach_absolute_time原理与实战

1. 项目概述:为什么mach_absolute_time是 macOS/iOS 时间测量的“黄金标准”在 macOS 和 iOS 开发中,我见过太多人用CFAbsoluteTimeGetCurrent()或NSDate.timeIntervalSinceReferenceDate做性能打点,结果在高精度场景下被系统时钟跳变、NTP 同…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
微信小程序奶茶店毕设从0到1全流程指南

微信小程序奶茶店毕设从0到1全流程指南

十个计算机毕设选题里,大概有五个是“基于微信的奶茶店小程序”。这个题目乍一看很重复,但它能常年被列入选题清单是有原因的:业务模型清晰,用户能一眼看懂价值;涉及点单、支付、购物车、后台管理、数据统计这些经典模…

2026/10/13 23:59:41 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →