别再死记硬背了!用Python+Matplotlib动态演示5G NR调度中的Slot与Mini-Slot
2026/4/18 10:47:15 网站建设 项目流程

用Python动态可视化5G NR调度:Slot与Mini-Slot的实战解析

在5G NR的学习过程中,帧结构和调度机制往往是让开发者最头疼的部分。那些抽象的时隙图、晦涩的协议文档,以及复杂的调度算法,常常让人望而却步。但如果我们换一种方式——用代码动态生成这些调度过程,一切就会变得直观起来。本文将带你用Python和Matplotlib,从零构建一个5G NR调度可视化工具,让Slot和Mini-Slot的调度过程"活"起来。

1. 环境准备与基础概念

在开始编码前,我们需要明确几个核心概念。5G NR的调度单位主要分为两种:Slot-basedNon-slot based(即Mini-Slot)。Slot是固定14个OFDM符号的时域单位,而Mini-Slot则更加灵活,支持2、4、7个符号的配置。这种灵活性使得5G能够更好地适应不同业务的需求,比如低时延的URLLC业务就更适合使用Mini-Slot。

首先安装必要的Python库:

pip install matplotlib numpy ipywidgets

我们将使用以下核心组件:

  • Matplotlib:用于绘制动态的帧结构图
  • NumPy:处理数值计算
  • IPyWidgets:创建交互式控件

提示:建议在Jupyter Notebook中运行本文代码,以获得最佳交互体验。

2. 构建TDD帧结构可视化

让我们从最基础的TDD帧结构开始。假设我们使用30kHz子载波间隔,上下行配比为1:4(即1个下行Slot后跟4个上行Slot)。首先定义Slot类型:

import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Rectangle from ipywidgets import interact, IntSlider # Slot类型定义 SLOT_DL = 0 # 纯下行 SLOT_UL = 1 # 纯上行 SLOT_FLEX = 2 # 灵活Slot

接下来,我们创建一个函数来绘制单个Slot的结构:

def draw_slot(ax, slot_type, slot_idx, num_symbols=14): colors = {'DL': '#1f77b4', 'UL': '#ff7f0e', 'GP': '#2ca02c', 'SRS': '#d62728'} if slot_type == SLOT_DL: for i in range(num_symbols): ax.add_patch(Rectangle((i, slot_idx), 1, 1, color=colors['DL'])) elif slot_type == SLOT_UL: for i in range(num_symbols): ax.add_patch(Rectangle((i, slot_idx), 1, 1, color=colors['UL'])) else: # 灵活Slot # 假设前3个符号下行,接着8个符号上行,最后3个GP/SRS ax.add_patch(Rectangle((0, slot_idx), 3, 1, color=colors['DL'])) ax.add_patch(Rectangle((3, slot_idx), 8, 1, color=colors['UL'])) ax.add_patch(Rectangle((11, slot_idx), 2, 1, color=colors['GP'])) ax.add_patch(Rectangle((13, slot_idx), 1, 1, color=colors['SRS'])) ax.set_xlim(0, num_symbols) ax.set_ylim(0, 5) ax.set_xticks(np.arange(num_symbols)) ax.set_yticks([]) ax.set_title(f'Slot {slot_idx + 1} Structure')

通过这个基础函数,我们可以轻松扩展出完整的帧结构可视化:

def visualize_frame_structure(): fig, ax = plt.subplots(figsize=(12, 4)) # 1:4 TDD配置:1个下行Slot + 4个上行Slot slot_types = [SLOT_DL, SLOT_UL, SLOT_UL, SLOT_UL, SLOT_UL] for i, slot_type in enumerate(slot_types): draw_slot(ax, slot_type, i) plt.tight_layout() plt.show() visualize_frame_structure()

3. 动态调度过程模拟

理解了静态帧结构后,我们来模拟动态调度过程。关键是要展示基站(gNB)如何根据UE反馈的CQI等信息进行调度决策。

首先定义CQI与MCS的对应关系:

CQI索引调制方式编码率频谱效率(bits/symbol)
1QPSK0.0760.152
2QPSK0.1170.234
............
964QAM0.6013.604
1064QAM0.7024.212

在代码中,我们可以这样实现CQI到MCS的映射:

cqi_to_mcs = { 1: {'modulation': 'QPSK', 'code_rate': 0.076, 'efficiency': 0.152}, 2: {'modulation': 'QPSK', 'code_rate': 0.117, 'efficiency': 0.234}, # ... 中间省略 ... 9: {'modulation': '64QAM', 'code_rate': 0.601, 'efficiency': 3.604}, 10: {'modulation': '64QAM', 'code_rate': 0.702, 'efficiency': 4.212} } def get_mcs(cqi): return cqi_to_mcs.get(min(max(cqi, 1), 10), cqi_to_mcs[1])

接下来,我们创建一个动态调度模拟器:

def simulate_scheduling(cqi=5, use_mini_slot=False): fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(12, 8)) # 绘制帧结构 slot_types = [SLOT_DL, SLOT_UL, SLOT_UL, SLOT_UL, SLOT_FLEX] for i, slot_type in enumerate(slot_types): draw_slot(ax1, slot_type, i) # 根据CQI决定资源分配 mcs_info = get_mcs(cqi) num_rbs = min(int(cqi * 2.5), 100) # 模拟RB分配 # 绘制资源分配 if use_mini_slot: # Mini-Slot分配(2符号) ax1.add_patch(Rectangle((4, 0), 2, 1, color='red', alpha=0.3)) ax1.text(4.5, 0.5, f'MCS: {mcs_info["modulation"]}\nRBs: {num_rbs}', ha='center', va='center', color='black') else: # 常规Slot分配 ax1.add_patch(Rectangle((0, 0), 14, 1, color='red', alpha=0.3)) ax1.text(7, 0.5, f'MCS: {mcs_info["modulation"]}\nRBs: {num_rbs}', ha='center', va='center', color='black') # 绘制CQI变化曲线 ax2.plot([1, 2, 3, 4, 5], [3, cqi, 7, 5, 8], 'o-') ax2.set_ylabel('CQI') ax2.set_xlabel('Time (ms)') ax2.set_title('Channel Quality Variation') ax2.set_ylim(0, 11) plt.tight_layout() plt.show() interact(simulate_scheduling, cqi=IntSlider(min=1, max=10, step=1, value=5), use_mini_slot=False)

4. Mini-Slot的灵活调度实现

Mini-Slot是5G NR引入的重要特性,特别适合低时延场景。让我们实现一个对比可视化,展示Slot和Mini-Slot的差异。

首先定义Mini-Slot的配置参数:

mini_slot_configs = { '2符号': {'length': 2, 'color': '#9467bd'}, '4符号': {'length': 4, 'color': '#8c564b'}, '7符号': {'length': 7, 'color': '#e377c2'} }

然后创建一个对比可视化函数:

def compare_slot_vs_minislot(): fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 4)) # 标准Slot调度 draw_slot(ax1, SLOT_DL, 0) ax1.add_patch(Rectangle((0, 0), 14, 1, color='red', alpha=0.3)) ax1.set_title('Slot-Based Scheduling (14 symbols)') # Mini-Slot调度 draw_slot(ax2, SLOT_DL, 0) for i, (name, config) in enumerate(mini_slot_configs.items()): start = i * 4 ax2.add_patch(Rectangle((start, 0), config['length'], 1, color=config['color'], alpha=0.5)) ax2.text(start + config['length']/2, 0.5, name, ha='center', va='center') ax2.set_title('Mini-Slot Scheduling') plt.tight_layout() plt.show() compare_slot_vs_minislot()

这个对比清晰地展示了Mini-Slot如何实现更细粒度的资源分配。在实际应用中,基站会根据业务需求动态选择调度方式:

  • eMBB业务:通常使用标准Slot,追求高吞吐量
  • URLLC业务:倾向使用Mini-Slot,满足低时延要求
  • mMTC业务:可能混合使用,根据设备状态调整

5. 完整调度系统模拟

现在,我们将所有组件整合成一个完整的调度系统模拟器。这个模拟器将展示:

  1. UE测量并上报CQI
  2. gNB根据CQI选择MCS和资源分配方式
  3. 动态决定使用Slot还是Mini-Slot
  4. 可视化整个调度决策过程
def full_scheduling_simulation(cqi_history=[5, 7, 4, 6, 8]): fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10)) # 绘制帧结构 slot_types = [SLOT_DL, SLOT_UL, SLOT_FLEX, SLOT_DL, SLOT_UL] for i, slot_type in enumerate(slot_types): draw_slot(ax1, slot_type, i) # 模拟调度决策 for i, cqi in enumerate(cqi_history): mcs_info = get_mcs(cqi) # 根据CQI决定使用Slot还是Mini-Slot use_mini_slot = cqi < 5 # 信道质量差时使用Mini-Slot快速重传 if use_mini_slot: # 随机选择一个Mini-Slot配置 config = list(mini_slot_configs.values())[i % 3] length = config['length'] start = i * 3 % 12 # 随机起始位置 ax1.add_patch(Rectangle((start, i), length, 1, color=config['color'], alpha=0.7)) ax1.text(start + length/2, i + 0.5, f'CQI:{cqi}\n{config["length"]}sym', ha='center', va='center') else: ax1.add_patch(Rectangle((0, i), 14, 1, color='red', alpha=0.3)) ax1.text(7, i + 0.5, f'CQI:{cqi}\nSlot', ha='center', va='center') # 绘制CQI变化曲线 ax2.plot(range(len(cqi_history)), cqi_history, 'o-') ax2.set_ylabel('CQI') ax2.set_xlabel('Time (ms)') ax2.set_title('Channel Quality Indicator (CQI) over Time') ax2.set_ylim(0, 11) ax2.grid(True) plt.tight_layout() plt.show() # 交互式控件 cqi_sliders = [IntSlider(min=1, max=10, value=5) for _ in range(5)] interact(full_scheduling_simulation, cqi_history=cqi_sliders);

在实际项目中,这种可视化工具可以帮助开发者:

  • 直观理解调度算法行为
  • 调试调度参数配置
  • 向非技术人员解释5G调度原理
  • 教学演示核心概念

6. 扩展与优化方向

我们的基础可视化框架已经完成,但还有多种优化方向可以探索:

性能优化技巧

  • 使用Matplotlib的动画API实现平滑过渡
  • 添加更多真实5G参数配置选项
  • 实现多UE竞争资源场景

教学功能增强

  • 添加逐步解释注释
  • 实现错误场景模拟(如HARQ重传)
  • 对比不同子载波间隔的影响
# 示例:添加动画效果 from matplotlib.animation import FuncAnimation def animate_scheduling(frame): ax.clear() cqi = frame % 10 + 1 # 模拟CQI变化 simulate_scheduling_static(cqi, frame % 2 == 0) fig, ax = plt.subplots(figsize=(12, 6)) ani = FuncAnimation(fig, animate_scheduling, frames=20, interval=500) plt.close()

对于希望深入学习的开发者,可以考虑以下扩展:

  1. 集成更多3GPP标准参数
  2. 添加物理层过程模拟(如信道编码)
  3. 实现跨层优化可视化(RLC/MAC互动)
  4. 构建Web交互界面(使用Plotly Dash)

注意:完整实现这些扩展需要更深入的5G协议知识,建议参考3GPP 38系列规范。

通过这个项目,我们不仅掌握了5G NR调度的核心概念,还构建了一个强大的可视化分析工具。这种"通过代码学习协议"的方法,相比传统理论学习更加高效和直观。

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

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

立即咨询