Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

False results for a simple wall model - sainity test #653

Open
AviAvyahu opened this issue Nov 7, 2024 · 2 comments
Open

False results for a simple wall model - sainity test #653

AviAvyahu opened this issue Nov 7, 2024 · 2 comments

Comments

@AviAvyahu
Copy link

Hi,
As a part of sainity tests I run to verify I understand the limitations of ray tracing in rf propagation, I compare the Sionna algorithm to a simple knife edge model.
To do so, I created several option for obstacles: a 2d sheet, a wedge (with a small, 1 degree, angle) and a 'wall' (a very thin brick, 10cm/1mm wide).
All of these elements are 20m tall and 20m wide. the distance between the rx and tx from the element is 5m, so knife edge approximation should hold in the height range I test (obstacle is -1m to 2m high).
In this test, I run a physical problem that is basically the same - a very thin obstacle that diffracts the electrical field. In the algorithm, however, I get a different result for each such test:
image
Here, height represent the height of the reciever and transciever, so for negative values the obstacle interrupts line of sight

Several issues come up:

  1. The calculation gets truncated for the thin wall as soon as the obstacle hits line of sight.

My guess is that the algorithm doesn't calculate second order diffraction. How can I change it? I attach an example of the diffraction I expect it to calculate:
image

In the notebook: "Tutorial on Diffraction" it seems like the lgorithm does such second order diffraction calculation by using coverage_map (in the last few figures).

  1. There is also some error in the sheet test, in lower power reading we get some kind of oscillating error that I can't quite figure out its cause.

  2. The final error I see is at the very border of the ISB. I see a spike in the power recieved (which seem to be positive or negative, depending the specifics of the scene). Do you know what cause this? I didn't see such phenomena in the "Tutorial on Diffraction" notebook.

  3. the value, even for the wedge, seem to deviate from the classic knife edge calculation. I still hadn't looked thoroughly into it so maybe this is an error in my KE code. this issue bother me the least...

I attach below the code that generated these plots and the files I load as scenes.

scene_list = ['wedge','thin_wall','wall','sheet']
angle_list = [1, 30 ,60 ,90]

scene_test = 'thin_wall' # here i choose the scene i want to test
angle_test = 1

if scene_test == 'wedge':
  scene_name = "wedge_"+str(angle_test)+"degs.xml"
else:
  scene_name = scene_test + ".xml"

# """ define height range """
h_start = -2
h_stop = 1
h_step = 0.05
num = int((h_stop-h_start)/h_step)+1
heights = np.linspace(h_start, h_stop, num=num)

pol = 'h' # 'h' for horizontal

frequency = 2e9 # Hz
distance = 10   # m

power_list = []
power_list_OF = []

start_time = time.time()
for [i_h,height] in enumerate(heights):
  """ load scene """
  scene = load_scene(scene_name)
  scene.frequency = frequency # 1GHz
  # scene.objects["wedge"].radio_material = "itu_metal" # Almost perfect reflector
  # scene.add(custom_material)
  # obj = scene.get('elm__4') # obj is a SceneObject
  # obj.radio_material = "my_material" # "my_object" is made of "my_material"
  element = list(scene.objects.keys())[0] # get the name of the first element in the scene (in our case, the only one)
  scene.objects[element].radio_material = "itu_metal"

  """ define transmitter and reciever properties """

    # Configure the antenna arrays used by the transmitters and receivers
  scene.tx_array = PlanarArray(num_rows=1,
                                num_cols=1,
                                vertical_spacing=0.5,
                                horizontal_spacing=0.5,
                                pattern="iso", # isotropical antenna
                                polarization="H") # verical\horizontal polarization

  scene.rx_array = scene.tx_array

  # Configure the antenna arrays used by the transmitters and receivers

  """ place transmitter and receivers """

  if pol=='v': alpha = PI/2
  if pol=='h': alpha = 0
  # by coordinate

  """ here we can place the for loop """

  alpha = 0
  tx_pos = [ 5, 0,height] # [x,y,z]
  rx_pos = [-5, 0,height]
  tx_pos = tf.constant(tx_pos,dtype=tf.float32)
  rx_pos = tf.constant(rx_pos,dtype=tf.float32)

  scene.add(Transmitter(name="tx",
                        position=tx_pos,
                        orientation=[0,0,float(alpha)]))
  scene.add(Receiver(name=f"rx",
                        position=rx_pos,
                        orientation= [0, 0, float(alpha)]))

  """ run the simulation """

  # Compute paths between the transmitter and all receivers
  paths = scene.compute_paths(num_samples=1e6,
                              los=True,
                              reflection=False,
                              diffraction=True,
                              scattering=False,
                              edge_diffraction=True)

  """ run simulation and calc power """

  # Obtain channel impulse responses
  # We squeeze irrelevant dimensions
  # [num_rx, max_num_paths]
  E_field, tau = [np.squeeze(t) for t in paths.cir()]
  # sum over all possible paths
  power = 20*np.log10(np.abs(np.sum(E_field, axis=-1)))
  power_list.append(power)
  power_list_OF.append(power+(32.4+20*np.log10(frequency*1e-9*distance)))
  if i_h == 0:
    print(f'estimates simulation time is: {(time.time()-start_time)*len(heights)/60:.1f} minutes = {(time.time()-start_time)*len(heights):.1f} seconds')

fig = plt.figure()
plt.plot(heights, power_list_OF)
plt.xlabel("height [m]");
plt.ylabel(r"loss over friis (dB)");
plt.xlim([h_start, h_stop]);
# plt.ylim([-100, -59]);
# plt.xlim([0, PI]);
plt.grid(which='major')

Thanks in advance

wedge_export.zip

@jhoydis
Copy link
Collaborator

jhoydis commented Nov 8, 2024

Hi @AviAvyahu,

  1. Sionna only implements first-order diffraction for now.

  2. Not sure what you mean here.

  3. I have not yet looked in detail in the issue you describe, but I have the feeling that it might be related to the case where the edge of the screen lies on the line that goes through the transmitter and receiver. In this case, it is not clearly defined wether a LoS path exist or not. Could you try to regenerate your plot by omitting this case and maybe choose a height equal to 0+/- a small constant?

  4. Let us know once you have properly looked into it.

@AviAvyahu
Copy link
Author

Thank you for the quick reply :)
Regarding the first question - just to be clear: in the following scene, do I expect to see null values in the red zone?
image

If so, a single wall of arbitrary thickness (for example 1 mm), give rise to infinite loss (which is of course, false). Is it a "built-in" limitation of the ray tracing method or can we solve this problem somehow?

In the following figure (from "Tutorial on Diffraction" in the Sionna documentation), if i would put a transmitter at ground level, there will be no electric field if a building blocks a diffraction's LOS?
image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants