-
Notifications
You must be signed in to change notification settings - Fork 334
Description
The channel delay spread in the new version v1 does not seem consistent with the pervious version v0.19. In my special example below it seems that the channel spread in newer version seems to have a much larger number of shorter paths and generally very different from the delay spread seen in previous version.
A somewhat similar question was asked previously here:
#934
but the question there was only concerning the power intensity of each path being much lower. However, aside from the intensity being different, the actual delay spread is totally different which is why I asked separate question. And furthermore, even turning off the scattering with max_depth=10 the unscattered delay spread is still different from the previous version. That is why I created a new issue for this.
The following code is provided as an example in the simple street canyon with cars. A single transmitter and single reciever with the given positions and look ats. You can change the positions and still get different delay spread for v1.1 vs v0.19. You can also turn off the scattering and set max_depth to high value and see that even without scattering they are different.
from sionna.rt.scene import simple_street_canyon_with_cars
#################################################
#### CHANGE YOUR CONFIGURATIONS IN HERE ONLY ####
#################################################
max_depth = 1 # Defines max number of ray interactions
# System parameters
CarrierFreq = 10e9
isSyntheticArray = True
tx_center=np.array([1., -7.5, 30.])
tx_look_at = np.array([0., 0., 1.])
rx_center = np.array([-1., -7.5, 30.])
rx_look_at = np.array([0., 0., 1.])
# ray tracing sample params
num_rays = 1.e7
num_paths_keep = 20000.
scene=simple_street_canyon_with_cars
################################################
# initialize the simulation
sim = ChannelDelaySpreadSimulation(
CarrierFreq = CarrierFreq ,
tx_center = tx_center,
tx_look_at = tx_look_at ,
rx_center = rx_center,
rx_look_at = rx_look_at,
num_rays = num_rays ,
num_paths_keep = num_paths_keep,
max_depth = max_depth,
isSyntheticArray = isSyntheticArray,
scene=scene
)
# compute the channel response
a_total, tau_total = sim.RT_sim_and_time_channel_estimation()
# plot the delay spread
with tf.device('/CPU:0'):
a_test = np.abs(np.squeeze(a_total))
tau_test = np.squeeze(tau_total.numpy())
plt.figure(figsize=(15,5))
plt.stem(tau_test, a_test)
plt.ylim(top=2e-5, bottom=0)
plt.grid(True)
plt.ylabel("Intensity")
plt.xlabel("Delay")
plt.title("Delay spread")
plt.savefig("delayspread.png")
plt.close()
Then
For version 0.19 use this class:
# sionna v0.19
import matplotlib.pyplot as plt
import numpy as np
import os
gpu_num = 0 # Use "" to use the CPU
os.environ["CUDA_VISIBLE_DEVICES"] = f"{gpu_num}"
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from sionna.rt import load_scene, Transmitter, Receiver, PlanarArray, Camera
# Configure the notebook to use only a single GPU and allocate only as much memory as needed
# For more details, see https://www.tensorflow.org/guide/gpu
gpus = tf.config.list_physical_devices('GPU')
if gpus:
try:
tf.config.experimental.set_memory_growth(gpus[0], True)
except RuntimeError as e:
print(e)
class ChannelDelaySpreadSimulation():
def __init__(self, scene,
CarrierFreq,
tx_center, tx_look_at,
rx_center, rx_look_at,
max_depth, num_rays, num_paths_keep,
isSyntheticArray) -> None:
self.CarrierFreq = CarrierFreq
self.tx_center = tx_center
self.tx_look_at = tx_look_at
self.rx_center = rx_center
self.rx_look_at = rx_look_at
self.num_rays = num_rays
self.num_paths_keep = num_paths_keep
self.max_depth = max_depth
self.isSyntheticArray = isSyntheticArray
self.scat_keep_prob = (num_paths_keep / num_rays)
print("Loading the Scene...")
self.scene = load_scene(scene)
# Configure radio materials for scattering
# By default the scattering coefficient is set to zero
for rm in self.scene.radio_materials.values():
rm.scattering_coefficient = 0.5
self.scene.frequency = CarrierFreq
'''channel simulation part'''
# Configure antenna array for the transmitter
self.scene.tx_array = PlanarArray(num_rows=1,
num_cols=1,
vertical_spacing=0.5,
horizontal_spacing=0.5,
pattern="tr38901",
polarization="V")
# Create transmitter
tx_1 = Transmitter(name="tx_1", position=tx_center, look_at=tx_look_at)
# Selecting UEs based on the location and parameters of the base station
self.scene.add(tx_1)
# Configure antenna array for all receivers
self.scene.rx_array = PlanarArray(num_rows=1,
num_cols=1,
vertical_spacing=0.5,
horizontal_spacing=0.5,
pattern="tr38901",
polarization="V")
# Create receivers
rx = Receiver(name=f"rx_1", position=rx_center, look_at=rx_look_at)
self.scene.add(rx)
# And visualize the scene
tx_pos = self.scene.transmitters["tx_1"].position.numpy()
bird_pos = tx_pos.copy()
bird_pos[-1] = 200 # Set height of coverage map above tx
self.bird_cam = Camera(name='bird_cam', position=bird_pos, look_at=tx_pos)
def RT_sim_and_time_channel_estimation(self, plot=False):
# Simulate begins
print("Ray-Tracing Simulation...")
tf.random.set_seed(42)
traced_paths = self.scene.trace_paths(max_depth=self.max_depth,
los=True,
reflection=True,
diffraction=False,
scattering=True,
scat_keep_prob=self.scat_keep_prob,
num_samples=self.num_rays,
check_scene=True)
paths = self.scene.compute_fields(*traced_paths, check_scene=False)
paths.normalize_delays = True
a_standstill_temp, tau_standstill_temp = paths.cir()
with tf.device('/CPU:0'):
a_total = tf.identity(a_standstill_temp)
tau_total = tf.identity(tau_standstill_temp)
return a_total, tau_total
For version 1.1 use this class:
# sionna v1.1
import matplotlib.pyplot as plt
import numpy as np
import os
gpu_num = 0 # Use "" to use the CPU
os.environ["CUDA_VISIBLE_DEVICES"] = f"{gpu_num}"
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '3'
import tensorflow as tf
from sionna.rt import load_scene, Transmitter, Receiver, PlanarArray, Camera, PathSolver
# Configure the notebook to use only a single GPU and allocate only as much memory as needed
# For more details, see https://www.tensorflow.org/guide/gpu
gpus = tf.config.list_physical_devices('GPU')
if gpus:
try:
tf.config.experimental.set_memory_growth(gpus[0], True)
except RuntimeError as e:
print(e)
tf.random.set_seed(1) # Set global random seed for reproducibility
class ChannelDelaySpreadSimulation():
def __init__(self, scene,
CarrierFreq,
tx_center, tx_look_at,
rx_center, rx_look_at,
max_depth, num_rays, num_paths_keep,
isSyntheticArray) -> None:
self.CarrierFreq = CarrierFreq
self.tx_center = tx_center
self.tx_look_at = tx_look_at
self.rx_center = rx_center
self.rx_look_at = rx_look_at
self.num_rays = num_rays
self.num_paths_keep = num_paths_keep
self.max_depth = max_depth
self.isSyntheticArray = isSyntheticArray
print("Loading the Scene...")
self.scene = load_scene(scene, merge_shapes=False)
# Configure radio materials for scattering
# By default the scattering coefficient is set to zero
for rm in self.scene.radio_materials.values():
rm.scattering_coefficient = 0.5
rm.thickness = 1.e6
self.scene.frequency = CarrierFreq
'''channel simulation part'''
# Configure antenna array for the transmitter
self.scene.tx_array = PlanarArray(num_rows=1,
num_cols=1,
pattern="tr38901",
polarization="V")
# Create transmitter
tx_1 = Transmitter(name="tx_1", position=tx_center, look_at=tx_look_at)
# Selecting UEs based on the location and parameters of the base station
self.scene.add(tx_1)
# Configure antenna array for all receivers
self.scene.rx_array = PlanarArray(num_rows=1,
num_cols=1,
pattern="tr38901",
polarization="V")
# Create receivers
rx = Receiver(name=f"rx_1", position=rx_center, look_at=rx_look_at)
self.scene.add(rx)
# And visualize the scene
tx_pos = self.scene.transmitters["tx_1"].position.numpy()
bird_pos = tx_pos.copy()
bird_pos[-1] = 200 # Set height of coverage map above tx
self.bird_cam = Camera(position=bird_pos, look_at=tx_pos)
def RT_sim_and_time_channel_estimation(self, plot=False):
# Simulate begins
print("Ray-Tracing Simulation...")
solver = PathSolver()
paths = solver( self.scene,
max_depth=self.max_depth,
synthetic_array=self.isSyntheticArray,
los=True,
specular_reflection=True,
diffuse_reflection=True,
refraction=False,
samples_per_src= int(self.num_paths_keep),
max_num_paths_per_src = int(self.num_rays) ,
seed = 42
)
(a_real, a_img), tau = paths.cir()
with tf.device('/CPU:0'):
a_total = tf.complex(tf.identity(a_real), tf.identity(a_img))
tau_total = tf.identity(tau)
return a_total, tau_total