附加信息#
已知限制#
电磁引擎#
电磁引擎的关键参数是
每个 RU 发射的射线数量
每条射线的最大散射事件数
宽带 CFR 的频率采样数
UE 的数量
正在使用的天线面板的天线数量。
这些参数与电磁引擎运行期间的 GPU 内存消耗直接相关。相应的限制如下表所示。
参数 |
最大值 |
---|---|
每个 RU 发射的射线数量 |
1,000,000 |
每条射线的最大散射事件数 |
5 |
包括传输在内的每条射线的最大散射事件数 |
10 |
宽带 CFR 的频率采样数(FFT 大小) |
4096 |
UE 的数量 |
10,000 |
每个 RU 面板的天线单元数量 |
64 |
每个 UE 面板的天线单元数量 |
8 |
对于大型仿真,如果错误日志报告仿真未成功,建议降低发射射线数、散射事件数,使 UE 群体更稀疏,或关闭漫射。
在功能上,
在选定的最大散射事件数范围内,衍射目前每条射线只能发生一次
仅直接漫射散射(漫射顶点在 RU 和 UE 的视距范围内)
只有镜面反射可以与每条射线的传输同时发生
每个 RU-UE 对考虑的射线或路径数量限制为最大值
\(500 \times\) RU 天线单元数量 \(\times\) UE 天线单元数量
最强路径
电磁引擎目前支持以下天线模型
各向同性,
无穷小偶极子,
半波偶极子,
微带贴片,
以及用户自定义输入,可以是天线单元级别或面板级别。
有源单元方向图目前只能为半波偶极子计算。
RAN 仿真#
对于 RAN 仿真,以下是一些固定的配置和限制。我们计划在未来的版本中引入更多功能并增强灵活性。
在 RU 侧,支持 64 根天线(或 32 根双极化天线)或 4 根天线(或 2 根双极化天线)。在 UE(用户设备)侧,仅支持 4 根天线(或 2 根双极化天线)。
仅支持 100 MHz 带宽和 273 个 PRB。
当 RU 配备 4 根天线时,仅支持 SU-MIMO。
仅支持 30 kHz 子载波间隔。
当 RU 有 4 根天线时,不应用波束成形。当 RU 有 64 根天线时,应用正则化 ZF 波束成形。
MMSE-IRC 无差别地应用于接收机。
所有 RU 和 UE 的功率设置在小区和 UE 之间必须相同。
DMRS 位置固定在符号 2、3、10 和 11 中。
PRB 以 PRB 组级别调度,每个 PRB 组包含 4 个 PRB。
如果启用 HARQ,则在每时隙基础上运行,假设完全了解控制信道信息,并在传输失败的时隙后一个时隙立即重传。
如果启用 HARQ,则在 CRC 校验失败的情况下,最多允许 4 次传输(即一次新传输,然后是 3 次重传)。传输与冗余版本 (RV) 相关联,顺序为 0、2、3、1。
除了 -174 dBm/Hz 的固定热噪声外,每个接收机天线还增加了一个噪声系数。
当未启用训练时,SRS 仅在每个 S 时隙上独占调度。S 时隙专门用于 SRS。
当启用训练时,SRS 在第一个 SU 或 UU 时隙期间调度。
对于 SRS 时隙,当 RU 有 4 根天线时,所有 14 个符号都可以分配用于 SRS 传输。如果 RU 有 64 根天线,则只有 4 个符号可以分配用于 SRS 传输。
MAC 调度器#
HARQ 重传是非自适应的:原始传输的相同调度方案(PRB 分配、层和 MCS 选择)始终重用于 HARQ 重传。通过采用可能改变重传调度决策的先进算法,可以进一步改进,并将在未来的版本中考虑。
层选择是次优的:鉴于波束成形尚未应用,当前的层选择算法尚未优化。通过采用针对缺少波束成形的层选择算法,可以预期改进的数据传输性能。当完全支持波束成形时,AODT 将提供最佳的波束成形感知层选择算法。
MCS 选择:目前,MCS 选择算法依赖于为 AWGN 信道下单层传输导出的 SINR 到 MCS 查找表。此查找表中的 SINR 到 MCS 映射对于多层传输可能不准确。可以使用单独的 SINR 到 MCS 查找表来改进这一点,这些查找表用于不同数量的层和不同的信道特性。
数据库模式#
空中全域数字孪生生成的仿真数据保存到 Clickhouse 数据库中。以下部分描述了数据库表以及访问该数据的示例 Python 脚本。
数据库表#
1. db_info#
字段 |
类型 |
注释 |
---|---|---|
scene_url |
string |
Nucleus 服务器上场景的路径 |
scene_timestamp |
string |
场景最初打开时的时间戳 |
db_author |
string |
数据库作者,如 UI 配置选项卡中所指定 |
db_notes |
string |
任何附加说明,如 UI 配置选项卡中所指定 |
db_timestamp |
string |
数据库时间戳,如 UI 配置选项卡中所指定 |
db_schemas_version |
string |
数据库模式的版本 |
db_content |
string |
来自仿真的序列化 Prim,用于数据库回放 |
du_asset_path |
string |
Nucleus 服务器上 DU 资产的路径 |
ru_asset_path |
string |
Nucleus 服务器上 RU 资产的路径 |
ue_asset_path |
string |
Nucleus 服务器上 UE 资产的路径 |
spawn_zone_asset_path |
string |
Nucleus 服务器上生成区域资产的路径 |
panel_asset_path |
string |
Nucleus 服务器上天线面板资产的路径 |
opt_in_tables |
array(string) |
可选表名称列表 |
2. time_info#
字段 |
类型 |
注释 |
---|---|---|
time_idx |
uint32 |
仿真的时间索引 |
batch_idx |
uint32 |
仿真的批次索引 |
slot_idx |
uint32 |
仿真的时隙索引 |
symbol_idx |
uint32 |
仿真的符号索引 |
3. raypaths#
字段 |
类型 |
注释 |
---|---|---|
time_idx |
uint32 |
仿真的时间索引 |
ru_id |
uint32 |
UI 场景小部件中定义的 RU ID |
ue_id |
uint32 |
UI 场景小部件中定义的 UE ID |
interaction_types |
array(enum) |
交互类型:发射 = 0,反射 = 1,衍射 = 2,漫射 = 3,接收 = 4,传输 = 5 |
points |
array(tuple(float32, float32, float32)) |
存储交互点的 (x, y, z) 坐标 |
normals |
array(tuple(float32, float32, float32)) |
存储交互点的 (x, y, z) 法线 |
tap_power |
float32 |
射线路径信道抽头的功率,单位为瓦特 |
4. cirs#
字段 |
类型 |
注释 |
---|---|---|
time_idx |
uint32 |
仿真的时间索引 |
ru_id |
uint32 |
UI 场景小部件中定义的 RU ID |
ue_id |
uint32 |
UI 场景小部件中定义的 UE ID |
ru_ant_el |
tuple(uint32, uint32, uint32) |
RU 天线面板的天线单元索引元组 <h,v,p> |
ue_ant_el |
tuple(uint32, uint32, uint32) |
Tuple <h,v,p> of antenna element indices for the UE antenna panel |
cir_re |
array(float32) |
信道冲激响应的实部 |
cir_im |
array(float32) |
信道冲激响应的虚部 |
cir_delay |
array(float32) |
传播延迟,单位为秒 |
其中,在元组<h,v,p>中
h 是水平维度中单元的索引
v 是垂直维度中单元的索引
p 是极化的索引
5. cfrs#
字段 |
类型 |
注释 |
---|---|---|
time_idx |
uint32 |
仿真的时间索引 |
ru_id |
uint32 |
UI 场景小部件中定义的 RU ID |
ue_id |
uint32 |
UI 场景小部件中定义的 UE ID |
ru_ant_el |
tuple(uint32, uint32, uint32) |
RU 天线面板的天线单元索引元组 <h,v,p> |
ue_ant_el |
tuple(uint32, uint32, uint32) |
Tuple <h,v,p> of antenna element indices for the UE antenna panel |
cfr_re |
array(float32) |
信道频率响应的实部 |
cfr_im |
array(float32) |
信道频率响应的虚部 |
其中,在元组<h,v,p>中
h 是水平维度中单元的索引
v 是垂直维度中单元的索引
p 是极化维度的索引。
6. panels#
字段 |
类型 |
注释 |
---|---|---|
panel_id |
uint32 |
面板的索引 |
panel_name |
string |
UI 场景小部件中定义的面板名称 |
antenna_names |
array(string) |
面板中天线单元的名称 |
antenna_pattern_indices |
array(uint32) |
天线单元的索引 |
frequencies |
array(float32) |
天线单元辐射方向图的频率,单位为赫兹 |
thetas |
array(float32) |
天线单元辐射方向图的仰角,单位为弧度 |
phis |
array(float32) |
天线单元辐射方向图的方位角,单位为弧度 |
reference_freq |
float32 |
面板的中心频率 |
字段 |
类型 |
注释 |
---|---|---|
dual_polarized |
uint8 |
指示面板是否为双极化。1=双极化,0=单极化。 |
num_loc_antenna_horz |
uint32 |
平面阵列中的列数 |
nnum_loc_antenna_vert |
uint32 |
平面阵列中的行数 |
antenna_spacing_horz |
float32 |
天线单元的水平间距,单位为厘米 |
antenna_spacing_vert |
float32 |
天线单元的垂直间距,单位为厘米 |
antenna_roll_angle_first_polz |
float32 |
天线单元的旋转(以弧度为单位),对应于第一极化 |
antenna_roll_angle_second_polz |
float32 |
天线单元的旋转(以弧度为单位),对应于第二极化。仅用于双极化单元。 |
7. patterns#
字段 |
类型 |
注释 |
---|---|---|
pattern_id |
uint32 |
方向图的索引 |
pattern_type |
uint32 |
天线单元的类型:各向同性 = 0,无穷小 = 1,半波偶极子 = 2,矩形微带 = 3,自定义 >= 100 |
e_theta_re |
array(array(float32)) |
沿 |
e_theta_im |
array(array(float32)) |
沿 |
e_phi_re |
array(array(float32)) |
沿 |
e_phi_im |
array(array(float32)) |
沿 |
8. ues#
字段 |
类型 |
注释 |
---|---|---|
ID |
uint32 |
UI 场景小部件中定义的 UE ID |
is_manual |
boolean |
指示 UE 是否为手动生成 (1) 或程序化生成 (0) |
is_manual_mobility |
boolean |
指示手动 UE 是否具有用户显式添加的航点 |
radiated_power |
float32 |
UE 的辐射功率(单位:瓦特) |
height |
float32 |
UE 的高度,单位为米 |
mech_tilt |
float32 |
UE 天线面板的倾角,单位为度 |
panel |
array(uint32) |
此 UE 的天线面板索引数组 |
batch_indices |
array(uint32) |
此 UE 的批次索引数组 |
waypoint_ids |
array(array(uint32)) |
每批次航点标识符 [批次,标识符] |
waypoint_points |
array(array(tuple(float32,float32,float32))) |
每批次航点位置 [批次,航点 (x, y, z)] |
waypoint_stops |
array(array(float32)) |
每批次航点停留时间,单位为秒 [批次,停留时间] |
字段 |
类型 |
注释 |
---|---|---|
waypoint_speeds |
array(array(float32)) |
每批次航点速度,单位为米/秒 [批次,速度] |
trajectory_ids |
array(array(uint32)) |
每批次沿 UE 轨迹的航点标识符 [批次,标识符] |
trajectory_points |
array(array(tuple(float32,float32,float32))) |
每批次沿 UE 轨迹的点 [批次,点 (x, y, z)] |
trajectory_stops |
array(array(float32)) |
每批次沿 UE 轨迹的停留时间(单位:秒)[批次,停留时间] |
trajectory_speeds |
array(array(float32)) |
每批次沿 UE 轨迹的航点速度(单位:米/秒)[批次,速度] |
route_positions |
array(array(tuple(float32,float32,float32))) |
每批次沿采样路线的位置 [批次,点 (x, y, z)] |
route_orientations |
array(array(tuple(float32,float32,float32))) |
每批次沿采样路线的 UE 方向 [批次,方向 (x, y, z)] |
route_speeds |
array(array(float32)) |
每批次沿采样路线的速度(单位:米/秒)[批次,速度] |
route_times |
array(array(float32)) |
每批次沿采样路线的时间(单位:秒)[批次,时间] |
bler_target |
float32 |
UE 的目标 BLER |
is_indoor_mobility |
boolean |
用户是否具有室内移动性 |
9. rus#
字段 |
类型 |
注释 |
---|---|---|
ID |
uint32 |
UI 场景小部件中定义的 RU ID |
subcarrier_spacing |
float32 |
子载波间隔(单位:Hz) |
fft_size |
uint32 |
宽带 CFR 计算中使用的频率采样数 |
radiated_power |
float32 |
RU 的辐射功率(单位:瓦特) |
height |
float32 |
RU 的高度,单位为米 |
mech_azimuth |
float32 |
RU 的机械方位角旋转角度,单位为度 |
mech_tilt |
float32 |
mech_tilt |
panel |
array(uint32) |
RU 的机械倾角,单位为度 |
panel |
array(float32) |
此 RU 的天线面板索引数组 |
position |
uint32 |
RU 在场景中的位置。该数组包含 3 个元素 (x, y, z)。 |
du_id |
boolean |
与此 RU 关联的 DU 的索引。 |
du_manual_assign
字段 |
类型 |
注释 |
---|---|---|
ID |
uint32 |
此 RU 是否手动分配给 DU |
subcarrier_spacing |
float32 |
子载波间隔(单位:Hz) |
fft_size |
uint32 |
宽带 CFR 计算中使用的频率采样数 |
10. dus# |
uint32 |
DU ID,如 UI 场景小部件中所定义 |
num_antennas |
float32 |
DU 的天线数量 |
panel |
array(float32) |
max_channel_bandwidth |
DU 支持的最大信道带宽
字段 |
类型 |
注释 |
---|---|---|
DU 的 (x, y, z) 坐标,单位与 USD 地图相同 |
string |
11. scenario# |
default_ue_panel |
string |
分配给 UE 的默认面板 ID |
default_ru_panel |
分配给 RU 的默认面板 ID |
num_emitted_rays_in_thousands |
int32 |
分配给 RU 的默认面板 ID |
发射射线数(x 1000) |
num_scene_interactions_per_ray |
uint32 |
射线与环境交互的次数。0 = 无交互(视距) |
max_paths_per_ru_ue_pair |
分配给 RU 的默认面板 ID |
每 RU/UE 对的最大射线路径数 |
ray_sparsity |
分配给 RU 的默认面板 ID |
总计算射线数与 UI 中显示的射线数的比率 |
num_batches |
分配给 RU 的默认面板 ID |
批次数,其中每个批次代表 UE 在不同位置的重新投放 |
slots_per_batch |
分配给 RU 的默认面板 ID |
每个批次仿真的时隙数 |
symbols_per_slot |
float32 |
一个时隙中的符号数。1 或 14。 |
duration |
float32 |
仿真的持续时间(单位:秒) |
字段 |
类型 |
注释 |
---|---|---|
interval |
仿真的采样时间(单位:秒) |
enable_wideband_cfrs |
Boolean |
uint32 |
True=>CFR 包含整个 FFT 大小的频点。False=>CFR 包含中心频率处的一个频点。 |
num_ues |
float32 |
仿真中 UE 的总数 |
ue_height |
float32 |
UE 高度,单位为米 |
ue_min_speed |
float32 |
UE 最小速度,单位为米/秒 |
ue_max_speed |
uint8 |
UE 最大速度,单位为米/秒 |
is_seeded |
uint32 |
指示移动性是否播种 |
seed |
boolean |
用于定义 UE 批次投放和轨迹随机性的种子 |
simulate_ran |
boolean |
启用 RAN 仿真 |
enable_training |
启用训练仿真 |
diffuse_type |
enum |
float32 |
漫射类型:朗伯 = 0,定向 = 1 |
rx_sphere_radius_m |
float32 |
接收球半径,单位为米 |
percentage_indoor_ues
字段 |
类型 |
注释 |
---|---|---|
仿真中室内 UE 的百分比 |
uint32 |
12. telemetry# |
batch_id |
仿真的批次索引 |
slot_id |
unit32 |
string |
批次内的时隙索引 |
ru_id |
uint32 |
link |
ue_id |
uint32 |
此遥测结果是用于下行链路 (“DL”) 还是上行链路 (“UL”) |
RU ID |
uint32 |
UE ID |
startPrb |
uint32 |
调度器分配给此 UE 的起始 PRB |
nPrb |
uint8 |
调度器分配给此 UE 的 PRB 数量 |
mcs |
uint8 |
调度器分配给此 UE 的 MCS 索引 |
layers |
uint32 |
此 UE 使用的层数 |
tbs |
uint8 |
为此 UE 调度的传输块 (TB) 大小(单位:字节) |
rv |
uint32 |
此传输使用的冗余版本 |
outcome |
float32 |
子载波间隔(单位:Hz) |
传输块是否成功解码 (1) 或未成功解码 (0) |
float32 |
scs |
preEqSinr |
float32 |
均衡前 SINR |
postEqSinr
字段 |
类型 |
注释 |
---|---|---|
均衡后 SINR |
string |
13. ran_config# |
tdd_pattern |
array(uint32) |
TDD 模式 |
srs_slots |
array(uint32) |
帧内发生 SRS 传输的时隙号列表。 |
pusch_slots |
uint8 |
帧内发生 PUSCH 传输的时隙号列表。 |
dl_harq_enabled |
uint8 |
指示是否启用 DL HARQ |
ul_harq_enabled |
string |
指示是否启用 UL HARQ |
beamforming_csi |
string |
波束成形 CSI 的来源: “CFR” 或 “SRS”。 |
mac_csi |
string |
MAC 调度 CSI 的来源: “CFR” 或 “SRS”。 |
pusch_channel_estimation |
string |
用于 PUSCH 信道估计的方法: “MMSE” 或 “ML” |
scheduler_mode |
uint8 |
PRB 调度算法: “PF” 或 “RR” |
mu_mimo_enabled |
float32 |
指示是否启用 MU-MIMO |
dl_srs_snr_thr |
float32 |
用于确定下行链路中 MU-MIMO 可行性的 SRS SNR 阈值 |
ul_srs_snr_thr |
float32 |
用于确定上行链路中 MU-MIMO 可行性的 SRS SNR 阈值 |
dl_chan_corr_thr |
float32 |
下行链路中 MU-MIMO 分组决策的信道相关性阈值 |
ul_chan_corr_thr |
uint8 |
上行链路中 MU-MIMO 分组决策的信道相关性阈值 |
beamforming_enabled |
string |
指示是否启用波束成形 |
beamforming_scheme
字段 |
类型 |
注释 |
---|---|---|
time_idx |
uint32 |
波束成形方案:“子载波级别 ZF 波束成形”、“PRBG 级别 ZF 波束成形”或“UEG 级别 ZF 波束成形” |
14. training_result# |
string |
仿真的当前时间索引 |
name |
模型的可选名称 |
training_losses |
array(tuple(uint32,float32)) |
模型的可选名称 |
训练损失:对于给定的时间索引,可能有多次迭代训练,因此格式为 [(迭代 0, 损失 0), (迭代 1, 损失 1), …] |
validation_losses |
模型的可选名称 |
可选的验证损失,格式与训练损失相同 |
test_losses |
模型的可选名称 |
可选的测试损失,格式与训练损失相同 |
baseline_losses |
string |
基线损失,格式与训练损失相同 |
title |
string |
UI 中损失图的可选标题,例如“训练损失” |
y_label |
string |
UI 中损失图的可选 y 轴标签,例如“MSE (dB)” |
x_label
UI 中损失图的可选 x 轴标签,例如“时隙”
15. world#
字段 |
类型 |
注释 |
---|---|---|
保留 |
string |
16. materials# |
label |
捕获 UI 场景中设置的材料集 |
itu_r_p2040_a |
float64 |
捕获 UI 场景中设置的材料集 |
ITU-R P2040 ‘a’ 参数 \(^{[1]}\) |
itu_r_p2040_b |
捕获 UI 场景中设置的材料集 |
ITU-R P2040 ‘b’ 参数 \(^{[1]}\) |
itu_r_p2040_c |
捕获 UI 场景中设置的材料集 |
ITU-R P2040 ‘c’ 参数 \(^{[1]}\) |
itu_r_p2040_d |
捕获 UI 场景中设置的材料集 |
ITU-R P2040 ‘d’ 参数 \(^{[1]}\) |
scattering_xpd |
捕获 UI 场景中设置的材料集 |
散射交叉极化/同极化功率比 |
rms_roughness |
捕获 UI 场景中设置的材料集 |
表面粗糙度的均方根 |
scattering_coeff |
分配给 RU 的默认面板 ID |
散射系数 |
exponent_alpha_r |
分配给 RU 的默认面板 ID |
定向漫射模型中前向散射瓣的整数指数参数 |
exponent_alpha_i |
捕获 UI 场景中设置的材料集 |
定向漫射模型中后向散射瓣的整数指数参数 |
lambda_r |
捕获 UI 场景中设置的材料集 |
定向漫射模型中前向散射功率与总散射功率之比 |
thickness_m
材料的厚度,单位为米
[1] ITU,《建筑物材料和结构对约 100 MHz 以上无线电波传播的影响》,建议 P.2040-3,2023 年 8 月,表 3。
访问数据库中的结果#
一些关于如何访问数据库结果的示例与源代码捆绑在一起,位于 examples/ 目录中。这些脚本用作模板,可以扩展用于您自己的数据分析。
Clickhouse 脚本示例#
$ clickhouse-client
:) show databases
有两种运行 ClickHouse 脚本的方法 - 使用 Jupyter 笔记本或作为 Python 脚本。下面解释了这两种方法。
要作为脚本运行,必要的软件包在开发容器内部可用。有关如何启动开发容器的信息,请参阅本指南的 安装 章节。然后,使用
clickhouse-client
或使用 UI 中 Configurations 选项卡中的数据库名称来识别感兴趣的数据库名称。在本节中,我们将
RU
与tx
互换使用,将UE
与rx
互换使用。示例假设以下数据库配置
数据库名称:yoda_2024_4_15_13_4_6
主机名:localhost
python3 extract_CIR_sample.py --hostname <hostname> --database <database_name> --sample <time_idx> --RU <tx_id> --UE <rx_id>
1. extract_CIR_sample.py#
python3 extract_CIR_sample.py --hostname "localhost" --database "yoda_2024_4_15_13_4_6" --sample 5 --RU 1 --UE 2
提供此脚本是为了说明如何访问数据库中的 cirs 表。
例如,要检索样本 5、ue_0002 和 ru_0001 的 CIR,请运行以下命令
该脚本获取所需的 CIR,并将它们写入二进制文件 sample-cir-<time_idx>.dat。可以使用 pickle Python 模块访问二进制文件。序列化的数据结构具有以下定义
data:包含每个射线路径的复振幅
delay:包含关联的到达时间,单位为秒
数据和延迟字典的形状为
[time_idx, tx_id, rx_id]
,其中最内层维度rx_id
是大小为以下值的平铺数组\( \left(Max_{Paths}, N_{hor.}^{\left(rx\right)} \times N_{vert.}^{\left(rx\right)} \times N_{pol.}^{\left(rx\right)}, N_{hor.}^{\left(tx\right)} \times N_{vert.}^{\left(tx\right)} \times N_{pol.}^{\left(tx\right)} \right) \)
\(Max_{Paths}\) 是 CIR 中样本的长度,
\(N_{hor.}^{yx}\) 是 \(yx\) 面板中水平天线站点的数量(不考虑极化)
\(N_{vert.}^{yx}\) 是 \(yx\) 面板中垂直天线站点的数量(不考虑极化)
\(N_{pol.}^{yx}\) 是 \(yx\) 面板中每个天线站点使用的极化数量。
也就是说,数组按照以下顺序平铺
[\(h_{0}v_{0}p_{0}\), \(h_{0}v_{0}p_{1}\) … \(h_{0}v_{N_{vert}}p_{1}\) … \(h_{N_{hor}}v_{N_{vert}}p_{1}\) ],其中,h,v,p 对应于天线面板的水平、垂直和极化维度。
python3 extract_CIR_sample.py --hostname <hostname> --database <database_name> --sample <time_idx> --RU <tx_id> --UE <rx_id>
2. extract_CFR_sample.py#
python3 extract_CFR_sample.py --hostname "localhost" --database "yoda_2024_4_15_13_4_6" --sample 5 --RU 1 --UE 2
extract_CFR_sample.py
从 cfrs 表中读取信道频率响应 (CFR)。
例如,如果我们需要样本 5、ue_0002 和 ru_0001 的 CFR,请运行以下命令
该脚本获取所需的 CFR,并将其添加到字典中,然后写入 sample-cfr-<time_idx>.dat 二进制文件。序列化的数据结构包含一个字典 data
,其中包含指定 RU 和 UE 天线对的信道频率响应。data
的形状类似于上一节中 CIR 的形状,除了最内层平铺数组的大小为: \( \left(NFFT, N_{hor.}^{\left(rx\right)} \times N_{vert.}^{\left(rx\right)} \times N_{pol.}^{\left(rx\right)}, N_{hor.}^{\left(tx\right)} \times N_{vert.}^{\left(tx\right)} \times N_{pol.}^{\left(tx\right)} \right) \)
其中 \(NFFT\) 是 FFT 的大小,用于将时域样本转换为频域样本。
除了 CFR 之外,该脚本还转储以下标量量
fft_size
:CFR 的大小scs
:子载波间隔
ue_fc
:UE 的中心频率
脚本 extract_CIR.py
和 extract_CFR.py
提取所有 RU/UE 天线对和所有时间样本的数据。为了加快从数据库中读取如此大量数据的速度,这些脚本使用了用 C++ 编写的快速读取器。一个名为 chapi_bindings 的预编译库。
cfrs = read_cfrs_db(hostname,database)
cirs,delays = read_cfrs_db(hostname,database)
例如
cfrs = read_cfrs_db("localhost","yoda_2024_4_15_13_4_6")
cirs,delays = read_cfrs_db("localhost",yoda_2024_4_15_13_4_6)
这些绑定由 extract_CIR.py
和 extract_CFR.py
调用,以便生成 pickle 文件 cirs.dat
或 cfrs.dat
。用法如下
python3 extract_CIR.py --database <database_name> --hostname <hostname>
PYTHONPATH=build/examples python3 examples/extract_CIR_sample.py --database "yoda_2024_4_15_13_4_6" --hostname "localhost"
请注意,与 extract_CFR_sample.py
不同,read_cfrs_db()
函数仅返回 CFR,而不返回其他标量量。
5. plot_PDP_from_CIR.py#
该脚本生成与其中一个 RU/UE 天线链路相关的信道脉冲响应图。
python3 plot_PDP_from_CIR.py --filename sample-cir-<time_idx>.dat --sample <time_idx> --RU <tx_id> --UE <rx_id> --suppress
6. plot_PDP_from_CFR.py#
信道脉冲响应也可以通过运行以下命令,使用信道频率响应数据计算并绘制出来
python3 plot_PDP_from_CFR.py --filename sample-cir-<time_idx>.dat --sample <time_idx> --RU <tx_id> --UE <rx_id>
7. plot_PAS_from_CIR.py#
此脚本使用 raypaths 表中的射线来计算上行链路功率谱。
python3 plot_PAS_from_CIR.py --filename sample-cir-<time_idx>.dat --sample <time_idx> --RU <tx_id> --UE <rx_id> --angle [azimuth|zenith] --suppress
8. plot_CFR.py#
最后,要可视化信道频率响应,请运行
python plot_CFR.py -filename sample-<time_idx>.dat --sample <time_idx> --RU <tx_id> --UE <rx_id>
Jupyter 笔记本#
这些脚本可以通过 Jupyter 笔记本方便地运行。以下笔记本在 examples/notebooks 目录中提供
CFR.ipynb
CIR.ipynb
ExportData.ipynb
ImportData.ipynb
可以通过使用后端地址 http://omniverse-server:8888/ 打开 Web 浏览器来访问 Jupyter 笔记本。
从 H5 文件访问 Rx 信号数据#
在 RAN 仿真模式下运行时,如果在 config_ran.json 中为“RX FT filename”指定了文件名,则接收到的信号(即 I/Q 样本)将保存到具有指定文件名的 H5 文件中,用于每个 PDSCH/PUSCH 时隙。以下是如何使用 Python 脚本访问数据的示例
import h5py
file_path = "/home/aerial/asim_em/rx_dump.h5"
with h5py.File(file_path, 'r') as h5_file:
slot = '0'
dataset_name = 'mRxSignal'
rx_data = h5_file[slot][dataset_name][:] # shape: (active cell num, rx ant num, symbol num, subcarrier num)
slot_type = h5_file[slot]["slot_type"][:] # 0: DL, 1: UL
EM 引擎接口#
EM 引擎由 NVIDIA 直接开发,但它通过特定的接口以模块化方式嵌入到 Aerial Omniverse Digital Twin 中。这允许在必要时支持集成不同的 EM 引擎。本节旨在通过概述 NVIDIA EM 引擎的关键机制来为这种可能性做好准备。
NVIDIA 的 EM 引擎 API 提供了以下功能:
管理设备内存,
执行 EM 计算,
并将结果复制到主机内存。
所有类、成员函数和变量都在 aerial_emsolver_api.h
头文件中定义,并使用 C++/CUDA 原始数据类型。
数据类型#
d_complex
typedef thrust::complex<float> d_complex
Thrust 复数数据类型,用于主机代码和设备代码。
d_complex4
typedef struct d_complex4 { d_complex m[4]{}; } d_complex4
四个
d_complex
元素的数组。Matrix4x4
typedef struct Matrix4x4 { float m[4][4]{}; } Matrix4x4
一个 \(4\times4\) 的
d_complex
元素矩阵。EMMaterial
struct EMMaterial { float4 abcd{}; float roughness_rms{}; float k_xpol{}; float scattering_coeff{}; int exponent_alpha_R{}; int exponent_alpha_I{}; float lambda_R{}; float thickness_m{}; }
一个存储 EM 材料参数的结构体。
成员
描述
abcd
一个
float4
,存储用于计算相对介电常数 ITU-R P2040 a、b、c 和 d 参数 [1]roughness_rms
表面粗糙度的均方根(类型为
float
),单位为米k_xpol
散射交叉极化/共极化功率比(类型为
float
)rms_roughness
exponent_alpha_R
定向漫反射模型中前向散射瓣(在镜面反射方向)的整数指数(类型为
int
)exponent_alpha_I
定向漫反射模型中后向散射瓣(在入射方向)的整数指数(类型为
int
)lambda_R
定向漫反射模型中前向散射功率与总散射功率之比(类型为
float
)lambda_r
单层材料的厚度(类型为
float
),单位为米
漫反射模型可以是朗伯型或定向型,并且有两种方法可以调整漫反射散射模式
使用固定的正
scattering_coeff
(ER 模型),它不依赖于入射波的入射角。此系数用于计算反射减少因子和用于漫反射散射的功率比例。在这种情况下,roughness_rms
参数被忽略,因为(abcd, scattering_coeff, k_xpol)
和(abcd, scattering_coeff, k_xpol, exponent_alpha_R, exponent_alpha_I, lambda_R, thickness_m)
集合分别足以用于朗伯型和定向漫反射模型。使用
roughness_rms
来表征瑞利反射减少因子 [4], [5] 和漫反射散射的功率比例。在这种情况下,scattering_coeff
参数被忽略,因为(abcd, roughness_rms, k_xpol)
和(abcd, roughness_rms, k_xpol, exponent_alpha_R, exponent_alpha_I, lambda_R, thickness_m)
集合分别足以用于朗伯型和定向漫反射模型。
默认情况下,对于具有正 scattering_coeff
的材料,使用第一种方法。否则,如果 scattering_coeff = 0.0
,则使用第二种方法。对于定向漫反射模型,公式 [3] 是互易的。当 lambda_R = 1.0
时,定向漫反射模型变为单瓣漫反射 (SLD) 模型,前向瓣包含总漫反射散射功率。不同的是,该模型将使用两个瓣。
对于反射和透射系数,使用 ITU 建议书 P.2040-3 中具有单一厚度的单层平板模型。
EM_INTERACT_TYPE
enum EM_INTERACT_TYPE : unsigned int { Emission = 0, Reflection = 1, Diffraction = 2, Diffuse = 3, Reception = 4, Transmission = 5, Reserved, }
每个射线的 EM 交互类型枚举。
EM_DIFFUSE_TYPE
enum EM_DIFFUSE_TYPE : unsigned int { Lambertian = 0, Directional = 1 }
EM 漫反射类型枚举。
RayPath
struct RayPath { int tx_id{}; int rx_id{}; int tx_ij[2]{}; int rx_ij[2]{}; int rx_index{}; EM_INTERACT_TYPE point_types[MAX_NUM_INTERACTIONS_WITH_TRANSMISSION+2]{}; float3 points[MAX_NUM_INTERACTIONS_WITH_TRANSMISSION+2]{}; int prim_ids[MAX_NUM_INTERACTIONS_WITH_TRANSMISSION+2]{}; float3 normals[MAX_NUM_INTERACTIONS_WITH_TRANSMISSION+2]{}; int num_points{}; d_complex cir_ampl[4]{}; float cir_delay{}; __host__ __device__ RayPath() {} __host__ __device__ RayPath(int* tx_ij, int* rx_ij, float3* points, EM_INTERACT_TYPE* point_types, int* prim_ids, float3* normals, int tx_id, int rx_id, int rx_index, int num_points); }
一个存储传播路径的几何和 EM 数据的结构体。
成员
描述
tx_id
RU 的 ID(类型为
int
)rx_id
UE 的 ID(类型为
int
)tx_ij
RU 面板内天线元素的索引(类型为
int
,i
代表水平索引,j
代表垂直索引)的双元素数组rx_ij
UE 面板内天线元素的索引(类型为
int
,i
代表水平索引,j
代表垂直索引)的双元素数组rx_index
UE 的索引(类型为
int
)point_types
一个
EM_INTERACT_TYPE
数组,存储路径上各点的 EM 交互类型points
一个
float3
数组,存储交互点的 (x, y, z) 坐标,单位与 USD 地图相同*prim_ids
一个
int
数组,存储交互点处几何图元的索引:反射的命中三角形索引,衍射的命中边缘索引,否则为 -1normals
一个
float3
数组,存储交互点处的法线num_points
从 RU 到 UE 的交互点数量(类型为
int
)cir_ampl
一个包含四个复数值元素的数组,存储四个 UE-RU 极化组合的路径 CIR 幅度**
cir_delay
路径的传播延迟(类型为
float
),单位为秒*地图单位由 USD 文件中的
Meters Per Unit
确定。例如,如果Meters Per Unit = 1
,则地图单位为米;如果Meters Per Unit = 0.01
,则地图单位为厘米。**cir_ampl[i*2 + j]
用于 UE 的第 \(i\) 个极化和 RU 的第 \(j\) 个极化,其中 \(i \in \left[0, 1\right]\) 和 \(j \in \left[0, 1\right]\)。ANTENNA_TYPE
enum ANTENNA_TYPE : unsigned int { Isotropic = 0, Infinitesimal_dipole = 1, Halfwave_dipole = 2, Rec_microstrip_patch = 3 }
EM 求解器当前支持的内置天线类型枚举。
AntennaPattern
struct AntennaPattern { int pattern_type{}; std::vector<std::vector<d_complex>> ampls_theta{}; std::vector<std::vector<d_complex>> ampls_phi{}; }
一个结构体,存储给定天线元素的辐射方向图,用于内置或自定义天线类型。当前版本仅支持单频方向图。
成员
描述
pattern_type
一个整数,指示
ANTENNA_TYPE
枚举中定义的辐射方向图类型(类型为int
)ampls_theta
一个二维向量,存储天线辐射场沿 theta 方向的复数值幅度(类型为
d_complex
),每个内部向量存储一个频率的幅度ampls_phi
一个二维向量,存储天线辐射场沿 phi 方向的复数值幅度(类型为
d_complex
),每个内部向量存储一个频率的幅度对于内置天线类型,辐射场由 EM 引擎解析计算,并且
ampls_theta
和ampls_phi
成员变量被忽略。例如,对于Infinitesimal_dipole
方向图类型,AntennaPattern
对象是AntennaPattern pattern = {.pattern_type = 1, .ampls_theta = {}, .ampls_phi = {}};
AntennaPanel
struct AntennaPanel { std::string panel_name{}; std::vector<std::string> antenna_names{}; std::vector<int> antenna_pattern_indices{}; std::vector<float> frequencies{}; std::vector<float> thetas{}; std::vector<float> phis{}; double reference_freq{}; bool dual_polarized{}; int num_loc_antenna_horz{}; int num_loc_antenna_vert{}; double antenna_spacing_horz{}; double antenna_spacing_vert{}; double antenna_roll_angle_first_polz{}; double antenna_roll_angle_second_polz{}; }
一个结构体,存储给定天线面板的信息。面板中天线元素的数量为
num_loc_antenna_horz*num_loc_antenna_vert*num_polarizations
。成员
描述
panel_name
面板的名称(类型为
string
)antenna_names
面板中所有天线元素的名称向量(类型为
string
)antenna_pattern_indices
面板中天线元素的
patterns
向量的索引向量(类型为int
)frequencies
面板中天线元素的辐射方向图的频率向量(类型为
float
),单位为赫兹thetas
存储面板中所有天线元素的辐射方向图的仰角(类型为
float
)的向量,单位为弧度phis
存储面板中所有天线元素的辐射方向图的方位角(类型为
float
)的向量,单位为弧度reference_freq
面板的中心频率(类型为
double
),单位为赫兹dual_polarized
一个
bool
变量,指示面板天线是双极化(true)还是单极化(false)num_loc_antenna_horz
沿行平面阵列中天线元素位置的数量(类型为
int
)num_loc_antenna_vert
沿列平面阵列中天线元素位置的数量(类型为
int
)antenna_spacing_horz
水平天线元素间距(类型为
double
),单位为厘米antenna_spacing_vert
垂直天线元素间距(类型为
double
),单位为厘米antenna_roll_angle_first_polz
实现第一极化的天线元素的角位移(类型为
double
),单位为弧度antenna_roll_angle_second_polz
实现第二极化的元素的角位移(类型为
double
),单位为弧度AntennaInfo
struct AntennaInfo { std::vector<AntennaPanel> panels{}; std::vector<AntennaPattern> patterns{}; }
一个结构体,封装所有天线面板和天线辐射方向图的信息。
成员
描述
panels
面板向量(类型为
AntennaPanel
)patterns
方向图向量(类型为
AntennaPattern
)TXInfo
struct TXInfo { int tx_ID{}; float3 tx_center{}; Matrix4x4 Ttx{}; std::vector<int> panel_id{}; float height{}; float mech_azimuth_deg{}; float mech_tilt_deg{}; float carrier_freq{}; float carrier_bandwidth{}; float subcarrier_spacing{}; int fft_size{}; float radiated_power{}; std::vector<std::string> antenna_names{}; std::vector<int> antenna_pattern_indices{}; bool dual_polarized_antenna{}; std::vector<float3> antenna_rotation_angles{}; int num_loc_antenna_horz{}; int num_loc_antenna_vert{}; std::vector<float3> loc_antenna{}; std::vector<std::pair<int, int>> ij_antenna{}; }
一个结构体,存储 RU 信息。
成员
描述
tx_ID
RU 的 ID(类型为
int
)tx_center
RU 中心的 (x, y, z) 坐标(类型为
float3
),单位与 USD 地图相同Ttx
RU 的
Matrix4x4
变换矩阵,结合了平移和旋转,单位与 USD 地图相同panel_id
一个索引向量(类型为
int
),标识 RU 使用的面板;目前仅支持大小为 1height
从 RU 底部到 RU 中心计算的高度(类型为
float
),单位为厘米mech_azimuth_deg
RU 的机械方位角(类型为
float
),单位为度mech_tilt_deg
RU 的机械倾斜角(类型为
float
),单位为度carrier_freq
RU 的载波频率(类型为
float
),单位为赫兹subcarrier_spacing
子载波间隔(类型为
float
),单位为赫兹fft_size
用于宽带 CFR 计算的 FFT 大小(类型为
int
)radiated_power
RU 的辐射功率(类型为
float
),单位为瓦特antenna_names
RU 面板中所有天线元素的名称向量(类型为
string
)antenna_pattern_indices
RU 面板中天线元素的
patterns
向量的索引向量(类型为int
)dual_polarized_antenna
一个
bool
变量,指示 RU 天线面板是由双极化(true)还是单极化(false)元素组成antenna_rotation_angles
一个三元组向量,存储天线的旋转角(类型为
float3
):第一个三元组用于第一极化,在双极化天线的情况下,第二个三元组用于第二极化num_loc_antenna_horz
RU 天线面板内水平方向上的天线元素位置数量(类型为
int
)num_loc_antenna_vert
RU 天线面板内垂直方向上的天线元素位置数量(类型为
int
)loc_antenna
RU 天线面板内天线位置的 (x, y, z) 向量(类型为
float3
),单位与 USD 地图相同*ij_antenna
一个索引对向量(类型为
int
),存储 RU 天线面板中天线元素的水平和垂直索引注意:
TXInfo
中的天线位置和(i, j)
天线索引在顺序上是一致的:例如,位于索引为(i, j)
且极化为p
的位置的元素是antenna_names[i*num_loc_antenna_vert*num_polarizations + j*num_polarizations + p - 1]
,其中num_polarizations
对于单极化面板为 1,对于双极化面板为 2。此外,(i, j) = (0, 0)
表示天线阵列中左下角的天线位置。这些约定也用于下面的RXInfo
结构体。值得注意的是,在图形界面中,阵列的顶部和底部是倒置的,即在图形界面顶部的内容在 EM 求解器中被认为是底部。RXInfo
struct RXInfo { int rx_ID{}; float3 rx_center{}; Matrix4x4 Trx{}; std::vector<int> panel_id{}; float radiated_power{}; std::vector<std::string> antenna_names{}; std::vector<int> antenna_pattern_indices{}; bool dual_polarized_antenna{}; std::vector<float3> antenna_rotation_angles{}; int num_loc_antenna_horz{}; int num_loc_antenna_vert{}; std::vector<float3> loc_antenna{}; std::vector<std::pair<int, int>> ij_antenna{}; }
一个结构体,存储 UE 信息。
成员
描述
rx_ID
UE 的 ID(类型为
int
)rx_center
UE 中心的 (x, y, z) 坐标(类型为
float3
),单位与 USD 地图相同Trx
UE 的
Matrix4x4
变换矩阵,结合了平移和旋转,单位与 USD 地图相同panel_id
一个索引向量(类型为
int
),标识 UE 使用的面板;目前仅支持大小为 1radiated_power
UE 的辐射功率(类型为
float
),单位为瓦特antenna_names
UE 面板中所有天线元素的名称向量(类型为
string
)antenna_pattern_indices
UE 面板中天线元素的
patterns
向量的索引向量(类型为int
)dual_polarized_antenna
一个
bool
变量,指示 UE 天线面板是由双极化(true)还是单极化(false)元素组成antenna_rotation_angles
一个三元组向量,存储天线的旋转角(类型为
float3
):第一个三元组用于第一极化,在双极化天线的情况下,第二个三元组用于第二极化num_loc_antenna_horz
UE 天线面板内水平方向上的天线元素位置数量(类型为
int
)num_loc_antenna_vert
UE 天线面板内垂直方向上的天线元素位置数量(类型为
int
)loc_antenna
RU 天线面板内天线位置的 (x, y, z) 向量(类型为
float3
),单位与 USD 地图相同ij_antenna
一个索引对向量(类型为
int
),存储 UE 天线面板中天线元素的水平和垂直索引Mesh
struct Mesh { std::vector<float3> mesh_vertices{}; std::vector<int> triangle_material_ids{}; bool is_diffusion{}; bool is_diffraction{}; bool is_transmission{}; };
一个结构体,存储场景中三角形网格的信息。
成员
描述
mesh_vertices
三角形网格的顶点向量(类型为
float3
)*,单位与 USD 地图相同triangle_material_ids
网格三角形的材质索引向量(类型为
int
)is_diffusion
标志(类型为
boolean
),指示网格是否启用漫反射(True
)或未启用(False
)is_diffraction
标志(类型为
boolean
),指示网格是否启用衍射(True
)或未启用(False
)is_transmission
标志(类型为
boolean
),指示网格是否启用透射(True
)或未启用(False
)注意:顶点以 3 个元素的元组分组,用于构建三角形,例如,第一个三角形的顶点为 {[0], [1], [2]},第二个三角形的顶点为 {[3], [4], [5]},依此类推。对于每个三角形,顶点缠绕顺序为逆时针,以便其正面法线对于建筑物网格指向外侧,对于地面网格指向上方。
GeometryInfo
struct GeometryInfo { std::vector<Mesh> building_mesh{}; std::vector<Mesh> terrain_mesh{}; std::unordered_map<std::string, std::pair<int,EMMaterial>> material_dict{}; float meters_per_unit = 0.01f; };
一个结构体,存储场景中几何体的信息。
成员
描述
building_mesh
场景中建筑物网格的向量(类型为
Mesh
)terrain_mesh
场景中地形网格的向量(类型为
Mesh
)material_dict
材质字典的无序映射,存储场景中的所有材质:键是材质名称(类型为
string
),值是<int, EMMaterial>
对meters_per_unit
网格空间单位中米的数量的常数值(类型为
float
),默认值为 0.010.01
RTConfig
struct RTConfig { int num_rays_in_thousands{}; int max_num_bounces{}; float rx_sphere_radius_cm{}; EM_DIFFUSE_TYPE em_diffuse_type{}; bool use_only_first_antenna_pair{}; bool calc_tau_mins{}; bool simulate_ran{}; }
一个结构体,存储射线追踪参数的配置。
成员
描述
num_rays_in_thousands
以千为单位的发射射线数量(类型为
int
)max_num_bounces
每条发射射线的最大散射事件数(类型为
int
)rx_sphere_radius_cm
接收球半径(类型为
float
),单位为厘米enable_training
漫反射类型,用于指示漫反射散射模型(类型为
EM_DIFFUSE_TYPE
):朗伯型 = 0,定向型 = 1use_only_first_antenna_pair
一个
bool
变量,设置为true
时,仅从runEMSolver()
返回第一个 RU-UE 天线对的结果calc_tau_mins
一个
bool
变量,设置为true
时,runEMSolver()
返回最小传播延迟seed
a
bool
变量,当设置为true
时,启用完整的 RAN 仿真
计算互耦方向图#
compute_mutual_coupling_patterns()
std::vector<emsolver::AntennaPattern> compute_mutual_coupling_patterns(const emsolver::AntennaPanel &panel);
计算天线方向图,包括互耦效应。
支持的 CUDA 架构#
supported_cuda_architectures()
std::vector<uint32_t> supported_cuda_architectures();
根据 emsolver 库编译返回支持的 CUDA 架构列表,例如 [80, 86, 89, 90]。
类 AerialEMSolver#
AerialEMSolver()
AerialEMSolver(const std::vector<TXInfo>& tx_info, const std::vector<RXInfo>& rx_info, const AntennaInfo& antenna_info, const GeometryInfo& geometry_info, const RTConfig& rt_cfg, cudaStream_t ext_stream);
AerialEMSolver 对象的构造函数。
输入/输出
参数
描述
[输入]
tx_info
一个
TXInfo
结构体向量,存储 RU 的信息[输入]
rx_info
一个
RXInfo
结构体向量,存储 UE 的信息[输入]
antenna_info
AntennaInfo
结构体,存储所有天线面板和天线辐射方向图的信息[输入]
geometry_info
GeometryInfo
结构体,存储场景几何体和材质的信息[输入]
rt_cfg
RTConfig
结构体,存储射线追踪配置[输入]
ext_stream
CUDA 流索引(类型为
cudaStream_t
)~AerialEMSolver()
~AerialEMSolver()
AerialEMSolver 对象的析构函数。
allocateDeviceMemForResults()
int32_t allocateDeviceMemForResults(const std::vector<TXInfo>& tx_info, const std::vector<RXInfo>& rx_info, const std::vector<uint32_t>& tx_indices, const std::vector<std::vector<uint32_t>>& rx_indices, const RTConfig& rt_cfg, const int symbols_per_slot, std::vector<d_complex*>& d_all_CFR_results, std::vector<float*>& d_all_tau_mins);
分配设备 (GPU) 内存以存储 EM 引擎的结果。
输入/输出
参数
描述
[输入]
tx_info
一个
TXInfo
结构体向量,存储所有 RU 的信息[输入]
rx_info
一个
RXInfo
结构体向量,存储所有 UE 的信息[输入]
tx_indices
RU 的索引向量(类型为
uint32_t
),这些 RU 的结果需要计算[输入]
rx_indices
所选 UE 的索引向量的向量(类型为
uint32_t
),用于每个 RU,这些 RU 的结果需要计算[输入]
rt_cfg
RTConfig
结构体,存储射线追踪配置[输入]
slots_per_batch
一个时隙中的符号数(类型为
int
)(1 或 14)[输出]
d_all_CFR_results
设备指针向量(类型为
d_complex
),每个指针指向存储给定 RU 相关联的 UE 的 CFR 的内存地址。该向量的内容遵循tx_indices
的内容[输出]
d_all_tau_mins
设备指针向量(类型为
float
),每个指针指向存储给定 RU 相关联的 UE 的最小传播延迟的内存地址。该向量的内容遵循tx_indices
的内容第 \(i\) 个 RU 的所有 CFR 结果,即
d_all_CFR_results_i = d_all_CFR_results[i]
,以多维数组的扁平化表示形式存储在设备内存中,其索引顺序为<ue_idx>、 <symbol_idx>、 <freq_idx>、 <ue_ant_idx>、 <ue_ant_pol_idx>、 <ru_ant_idx>、 <ru_ant_pol_idx>
。例如,
d_all_CFR_results_i
的前 6 个元素,假设第 \(i\) 个 RU 配备了双极化天线,并且所有关联的 UE 也都配备了双极化天线,则为对于最小延迟结果,所有 RU-UE 天线对都只有一个最小延迟(即,一个 RU-UE 对一个值,并且
d_all_CFR_results[i]
包含从第 \(i\) 个 RU 到其关联 UE 的最小延迟)。runEMSolver()
int32_t runEMSolver(const unsigned int time_idx, const std::vector<TXInfo>& tx_info, const std::vector<RXInfo>& rx_info, const AntennaInfo& antenna_info, const std::vector<uint32_t>& tx_indices, std::vector<std::vector<uint32_t>>& rx_indices, const RTConfig& rt_cfg, const int symbol_idx, const int symbols_per_slot, std::vector<RayPath>& all_ray_path_results, std::vector<d_complex*>& d_all_CFR_results, std::vector<float*>& d_all_tau_mins);
启动 EM 引擎。
输入/输出
参数
描述
[输入]
time_idx
仿真中的时间索引(类型为
unsigned int
)[输入]
tx_info
一个
TXInfo
结构体向量,存储所有 RU 的信息[输入]
rx_info
一个
RXInfo
结构体向量,存储所有 UE 的信息[输入]
antenna_info
AntennaInfo
结构体,存储所有天线面板和天线辐射方向图的信息[输入]
tx_indices
RU 的索引向量(类型为
uint32_t
),这些 RU 的结果需要计算[输入]
rx_indices
所选 UE 的索引向量的向量(类型为
uint32_t
),用于每个 RU,这些 RU 的结果需要计算[输入]
rt_cfg
RTConfig
结构体,存储射线追踪配置[输入]
symbol_idx
时隙内的符号索引(类型为
int
)[输入]
slots_per_batch
一个时隙中的符号数(类型为
int
)(1 或 14)[输入]
all_ray_path_results
一个
RayPath
结构体向量,存储从所有选定的 RU 到其关联 UE 的所有传播结果[输出]
d_all_CFR_results
设备指针向量(类型为
d_complex
),每个指针指向存储给定 RU 相关联的 UE 的 CFR 的内存地址。该向量的内容遵循tx_indices
的内容[输出]
d_all_tau_mins
设备指针向量(类型为
float
),每个指针指向存储给定 RU 相关联的 UE 的最小传播延迟的内存地址。该向量的内容遵循tx_indices
的内容copyResultsFromDeviceToHost()
int32_t copyResultsFromDeviceToHost(const std::vector<uint32_t>& tx_indices, const std::vector<std::vector<uint32_t>>& rx_indices, const RTConfig& rt_cfg, const int symbols_per_slot, const std::vector<d_complex*>& d_all_CFR_results, std::vector<std::vector<d_complex>>* all_CFR_results);
将 EM 引擎的结果从设备复制到主机。
输入/输出
参数
描述
[输入]
tx_indices
RU 的索引向量(类型为
uint32_t
),这些 RU 的结果需要计算[输入]
rx_indices
所选 UE 的索引向量的向量(类型为
uint32_t
),用于每个 RU,这些 RU 的结果需要计算[输入]
rt_cfg
RTConfig
结构体,存储射线追踪配置[输入]
slots_per_batch
一个时隙中的符号数(类型为
int
)(1 或 14)[输入]
d_all_CFR_results
设备指针向量(类型为
d_complex
),每个指针指向存储给定 RU 相关联的 UE 的 CFR 的内存地址。该向量的内容遵循tx_indices
的内容[输出]
all_CFR_results
指向主机端向量的指针,该向量包含 CFR 结果,其中内部向量保存从一个 RU 到其关联 UE 的 CFR,外部向量遵循
tx_indices
deAllocateDeviceMemForResults()
int32_t deAllocateDeviceMemForResults(const RTConfig& rt_cfg, std::vector<d_complex*>& d_all_CFR_results, std::vector<float*>& d_all_tau_mins);
释放先前用于 EM 引擎结果的设备内存。
输入/输出
参数
描述
[输入]
rt_cfg
RTConfig
结构体,存储射线追踪配置[输入]
d_all_CFR_results
设备指针向量(类型为
d_complex
):每个指针指向一个设备内存,该内存保存从一个 RU 到其关联 UE 的 CFR 的复数值幅度。向量的大小等于 tx_indices 的大小[输入]
d_all_tau_mins
设备指针向量(类型为
float
),每个指针指向存储给定 RU 相关联的 UE 的最小传播延迟的内存地址。该向量的内容遵循tx_indices
的内容
错误处理#
EM 引擎具有内置的错误处理机制。发生错误或无效情况的函数会被记录下来,并且错误消息会传播到本地和控制台以及图形界面中的控制台选项卡。
EMLogLevel
enum class EMLogLevel {ERROR=0, NOTIFY=1, WARNING=2, INFO=3, DEBUG=4, VERBOSE=5}
用于日志记录级别的枚举。
EMLogCallback
EMLogCallback = std::function<void(EMLogLevel, const std::string&)>;
回调函数原型。
registerLogCallback()
int32_t registerLogCallback(EMLogCallback func);
用于注册回调函数(类型为
EMLogCallback
)以进行错误处理的函数。deregisterLogCallback()
int32_t deregisterLogCallback();
用于注销当前已注册的回调函数的函数。
源代码和开发容器#
在开发容器中构建源代码时,必须将 examples/CMakeLists.txt 中的 Python 版本从 3.11 更改为 3.10,以便在该文件中
find_package(Python 3.10 REQUIRED COMPONENTS Interpreter Development)
run_aodt_sim_devel.sh
脚本将源代码挂载到容器中,以便在开发容器内进行的编辑和构建操作可以持久保存在主机磁盘上。
在开发容器内运行代码之前,必须停止安装脚本启动的 aodt_sim
容器。
cd $HOME/aodt_1.2.0/backend
docker-compose stop connector
容器停止后,我们可以按照以下说明构建 aodt_sim
可执行文件
cd aodt_sim
# Set to desired GPU number. E.g., 0 to use GPU device 0 from inside the container.
GPU=0 ./container/run_aodt_sim_devel.sh
docker exec -it c_aodt_sim_$USER /bin/bash
# Inside the development container
cmake -Bbuild -GNinja -DCMAKE_CUDA_ARCHITECTURES="80;86;89;90" -DNVTX_ENABLED=OFF -DCMAKE_BUILD_TYPE=RelWithDebInfo
cmake --build build
# Test the build
OMNI_USER=omniverse OMNI_PASS=aerial_123456 ./build/aodt_sim --nucleus omniverse://omniverse-server --broadcast broadcast --log debug
上面的示例假设已执行安装脚本。作为安装的一部分,已将行添加到 /etc/hosts
文件中,该文件解析 omniverse-server
和 clickhouse
的 IP 地址;两者都将解析为后端服务器的 IP 地址。
错误报告#
向 NVIDIA 报告错误时,以下信息可确保错误能够被重现并得到正确解决。
Aerial Omniverse Digital Twin 发布版本
发生错误时的系统配置
问题的详细描述(错误或意外结果)以及重现步骤。
可以通过 NVIDIA Aerial Developer Forum 报告错误,为此需要一个 开发者帐户。