Additional Information
EM engine
The key parameters for the EM engine are:
the number of rays emitted at every RU
the maximum number of scattering events for each ray
the number of frequency samples for the wideband CFR
the number of UEs
the number of antennas for the antenna panels in use.
These parameters are directly linked to the consumption of GPU RAM during the operation of the EM engine. The corresponding limits are as per the following table.
Parameter | Maximum value |
---|---|
Number of rays emitted at every RU | 1,000,000 |
Maximum number of scattering events per ray | 5 |
Number of frequency samples (FFT size) for the wideband CFR | 4096 |
Number of UEs | 10,000 |
Number of antenna elements per RU panel | 64 |
Number of antenna elements per UE panel | 8 |
For large simulations, if there is an error log reporting that the simulation does not succeed, lowering the number of emitted rays, the number of scattering events, making the population of UEs sparser, or turning off the diffusion is suggested.
Functionally,
across the selected maximum number of scattering events, diffraction currently can only occur once per ray
only direct diffuse scattering (diffuse vertex is in line-of-sight to both the RU and the UE)
the number of rays or paths considered for each RU-UE pair is limited to a max of
\(500 \times\) Number of RU antenna elements \(\times\) Number of UE antenna elements
strongest paths
EM engine currently supports the following antenna models:
isotropic,
infinitesimal dipole,
halfwave dipole,
microstrip patch,
and custom user input, either at antenna element level or panel level.
Active Element Patterns can currently only be calculated for halfwave dipoles.
RAN simulation
For RAN simulation, here are some of the fixed configurations and limitations. We plan to introduce additional features and enhance flexibility in future releases.
Supports only 4 transmit antennas (or 2 dual-polarized antennas) and 4 receiver antennas (or 2 dual-polarized antennas).
Supports only a 100 MHz bandwidth with 273 PRBs.
Supports only Single-User MIMO (SU-MIMO).
Supports only 30 kHz subcarrier spacing.
Beamforming is not applied.
MMSE-IRC is applied indiscriminately at the receivers.
The power settings for all RUs and UEs must be identical across cells and UEs.
DMRS positions are fixed in symbols 2, 3, 10, and 11.
PRBs are scheduled at the PRB group level, with each PRB group containing 4 PRBs.
HARQ, if enabled, operates on a per-slot basis, assuming perfect knowledge of control channel information and immediate retransmission at a slot after a failed transmission slot.
HARQ, if enabled, will allow a maximum of 4 transmissions (i.e. a new transmission, followed by 3 re-transmissions), in case of CRC failures. Transmissions are associated with redundancy versions (RV) in the order of 0, 2, 3, 1.
In addition to a fixed thermal noise of -174 dBm/Hz, a noise figure is added at each receiver antenna.
When training is not enabled, SRS is scheduled exclusively on every S slot. The S slot is dedicated solely to SRS.
When training is enabled, SRS is scheduled during the first SU or UU slots.
For an SRS slot, all 14 symbols can be allocated for SRS transmission.
MAC scheduler
HARQ re-transmission is non-adaptive: the same scheduling solution (PRB allocation, layer and MCS selection) for the original transmissions is always reused for the HARQ re-transmissions. Further improvement is possible by employing advanced algorithms that may alter the scheduling decisions for re-transmissions and will be considered in future releases.
layer selection is sub-optimal: given that the beamforming is not applied yet, the current layer selection algorithm has not been optimized. An improved data transmission performance can be expected by employing a layer selection algorithm tailored to the lack of beamforming. AODT will offer optimal a beamforming-aware layer selection algorithm when beamforming is fully supported.
MCS selection: currently, the MCS selection algorithm relies on SINR-to-MCS lookup table derived for single-layer transmissions under AWGN channel. The SINR-to-MCS mappings in this lookup table may not be accurate for transmissions with more than one layer. This can be improved using separate SINR-to-MCS lookup tables for different numbers of layers and different channel characteristics.
The simulation data generated by the Aerial Omniverse Digital Twin is saved to a Clickhouse database. The following section describes the database tables and example Python scripts to access that data.
Database Tables
1. db_info
Field | Type | Comment |
---|---|---|
scene_url | string | Path to the scene on the Nucleus server |
scene_timestamp | string | Timestamp of when the scene was originally opened |
db_author | string | Database author, as specified in the UI Configuration tab |
db_notes | string | Any additional notes, as specified in the UI Configuration tab |
db_timestamp | string | Database timestamp, as specified in the UI Configuration tab |
db_schemas_version | string | The version of database schemas |
2. time_info
Field | Type | Comment |
---|---|---|
time_idx | uint32 | Time index of the simulation |
batch_idx | uint32 | Batch index of the simulation |
slot_idx | uint32 | Slot index of the simulation |
symbol_idx | uint32 | Symbol index of the simulation |
3. raypaths
Field | Type | Comment |
---|---|---|
time_idx | uint32 | Time index of the simulation |
ru_id | uint32 | RU ID as defined in the UI stage widget |
ue_id | uint32 | UE ID as defined in the UI stage widget |
interaction_types | array(enum) | Type of interactions: emission = 0, reflection = 1, diffraction = 2, diffuse = 3, reception = 4 |
points | array(tuple(float32, float32, float32)) | Stores the (x, y, z) coordinates of interaction points |
normals | array(tuple(float32, float32, float32)) | Stores the (x, y, z) normals at the interaction points |
tap_power | float32 | Power of the raypath channel tap in Watts |
4. cirs
Field | Type | Comment |
---|---|---|
time_idx | uint32 | Time index of the simulation |
ru_id | uint32 | RU ID as defined in the UI stage widget |
ue_id | uint32 | UE ID as defined in the UI stage widget |
ru_ant_el | tuple(uint32, uint32, uint32) | Tuple |
ue_ant_el | tuple(uint32, uint32, uint32) | Tuple |
cir_re | array(float32) | Real part of the channel impulse response |
cir_im | array(float32) | Imaginary part of the channel impulse response |
cir_delay | array(float32) | Propagation delay in seconds |
where, in the tuple<h,v,p>
h is the index of the element in horizontal dimension
v is the index of the element in vertical dimension
p is the index of the polarization
5. cfrs
Field | Type | Comment |
---|---|---|
time_idx | uint32 | Time index of the simulation |
ru_id | uint32 | RU ID as defined in the UI stage widget |
ue_id | uint32 | UE ID as defined in the UI stage widget |
ru_ant_el | tuple(uint32, uint32, uint32) | Tuple |
ue_ant_el | tuple(uint32, uint32, uint32) | Tuple |
cfr_re | array(float32) | Real part of the channel frequency response |
cfr_im | array(float32) | Imaginary part of the channel frequency response |
where, in the tuple<h,v,p>
h is the index of the element in horizontal dimension
v is the index of the element in vertical dimension
p is the index of the polarization dimension.
6. panels
Field | Type | Comment |
---|---|---|
panel_id | uint32 | Index of the panel |
panel_name | string | Name of the panel as defined in the UI stage widget |
antenna_names | array(string) | Name of antenna elements in the panel |
antenna_pattern_indices | array(uint32) | Index of the antenna elements |
frequencies | array(float32) | Frequencies for the radiation patterns of the antenna elements, in Hertz |
thetas | array(float32) | Elevation angles of the radiation pattern of the antenna elements, in radians |
phis | array(float32) | Azimuth angles of the radiation pattern of the antenna elements, in radians |
reference_freq | float32 | Center frequency of the panel |
Field | Type | Comment |
---|---|---|
dual_polarized | uint8 | Indicates if panel is dual-polarized. 1=dual polarization, 0=single polarization. |
num_loc_antenna_horz | uint32 | Number of columns in the planar array |
nnum_loc_antenna_vert | uint32 | Number of rows in the planar array |
antenna_spacing_horz | float32 | Horizontal spacing of the antenna elements, in cm |
antenna_spacing_vert | float32 | Vertical spacing of the antenna elements, in cm |
antenna_roll_angle_first_polz | float32 | Rotation (in radians) of the antenna element, corresponding to the first polarization |
antenna_roll_angle_second_polz | float32 | Rotation (in radians) of the antenna element, corresponding to the second polarization. Only used for dual-polarized elements. |
7. patterns
Field | Type | Comment |
---|---|---|
pattern_id | uint32 | Index of the pattern |
pattern_type | uint32 | Type of the antenna element: isotropic = 0, infinitesimal = 1, halfwave_dipole = 2, rec_microstrip = 3, custom >= 100 |
e_theta_re | array(array(float32)) | Real part of the antenna radiated field along theta direction, each inner vector stores the amplitudes for one frequency |
e_theta_im | array(array(float32)) | Imaginary part of the antenna radiated field along theta direction, each inner vector stores the amplitudes for one frequency |
e_phi_re | array(array(float32)) | Real part of the antenna radiated field along phi direction, each inner vector stores the amplitudes for one frequency |
e_phi_im | array(array(float32)) | Imaginary part of the antenna radiated field along phi direction, each inner vector stores the amplitudes for one frequency |
8. ues
Field | Type | Comment |
---|---|---|
ID | uint32 | UE ID as defined in the UI stage widget |
is_manual | boolean | Indicates if the UE was generated manually (1) or procedurally (0) |
is_manual_mobility | boolean | Whether or not the manual UE has waypoints explicitly added by the user |
radiated_power | float32 | UE’s radiated power (in Watts) |
height | float32 | Height of the UE in meters |
mech_tilt | float32 | Tilt of of UE antenna panel in degrees |
panel | array(uint32) | Array of antenna panel indices for this UE |
batch_indices | array(uint32) | Array of batch indices for this UE |
waypoint_ids | array(array(uint32)) | Per-batch waypoint identifiers [batch, ids] |
waypoint_points | array(array(tuple(float32,float32,float32))) | Per-batch waypoint positions [batch, waypoints(x, y, z)] |
waypoint_stops | array(array(float32)) | Per-batch waypoint stop times in seconds [batch, stops] |
Field | Type | Comment |
---|---|---|
waypoint_speeds | array(array(float32)) | Per-batch waypoint speeds in m/s [batch, speeds] |
trajectory_ids | array(array(uint32)) | Per-batch waypoint identifiers along UE trajectory [batch, ids] |
trajectory_points | array(array(tuple(float32,float32,float32))) | Per-batch points along UE trajectory [batch, points(x, y, z)] |
trajectory_stops | array(array(float32)) | Per-batch stop times (in seconds) along UE trajectory [batch, stops] |
trajectory_speeds | array(array(float32)) | Per-batch speed (in m/s) at waypoints along UE trajectory [batch, speeds] |
route_positions | array(array(tuple(float32,float32,float32))) | Per-batch positions along sampled route [batch, points(x, y, z)] |
route_orientations | array(array(tuple(float32,float32,float32))) | Per-batch UE orientations along sampled route [batch, orientations(x, y, z)] |
route_speeds | array(array(float32)) | Per-batch speeds (in m/s) along sampled route. [batch, speeds] |
route_times | array(array(float32)) | Per-batch times (in seconds) along sampled route. [batch, times] |
9. rus
Field | Type | Comment |
---|---|---|
ID | uint32 | RU ID as defined in the UI stage widget |
subcarrier_spacing | float32 | Subcarrier spacing (in Hz) |
fft_size | uint32 | Number of frequency samples used in the wideband CFR calculation |
radiated_power | float32 | RU’s radiated power (in Watts) |
height | float32 | Height of the RU in meters |
mech_azimuth | float32 | Mechanical azimuth rotation angle of the RU, in degrees |
mech_tilt | float32 | Mechanical tilt angle of the RU, in degrees |
panel | array(uint32) | Array of antenna panel indices for this RU |
position | array(float32) | Position of the RU in the stage. The array contains 3 elements (x, y, z). |
du_id | uint32 | Index of the DU that this RU is associated with. |
du_manual_assign | boolean | Whether or not this RU is manually assgined to the DU du_id |
10. dus
Field | Type | Comment |
---|---|---|
ID | uint32 | DU ID as defined in the UI stage widget |
subcarrier_spacing | float32 | Subcarrier spacing (in Hz) |
fft_size | uint32 | Number of frequency samples used in the wideband CFR calculation |
num_antennas | uint32 | Number of antenna for the DU |
max_channel_bandwidth | float32 | Maximum channel bandwidth supported by the DU |
position | array(float32) | The (x , y, z) coordinates of the DU, in centimeters |
11. scenario
Field | Type | Comment |
---|---|---|
default_ue_panel | string | The default panel ID assigned to UEs |
default_ru_panel | string | The default panel ID assigned to RUs |
num_emitted_rays_in_thousands | int32 | Number of emitted rays (x 1000) |
num_scene_interactions_per_ray | int32 | Number of interactions that a ray has with the environment. 0 = no interaction (line of sight) |
max_paths_per_ru_ue_pair | uint32 | Maximum number of raypaths per RU/UE |
ray_sparsity | int32 | Ratio of total computed rays to rays shown in the UI |
num_batches | int32 | Number of batches, where each batch represents a re-drop of the UE in a different position |
slots_per_batch | int32 | Number of slots to simulate for each batch |
symbols_per_slot | int32 | Number of symbols in a slot. Either 1 or 14. |
duration | float32 | The duration (in seconds) of the simulation |
interval | float32 | The sampling time (in seconds) of the simulation |
Field | Type | Comment |
---|---|---|
enable_wideband_cfrs | Boolean | True=>CFRs contain frequency points for the entire FFT size. False=>CFRs contain one frequency point at the center frequency. |
num_ues | uint32 | The total number of UEs in the simulation |
ue_height | float32 | UE height in meters |
ue_min_speed | float32 | Minimum UE speed in meters per second |
ue_max_speed | float32 | Maximum UE speed in meters per second |
is_seeded | uint8 | Indicates if mobility is seeded or not |
seed | uint32 | Seed used to define the randomness of UE batch drops and trajectories |
simulate_ran | boolean | Enable RAN simulations |
enable_training | boolean | Enable training simulations |
diffuse_type | enum | Diffuse type: Lambertian = 0, Directional = 1 |
rx_sphere_radius_m | float32 | Reception sphere radius, in meters |
12. telemetry
Field | Type | Comment |
---|---|---|
batch_id | uint32 | The batch index of the simulation |
slot_id | unit32 | The slot index within the batch |
link | String | If this telemetry result is for downlink (“DL”) or uplink (“UL”) |
ru_id | uint32 | RU ID |
ue_id | uint32 | UE ID |
startPrb | uint32 | Start PRB that the scheduler has assigned to this UE |
nPrb | uint32 | Number of PRBs that the scheduler has assigned to this UE |
mcs | uint8 | MCS index that the scheduler has assigned to this UE |
layers | uint8 | Number of layers used by this UE |
tbs | uint32 | Transport block (TB) size (in bytes) that was scheduled for this UE |
rv | uint8 | The redundancy version used for this transmission |
outcome | uint32 | If the transport block was successfully decoded (1) or not (0) |
scs | float32 | Subcarrier spacing (in Hz) |
13. training_result
Field | Type | Comment |
---|---|---|
time_idx | uint32 | Current time index of the simulation |
name | string | Optional name of a model |
training_losses | array(tuple(uint32,float32)) | Training losses: there may be multiple iterations trained for a given time index, so format is [(iteration0, loss0), (iteration1, loss1), …] |
validation_losses | array(tuple(uint32,float32)) | Optional validation losses, same format as training losses |
test_losses | array(tuple(uint32,float32)) | Optional test losses, same format as training losses |
baseline_losses | array(tuple(uint32,float32)) | Baseline losses, same format as training losses |
title | string | Optional title of loss plot in the UI, e.g. Training Loss |
y_label | string | Optional y-label of loss plot in the UI, e.g. MSE (dB) |
x_label | string | Optional x-label of loss plot in the UI, e.g. Slot |
14. world
Reserved
15. materials
Field | Type | Comment |
---|---|---|
label | string | Captures the material set in the UI stage |
itu_r_p2040_a | float64 | ITU-R P2040 ‘a’ parameter \(^{[1]}\) |
itu_r_p2040_b | float64 | ITU-R P2040 ‘b’ parameter \(^{[1]}\) |
itu_r_p2040_c | float64 | ITU-R P2040 ‘c’ parameter \(^{[1]}\) |
itu_r_p2040_d | float64 | ITU-R P2040 ‘d’ parameter \(^{[1]}\) |
scattering_xpd | float64 | Scattering cross-polarization/co-polarization power ratio |
rms_roughness | float64 | Root mean squared of the surface roughness |
scattering_coeff | float64 | Scattering coefficient |
exponent_alpha_r | int32 | Integer exponent parameter for the forward scattering lobe in the Directional diffuse model |
exponent_alpha_i | int32 | Integer exponent parameter for the barward scattering lobe in the Directional diffuse model |
lambda_r | float64 | Ratio between the forward scattering power and the total scattering power in the Directional diffuse model |
[1] Table 3 of ITU, “Effects of building materials and structures on radio wave propagation above about 100 MHz”, Recommendation P.2040-3, August 2023.
Accessing the results in the database
Some examples of how to access the database results are bundled with the source code in the examples/ directory. These scripts serve as a template, and can be extended for your own data analysis.
Example clickhouse scripts
There are two ways to run the ClickHouse scripts - using the Jupyter notebooks or as Python scripts. Both approaches are explained below.
To run as scripts, the necessary packages are available inside of the development container. Refer to the Installation section of this guide for how to start the development container. Then identify the name of the database of interest by using the clickhouse-client
or using the database name in the Configurations tab in the UI.
$ clickhouse-client
:) show databases
In this section, we use RU
interchangeably with tx
and UE
interchangeably with rx
. The examples assume the following database configuration:
Database Name: yoda_2024_4_15_13_4_6
hostname: localhost
1. extract_CIR_sample.py
This script is provided to illustrate access to the cirs table in the database.
python3 extract_CIR_sample.py --hostname <hostname> --database <database_name> --sample <time_idx> --RU <tx_id> --UE <rx_id>
For example to retrieve the CIR for sample 5, for ue_0002 and ru_0001, run the folllowing command:
python3 extract_CIR_sample.py --hostname "localhost" --database "yoda_2024_4_15_13_4_6" --sample 5 --RU 1 --UE 2
The script fetches the desired CIRs and writes them to the binary file sample-cir-<time_idx>.dat. The binary file can be accessed using the pickle Python module. The pickled data structures have the following definition:
data: holds the complex amplitude of each raypath
delay: holds the associated time of arrival in seconds
The shape of the data and delay dictionaries is [time_idx, tx_id, rx_id]
, where the inner-most dimension rx_id
is a flat array of size
\( \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}\) is the length of the CIR in samples,
\(N_{hor.}^{yx}\) is the number of horizontal antenna sites (without considering polarization) in the \(yx\) panel
\(N_{vert.}^{yx}\) is the number of vertical antenna sites (without considering polarization) in the \(yx\) panel
\(N_{pol.}^{yx}\) is the number of used polarizations per antenna site in the \(yx\) panel.
That is, the array is flattened according to the following order:
[\(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}\) ] , where, h,v,p correspond to the horizontal, vertical and polarization dimension of the antenna panel.
2. extract_CFR_sample.py
The extract_CFR_sample.py
reads the channel frequency response (CFR) from the cfrs table.
python3 extract_CIR_sample.py --hostname <hostname> --database <database_name> --sample <time_idx> --RU <tx_id> --UE <rx_id>
For example, if we need the CFR for sample 5, for ue_0002 and ru_0001, run the following command:
python3 extract_CFR_sample.py --hostname "localhost" --database "yoda_2024_4_15_13_4_6" --sample 5 --RU 1 --UE 2
The script fetches the desired CFRs and adds it to a dictionary that is then written to the sample-cfr-<time_idx>.dat binary file. The pickled data structure contains a dictionary data
that holds the channel frequency response for the specified RU and UE antenna pairs. The shape of data
is similar to the shape of the CIR from the previous section, except that the innermost flattened array is of size:
\(
\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)
\)
where \(NFFT\) is the size of the FFT to convert from the time domain samples to frequency domain samples.
Besides the CFR, the script also dumps the following scalar quantities:
fft_size
: Size of the CFRscs
: Subcarrier spacingue_fc
: Center frequency of the UEru_fc
: Center frequency of the RU
3. extract_CIR.py and extract_CFR.py
The scripts extract_CIR.py
and extract_CFR.py
extract data for all RU/UE antenna pairs and all time samples. To speed up reading such a large amount of data from the database, these scripts make use of a fast reader written in C++. The source code to the reader is provided in the examples/ directory and can be compiled into a shared library in the development container. See Readme_chapi.md for more details. The library provides the following Python bindings:
cfrs = read_cfrs_db(hostname,database)
cirs,delays = read_cfrs_db(hostname,database)
For example:
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)
These bindings are called by extract_CIR.py
and extract_CFR.py
in order to generate pickle files cirs.dat
or cfrs.dat
. The usage is as follows:
python3 extract_CIR.py --database <database_name> --hostname <hostname>
python3 extract_CIR_sample.py --database "yoda_2024_4_15_13_4_6" --hostname "localhost"
Note that unlike extract_CFR_sample.py
, the read_cfrs_db()
function only returns the CFRs, not the other scalar quantities.
5. plot_PDP_from_CIR.py
The script produces a figure of the channel impulse response associated with one of the RU/UE antenna links.
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
The channel impulse response can also be calculated and plotted using the channel frequency response data by running:
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
This script uses the rays in the raypaths table to calculate the uplink power angular spectrum.
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
Finally, to visualize the channel frequency response, run:
python plot_CFR.py -filename sample-<time_idx>.dat --sample <time_idx> --RU <tx_id> --UE <rx_id>
Jupyter notebooks
The scripts can be conveniently run through Jupyter notebooks. The following notebooks are available in the examples/ directory:
extract_CFR_sample.ipynb
extract_CIR_sample.ipynb
Fast Clickhouse Access.ipynb
The Jupyter Notebooks can be accessed by opening a web browser using the address of the backend http://omniverse-server:8888/. The webpage may ask for a token the first time. As mentioned in the Installation section of this guide, the token is shown at the end of the install process. The token may also be found on the backend server, in the docker compose examples.
cd <installation path>/examples
docker compose -f docker-compose-examples.yaml logs | grep token=
The EM engine is developed directly by NVIDIA, but it is modularly embedded in the Aerial Omniverse Digital Twin through a specific interface. This allows supporting the integration of different EM engines if necessary. This section aims at preparing for such a possibility by providing an overview of the key mechanics of NVIDIA’s EM engine.
NVIDIA’s EM engine API provides functions to
manage the device memory,
perform EM calculations,
and copy results to host memory.
All classes, member functions and variables are defined in the aerial_emsolver_api.h
header and make use of the C++/CUDA primitive data types.
Data types
d_complex
typedef thrust::complex<float> d_complex
Thrust complex data type used in both host code and device code.
d_complex4
typedef struct d_complex4 { d_complex m[4]{}; } d_complex4
An array of four
d_complex
elements.Matrix4x4
typedef struct Matrix4x4 { float m[4][4]{}; } Matrix4x4
A \(4\times4\) matrix of
d_complex
elements.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{} }
A struct storing EM material parameters.
Member
Description
abcd a float4
storing ITU-R P2040 a, b, c, and d parameters for calculating the relative permittivity 1roughness_rms the root mean square of the surface roughness (type float
), in metersk_xpol scattering cross-polarization/col-polarization power ratio (type float
)scattering_coeff scattering coefficient in the effective roughness (ER) model 2, 3 (type float
)exponent_alpha_R integer exponent of the forward scattering lobe (in the specular reflection direction) in the Directional diffuse model (type int
)exponent_alpha_I integer exponent of the backward scattering lobe (in the incidence direction) in the Directional diffuse model (type int
)lambda_R ratio between the forward scattering power and the total scattering power in the Directional diffuse model (type float
)
The diffuse model can be either Lambertian or Directional, and there are two ways to tune the diffuse scattering pattern:
using a fixed positive
scattering_coeff
(the ER model), which does not depend on the incidence angle of the impinging wave. This coefficient is used to calculate the reflection reduction factor and the fraction of power used for diffuse scattering. In this case , theroughness_rms
parameter is ignored, as the sets of(abcd, scattering_coeff, k_xpol)
and(abcd, scattering_coeff, k_xpol, exponent_alpha_R, exponent_alpha_I, lambda_R)
are sufficient for Lambertian and Directional diffuse models, respectively.using
roughness_rms
to characterize the Rayleigh reflection reduction factor 4, 5 and the fraction of power for diffuse scattering. In this case, thescattering_coeff
parameter is ignored, as the sets of(abcd, roughness_rms, k_xpol)
and(abcd, roughness_rms, k_xpol, exponent_alpha_R, exponent_alpha_I, lambda_R)
are sufficient for Lambertian and Directional diffuse models, respectively.
By default, for a material with a positive scattering_coeff
, the first method is used. Otherwise if scattering_coeff = 0.0
then the second method is used. For the Directional diffuse model, the formulation 3 is reciprocal. When lambda_R = 1.0
, the Directional diffuse model becomes single-lobe diffuse (SLD) model and the forward lobe contains the total diffuse scattering power. Differently, the model will make use of two lobes.
EM_INTERACT_TYPE
enum EM_INTERACT_TYPE : unsigned int { Emission = 0, Reflection = 1, Diffraction = 2, Diffuse = 3, Reception = 4, Reserved, }
An enumeration of EM interaction types per ray.
EM_DIFFUSE_TYPE
enum EM_DIFFUSE_TYPE : unsigned int { Lambertian = 0, Directional = 1 }
An enumeration of EM diffuse type.
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+2]{}; float3 points[MAX_NUM_INTERACTIONS+2]{}; int prim_ids[MAX_NUM_INTERACTIONS+2]{}; float3 normals[MAX_NUM_INTERACTIONS+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, int txrxPairID) : tx_ij{tx_ij[0], tx_ij[1]}, rx_ij{rx_ij[0], rx_ij[1]} { this->tx_id = tx_id; this->rx_id = rx_id; this->rx_index = rx_index; this->num_points = num_points; for(int i=0; i<num_points; i++) { this->points[i] = make_float3(points[i].x, points[i].y, points[i].z); this->prim_ids[i] = prim_ids[i]; this->normals[i] = make_float3(normals[i].x, normals[i].y, normals[i].z); this->point_types[i] = point_types[i]; } for(int i=0; i<4; i++) { this->cir_ampl[i] = d_complex(0.0, 0.0); } this->cir_delay = 0.0; } }
A struct storing geometry and EM data of a propagation path.
Member
Description
tx_id ID of the RU (type int
)rx_id ID of the UE (type int
)tx_ij two-element array of indices (type int
,i
for horizontal index andj
for vertical index) of the antenna element within the RU panelrx_ij two-element array of indices (type int
,i
for horizontal index andj
for vertical index) of the antenna element within the UE panelrx_index index of the UE (type int
)point_types an array of EM_INTERACT_TYPE
storing the EM interaction types for points along the pathpoints an array of float3
storing the (x, y, z) coordinates of interaction points, in centimetersprim_ids an array of int
storing the indices of the geometry primitive at the interaction points: the hit triangle index for a reflection, hit edge index for a diffraction, -1s otherwisenormals an array of float3
storing the normals at the interaction pointsnum_points number of interaction points from the RU to UE (type int
)cir_ampl an array of four complex-valued elements storing the path CIR amplitude for four UE-RU polarization combinations* cir_delay propagation delay of the path (type float
), in seconds*
cir_ampl[i*2 + j]
is for the UE’s \(i\)-th polarization and RU’s \(j\)-th polarization, for \(i \in \left[0, 1\right]\) and \(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 }
An enumeration for the built-in antenna types currently supported by the EM solver.
AntennaPattern
struct AntennaPattern { int pattern_type{}; std::vector<std::vector<d_complex>> ampls_theta{}; std::vector<std::vector<d_complex>> ampls_phi{}; }
A struct storing radiation pattern for a given antenna element, for either a built-in or a custom antenna type. The current version only supports patterns at a single frequency.
Member
Description
pattern_type an integer indicating the radiation pattern type as defined in the ANTENNA_TYPE
enum (typeint
)ampls_theta a two-dimensional vector storing complex-valued amplitudes (type d_complex
) of the antenna radiated field along the theta direction, each inner vector stores the amplitudes for one frequencyampls_phi a two-dimensional vector storing complex-valued amplitudes (type d_complex
) of the antenna radiated field along the phi direction, each inner vector stores the amplitudes for one frequencyFor built-in antenna types, the radiation fields are analytically calculated by the EM engine, and the
ampls_theta
andampls_phi
member variables are ignored. For example, for anInfinitesimal_dipole
pattern type, theAntennaPattern
object is: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{}; }
An struct storing information for a given antenna panel. The number of antenna elements in a panel is
num_loc_antenna_horz*num_loc_antenna_vert*num_polarizations
.Member
Description
panel_name name of the panel (type string
)antenna_names a vector of names (type string
) of all antenna elements in the panelantenna_pattern_indices a vector of indices (type int
) to thepatterns
vector for the antenna elements in the panelfrequencies a vector of frequencies (type float
) for the antenna radiation patterns of the antenna elements in the panel, in Hertzthetas a vector storing elevation angles (type float
) of the radiation pattern for all antenna elements in the panel, in radiansphis a vector storing azimuth angles (type float
) of the radiation pattern for all antenna elements in the panel, in radiansreference_freq center frequency (type double
) of the panel, in Hertzdual_polarized a bool
variable to indicate if the panel antennas are dual- (true) or single- polarized (false)num_loc_antenna_horz number of antenna element locations (type int
) in the planar array along a rownum_loc_antenna_vert number of antenna element locations (type int
) in the planar array along a columnantenna_spacing_horz horizontal antenna element spacing (type double
), in centimetersantenna_spacing_vert vertical antenna element spacing (type double
), in centimetersantenna_roll_angle_first_polz angular displacement of the antenna element realizing the first polarization (type double
), in radiansantenna_roll_angle_second_polz angular displacement of the element realizing the second polarization (type double
), in radiansAntennaInfo
struct AntennaInfo { std::vector<AntennaPanel> panels{}; std::vector<AntennaPattern> patterns{}; }
A struct encapsulating information of all antenna panels and antenna radiation patterns.
Member
Description
panels vector of panels (type AntennaPanel
)patterns vector of patterns (type 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{}; }
An struct storing RU information.
Member
Description
tx_ID ID of the RU (type int
)tx_center (x , y, z) coordinates of the RU center (type float3
), in centimetersTtx a Matrix4x4
transformation matrix for the RU combining translation and rotation, in centimeterspanel_id a vector of indices (type int
) identifying the panels used by the RU; currently only size 1 is supportedheight height (type float
) calculated from RU base to the RU center, in centimetersmech_azimuth_deg mechanical azimuth (type float
) of the RU, in degreesmech_tilt_deg mechanical tilt (type float
) of the RU, in degreescarrier_freq carrier frequency (type float
) of the RU, in Hertzsubcarrier_spacing sub-carrier spacing (type float
), in Hertzfft_size FFT size (type int
) used for wideband CFR calculationradiated_power radiated power (type float
) of the RU, in Wattsantenna_names a vector of names (type string
) of all antenna elements in the RU panelantenna_pattern_indices a vector of indices (type int
) to thepatterns
vector for the antenna elements in the RU paneldual_polarized_antenna a bool
variable to indicate if the RU antenna panel is composed by dual- (true) or single- polarized (false) elementsantenna_rotation_angles a vector of triplets storing rotation angles (type float3
) of the antennas: the first triplet is for the first polarization, and in case of dual-polarized antennas, the second triplet is for the second polarizationnum_loc_antenna_horz number of antenna element locations (type int
) in the horizontal direction within the RU antenna panelnum_loc_antenna_vert number of antenna element locations (type int
) in the vertical direction within the RU antenna panelloc_antenna vector of (x, y, z) of antenna positions within the RU antenna panel (type float3
), in centimeters*ij_antenna a vector of pairs of indices (type int
) storing horizontal and vertical indices of the antenna elements in the RU antenna panelNote: The antenna locations and the
(i, j)
antenna indices in theTXInfo
are order-consistent: e.g. the element at location indexed by(i, j)
with polarizationp
, isantenna_names[i*num_loc_antenna_vert*num_polarizations + j*num_polarizations + p - 1]
, wherenum_polarizations
is 1 for single-polarized panels and 2 for dual-polarized panels. In addition,(i, j) = (0, 0)
indicates the bottom-left antenna location in the antenna array. These conventions are also used forRXInfo
struct below. It is worth noticing that, in the graphical interface, the top and the bottom of the array are inverted, i.e., what is at the top in the graphical interface is considered at the bottom in EM solver.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{}; }
An struct storing UE information.
Member
Description
rx_ID ID of the UE (type int
)rx_center (x , y, z) coordinates of the UE center (type float3
), in centimetersTrx a Matrix4x4
transformation matrix for the UE combining translation and rotation, in centimeterspanel_id a vector of indices (type int
) identifying the panels used by the UE; currently only size 1 is supportedradiated_power radiated power (type float
) of the UE, in Wattsantenna_names a vector of names (type string
) of all antenna elements in the UE panelantenna_pattern_indices a vector of indices (type int
) to thepatterns
vector for the antenna elements in the UE paneldual_polarized_antenna a bool
variable to indicate if the UE antenna panel is composed by dual- (true) or single- polarized (false) elementsantenna_rotation_angles a vector of triplets storing rotation angles (type float3
) of the antennas: the first triplet is for the first polarization, and in case of dual-polarized antennas, the second triplet is for the second polarizationnum_loc_antenna_horz number of antenna element locations (type int
) in the horizontal direction within the UE antenna panelnum_loc_antenna_vert number of antenna element locations (type int
) in the vertical direction within the UE antenna panelloc_antenna vector of (x, y, z) of antenna positions within the RU antenna panel (type float3
), in centimetersij_antenna a vector of pairs of indices (type int
) storing horizontal and vertical indices of the antenna elements in the UE antenna panelMesh
struct Mesh { std::vector<float3> mesh_vertices{}; std::vector<int> triangle_material_ids{}; std::vector<int> triangle_diffuse_attr{}; };
A struct storing information of a triangular mesh in the scene.
Member
Description
mesh_vertices a vector of vertices (type float3
) of the triangular mesh*, in centimeterstriangle_material_ids a vector of material indices (type int
) of the mesh’s trianglestriangle_diffuse_attr a vector of diffuse attributes (type int
) of the mesh’s triangles, 0 if the triangle is non-diffuse and 1 otherwiseNotes: The vertices are grouped in tuples of 3 elements for the building triangles, e.g., vertices {[0], [1], [2]} for the first triangle, vertices {[3], [4], [5]} for the second triangles and so on. For each triangle, the vertex winding order is counter-clockwise so that its front face normal points outward for the building meshes and upward for the ground meshes.
GeometryInfo
struct GeometryInfo { std::vector<Mesh> building_mesh{}; std::vector<Mesh> terrain_mesh{}; std::unordered_map<std::string, std::pair<int,EMMaterial>> material_dict{}; };
A struct storing information for the geometries in the scene.
Member
Description
building_mesh a vector of building meshes (type Mesh
) in the sceneterrain_mesh a vector of terrain meshes (type Mesh
) in the scenematerial_dict an unordered map for the material dictionary storing all materials in the scene: key is the material name (type string
) and value is a pair of<int, EMMaterial>
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{}; }
A struct storing the configuration of the raytracing parameters.
Member
Description
num_rays_in_thousands number of emitted rays in thousands (type int
)max_num_bounces maximum number of scattering events for each emitted ray (type int
)rx_sphere_radius_cm reception sphere radius (type float
), in centimetersdiffuse_type diffuse type to indicate the diffuse scattering model (type EM_DIFFUSE_TYPE
): Lambertian = 0, Directional = 1use_only_first_antenna_pair a bool
variable, when set totrue
only the results for the first RU-UE antenna pair are returned fromrunEMSolver()
calc_tau_mins a bool
variable, when set totrue
,runEMSolver()
returns the minimum propagation delayssimulate_ran a bool
variable, when set totrue
the full RAN simulation is enabled
Class 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)
Constructor for the AerialEMSolver object.
In/out
Parameter
Description
[in] tx_info a vector of TXInfo
structs storing the information of the RUs[in] rx_info a vector of RXInfo
structs storing the information of the UEs[in] antenna_info AntennaInfo
struct storing the information of all antenna panels and antenna radiation patterns[in] geometry_info GeometryInfo
struct storing the information of the scene geometry and materials[in] rt_cfg RTConfig
struct storing the ray tracing configurations[in] ext_stream CUDA stream index (type cudaStream_t
)~AerialEMSolver()
~AerialEMSolver()
Destructor for the AerialEMSolver object.
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)
Allocation of device (GPU) memory to store the results of the EM engine.
In/out
Parameter
Description
[in] tx_info a vector of TXInfo
structs storing the information of all the RUs[in] rx_info a vector of RXInfo
structs storing the information of all the UEs[in] tx_indices a vector of indices (type uint32_t
) for the RUs whose results need to be computed[in] rx_indices a vector of vectors of indices (type uint32_t
) of selected UEs for each RUs whose results need to be computed[in] rt_cfg RTConfig
struct storing the raytracing configuration[in] symbols_per_slot number of symbols (type int
) in one slot (either 1 or 14)[out] d_all_CFR_results a vector of device pointers (type d_complex
), each pointing to memory address holding the CFRs for the UEs associated to a given RU. The content of the vector follows the content oftx_indices
[out] d_all_tau_mins a vector of device pointers (type float
), each pointing to memory address holding the minimum propagation delay for the UEs associated to a given RU. The content of the vector follows the content oftx_indices
All CFR results for the \(i\)-th RU, i.e.,
d_all_CFR_results_i = d_all_CFR_results[i]
, are stored in the device memory as a flattened representation of multidimensional array whose indices, in order, are<ue_idx>, <symbol_idx>, <freq_idx>, <ue_ant_idx>, <ru_ant_idx>, <ue_ant_pol_idx>, <ru_ant_pol_idx>
. Similar arrangement is used for the minimum delay results.For example, the first 6 elements of
d_all_CFR_results_i
, with the \(i\)-the RU being equipped with dual-polarized antennas and all associated UEs having two single-polarized antennas, are: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)
Launch the EM engine.
In/out
Parameter
Description
[in] time_idx time index (type unsigned int
) in the simulation[in] tx_info a vector of TXInfo
structs storing the information of all the RUs[in] rx_info a vector of RXInfo
structs storing the information of all the UEs[in] antenna_info AntennaInfo
struct storing the information of all antenna panels and antenna radiation patterns[in] tx_indices a vector of indices (type uint32_t
) for the RUs whose results need to be computed[in] rx_indices a vector of vectors of indices (type uint32_t
) of selected UEs for each RUs whose results need to be computed[in] rt_cfg RTConfig
struct storing the ray tracing configurations[in] symbol_idx symbol index (type int
) within a slot[in] symbols_per_slot number of symbols (type int
) in one slot (either 1 or 14)[in] all_ray_path_results a vector of RayPath
structs storing all propagation results from all selected RUs to their associated UEs[out] d_all_CFR_results a vector of device pointers (type d_complex
), each pointing to memory address holding the CFRs for the UEs associated to a given RU. The content of the vector follows the content oftx_indices
[out] d_all_tau_mins a vector of device pointers (type float
), each pointing to memory address holding the minimum propagation delay for the UEs associated to a given RU. The content of the vector follows the content oftx_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)
Copy the results of the EM engine from device to host.
In/out
Parameter
Description
[in] tx_indices a vector of indices (type uint32_t
) for the RUs whose results need to be computed[in] rx_indices a vector of vectors of indices (type uint32_t
) of selected UEs for each RUs whose results need to be computed[in] rt_cfg RTConfig
struct storing the ray tracing configurations[in] symbols_per_slot number of symbols (type int
) in one slot (either 1 or 14)[in] d_all_CFR_results a vector of device pointers (type d_complex
), each pointing to memory address holding the CFRs for the UEs associated to a given RU. The content of the vector follows the content oftx_indices
[out] all_CFR_results a pointer to a host-side vector of vectors for the CFR results, with the inner vector holding the CFRs from one RU to its associated UEs and the outer vector following 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)
Deallocate device memory previously used for the EM engine results.
In/out
Parameter
Description
[in] rt_cfg RTConfig
struct storing the ray tracing configurations[in] d_all_CFR_results a vector of device pointers (type d_complex
): each of them pointing to a device memory that holds complex-valued amplitude of the CFRs from one RU to its associated UEs. The size of the vector is equal to size of the tx_indices[in] d_all_tau_mins a vector of device pointers (type float
), each pointing to memory address holding the minimum propagation delay for the UEs associated to a given RU. The content of the vector follows the content oftx_indices
Error handling
The EM engine has built-in error handling. The function where the error or invalid condition occurs is recorded and error messages are propagated to both the local and console and the Console tab in the graphical interface.
EMLogLevel
enum class EMLogLevel {ERROR=0, NOTIFY=1, WARNING=2, INFO=3, DEBUG=4, VERBOSE=5}
An enumeration for the level of logging.
EMLogCallback
EMLogCallback = std::function<void(EMLogLevel, const std::string&)>
Callback function prototype.
registerLogCallback()
int32_t registerLogCallback(EMLogCallback func)
Function to register a callback function (type
EMLogCallback
) for error handling.deregisterLogCallback()
int32_t deregisterLogCallback()
Function to deregister the currently registered callback function.
When building the source code in the dev. container, the Python version in examples/CMakeLists.txt must be changed from 3.11 to 3.10, so that in the file
find_package(Python 3.10 REQUIRED COMPONENTS Interpreter Development)
The run_aodt_sim_devel.sh
script mounts the source code into the container so that edits and builds within the development container persist on the host disk.
The following lines must be added at the end of the run command in ./container/run_aodt_sim_devel.sh
to access the Nucleus and Clickhouse servers from inside the container:
--userns=host --ipc=host \
--add-host=omniverse-server:host-gateway \
--add-host=clickhouse:host-gateway \
${CONTAINER} /bin/bash ${CMDSTR}
Before running the code inside the dev. container, the aodt_sim
container started by the install script must be stopped.
cd $HOME/backend_bundle
docker-compose stop connector
Once the container is stopped, we can follow these instructions to build the aodt_sim
executable:
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
# Set SM to the value for the GPU being used. Examples include
# A100=80, H100=90, RTX6000 Ada or L40=89
SM=80
cmake -Bbuild -GNinja -DCMAKE_CUDA_ARCHITECTURES=$SM -DNVTX_ENABLED=OFF -DENABLE_CCACHE=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
The example above assumes that the installation scripts have been executed. As part of the installation, lines have been added to the /etc/hosts
file that resolves the IP addresses of omniverse-server
and clickhouse
; both will resolve to the IP address of the backend server.
When reporting bugs to NVIDIA, the following information ensures that the error can be reproduced and correctly addressed.
The Aerial Omniverse Digital Twin release version
The system configuration where the bug occurs
A detailed description of the issue (errors or unexpected outcomes) and of the steps to reproduce it.
Bugs can be reported via the NVIDIA Aerial Developer Forum, for which a developer account and is necessary.
ITU, “Effects of building materials and structures on radio wave propagation above about 100 MHz”, Recommendation P.2040-3, August 2023.
V. Degli-Esposti, F. Fuschini, E. M. Vitucci, and G. Falciasecca, “Measurement and modelling of scattering from buildings,” IEEE Trans. Antennas Propag., vol. 55, no. 1, pp. 143–153, January 2007.
E. M. Vitucci et. at., “A Reciprocal Heuristic Model for Diffuse Scattering From Walls and Surfaces,” IEEE Trans. Antennas Propag., vol. 71, no. 7, July 2023.
W. S. Ament, “Toward a Theory of Reflection by a Rough Surface,” in Proceedings of the IRE, vol. 41, no. 1, pp. 142-146, Jan. 1953.
S. Ju et al., “Scattering Mechanisms and Modeling for Terahertz Wireless Communications,” 2019 IEEE International Conference on Communications (ICC).