### Install Sionna RT from Source Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Installs Sionna RT by cloning the repository and running pip install from the root directory. This method is useful for development or when needing the latest code. ```bash pip install . ``` -------------------------------- ### Install Sionna RT via Pip Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Recommended installation method for Sionna RT using pip. Ensure you have Python and pip installed. ```bash pip install sionna-rt ``` -------------------------------- ### Setup Trainable Scene for Material Calibration Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Creates a new scene identical to the reference scene but with a reflector material whose conductivity is intended to be trainable. This setup is for calibrating material parameters using gradient descent. ```python trainable_scene = load_scene(rt.scene.simple_reflector, merge_shapes=False) trainable_scene.add(Transmitter("tx", position=(-2., 0., 1))) trainable_scene.add(Receiver("rx", position=(2., 0., 1))) trainable_scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") trainable_scene.rx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") ``` -------------------------------- ### Build and Serve Documentation Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Builds the HTML documentation and serves it locally using Python's http.server. Requires pandoc to be installed manually. ```bash python -m http.server --dir build/html ``` -------------------------------- ### Install Test Requirements Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Installs the necessary Python packages for running unit tests. Execute this command from the repository's root directory. ```bash pip install '.[test]' ``` -------------------------------- ### Install and Import Sionna RT Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Installs Sionna RT if not already present and imports necessary components. It also prints the selected Mitsuba variant. ```python # Import or install Sionna try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt # Other imports %matplotlib inline import matplotlib.pyplot as plt import mitsuba as mi import numpy as np no_preview = True # Toggle to False to use the preview widget # Import relevant components from Sionna RT from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver, Camera, PathSolver, RadioMapSolver, subcarrier_frequencies # Query the Mitsuba variant that was automatically selected by Sionna RT. # There should be no need to adjust it, but if you do, make sure to select # a variant ending in `*_ad_mono_polarized`. print(f"Mitsuba variant: {mi.variant()}") ``` -------------------------------- ### Load Integrated Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Loads an integrated example scene. Try 'sionna.rt.scene.etoile' as an alternative. ```python # Load integrated scene scene = load_scene(sionna.rt.scene.munich) # Try also sionna.rt.scene.etoile ``` -------------------------------- ### Scene Setup with Trainable Antenna Pattern Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_antenna_patterns.rst Loads a scene, creates a Mitsuba optimizer, and configures a transmitter with a trainable antenna pattern. This sets up the environment for gradient computation. ```python from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver # Load empty scene scene = load_scene() # Create a Mitsuba Optimizer opt = mi.ad.Adam(lr=1e-2) # Define transmit array with trainable antenna pattern scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="trainable", opt=opt, polarization="V") scene.rx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") # Add transmitter and receiver to the scene scene.add(Transmitter(name="tx", position=[0,0,0])) scene.add(Receiver(name="rx", position=[10,10,10])) ``` -------------------------------- ### Import Sionna RT Library Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Imports the Sionna RT library. If not installed, it attempts to install it using pip. ```python import sionna.rt try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt ``` -------------------------------- ### Import Sionna and Dependencies Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Radio-Maps.ipynb Imports necessary libraries including numpy, mitsuba, matplotlib, and Sionna's ray tracing module. Includes a check to install Sionna if not found. ```python import numpy as np import mitsuba as mi import matplotlib as mpl import matplotlib.pyplot as plt # Import or install Sionna try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt from sionna.rt import load_scene, Camera, Transmitter, Receiver, PlanarArray, PathSolver, RadioMapSolver, load_mesh, watt_to_dbm, transform_mesh, cpx_abs_square no_preview = True # Toggle to False to use the preview widget # instead of rendering for scene visualization ``` -------------------------------- ### Install Development Requirements Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Installs Python packages required for development, including tools for extending the library. Run from the repository's root directory. ```bash pip install '.[dev]' ``` -------------------------------- ### Import Sionna RT and Dependencies Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scene-Edit.ipynb Imports necessary libraries including drjit, mitsuba, and Sionna RT. Includes a check to install Sionna RT if it's not found. ```python import drjit as dr import mitsuba as mi # Import or install Sionna try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt no_preview = True # Toggle to False to use the preview widget # instead of rendering for scene visualization from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver, Camera, PathSolver, ITURadioMaterial, SceneObject ``` -------------------------------- ### Configure and Add Transmitter to Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Loads a scene, configures transmitter and receiver antenna arrays, creates a transmitter instance, and adds it to the scene. This is a setup step before ray tracing. ```python scene = load_scene(sionna.rt.scene.munich, merge_shapes=True) # Merge shapes to speed-up computations # Configure antenna array for all transmitters scene.tx_array = PlanarArray(num_rows=1, num_cols=1, vertical_spacing=0.5, horizontal_spacing=0.5, pattern="tr38901", polarization="V") # Configure antenna array for all receivers scene.rx_array = PlanarArray(num_rows=1, num_cols=1, vertical_spacing=0.5, horizontal_spacing=0.5, pattern="dipole", polarization="cross") # Create transmitter tx = Transmitter(name="tx", position=[8.5,21,27], display_radius=2) # Add transmitter instance to scene scene.add(tx) ``` -------------------------------- ### Configure Scattering and Simulate Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Configures a scene for diffuse reflection with a Lambertian scattering pattern and simulates paths to compare ray tracing results with the far-wall approximation. Requires scene setup, scattering coefficient, and frequency configuration. ```python s = 0.7 # Scattering coefficient # Configure the radio material scene.get("reflector").radio_material.scattering_pattern = LambertianPattern() scene.get("reflector").radio_material.scattering_coefficient = s # Set the carrier frequency scene.frequency = 3.5e9 wavelength = scene.wavelength r_is = [0.1, 1, 2, 5, 10] # Varying distances received_powers = [] theo_powers = [] for r_i in r_is: # Update the positions of TX and RX d = r_i/sqrt(2) scene.get("tx").position = [-d, 0, d] scene.get("rx").position = [d, 0, d] paths = p_solver(scene=scene, los=False, specular_reflection=False, diffuse_reflection=True) received_powers.append(10*log10(dr.sum(cpx_abs(paths.a)**2).numpy())) # Compute theoretically received power using the far-wall approximation theo_powers.append(10*log10((wavelength[0]*s/(4*dr.pi*r_i**2))**2/(2*dr.pi))) plt.figure() plt.plot(r_is, received_powers) plt.plot(r_is, theo_powers, "--") plt.title("Validation of the Scattered Field Power") plt.xlabel(r"$r_i$ (m)") plt.ylabel("Received power (dB)"); plt.legend(["Ray tracing", '"Far"-wall approximation']); ``` -------------------------------- ### Import Sionna RT and Dependencies Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Imports necessary libraries for ray tracing, including Sionna RT, NumPy, Matplotlib, and Dr.Jit. It also includes a check to install Sionna RT if it's not already present. ```python from math import sqrt, log10 import numpy as np import drjit as dr import matplotlib.pyplot as plt # Import or install Sionna try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt from sionna.rt import LambertianPattern, DirectivePattern, BackscatteringPattern, load_scene, Camera, Transmitter, Receiver, PlanarArray, PathSolver, RadioMapSolver, cpx_abs, cpx_convert no_preview = True # Toggle to False to use the preview widget # instead of rendering for scene visualization ``` -------------------------------- ### Load Scene and Access Objects Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Loads a scene and displays the available SceneObjects. Use this to get an overview of the scene's components. ```python scene = load_scene(sionna.rt.scene.simple_street_canyon, merge_shapes=False) scene.objects ``` -------------------------------- ### Render Scene with Updated Camera Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Renders the scene again with an updated camera position and look-at point, useful for visualizing the setup after adding transmitters and receivers. ```python my_cam.position = [-30,100,100] my_cam.look_at([10,0,0]) if no_preview: scene.render(camera=my_cam); ``` -------------------------------- ### Convert Dr.Jit arrays to other frameworks Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_compat_frameworks.rst Shows how to convert Dr.Jit arrays to Numpy, Jax, TensorFlow, and PyTorch arrays using zero-copy methods. Ensure the target frameworks are installed. ```python # Note that the desired framework(s) need(s) to be installed for # the following code to work. x = mi.Float([1,2,3]) print(type(x.numpy())) print(type(x.jax())) print(type(x.tf())) print(type(x.torch())) ``` -------------------------------- ### Load Scene and List Objects Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/scene_object.rst Loads a predefined scene and prints a list of all scene objects contained within it. This is a common starting point for scene manipulation. ```python scene = load_scene(sionna.rt.scene.munich) print(scene.objects) ``` -------------------------------- ### Configuration and Imports for Sionna RT Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Imports necessary libraries for Sionna RT, including plotting, NumPy, and various Sionna RT modules. It also includes a check to install Sionna if not already present and sets a flag for preview rendering. ```python %matplotlib inline import matplotlib.pyplot as plt import numpy as np # Import or install Sionna try: import sionna.rt except ImportError as e: import os os.system("pip install sionna-rt") import sionna.rt no_preview = True # Toggle to False to use the preview widget # instead of rendering for scene visualization from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver, Camera, RadioMapSolver, PathSolver from sionna.rt.utils import r_hat, subcarrier_frequencies ``` -------------------------------- ### PyTorch training loop for Sionna RT Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_compat_frameworks.rst Illustrates implementing a gradient-based optimization loop in PyTorch to adjust radio material properties in Sionna RT. The example involves optimizing wall properties to maximize received signal strength. ```python import torch import numpy as np import sionna.rt from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver, \ PathSolver, RadioMaterial, cpx_abs_square # Load scene and place TX/RX scene = load_scene(sionna.rt.scene.simple_reflector, merge_shapes=False) scene.tx_array = PlanarArray(num_cols=1, num_rows=1, ``` -------------------------------- ### Differentiable Custom Scattering Pattern Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_scattering_patterns.rst Illustrates how to create a custom scattering pattern with differentiable parameters using Dr.Jit. This example sets up a scene, assigns the custom pattern to a material, and computes paths to enable gradient backpropagation. ```python import mitsuba as mi import drjit as dr import sionna from sionna.rt import RadioMaterial, ScatteringPattern, register_scattering_pattern, load_scene, Transmitter, Receiver, PlanarArray, PathSolver # Custom scattering pattern with differentiable parameters # Only meant for illustration purposes class MyPattern(ScatteringPattern): """ Custom scattering pattern implementing the function cos(theta_o)^n. """ def __init__(self, n: int): self.n = n self.normalization = dr.sqrt((n+1)/(2*dr.pi)) self.v = mi.Vector3f([0,0,1]) dr.enable_grad(self.v) # Enable gradient computation for v def __call__(self, k_i_local, k_o_local): pattern = dr.sum(self.v*k_o_local, axis=0)**self.n return pattern * dr.rcp(self.normalization) # Register new scattering pattern register_scattering_pattern("my_pattern", MyPattern) # Load scene, add transmitter and receiver scene = load_scene(sionna.rt.scene.simple_reflector) scene.add(Transmitter("tx", position=[-3,0,1.5])) scene.add(Receiver("rx", position=[3,0,1.5])) scene.tx_array = PlanarArray(num_cols=1, num_rows=1, pattern="iso", polarization="V") scene.rx_array = scene.tx_array # Create new radio material with custom scattering pattern # and assign it to the reflector (only object in the scene) my_mat = RadioMaterial(name="my_material", conductivity=10, relative_permittivity=5, scattering_coefficient=0.8, scattering_pattern="my_pattern", n=3) scene.get("merged-shapes").radio_material = my_mat # Compute propagation paths solver = PathSolver() # Switch the computation of field loop to "evaluated" mode to # enable gradient backpropagation through the loop solver.loop_mode = "evaluated" paths = solver(scene, diffuse_reflection=True) # Enable diffuse reflections # Compute total received power a_r, a_i = paths.a power = dr.sum(a_r**2 + a_i**2) ``` -------------------------------- ### Instantiate and Use Camera Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/camera.rst Instantiate a Camera, set its position, define its view direction using look_at, and render the scene. ```python scene = load_scene(rt.scene.munich) cam = Camera(position=(200., 0.0, 50.)) cam.look_at((0.0,0.0,0.0)) scene.render(cam) ``` -------------------------------- ### Instantiate Transmitter with Planar Array Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/radio_devices.rst Shows how to create a Transmitter and equip it with a 4x2 cross-polarized planar antenna array with isotropic antennas. ```python from sionna.rt import load_scene, PlanarArray, Transmitter scene = load_scene() scene.tx_array = PlanarArray(num_rows=4, num_cols=2, pattern="iso", polarization="cross") tx = Transmitter(name="tx", position=(0,0,0), power_dbm=22) scene.add(tx) ``` -------------------------------- ### Get Specific SceneObject Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Retrieves a specific SceneObject from the scene by its name. Useful for targeting individual objects for inspection or modification. ```python floor = scene.get("floor") ``` -------------------------------- ### Render Scene and Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Renders the scene with specified camera and paths, or provides a preview. Use 'scene.render' for detailed visualization and 'scene.preview' for a quick look. ```python if no_preview: scene.render(camera=cam, paths=paths, num_samples=512); else: scene.preview(paths=paths) ``` -------------------------------- ### Load Scene with Single Reflector Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Loads a scene containing a single reflector. This is a setup for modeling time evolution of channels via Doppler shift. ```python # Load scene with a single reflector scene = load_scene(sionna.rt.scene.simple_reflector, merge_shapes=False) ``` -------------------------------- ### Instantiate and Configure Transmitter Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/radio_devices.rst Demonstrates how to create a Transmitter with a specific AntennaArray configuration and add it to the scene. ```APIDOC ## Instantiate and Configure Transmitter ### Description This example shows how to instantiate a :class:`~sionna.rt.Transmitter` equipped with a :math:`4 \times 2` :class:`~sionna.rt.PlanarArray` with cross-polarized isotropic antennas and add it to the scene. ### Code Example ```python from sionna.rt import load_scene, PlanarArray, Transmitter scene = load_scene() scene.tx_array = PlanarArray(num_rows=4, num_cols=2, pattern="iso", polarization="cross") tx = Transmitter(name="tx", position=(0,0,0), power_dbm=22) scene.add(tx) ``` ``` -------------------------------- ### Load Scene and Configure Arrays Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Loads a simple scene with a quadratic reflector and configures transmitter and receiver arrays using PlanarArray for ray tracing experiments. ```python scene = load_scene(sionna.rt.scene.simple_reflector, merge_shapes=False) # Configure the transmitter and receiver arrays scene.tx_array = PlanarArray(num_rows=1, num_cols=1, vertical_spacing=0.5, horizontal_spacing=0.5, pattern="iso", polarization="V") scene.rx_array = scene.tx_array # Add a transmitter and receiver with equal distance from the center of the surface ``` -------------------------------- ### Get Transmitter Association for Each Cell Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Radio-Maps.ipynb This snippet retrieves and prints the shape of the transmitter association tensor for the 'sinr' metric, indicating for each cell which transmitter provides the strongest signal. ```python # Get for every cell the tx index providing the strongest value # of the chosen metric # [num_cells_y, num_cells_x] print(f'{rm.tx_association("sinr").shape=}') ``` -------------------------------- ### Load Scene and Set Camera Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Loads a street canyon scene with cars and sets up a camera. Use scene.preview() for interactive visualization or scene.render() for static images. ```python scene = load_scene(sionna.rt.scene.simple_street_canyon_with_cars, merge_shapes=False) cam = Camera(position=[50,0,130], look_at=[10,0,0]) if no_preview: scene.render(camera=cam); else: scene.preview(); ``` -------------------------------- ### Setting up a Scene for Mobility Simulation Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Configures a 3D scene with cars, a transmitter (TX), and a receiver (RX) for mobility simulations. Sets up antenna arrays and defines simulation parameters like max depth and refraction. ```python scene = load_scene(sionna.rt.scene.simple_street_canyon_with_cars, merge_shapes=False) cam = Camera(position=[50,0,130], look_at=[10,0,0]) # Parameters for ray tracing max_depth = 3 refraction = False # Toggle to true to see the impact of refraction diffraction = False # Toggle to true to see the impact of diffraction # TX and RX have directional antennas scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="tr38901", polarization="V") scene.rx_array = scene.tx_array # TX and RX are installed at the front of two different cars. # The directive antennas ensure that paths reaching an antenna from the back are close to zero. scene.add(Transmitter("tx", position=[22.7, 5.6, 0.75], orientation=[np.pi,0,0])) scene.add(Receiver("rx", position=[-27.8,-4.9, 0.75])) ``` -------------------------------- ### Render Scene to File Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Renders the scene using the 'preview' camera and saves it to a PNG file. This function is available only when a preview is open. ```python # Only availabe if a preview is open if not no_preview: scene.render_to_file(camera="preview", filename="scene.png", resolution=[650,500]); ``` -------------------------------- ### Load and Preview a Built-in Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/scene.rst Demonstrates how to load a scene using its identifier and then preview it. This is the standard way to access and visualize integrated scenes. ```python scene = load_scene(sionna.rt.scene.etoile) scene.preview() ``` -------------------------------- ### Add Multiple Transmitters and Recompute Radio Map Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Radio-Maps.ipynb Adds two new transmitters to the scene with specified positions, orientations, and power levels, then recomputes the radio map. This setup is for scenarios with multiple signal sources. ```python # Remove transmitters here so that the cell can be executed multiple times scene.remove("tx1") scene.remove("tx2") tx1 = Transmitter(name='tx1', position=[-150, -100, 20], orientation=[np.pi/6, 0, 0], power_dbm=21) scene.add(tx1) tx2 = Transmitter(name='tx2', position=np.array([0, 150 * np.tan(np.pi/3) - 100, 20]), orientation=[-np.pi/2, 0, 0], power_dbm=27) scene.add(tx2) rm = rm_solver( scene, max_depth=5, samples_per_tx=10**7, cell_size=(5, 5), center=[0, 0, 0], size=[400, 400], orientation=[0, 0, 0] ) ``` -------------------------------- ### Using Custom Radio Material in a Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Demonstrates how to load a scene, instantiate the custom radio material, and assign it to a reflector. The 'g' parameter is set low to observe its impact on reflected path gain. ```python scene_custom_mat = load_scene(rt.scene.simple_reflector, merge_shapes=False) scene_custom_mat.add(Transmitter("tx", position=(-2., 0., 1))) ``` -------------------------------- ### Create Empty Scene and Add Transmitter Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Radio-Maps.ipynb Initializes an empty scene and configures a single antenna transmitter. Suitable for basic mesh radio map computations. ```python # Empty scene scene = load_scene() # Use a single antenna with directive pattern scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="tr38901", polarization="V") # Add a transmitter scene.add(Transmitter(name="tx", position=[0, 0, 0], orientation=[0, 0, 0])) ``` -------------------------------- ### Configure Scene, Add Transmitter/Receiver, and Compute Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Set up transmitter and receiver arrays, add them to the scene, and compute propagation paths. This is a prerequisite for visualizing or analyzing signal propagation. ```python # Configure arrays for all transmitters and receivers in the scene scene.tx_array = PlanarArray(num_rows=1,num_cols=1,pattern="iso", polarization="V") scene.rx_array = scene.tx_array # Add a transmitter and a receiver scene.add(Transmitter("tx", [-25,0.1,50])) scene.add(Receiver("rx", [ 25,0.1,50])) # Compute paths p_solver = PathSolver() paths = p_solver(scene=scene, max_depth=1) # Visualize the scene and propagation paths if no_preview: cam = Camera(position=[0, 100, 50], look_at=[0,0,30]) scene.render(camera=cam, paths=paths); else: scene.preview(paths=paths) ``` -------------------------------- ### Render Scene with Preview Camera Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Renders the scene using the 'preview' camera, which corresponds to the current viewpoint in the interactive preview. Increase num_samples for higher quality. ```python # Only availabe if a preview is open if not no_preview: scene.render(camera="preview", num_samples=512); ``` -------------------------------- ### Setting up a Scene with Transmitter and Receiver Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Defines a scene with a transmitter and receiver positioned at specific coordinates. This is a prerequisite for path tracing. ```python dist = 5 d = dist/sqrt(2) scene.add(Transmitter(name="tx", position=[-d,0,d])) scene.add(Receiver(name="rx", position=[d,0,d])) ``` -------------------------------- ### Instantiate and Use PathSolver Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Initializes a PathSolver to compute propagation paths within a scene. Key parameters include max_depth for ray interactions and synthetic_array for antenna modeling. ```python # Instantiate a path solver # The same path solver can be used with multiple scenes p_solver = PathSolver() # Compute propagation paths paths = p_solver(scene=scene, max_depth=5, los=True, specular_reflection=True, diffuse_reflection=False, refraction=True, synthetic_array=False, seed=41) ``` -------------------------------- ### Render Scene with Camera and Coverage Map Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Renders the scene using a specified camera and overlays the coverage map with a color bar. This is a basic visualization step. ```python scene.render(camera=my_cam, radio_map=cm, rm_show_color_bar=True); ``` -------------------------------- ### Previewing the Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Displays a preview of the current scene. This is used when the 'no_preview' flag is false. ```python scene.preview() ``` -------------------------------- ### Instantiate Adam Optimizer for Training Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Initializes an Adam optimizer with a specified learning rate. This optimizer will be used to manage trainable variables during the gradient descent process for material parameter calibration. ```python # Adam optimizer learning_rate = 4e-2 opt = mi.ad.Adam(lr=learning_rate) ``` -------------------------------- ### Load Scene and Add Transmitter/Receiver Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Loads a simple scene with a reflector and adds a transmitter and receiver, each with a single antenna. This sets up the basic environment for radio material simulation. ```python scene = load_scene(rt.scene.simple_reflector, merge_shapes=False) scene.add(Transmitter("tx", position=(-2., 0., 1))) scene.add(Receiver("rx", position=(2., 0., 1))) scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") scene.rx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") ``` -------------------------------- ### Configure Radio Device Position and Orientation Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/radio_devices.rst Demonstrates how to set the position and orientation of a radio device after it has been added to the scene. ```python from sionna.rt import load_scene, Transmitter scene = load_scene() scene.add(Transmitter(name="tx", position=(0,0,0))) tx = scene.get("tx") tx.position=(10,20,30) tx.orientation=(0.3,0,0.1) ``` -------------------------------- ### Load Scene and Configure Transmitter/Receiver Arrays Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Loads a predefined street canyon scene and configures both the transmitter and receiver arrays to be identical planar arrays. Sets the carrier frequency and adds a transmitter to the scene. ```python scene = load_scene(sionna.rt.scene.simple_street_canyon) scene.frequency = 30e9 scene.tx_array = PlanarArray(num_rows=1, num_cols=1, vertical_spacing=0.5, horizontal_spacing=0.5, pattern="iso", polarization="V") scene.rx_array = scene.tx_array scene.add(Transmitter(name="tx", position=[-33,11,32], orientation=[0,0,0])) ``` -------------------------------- ### Configure Position and Orientation Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/api/radio_devices.rst Illustrates how to set and modify the position and orientation of a radio device within the scene. ```APIDOC ## Configure Position and Orientation ### Description This example demonstrates how to set and modify the position :math:`(x,y,z)` and orientation :math:`(\alpha, \beta, \gamma)` of a radio device. The orientation is specified through three angles corresponding to a 3D rotation. ### Code Example ```python from sionna.rt import load_scene, Transmitter scene = load_scene() scene.add(Transmitter(name="tx", position=(0,0,0))) tx = scene.get("tx") tx.position=(10,20,30) tx.orientation=(0.3,0,0.1) ``` ``` -------------------------------- ### Configure Transmitter and Generate Radio Map Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Mobility.ipynb Sets up a transmitter on a car, configures transmit and receive arrays, and initializes a RadioMapSolver. This snippet prepares the scene for radio map computation. ```python scene = load_scene(sionna.rt.scene.simple_street_canyon_with_cars, merge_shapes=False) cam = Camera(position=[50,0,130], look_at=[10,0,0]) # Configure a transmitter that is located at the front of "car_2" scene.add(Transmitter("tx", position=[22.7, 5.6, 0.75], orientation=[np.pi,0,0])) scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="tr38901", polarization="V") scene.rx_array = scene.tx_array # Create radio map solver rm_solver = RadioMapSolver() ``` -------------------------------- ### Inspect Individual Path Details Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_understanding_paths.rst This snippet demonstrates how to inspect the detailed properties of a specific propagation path, including its channel coefficient, propagation delay, angles of departure and arrival, and Doppler shift. It requires a pre-computed Paths object. ```python # Let us inspect a specific path in detail path_idx = 4 # Try out other values in the range [0, 14] # For a detailed overview of the dimensions of all properties, have a look at the API documentation print(f"--- Detailed results for path {path_idx} ---") print(f"Channel coefficient: {paths.a[0].numpy()[0,0,0,0,path_idx] + 1j*paths.a[1].numpy()[0,0,0,0,path_idx]}") print(f"Propagation delay: {paths.tau[0,0,0,0,path_idx].numpy()*1e6:.5f} us") print(f"Zenith angle of departure: {paths.theta_t.numpy()[0,0,0,0,path_idx]:.4f} rad") print(f"Azimuth angle of departure: {paths.phi_t.numpy()[0,0,0,0,path_idx]:.4f} rad") print(f"Zenith angle of arrival: {paths.theta_r.numpy()[0,0,0,0,path_idx]:.4f} rad") print(f"Azimuth angle of arrival: {paths.phi_r.numpy()[0,0,0,0,path_idx]:.4f} rad") print(f"Doppler shift: {paths.doppler.numpy()[0,0,0,0,path_idx]:.4f} Hz") ``` -------------------------------- ### Lint Code with Pylint Source: https://github.com/nvlabs/sionna-rt/blob/main/README.md Runs Pylint to check code quality and style. Execute from the repository's root directory, specifying the source directory. ```bash pylint src/ ``` -------------------------------- ### Configure Realistic Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Radio-Maps.ipynb Loads a scene, configures antenna arrays, and places transmitters with specified positions and power levels. This function is used to set up the environment for radio map computations. ```python def config_scene(num_rows, num_cols): """Load and configure a scene""" scene = load_scene(sionna.rt.scene.etoile) scene.bandwidth=100e6 # Configure antenna arrays for all transmitters and receivers scene.tx_array = PlanarArray(num_rows=num_rows, num_cols=num_cols, pattern="tr38901", polarization="V") scene.rx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") # Place transmitters positions = np.array( [[-150.3, 21.63, 42.5], [-125.1, 9.58, 42.5], [-104.5, 54.94, 42.5], [-128.6, 66.73, 42.5], [172.1, 103.7, 24], [232.8, -95.5, 17], [80.1, 193.8, 21] ]) look_ats = np.array( [[-216, -21,0], [-90, -80, 0], [-16.5, 75.8, 0], [-164, 153.7, 0], [247, 92, 0], [211, -180, 0], [126.3, 194.7, 0] ]) power_dbms = [23, 23, 23, 23, 23, 23, 23] for i, position in enumerate(positions): scene.add(Transmitter(name=f'tx{i}', position=position, look_at=look_ats[i], power_dbm=power_dbms[i])) return scene ``` -------------------------------- ### Render Scene with Custom Camera Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Creates a new camera with a specified position and look-at direction, then renders the scene using this custom camera. The output is a matplotlib figure. ```python # Create new camera with different configuration my_cam = Camera(position=[-250,250,150], look_at=[-15,30,28]) # Render scene with new camera* scene.render(camera=my_cam, resolution=[650, 500], num_samples=512); # Increase num_samples to increase image quality ``` -------------------------------- ### Previewing Specular Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Displays a preview of the computed specular paths. This is used when the 'no_preview' flag is false. ```python scene.preview(paths=paths) ``` -------------------------------- ### Custom Radio Material Implementation Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst This class defines a custom radio material using `RadioMaterialBase`. It handles initialization from parameters or Mitsuba properties and implements the `sample` method to compute the Jones matrix for reflection. ```python class CustomRadioMaterial(RadioMaterialBase): # The __init__ method builds the radio material from: # - A unique `name` to identify the material instance in the scene # - The gain parameter `g` # - An optional `color` for displaying the material in the previewer and renderer # Providing these 3 parameters to __init__ is how an instance of this radio material # is built programmatically. # # When loading a scene from an XML file, Mitsuba provides to __init__ # only an `mi.Properties` object containing all the properties of the material # read from the XML scene file. Therefore, when a `props` object is provided, # the other parameters are ignored and should not be given. def __init__( self, name : str | None = None, g : float | mi.Float | None = None, color : Tuple[float, float, float] | None = None, props : mi.Properties | None = None): # If `props` is `None`, then one is built from the # other parameters if props is None: props = mi.Properties("custom-radio-material") # Name of the radio material props.set_id(name) props["g"] = g if color is not None: props["color"] = mi.ScalarColor3f(color) # Read the gain from `props` g = 0.0 if "g" in props: g = props["g"] del props["g"] self._g = mi.Float(g) # The other parameters (`name`, `color`) are given to the # base class to complete the initialization of the material super().__init__(props) def sample( self, ctx : mi.BSDFContext, si : mi.SurfaceInteraction3f, sample1 : mi.Float, sample2 : mi.Point2f, active : bool | mi.Bool = True ) -> Tuple[mi.BSDFSample3f, mi.Spectrum]: # Read the incident direction of propagation in the local coordinate # system ki_prime = si.wi # Build the 3x3 change-of-basis matrix from the local basis to the world # basis. # `si.sh_frame` stores the three vectors that define the local interaction basis # in the world coordinate system. to_world = mi.Matrix3f(si.sh_frame.s, si.sh_frame.t, si.sh_frame.n).T # Direction of propagation of the reflected field in the local coordinate system kr_prime = mi.reflect(-ki_prime) # Compute the Jones matrix in the implicit world coordinate system # The `jones_matrix_to_world_implicit()` builds the Jones matrix with the # structure we need. sqrt_g = mi.Complex2f(dr.sqrt(self._g), 0.) jones_mat = jones_matrix_to_world_implicit(c1=sqrt_g, c2=sqrt_g, to_world=to_world, k_in_local=ki_prime, k_out_local=kr_prime) ## We now only need to prepare the outputs # Cast the Jones matrix to a `mi.Spectrum` to meet the requirements of ``` -------------------------------- ### PyTorch Training Loop for Path Gain Optimization Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_compat_frameworks.rst This snippet demonstrates a PyTorch training loop that optimizes the conductivity and thickness of a custom radio material to maximize path gain. It uses differentiable rendering (`dr.wrap`) to enable gradient computation through the path solver. ```python from sionna.rt import Scene, Transmitter, Receiver, RadioMaterial, PathSolver from sionna.rt.utils import dr_utils from sionna.utils import dr, cpx_abs_square import torch import numpy as np # Scene setup scene = Scene(pattern="iso", polarization="V") scene.rx_array = scene.tx_array scene.add(Transmitter("tx", position=[0,0,3])) scene.add(Receiver("rx", position=[0,0,-3])) # Create custom radio material and assign it to reflector my_mat = RadioMaterial(name="my_mat", conductivity=0.1, thickness=0.1, relative_permittivity=2.1) scene.get("reflector").radio_material = my_mat # Wrap path computation function within a PyTorch context p_solver = PathSolver() p_solver.loop_mode = "evaluated" # Needed for gradient compuation @dr.wrap(source="torch", target="drjit") def compute_paths(thickness, conductivity): # Avoid negative values of thickness and conductivity my_mat.thickness = dr.select(thickness.array<0, 0, thickness.array) my_mat.conductivity = dr.select(conductivity.array<0, 0, conductivity.array) paths = p_solver(scene, refraction=True) gain = dr.sum(dr.sum(cpx_abs_square(paths.a))) return gain # PyTorch training loop maximizing the path gain conductivity = torch.tensor(0.1, requires_grad=True) thickness = torch.tensor(0.2, requires_grad=True) optimizer = torch.optim.Adam([thickness, conductivity], lr=0.05) num_steps = 10 for step in range(num_steps): loss = -compute_paths(thickness, conductivity) optimizer.zero_grad() loss.backward() optimizer.step() if step in [0, num_steps-1]: print("Step: ", step) print("Path gain (dB): ", 10*np.log10(-loss.detach().numpy())) print("Thickness: ", my_mat.thickness[0]) print("Conductivity: ", my_mat.conductivity[0]) print("------------------------------------ ") ``` ```text Step: 0 Path gain (dB): -81.59713 Thickness: 0.15265434980392456 Conductivity: 0.05138068273663521 ------------------------------------ Step: 9 Path gain (dB): -58.89217 Thickness: 0.0 Conductivity: 0.0 ------------------------------------ ``` -------------------------------- ### Sample Interaction and Prepare BSDFSample Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Samples the interaction type (reflection or refraction) based on a probability and prepares a BSDFSample object. This is used when sampling new directions. ```python # Sample the interaction type. # We use the `sample1` parameter, which is assumed to be a float uniformly sampled # from (0,1). # The probability of selecting a specular reflection corresponds to the ratio of energy # that is reflected, i.e., `g`. reflection = sample1 < g # Select the Jones matrix and direction of the scattered wave according to the sampled # interaction type ko_prime = dr.select(reflection, kr_prime, kt_prime) jones_mat = dr.select(reflection, jones_mat_ref, jones_mat_tra) ## We now only need to prepare the outputs # Cast the Jones matrix to a `mi.Spectrum` to meet the requirements of # the BSDF interface of Mitsuba jones_mat = mi.Spectrum(jones_mat) # Instantiate and set the BSDFSample object bs = mi.BSDFSample3f() # Specifies the type of interaction that was sampled bs.sampled_component = dr.select(reflection, InteractionType.SPECULAR, InteractionType.REFRACTION) # Direction of the scattered wave in the world frame bs.wo = to_world@ko_prime # The next field of `bs` stores the probability that the sampled # interaction type and direction of scattering are sampled conditioned # on the given direction of incidence. bs.pdf = dr.select(reflection, g, 1.-g) # Not used but required to be set bs.sampled_type = mi.UInt32(+mi.BSDFFlags.DeltaReflection) bs.eta = 1.0 return bs, jones_mat ``` -------------------------------- ### Load and Render a Complex Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scene-Edit.ipynb Loads a complex scene ('etoile') with default merging and renders it using a specified camera configuration. Assumes 'no_preview' is set to True for rendering. ```python scene = load_scene(sionna.rt.scene.etoile) # Objects are merged by default cam = Camera(position=[-360,145,400], look_at=[-115,33,1.5]) if no_preview: scene.render(camera=cam); else: scene.preview(); ``` -------------------------------- ### Instantiate and Assign Custom Radio Material Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_custom_radio_materials.rst Loads a scene, adds transmitters and receivers, and instantiates the custom radio material. The custom material is then assigned to a scene object, replacing the default. ```python scene_custom_mat = load_scene(rt.scene.simple_reflector, merge_shapes=False) scene_custom_mat.add(Transmitter("tx", position=(-2., 0., 1))) scene_custom_mat.add(Receiver("rx-1", position=(2., 0.5, 1))) scene_custom_mat.add(Receiver("rx-2", position=(2., -0.5, -1))) scene_custom_mat.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") scene_custom_mat.rx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso", polarization="V") my_mat = EnhancedCustomRadioMaterial("custom-mat-instance", g=0.7) scene_custom_mat.objects["reflector"].radio_material = my_mat scene_custom_mat.remove("reflector-mat") print(scene_custom_mat.radio_materials) ``` -------------------------------- ### Render Scene (Static) Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Renders the scene using a specified camera. This is used when the interactive preview is disabled. ```python my_cam = Camera(position=[10,-100,100], look_at=[10,0,0]) scene.render(camera=my_cam); ``` -------------------------------- ### Configure Wedge Material and Frequency Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Sets the scene frequency to 1GHz and configures the wedge object to be made of metal with a specific thickness. ```python scene.frequency = 1e9 # 1GHz scene.objects["wedge"].radio_material = ITURadioMaterial("metal", itu_type="metal", thickness=100) ``` -------------------------------- ### Rendering Specular Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Scattering.ipynb Renders the computed specular paths using a camera. This is an alternative to scene preview. ```python scene.render(camera=my_cam, paths=paths); ``` -------------------------------- ### Load Scene Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Diffraction.ipynb Loads a pre-made simple wedge scene. Set merge_shapes to False to keep the wedge as a single object. ```python scene = load_scene(sionna.rt.scene.simple_wedge, merge_shapes=False) ``` -------------------------------- ### Compute Propagation Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/doc/source/developer/dev_understanding_paths.rst This snippet demonstrates how to load a scene, configure transmitters and receivers, and compute propagation paths using the PathSolver. It shows how to use the `synthetic_array` argument to control whether paths are calculated between individual antennas or the center of antenna arrays. ```python # Imports import sionna.rt from sionna.rt import load_scene, PlanarArray, Transmitter, Receiver, \ PathSolver # Load scene scene = load_scene(sionna.rt.scene.munich, merge_shapes=False) # Configure TX/RX antenna array scene.tx_array = PlanarArray(num_rows=2, num_cols=1, pattern="iso", polarization="V") scene.rx_array = scene.tx_array # Create TX/RX scene.add(Transmitter(name="tx", position=[8.5,21,27])) scene.add(Receiver(name="rx", position=[44,95,1.5])) # Compute propagation paths p_solver = PathSolver() # without a synthetic array paths = p_solver(scene=scene, max_depth=3, synthetic_array=False) # with a synthetic array paths_syn = p_solver(scene=scene, max_depth=3, synthetic_array=True) ``` -------------------------------- ### Visualize Propagation Paths Source: https://github.com/nvlabs/sionna-rt/blob/main/tutorials/Introduction.ipynb Renders the scene with the computed propagation paths. Uses scene.render for static rendering or scene.preview for interactive visualization. ```python if no_preview: scene.render(camera=my_cam, paths=paths, clip_at=20); else: scene.preview(paths=paths, clip_at=20); ```