RAN 数字孪生#

以下章节描述如何在三种不同的模式下运行仿真

  • 模式 1 - 仅电磁 (EM):使用射线追踪计算无线电传播

  • 模式 2 - 无线接入网 (RAN):除了 EM 仿真外,还运行 AERIAL 5G RAN 协议

  • 模式 3 - 机器学习示例 (ML):

    • ML 示例 1:EM + ML 信道预测

    • ML 示例 2:EM + RAN + ML 信道估计

仿真模式 1 - EM 仿真#

EM 仿真模式模拟虚拟 3D 环境中发射机和接收机之间的电磁传播。它生成它们之间的无线信道,但不执行 RAN 的任何组件。因此,它可以用于生成大量合成数据,这些数据可以通过 SQL 访问以进行进一步处理。

EM 模式和所有其他模式都需要一些共同的步骤

  1. 连接工作节点 - 工作节点是执行计算(射线追踪、信道仿真、天线建模以及 RAN 和 ML)的节点。工作节点通过 Nucleus 服务器与 UI 通信。

  2. 创建和配置天线面板

  3. 部署网络组件(RU 和 DU)

  4. 部署 UE 并配置其移动模式或重生设置

  5. 为 UE 和 RU 创建要使用的天线面板

  6. 配置射线追踪仿真并执行它们。

这些步骤将在下面更详细地描述。

将工作节点连接到 UI#

如前几节所述,空中全域数字孪生由五个子组件组成

  • 图形用户界面

  • Nucleus

  • ClickHouse

  • 场景导入器

  • 和 RAN 数字孪生,

其中 Nucleus 服务器是允许所有其他组件相互交互的元素。

我们运行仿真的入口点是图形用户界面。打开图形界面后,我们可以导航到配置选项卡以连接到 RAN 数字孪生的实例,这里也称为工作节点。

进入配置选项卡后,我们将输入 ClickHouse 服务器的 DB 主机DB 端口,然后按连接按钮。如果成功连接到服务器,连接按钮旁边的指示灯将从红色变为绿色。继续,我们可以添加 DB 名称,以及可选的 DB 作者DB 备注可以留空,也可以用于描述仿真的关键特征,这可以帮助我们在以后检索。我们可以随时单击断开连接按钮从数据库断开连接。

接下来,我们可以输入 Nucleus 服务器 URL,例如 omniverse://<Nucleus IP 主机名>,以及所需的实时会话名称广播频道名称是可选参数,用于额外隔离在同一节点上运行的多个工作节点。默认情况下,广播频道名称只是 broadcast。最后,我们可以指定安装期间在选定的 Nucleus 服务器上安装的 Assets 的 URL。

完成这些步骤后,我们就可以单击工具栏上的连接工作节点按钮,该按钮由一组齿轮表示。如果安装有问题并且图形用户界面无法与工作节点通信,则会弹出一个错误窗口。

../_images/attach_worker_error_window.png

相反,如果工作节点成功连接,齿轮图标将变为绿色,如下所示。要断开工作节点,我们可以再次单击齿轮图标并确认我们要断开工作节点。图标将再次变为灰色。

../_images/mobi_worker_locked.png ../_images/mobi_worker_unlocked.png

值得一提的是,不必每次都显式连接到数据库,因为连接工作节点也会连接到数据库。当然,DB 主机DB 端口需要有效才能发生这种情况。

连接工作节点后,我们就可以打开场景了。我们可以通过转到文件 > 打开并从 Nucleus 服务器中选择场景(例如 tokyo.usd)来完成此操作。或者,我们可以使用内容选项卡并双击我们要打开的文件。

在 UI 和工作节点都打开场景后,我们将在视口中看到 3D 地图,并且右上角的 Live 会话图标将变为绿色,表示实时会话处于活动状态。

添加天线面板#

接下来,我们需要创建 RU 和 UE 将要使用的天线面板。

我们可以通过右键单击 Stage 小部件并从上下文菜单中选择 Aerial > 创建面板 条目来创建新的天线阵列。新面板可以在 Stage 小部件的 Panels 条目下找到。通过选择新面板,我们可以检查其属性,并使用天线元件选项卡和属性小部件进行更改,如下图所示。

../_images/antenna_panel_property_widget.png

如果需要,在天线元件选项卡下,对于半波偶极子,可以使用计算 AEP 计算阵列中每个天线元件的有源元件方向图。这考虑了每个天线元件由于其他元件的存在而经历的互耦效应。

有关如何部署自定义天线方向图的更多详细信息,请参阅本指南的图形用户界面部分。

部署 RU#

要部署新的无线单元 (RU),只需用鼠标右键单击地图并选择 Aerial > 部署 RU。这将创建一个跟随鼠标的可移动资产。找到 RU 的位置后,我们可以单击以确认 RU 的位置。稍后可以通过选择 RU,右键单击它并使用上下文菜单中的 Aerial > 移动 RU 来移动 RU。

在给定的 RU 处于预期位置后,可以使用属性小部件修改其属性。最重要的是,如果 Panel Type 字段为空,我们需要关联一个面板类型。

部署 DU#

要部署 DU,我们可以右键单击地图区域并选择 Aerial > 部署 DU。我们可以手动或自动将 DU 关联到 RU。更多详细信息请参见本指南的图形用户界面部分。

部署 UE#

UE 可以通过两种方式部署 - 程序化或手动。要手动部署,我们可以导航到视口并右键单击我们希望 UE 位于的位置。从上下文菜单中选择 Aerial > 部署 UE 将在所需位置创建一个胶囊体。Stage 小部件的 UE 组中对应的条目将激活手动创建标志。

对于手动创建的 UE,我们还可以通过单击 UE 属性小部件中的编辑航点按钮来指定其移动路径。然后,在视口中,我们可以绘制一条折线,定义 UE 在地图上的预期轨迹。

../_images/ue_edit_waypoints_property_widget.png ../_images/drawing_ue_manual_waypoints.png

此外,以下属性可以为每个手动绘制的航点进行自定义

  • 速度:以米/秒为单位定义。

  • 方位角偏移:以度为单位测量。

  • 暂停时长:UE 在航点暂停的时间长度,以秒为单位。

../_images/ue_waypoint_attribute_widget.png

这种方法通常足以模拟小型场景,其中 UE 的数量有限。对于更大规模的 UE 群体,我们可以通过更改 Stage 小部件的 Scenario 条目中的参数程序化 UE 数量来程序化地生成它们。另一个参数室内程序化 UE 百分比控制程序化生成的 UE 中放置在室内的百分比。请注意,手动 UE 无法部署在室内。当工作节点连接时,按下工具栏中的生成 UE 按钮将程序化地创建足够的 UE,以使程序化 UE 的数量与 Scenario 中指定的数量相匹配。如果程序化 UE 数量低于现有程序化 UE 的数量,则将删除额外的程序化 UE 以匹配设置。

我们可以通过创建生成区域来限制程序化 UE 的生成位置,即通过在视口中右键单击并选择 Aerial > 部署生成区域。这将创建图中显示的边界框。

../_images/spawn_zone_bounding_box.png

可以使用工具栏中的移动旋转缩放按钮调整边界框的大小和位置。更详细地说,在选择这些操作之一后,我们可以拖动图中显示的红色/蓝色/绿色箭头和矩形来执行所需的变换。

../_images/scale_rotate_move_widget.png

在所有情况下,重要的是边界框与舞台的地面相交。否则,程序化 UE 将不会被放置在生成区域中。因此,我们可能希望从顶视图而不是透视图修改生成区域边界框(视图可以从视口顶部的相机视图小部件更改)。

../_images/camera_view.png

如果没有生成区域,或者生成区域边界框太小,则程序化 UE 将被放置在场景中的随机位置。程序化 UE 和手动 UE 可以混合用于给定的部署,并且手动 UE 不会在每次按下生成 UE 按钮时移动。

更改环境的散射属性#

将材质正确关联到场景几何体在产生无线电环境的真实表示中起着关键作用。目前,材质可以分配给每个建筑物和整个地形。为此,

  • 我们可以使用舞台视图或视口选择我们要编辑的建筑物,然后对于不包含分段建筑物数据的地图,修改 Building Materials 下的 Building 字段,以及字段

    • 建筑安装 定义

    • 墙面

    • 屋顶表面

    • 地面

    属性小部件中的 Building Materials 下;

  • 类似地,对于地形,我们可以选择舞台视图中的 ground_plane 资产,然后从属性小部件中修改 Ground Plane Material 字段。

对于建筑物,也可以通过在舞台小部件中选择 World/buildings 将给定材质批量分配给整个地图。

使用类似的过程和界面,我们还可以分配另外两个重要的属性

  • 启用 RF:此标志指示代表

    • 一栋建筑物,

    • 所有建筑物

    • 或地形

    的网格或网格是否可以与电磁场相互作用。如果未启用此标志,则电磁场将无法与所选资产的几何体相互作用;

  • 启用漫反射: 此选项反过来指定网格或网格(再次代表

    • 一栋建筑物

    • 所有建筑物

    • 或地形

    是否可以以漫反射方式与电磁场相互作用,即,此类网格的表面是否可以产生非镜面反射。

运行仿真#

在运行仿真之前,重要的是检查 Scenario 属性小部件中的所有参数是否与我们的意图一致,并且 Enable TrainingSimulate RAN 都未选中。

如上一节所述,仿真的持续时间和采样周期由 Scenario 中的 Simulation Mode 确定。

  • 仿真模式:持续时间 需要设置

    • 批次,

    • 持续时间,

    • 间隔

  • 仿真模式:时隙 则需要

    • 批次,

    • 每批次时隙数,

    • 每时隙样本数.

有关这些参数和其他参数的更多详细信息,请参阅描述 Scenario 舞台小部件的 图形用户界面 部分。

现在,我们可以使用生成 UE 按钮生成 UE 及其在仿真期间将遵循的轨迹。轨迹在视口小部件中显示为地面上的白色折线,在 Stage 小部件中显示为 runtime 范围的条目。一旦 UE 及其轨迹可用,我们可以通过按工具栏中的启动 UE 移动按钮来启动仿真。

在运行过程中,可以使用工具栏的 暂停 UE 移动停止 UE 移动 按钮暂停和停止仿真。仿真暂停时,可以按下生成 UE 按钮,但它不会生成新的轨迹集。为了这样做,必须使用 停止 UE 移动 按钮停止仿真。仿真的进度显示在进度条中。

../_images/sim_progress_bar.png

查看仿真结果#

仿真完成后,我们可以按工具栏上的播放按钮,或将时间轴小部件中的蓝色指示器移动到特定的感兴趣帧。要停止重放,我们可以单击停止按钮。

可以通过在仿真之前选择 RU 和 UE,并在属性小部件中启用 Show Raypaths 属性,来为每个 RU-UE 对打开或关闭射线的可视化。

如果在启动仿真之前未选择给定的 RU 或 UE,并且我们有兴趣查看该 RU-UE 对的射线,我们可以使用刷新遥测按钮。

无线电环境#

存储在数据库中的无线电环境结果是针对 RU 到 UE 方向的,即针对下行链路。具体来说,如果我们取

  • RU 处的总发射功率 \(P^{\left(RU\right)}\)

  • RU 处每个发射天线站点使用的极化数 \(N^{\left(RU\right)}_{pol.}\)

  • RU 处使用的水平天线元件数 \(N^{\left(RU\right)}_{hor.}\)

  • RU 处使用的垂直天线元件数 \(N^{\left(RU\right)}_{vert.}\)

  • FFT 点数 \(n\)

  • 在 UE 处观察到的每个链路的信道频率响应 \(\mathbf{H}_{i,j}^{\left(UE\right)}\left( k \right)\),对于给定的子载波 \(k\),跨越从第 \(i\) 个发射机天线到第 \(j\) 个接收机天线的链路

  • 在 UE 处观察到的每个链路的信道频率响应 \(\mathbf{H}_{i,j}^{\left(ch\right)}\left( k \right)\),对于给定的子载波 \(k\),跨越从第 \(i\) 个发射机天线到第 \(j\) 个接收机天线的链路,当每个子载波在传输时分配单位功率时

结果是这样的

\( \left<\mathbf{H}_{i,j}^{\left(UE\right)}, \mathbf{H}_{i,j}^{\left(UE\right)} \right> = \dfrac{P^{\left(RU\right)}}{n \cdot N^{\left(RU\right)}_{pol.} \cdot N^{\left(RU\right)}_{hor.} \cdot N^{\left(RU\right)}_{vert.}} \left<\mathbf{H}_{i,j}^{\left(ch\right)}, \mathbf{H}_{i,j}^{\left(ch\right)} \right>. \) \(\left\{\mathbf{H}_{i,j}^{\left(UE\right)}\left( k \right)\right\}_{i,j,k}\) 的集合存储在下一节讨论的 cfrs 表中。

如果我们定义 \( \mathbf{h}_{i,j}^{\left(UE\right)} = \dfrac{{\rm{iFFT}}_n \left[ \mathbf{H}_{i,j} ^ {\left( UE \right)}\right]}{\sqrt{n}} \) 和几何计算的信道脉冲响应为 \( h^{UE}_{i,j} \left(t\right) = \sum_w h^{\left(w \right)}_{i,j} \delta\left(t - \tau^{\left(w \right)}_{i,j} \right) \) 我们也有 \( \left<h^{UE}_{i,j}, h^{UE}_{i,j}\right> = \left<\mathbf{h}_{i,j}^{\left(wb\right)}, \mathbf{h}_{i,j}^{\left(wb\right)}\right> \) 其中 \(\left\{h_{i,j}^{\left(UE\right)}\right\}_{i,j}\) 的集合存储在即将到来的章节中讨论的 raypaths 表中。

最后,如果我们有兴趣计算上行链路中的信道频率响应,我们可以通过施加 \( \left<\mathbf{H}_{i,j}^{\left(RU\right)}, \mathbf{H}_{i,j}^{\left(RU\right)} \right>_{UL} = \dfrac{P^{\left(UE\right)}}{N^{\left(UE\right)}_{pol.} \cdot N^{\left(UE\right)}_{hor.} \cdot N^{\left(UE\right)}_{vert.}} \cdot \dfrac{N^{\left(RU\right)}_{pol.} \cdot N^{\left(RU\right)}_{hor.} \cdot N^{\left(RU\right)}_{vert.}}{P^{\left(RU\right)}} \left<\mathbf{H}_{i,j}^{\left(UE\right)}, \mathbf{H}_{i,j}^{\left(UE\right)} \right>_{DL}. \) 来实现。

数据库重放#

数据库的内容也可以用于可视化或重放以前的仿真。

  1. 在 UI 中可视化以前的结果:对于使用 1.2 或更高版本创建的数据库,单击配置选项卡中的重放按钮以在 UI 中查看以前的仿真结果。这不需要工作节点。

  2. 使用 UI 重放仿真:从数据库中检索以前配置的仿真设置,并使用 aodt_sim 工作节点和 UI 重新运行仿真。

  3. 不使用 UI 重放仿真:使用 aodt_sim 工作节点在没有 UI 的情况下重放仿真。

  • 注意:如果需要,请选中场景属性中的 启用种子移动,以确保 UE 移动在运行之间相同。

cd <path to aodt backend installation> # e.g. ~/aodt_1.2.0/backend
aerial:~/aodt_1.2.0/backend$ docker compose exec -it connector bash

# note command line options
aerial:/aodt/aodt_sim/build$ python -m aodt.app.sim --help

# replay simulation from a database (note your nucleus and clickhouse hostnames may be different)
aerial:/aodt/aodt_sim/build$ python -m aodt.app.sim --nucleus omniverse://omniverse-server --db-host clickhouse --db-replay --db-name-source <database name, e.g. aerial_2025_1_7_16_40_42>

# run without entering the container (can be used to run several databases via a script)
docker compose exec connector python -m aodt.app.sim --nucleus omniverse://omniverse-server --db-host clickhouse --db-replay --db-name-source <database name>

这样,仿真也可以在 UI 和 aodt_sim 工作节点共享的单个 GPU 上运行。

  1. 打开 UI 并使用相同的 GPU 连接 aodt_sim 工作节点。

  2. 设置所需的场景,然后单击生成 UE,这会将场景保存在数据库中以供以后重放。

  • 重要提示:如果使用单个 GPU 运行,请勿单击启动 UE 移动,因为在仿真期间不支持在 UI 和 aodt_sim 之间共享 GPU 计算和内存。

  1. 关闭 UI,使其不再使用 GPU,然后使用 --db-replay 模式在 aodt.app.sim 中运行仿真。

仿真模式 2 - RAN 仿真#

RAN 仿真模式建立在 EM 模式之上,并添加了物理 (PHY) 和媒体访问控制 (MAC) 层的关键要素。对于之前的模式,所有捕获 RAN 和 UE 之间详细交互的数据都可以通过 SQL 访问以进行进一步处理或分析。

要启用 RAN 的仿真,我们需要选择 Stage 小部件下的 Scenario 条目,并启用 Simulate RAN 复选框,如下图所示。这将 Scenario 中的 Simulation mode 字段限制为 Slots

然后,我们可以像在 EM 模式中一样定义批次数、每批次时隙数和每时隙样本数。具体来说,

  • 每时隙样本数 设置为 1 时,将在整个时隙中使用信道的单个前置实现

  • 而当 每时隙样本数 设置为 14 时,每个 OFDM 符号将与不同的信道实现进行卷积。

../_images/simulate_ran.png

如果 RU 在 RAN 仿真中配置了 64 天线面板,则 MAC 调度中启用 MU-MIMO。读者可以参考 MAC 调度 部分了解详细描述,并参考 RAN 参数 表了解相关参数。

RAN 参数#

RAN 参数存储在

/aodt/aodt_sim/src_be/components/common/config_ran.json

其中可以更改以下参数

含义

默认值

gNB 噪声系数

RU 功率放大器的噪声系数

0.5 dB

UE 噪声系数

UE 功率放大器的噪声系数

0.5 dB

DL HARQ 启用

启用 DL HARQ

0

UL HARQ 启用

启用 UL HARQ

0

TDD 模式

支持的 TDD 模式,可以添加其他模式

1:DDDSUUDDDD
2:DDDDDDDDDD
3:UUUUUUUUUU

仿真模式

指定仿真的 TDD 模式

1(即,DDDSUUDDDD)

每个 TTI 调度的最大 UE 数 - dl

每个小区每个 TTI 的最大 UE 数(用于 DL)

6(最大值:6)

每个 TTI 调度的最大 UE 数 - ul

每个小区每个 TTI 的最大 UE 数(用于 UL)

6(最大值:6)

调度器模式

指定 PRB 调度算法。选项:“PF”(比例公平调度器)或“RR”(轮询调度器)

“PF”

波束赋形器 CSI

指定波束赋形的 CSI。选项:“SRS”(SRS 估计信道)或“CFR”(地面实况信道)

“CFR”

MAC CSI

指定 L2 MAC 调度的 CSI。选项:“SRS”(SRS 估计信道)或“CFR”(地面实况信道)

“CFR”

波束赋形分组级别

指定波束赋形分组级别。选项:“SC”(每个子载波波束赋形)、“PRBG”(每个 PRBG 波束赋形)或“UEG”(每个 UEG 波束赋形)

“PRBG”

pusch 信道估计

指定估计方法。选项:“MMSE”或“ML”(基于机器学习的估计)

“MMSE”

信道估计持续时间

指定 MMSE 信道估计的延迟扩展窗口大小。选项:1(1 微秒)或 2(2 微秒)

2

MCS 选择模式

指定 MCS 选择的方法。目前,仅支持“OLLA”(外环链路自适应)。

“OLLA”

MU-MIMO 可行性的 SRS SNR 阈值 - dl

当 RU(无线单元)处有 64 个天线时适用。指定 SRS SNR 阈值以确定 UE 是否符合 DL 中的 MU-MIMO 分组条件。

2 dB

MU-MIMO 可行性的 SRS SNR 阈值 - ul

当 RU(无线单元)处有 64 个天线时适用。指定 SRS SNR 阈值以确定 UE 是否符合 UL 中的 MU-MIMO 分组条件

2 dB

MU-MIMO 分组的信道相关性阈值 - dl

当 RU 处有 64 个天线时适用。指定用于在 DL 中进行 MU-MIMO 分组决策的信道相关性阈值

0.2

MU-MIMO 分组的信道相关性阈值 - ul

当 RU 处有 64 个天线时适用。指定用于在 UL 中进行 MU-MIMO 分组决策的信道相关性阈值

0.2

固定 UE 层数 - dl

如果“启用固定层数”设置为 1,则始终为 UE 分配由 DL 中“固定层数”参数指定的层数

“启用固定层数”:0

固定 UE 层数 - ul

如果“启用固定层数”设置为 1,则始终为 UE 分配由 UL 中“固定层数”参数指定的层数

“启用固定层数”:0

RX FT 文件名

如果提供了文件名,则接收器处接收到的 I/Q 样本将保存到具有指定文件名的 H5 文件中

默认值:“”(禁用)

目前,只有一部分 RAN 参数可以在方便的 JSON 文件中进行修改。然而,后续版本将包括 RAN 中所有模块的完整配置参数。

仿真#

在设置完 config_ran.json 中描述的参数后,我们可以使用与 EM 模式相同的顺序运行仿真。然后将结果传播到

  • 图形界面,我们可以在其中可视化每个 UE 的瞬时吞吐量和调制编码方案 (MCS) 或 RU 级别的吞吐量和已分配 MCS 的统计分布;

  • 本地控制台,其中按时隙打印详细的调度信息(例如,PRB 分配和层数);

  • 选定的 ClickHouse 数据库,其中将存储完整的遥测数据。

图形用户界面#

仿真完成后,我们可以在 Stage 小部件中选择特定的 UE 或 RU,然后按工具栏中的播放按钮。在属性小部件中,我们将看到以下时间序列

  • UE 的瞬时吞吐量,

  • RU 的聚合瞬时吞吐量。

../_images/UE_thr.png ../_images/RU_thr.png

此外,我们可以直接在视口中 UE 的表示上方观察 UE 的瞬时吞吐量,如下所示。

../_images/UE_thr2.png

MAC 调度器为给定 UE 分配的 MCS 也可以在瞬时吞吐量下方找到。

../_images/UE_MCS.png

类似地,在 RU 处,我们可以找到整个仿真过程中使用的调制和编码方案的直方图。

../_images/RU_MCS.png

本地控制台#

如果可以访问,可以在运行 RAN 数字孪生的控制台中观察到更多详细信息。在每个时隙结束时,会打印一个表格,列出所有调度的 UE、PRB 分配(起始 PRB 索引和分配的 PRB 数量)、MCS、层数、存在 HARQ 时的冗余版本、预均衡 SINR、后均衡 SINR 和 CRC 结果,其中 0 表示成功解码。

==============================================  results  ================================================
cell idx   grp idx   ue id     startPrb     nPrb    MCS   layer     RV   sinrPreEq    sinrPostEq     CRC
   0         0         94       176          80       4      2       0     5.67         4.16           0
   0         1         95         4          36       0      2       0    -3.94        -2.43           0
   0         2        155        40          40       3      2       0     1.47         1.10           0
   0         3        175        80          96      27      1       0    34.94        40.00           0
   0         4        192       256          16       1      1       0    -6.14        -1.21           0
   0         5        193         0           4      26      2       0    36.21        26.23        9860658
   1         6         28       200          16      15      1       0    10.12        16.60           0
   1         7         58       216          56      10      1       0     3.95        10.01           0
   1         8         89         0          80      24      1       0    12.64        22.68        7891203
   1         9         92        80          12      27      1       0    35.69        40.00           0
   1        10        178       148          52      12      1       0     6.74        11.62           0
   1        11        184        92          56       7      1       0     2.02         7.28           0
   2        12         34       244          28      27      1       0    34.56        39.19           0
   2        13         47       124          48      15      1       0     6.36        15.37           0
   2        14         60        16          92      16      1       0     5.22        15.24           0
   2        15         68       172          72       9      1       0     3.41         9.45           0
   2        16        194         0          16      11      1       0     3.72        10.74           0
   2        17        199       108          16       3      2       0     9.68         4.18           0
   3        18         23       200           8      27      1       0    31.78        37.85           0
   3        19         56       208          28      20      1       0    14.68        19.20           0
   3        20         57         0          60       3      1       0    -0.52         5.20           0
   3        21         62        60         140      27      1       0    33.20        37.99           0
   3        22        160       260          12      15      1       0    14.91        20.29           0
   3        23        187       236          24      27      1       0    36.80        39.92           0
=========================================================================================================

ClickHouse 数据库#

全面的遥测数据可在用于仿真的数据库的 telemetry 表中获得。例如,

clickhouse-client

aerial :) select * from aerial_2024_4_16_14_28_33.telemetry

SELECT *
FROM aerial_2024_4_16_14_28_33.telemetry

Query id: e463ec6a-4e11-4197-88e0-8762a630181d

┌batch_id─┬─slot_id─┬─link─┬─ru_id─┬─ue_id─┬─startPrb─┬─nPrb─┬─mcs─┬─layers─┬───tbs─┬─rv─┬─outcome─┬───scs─┐─preEqSinr─┬─postEqSinr─┐
│       0        0  UL        0     46        28   132    0       1    372   0        1  30000   8.948093   15.192958 │
│       0        0  UL        0     49         0    28    0       1     80   0        1  30000  30.305893    36.59542 │
│       0        0  UL        0     53       160    24    0       2    141   0        1  30000   35.86527    38.16932 │
│       0        0  UL        0     94       184    88    0       2    497   0        0  30000  -2.340038     0.19586 │
│       0        0  UL        1    124         0   272    0       1    769   0        1  30000  11.380707    9.841505 │
│       0        1  UL        1    124         0   272    9       1   7813   0        1  30000   8.920734   15.117773 │
│       0        1  UL        2     34         0   272    0       1    769   0        1  30000   32.23978   37.145943 │
│       0        1  UL        3     23        20   252    0       1    705   0        1  30000  13.059542   23.430824 │
...

其中每一列的含义在 数据库模式 中进行了解释。

重要提示:有几个脚本可用于从数据库中提取信息。示例脚本和笔记本可以在 aodt_sim/examples 中找到,以提取和绘制 CIR/CFR、吞吐量、BLER、调度指标和存储在上述表格中的其他数据点。

MAC 调度#

MAC 调度任务由 Aerial cuMAC 执行,完全支持 UL 和 DL、HARQ 以及单小区和多小区联合调度。对于 4T4R SU-MIMO 和 64T64R MU-MIMO 仿真,分别支持两组不同的调度算法

  • 4T4R SU-MIMO: MAC 调度器管道由四个模块组成 - UE 选择、PRB 分配、层选择和 MCS 选择。

  • 64T64R MU-MIMO: MAC 调度器管道由三个模块组成 - MU-MIMO UE 排序、MU-MIMO UE 分组和 MCS 选择。

调度过程的数据流在以下图中说明。

../_images/RAN_MAC_RLC_RRC.png ../_images/scheduler.png

对于 4T4R SU-MIMO 调度,在每个时隙中执行以下过程:首先,将必要的输入数据提供给 cuMAC,然后 GPU 上依次运行四个 SU-MIMO 调度器功能。

  • UE 选择: 使用 RAN PHY 测量的 SINR 对每个小区进行 UE 下行选择。

  • PRB 分配: 使用 1) 来自 RAN PHY 的 SRS 信道估计,或 2) 来自信道仿真器引擎的 CFR(地面实况信道),为每个小区中选定的 UE 分配 PRB。

  • 层选择: 为每个选定的 UE 选择层。

  • MCS 选择: 使用 RAN PHY 测量的 SINR 为每个选定的 UE 选择 MCS。采用外环链路自适应来为测量的 SINR 添加正/负偏移。偏移由给定 UE 的上次调度传输的 ACK/NACK 结果调整。

对于 64T64R MU-MIMO 调度,在每个时隙中执行以下过程:首先,将必要的输入数据提供给 cuMAC,然后 GPU 上依次运行三个 MU-MIMO 调度器功能。

  • MU-MIMO UE 排序: 考虑 1) 比例公平 (PF) 指标,2) 基于 RAN PHY 测量的 SRS 宽带 SNR 的 MU-MIMO 传输可行性,以及 3) HARQ 重传状态,对每个小区中的所有活动 UE 进行排序。

  • MU-MIMO UE 分组: 对于每个小区,确定 1) 当前时隙选择的 UE,2) 频带上的 PRB 分配(子带划分),3) 每个子带的 UE 分组策略,4) 每个 UE 选择的层数,以及 5) 为 UE 组中每层分配的 nSCID(0 或 1)。MU-MIMO UE 分组基于来自 RAN PHY 的 SRS 信道估计完成。

  • MCS 选择: 使用 RAN PHY 测量的 SINR 为每个选定的 UE 选择 MCS。采用外环链路自适应来为测量的 SINR 添加正/负偏移。偏移由给定 UE 的上次调度传输的 ACK/NACK 结果调整。

仿真模式 3 - ML 示例#

在 AODT 中,仿真模型 1 和 2 可用于生成特定于站点的数据,以进行离线分析或 ML 训练。 例如,在运行仿真后,我们可以将诸如信道频率响应或网络性能指标之类的数据从 ClickHouse 数据库导入到数据摄取管道中,以供外部工具使用。 此外,Aerial Omniverse Digital Twin 也可用于在线训练 ML 模型,同时仿真也在演进。 这是仿真模式 3,通过使 aodt_sim 传递以下内容来实现:

  • 仿真状态,

  • UE 的位置及其速度,

  • 由 EM 引擎生成的所有信道数据,

  • 以及 RAN 在每个仿真时间步的遥测数据

通过绑定传递给 Python。

ML 示例概述#

目前,有两个示例展示了将 AI/ML 工具链与 AODT 连接的不同方式

  • 示例 1 说明了如何训练信道预测器,该预测器使用 EM 求解器生成的信道频率响应 (CFR)。 在此示例中,神经网络学习如何从给定的时间分隔的信道观测值中对 CFR 进行时间插值和外推。

  • 示例 2 展示了嵌入在 PUSCH 管道中的基于 ML 的信道估计器的推理。 在此示例中,神经网络将解调参考符号 (DMRS) 的最小二乘估计作为输入,并预测整个时隙网格上的信道值。

ML 示例 1 - 训练信道预测器#

为了说明如何在 AODT 中执行在线训练,我们可以使用一个最简单的示例来训练基于 EM 引擎计算的信道频率响应 (CFR) 的信道预测器。

信道老化是互易波束成形的一个众所周知的问题,特别是对于高速移动的 UE。 这是由于信道探测时和基站应用波束成形权重时无线电环境的差异造成的。 解决此问题的一种方法是使用神经网络来预测计划应用波束成形权重时的信道。

../_images/ml_ex1.png

为了训练神经网络来预测信道,我们首先在场景阶段小部件中设置以下参数。

  • 场景:5 个 UE 和 1 个 RU

  • 天线面板:2 个水平,2 个垂直元素,双极化未选中

  • 批次: 250

  • 每批时隙数: 6

  • 每时隙样本数: 1

  • UE 速度:最小和最大速度设置为 2.0 米/秒

  • 启用训练:选中

  • 仿真 RAN:未选中

在此示例中,信道预测器独立处理来自每个 RU 和 UE 天线对的信道,因此我们可以选择添加更多的 RU、UE 和天线元件,从而在每批中生成更多信道。

我们的神经网络将提前 5 个时隙估计信道。 也就是说,给定时隙 0 的信道,它将预测时隙 5 的信道。 因此,我们将每批时隙数设置为 6。 我们将批次数设置为 250,这为本示例在仿真时间和实现合理的训练损失之间提供了良好的折衷方案。 在每个批次中,UE 都会被重新放置。

按照为 EM 模式描述的步骤,我们可以单击生成 UE启动 UE 移动性以启动仿真。 仿真完成后,训练损失和验证损失将从数据库的 training_result 表中检索,并作为场景属性的一部分显示。 在此示例中,这些损失将与尝试执行相同操作的 LMMSE 滤波器的损失进行比较。 此类损失在图形界面中显示为基线损失。

在下一节中,我们将更详细地介绍如何训练更通用的模型。

示例 - 训练我们自己的模型#

在本节中,我们将讨论 Python API,以使用 Aerial Omniverse Digital Twin 训练我们自己的模型。 如前所述,API 公开了来自 UE 移动性模型的位置信息和来自 EM 引擎的信道信息。 因此,可以训练任何其他依赖于此类数据的模型。 以下讨论了在训练任何此类模型时要考虑的最少函数和数据结构集。

具体而言,aodt_sim 应用程序通过 Python 绑定调用 channel_predictor 目录中的 Python 源代码。 该目录包含以下文件。

|-- aodt_sim
|-- channel_predictor
|   |-- channel_predictor.py
|   |-- channel_predictor_bindings.cpython-310-x86_64-linux-gnu.so
|   |-- config.ini
|   |-- data_source.py
|   |-- plot_channels.py
|   |-- torch_utils.py
|   |-- train.py
|   |-- trainer.py
|   `-- weiner_filter.py

1 directory, 10 files

只有 channel_predictor/trainer.py 中的 Trainer 类及其成员函数 scenarioappend_cfraodt_sim Python 绑定所必需的,因此必须存在于任何用户修改的 Python 代码中。 scenario 函数在仿真开始时调用一次,append_cfr 函数在仿真的每个时间步调用。 其余文件特定于信道预测器示例,并且不与 aodt_sim 应用程序交互。 读者可以参考这些文件中的 Python 文档字符串以了解更多详细信息。 用户可以使用自己的 Python 代码替换它们。

class Trainer():
    """Class that manages training state"""
    def scenario(self, scenario_info, ru_ue_info):
    """Load scenario and initialize torch parameters

    Args:
        scenario_info (ScenarioInfo): Object containing information about the simulation scenario
        ru_ue_info (RuUeInfo): Object containing information about RUs and UEs

    Returns:
        int: Return code if status was successful (=0) or not (<0)
    """
    def append_cfr(self, time_info, ru_assoc_infos, cfrs):
    """Append channel frequency response (CFR)

    Args:
        time_info (TimeInfo): Simulation time information including batch/slot/symbol
        ru_assoc_infos (list(RuAssocInfo)): List of RU to UE association information
        cfrs (numpy.ndarray): Numpy array of channel frequency response

    Returns:
        TrainingInfo: Result of training including information about number of iterations trained for and losses
    """

信道预测 ML 示例 1 中使用的数据结构#

以下数据结构在 aodt_simTrainer 类之间传递。

ScenarioInfo#

字段

类型

注释

slot_symbol_mode

bool

True:时隙/符号仿真模式,
False:持续时间/间隔仿真模式

batches

uint32

场景中定义的批次数

slots_per_batch

uint32

场景中定义的每批时隙数

symbols_per_slot

uint32

场景中定义的每时隙样本数

duration

float32

基于每批时隙数和每时隙符号数计算的仿真持续时间

interval

float32

基于每批时隙数和每时隙符号数计算的间隔

ue_min_speed_mps

float32

UE 最小速度,单位为米/秒

ue_max_speed_mps

int32

UE 最大速度,单位为米/秒

seeded_mobility

int32

随机化 UE 移动性时是否使用种子

seed

int32

随机化 UE 移动性时使用的种子值

scale

float64

转换为 USD 场景中使用的单位(通常为厘米)时的比例因子

ue_height_m

float32

UE 高度,单位为米

RuUeInfo#

字段

类型

注释

num_ues

uint32

仿真中 RU 的数量

num_rus

uint32

仿真中 UE 的数量

ue_pol

uint32

UE 天线极化数

ru_pol

uint32

RU 天线极化数

ants_per_ue

uint32

每个 UE 的天线数

ants_per_ru

uint32

每个 RU 的天线数

fft_size

uint32

信道频率响应中的频率样本数

numerology

uint32

3GPP 38.211 中定义的 Numerology (μ)

TimeInfo#

字段

类型

注释

time_id

uint32

仿真的当前时间索引

batch_id

uint32

仿真的当前批次索引

slot_id

uint32

仿真的当前时隙索引

symbol_id

uint32

仿真的当前符号索引

UeInfo#

字段

类型

注释

ue_index

uint32

UE 索引(从 0 开始)

ue_id

uint32

在阶段小部件中定义的用户 ID

position_x

float32

UE 在阶段中的当前 x 位置

position_y

float32

UE 在阶段中的当前 y 位置

position_z

float32

UE 在阶段中的当前 z 位置

speed_mps

float32

UE 当前速度,单位为米/秒

RuAssocInfo#

字段

类型

注释

ru_index

uint32

RU 索引(从 0 开始)

ru_id

uint32

在阶段小部件中定义的 RU ID

associated_ues

list(UeInfo)

与此 RU 关联的 UE 列表

CFRs#

字段

类型

注释

cfrs

list(numpy.ndarray((ues, ue_ants, ru_ants, fft_size), dtype=numpy.complex64))

列表中所有 RU 的信道频率响应。 列表的元素是 [ue, ue_ant, ru_ant, fft_size] 形式的多维数组

TrainingInfo#

字段

类型

注释

time_id

uint32

仿真的当前时间索引

batch_id

uint32

仿真的当前批次索引

slot_id

uint32

仿真的当前时隙索引

symbol_id

uint32

仿真的当前符号索引

name

string

模型的可选名称,例如“信道预测器”

num_iterations\(^{*}\)

float32

在仿真的此时步中训练的迭代次数。 此处的迭代定义为通过模型的一次前向和一次后向传递。

training_losses

list(tuple(uint32, float32))

训练损失:对于给定的时间索引,可能会训练多次迭代,因此格式为 [(iteration0, loss0), (iteration1, loss1), …]

validation_losses

list(tuple(uint32, float32))

可选的验证损失,与训练损失格式相同

test_losses

list(tuple(uint32, float32))

可选的测试损失,与训练损失格式相同

baseline_losses

list(tuple(uint32, float32))

基线损失,与训练损失格式相同

title

string

UI 中损失图的可选标题,例如“训练损失”

y_label

string

UI 中损失图的可选 y 轴标签,例如“MSE (dB)”

x_label

string

UI 中损失图的可选 x 轴标签,例如“时隙”

如前所述,将在后续版本中添加用于训练 RAN 模型的其他 API。

注意:让我们考虑一个由 4 个 RU、4 个 UE、每个 UE 4 个天线、每个 RU 4 个天线组成的设置。 在仿真的每个时间步,将计算 256 个 CFR。 信道预测器独立考虑每个 RU/UE 天线对。 如果我们将预测配置为提前 6 个时隙,则时隙 0-4 将用于累积数据。 对于 16 的训练批次大小,将有足够的数据在时隙 5 上训练 256 个 CFR / 16(训练批次大小)= 16 次训练迭代(16 次前向/后向传递)。

ML 示例 2 - 推理信道估计器#

示例 2 说明了如何将使用 NVIDIA 的 Sionna 开发的机器学习模型引入 Aerial Omniverse Digital Twin,并在推理时评估其性能。

具体来说,在我们的示例中,

  1. 我们使用 NVIDIA 的 Sionna 和软件提供的随机信道模型(Urban Macro 或 UMa)训练了一个神经网络。

  2. 我们利用 NVIDIA 的 PyAerial 将我们的设计集成到 AODT 中的 PUSCH 接收器和 SRS 中。

  3. 最后,我们使用 EM 求解器生成的特定于站点的信道,在系统级别评估了模型的性能。

下图说明了在 AODT 中运行的最终系统,其中 ML 信道估计器从信道仿真器生成的信号中获取解调参考符号 (DMRS),并生成 OFDM 波形在整个频率/时间网格上的信道估计。

../_images/ml_ex2.png

运行 ML PUSCH 信道估计示例#

运行此示例需要三个步骤。

步骤 1 - 生成模型

要生成信道估计器模型,请使用 aodt_sim/external/cuBB/pyaerial/notebooks/channel_estimation 中的 PyAerial 信道估计笔记本。 笔记本应使用 interp=2 运行以用于 PUSCH DMRS,并通过设置例如 train_snrs=[-10, -5, 0, 5, 10, 15, 20, 25, 30, 35, 40]num_prbs = 1 来设置不同的 SNR 和 PRB。 对于每个 PRB 数量,应重复此过程,例如,对于集合 {1, 4, 16} 的每个元素重复一次。 在推理期间,信道估计模块将组合模型以匹配来自调度器的 PRB 分配。 至少,必须有一个 1 PRB 模型可用于处理不均匀的分配,而较大的 PRB 用于优化较大的分配。

这将为每个 SNR 和 PRB 点生成不同的模型,然后我们将在我们的切换方法中使用这些模型,该方法基于信号选择正确的模型。 更多详细信息可以在笔记本中找到。

步骤 2 - 使 AODT 可以访问模型

生成模型后,需要将它们公开给 aodt_sim。 这需要

  • config_est.ini 中用于 PUSCH DMRS 的参数 freq_interp_factor 设置为 2。

  • 使用 docker cp 命令将包含模型的文件夹移动到容器内

  • 在文件 config_est.ini 中添加模型文件夹的绝对路径; 例如,models_folder = '/home/saved_models'

不同 PRB 的模型应在目录名称中包含 PRB 的数量,例如 prbs=<num_prbs>。 首次在推理时加载模型时,将发现 PRB 子目录。 例如

tree /home/saved_models
...
└── saved_models_prbs=1_interp=4
    └── ch=UMa_n_iter=20000_batchsize=32_model=1PRBs
│       ├── model_SNR=-10.0.path
│       ├── model_SNR=-5.0.path
...
├── saved_models_prbs=4_interp=4   └── ch=UMa_n_iter=20000_batchsize=32_model=4PRBs
│       ├── model_SNR=-10.0.path
│       ├── model_SNR=-5.0.path
...
└── saved_models_prbs=16_interp=4
    └── ch=UMa_n_iter=20000_batchsize=32_model=16PRBs
│       ├── model_SNR=-10.0.path
│       ├── model_SNR=-5.0.path
...

步骤 3 - 配置 RAN 仿真

在图形界面中,唯一需要的配置是将 Simulate RAN 设置为启用。

对于后端配置,我们需要更改 src_be/components/common/config_ran.json 中的三个字段

  • “Simulation pattern”: 3,

  • “pusch channel estimation”: “ML”

  • “Fixed UE layers - ul”: { “Enable fixed layers”: 1, “Fixed layers”: 1 }

此配置确保 TDD 拆分仅由 UL 时隙组成,这有助于测试,因为信道估计已集成到 PUSCH 接收器管道中。 有关这些配置的更多详细信息,请参阅本文档RAN 参数部分中的表格。

运行 ML SRS 信道估计示例#

与 PUSCH 类似,我们在 SRS 中集成了相同的信道估计模型。 此功能目前处于实验阶段,但我们在下面提供了其执行说明

  1. 生成模型:与 PUSCH 中的相同,但有以下区别

    • PyAerial 信道估计笔记本中的 interp 变量应设置为 4,因为 AODT 中的 SRS 当前使用梳状大小 4。

    • PRB 的数量应等于 272,以匹配 aodt_sim 中的 SRS 配置。

  2. 使 AODT 可以访问模型:也与 PUSCH 中的相同,除了 config_est.ini 中的参数 freq_interp_factor 应设置为 4,以匹配 PyAerial 笔记本中的模型训练。

  3. 配置 RAN 仿真:config_ran.json 字段中需要更改默认配置的是

  • “Simulation pattern”: 1,

  • “Beamformers CSI”: “SRS+ML”

  • “MAC CSI”: “SRS+ML”

请注意,波束成形器仅在 S 时隙之后才会受到影响,因为 SRS 仅在此时隙中传输。

在 PUSCH ML 信道估计器之上构建#

此示例的源代码位于 aodt_sim/src_ml/channel_estimation 中。 可以扩展此示例以替换 PUSCH 接收器的其他模块。 以下文件是相关的

文件

描述

app/sim_main.cpp

仿真开始的主文件。

src/asim_loop.cpp

定义主要的第一级函数的位置。 此文件包含 handler_playhandler_play_full_sim,即定义在模式 1 (EM) 和模式 2 (RAN) 中运行的仿真器行为的函数。 ML 示例 2 的逻辑在 handler_play_full_sim 中,ML 示例 1 的逻辑主要存在于 asim_loop.cpp 中。

src_be/controller/src/be_ctrl.cu

包含 RAN 功能的后端控制器。 此文件调用 cuPHY PUSCH 接收器和发射器,以及 PyAerial 提供的模块化/组件式对应物。 文件 ml_estimator.cpp(如下)将 AODT 与机器学习信道估计器连接。 此外,此文件还包含将 PyAerial 使用的 cuPHY GPU 张量转换为 NumPy 数组的逻辑,这些数组可以在 Python 中解释和处理。 反向转换在估计后完成,同时将信道估计复制到正确的变量,以供 PUSCH 接收器使用。

src_ml/channel_estimator/ml_estimator.cpp

包含包装器类和 pybind11 绑定。 包装器在 C++ 仿真期间调用,以实例化 Python 解释器并执行初始化、模型加载和估计。

src_ml/channel_estimator/ml_estimator.hpp

声明将填充信道估计信息的类。

src_ml/channel_estimator/ch_estimator_class.py

主 Python 文件,定义实例化估计器对象、验证机器学习模型的正确路径、加载这些模型以及执行估计的逻辑。

src_ml/channel_estimator/ch_estimator_model.py

定义信道估计器模型和损失函数的位置。

信道预测 ML 示例 2 中使用的数据结构#

PuschEstimatorInfo 包含

  • 要传递给 ML 信道估计器的 LS 和 MMSE 信道估计,

  • RU 信息 RuInfo

  • 以及 UE 组信息 UeGroupInfo

在此,UE 组定义为共享相同时间-频率资源的协同调度 UE 组。

UeGroupInfo#

字段

类型

注释

group_idx

uint32

绝对组索引/标识符

ru_idx

uint32

绝对 RU 索引/标识符,如 UI 中定义

num_tot_layers

uint32

UE 组中的总层数,从每个 UE 的层数之和得出

num_prbs

uint32

UE 组*共享的 PRB 数量

num_symbs

uint32

一个时隙中的 DMRS 符号数 - 1 或 2

*注意:UE 组中的所有 UE 都假定使用相同数量的 PRB。 这不如假设每个 UE 可以有不同的频带分配通用,但可以大大简化方法。

RuInfo#

字段

类型

注释

num_rx_ants

uint32

RU 中的 RX 天线数

num_ue_groups

uint32

RU 中的 UE 组数。 如果禁用波束成形,则 UE 组数等于 UE 数

ue_groups

list(UeGroupInfo)

RU 调度的 UE 组列表

PuschEstimatorInfo#

字段

类型

注释

num_rus

uint32

Number of RUs

num_tot_groups

uint32

所有 RU 中的 UE 组总数

ru_infos

list(RuInfo)

大小为 num_rus 的列表,其中包含有关仿真中每个 RU 的信息

ls_estimates

list(ndarray(complex64))

大小为 num_tot_groups 的列表,其中每个元素都是 NumPy 数组。 对于第 \(i\) 个组,数组的维度为 [num_prbs \(_i\) x 6, num_tot_layers \(_i\), num_rx_ant \(_i\), num_symbs \(_i\)],类型为 NumPy 中的 complex64

mmse_estimates

list(ndarray(complex64))

大小为 num_tot_groups 的列表,其中包含每个 UE 组的信道估计。 对于第 \(i\) 个组,列表的每个元素都是大小为 [num_rx_ant \(_i\), num_tot_layers \(_i\), num_prbs \(_i\) x 12, num_symbs \(_i\)],类型为 NumPy 中的 complex64 的 NumPy 数组。