Radar Cross-Section (RCS)#

Sensing targets (SensingTarget) are scene objects that are modelled by their ScatteringModel rather than by their mesh and radio material. Such sensing targets are typically used to model objects that are sensed in a radar or integrated sensing and communication (ISAC) scenario, e.g., a car, a drone, or a pedestrian.

A ScatteringModel consists of a collection of scattering points, provided in the local coordinate system of the sensing target. Every scattering point carries a radar cross-section (RCS) and a cross-polarization matrix (CPM), both implemented as callables that are evaluated for a pair of incident and scattered directions. The RCS gives the cross-section \(\sigma\) [\(\text{m}^2\)] of the point scatters, whereas the CPM gives the complex \(2 \times 2\) matrix \(\mathbf{W}\) describing how the point transforms the polarization of the incident field. Together, they define the Jones matrix \(\mathbf{J} = \sqrt{\sigma}\mathbf{W}\) of the transfer function, so both are required for every scattering point.

Custom RCS and CPM callables can be used directly, or registered under a name with register_rcs() and register_cpm() so that they can be referred to by that name. Sionna provides ConstantRCS and ConstantCPM, which do not depend on the incident and scattered directions, as well as the models of the 3GPP specifications described in 3GPP TR 38.901 Models. A ConstantCPM without a cross-polarization ratio describes a scattering point which does not depolarize.

The RCSSolver computes the propagation paths that connect the transmitters to the receivers of a scene through the scattering points of its sensing targets. Paths that do not interact with a sensing target are not computed by this solver; use PathSolver to compute them.

The sensing targets are traced as absorbing objects, so that a target casts a radio shadow on the other targets and on the legs of the computed paths. The only exception is that a target does not occlude the scattering points it contains, i.e., the ones which lie within its bounding box, as the scattering response of a target is entirely described by its scattering model: a leg which starts from such a point is only tested for occlusion once it has left that bounding box. A scattering point placed outside of that box is occluded by its own target as it is by any other object of the scene.

The following code snippet shows how to add a sensing target with a single scattering point to a scene, and how to compute the paths scattered by it:

import mitsuba as mi
import sionna
from sionna.rt import load_scene, PlanarArray, Receiver, Transmitter
from sionna.rt.rcs import (ConstantCPM, ConstantRCS, RCSSolver,
                           ScatteringModel, SensingTarget)

scene = load_scene(sionna.rt.scene.simple_street_canyon)

scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso",
                             polarization="V")
scene.rx_array = scene.tx_array
scene.add(Transmitter(name="tx", position=[-32,-9,25]))
scene.add(Receiver(name="rx", position=[-32,11,31]))

# Sensing target shaped as a cuboid, with a single scattering point 2m
# below it whose cross-section is 1 square meter and which does not
# depolarize
model = ScatteringModel([0,0,-2], rcs=ConstantRCS(sigma=1.),
                        cpm=ConstantCPM())
target = SensingTarget(name="st", scattering_model=model,
                       length=4., width=2., height=1.5,
                       position=[-16,-10,60])
scene.add(target)
solver = RCSSolver()
paths = solver(scene)
class sionna.rt.rcs.RCSSolver(deterministic: bool = False)[source]#

Class implementing a radar cross-section (RCS) solver

This solver computes the propagation paths that connect the antennas of all transmitters to the antennas of all receivers of a scene through the scattering points of its sensing targets (SensingTarget). Every computed path therefore consists of a transmitter-to-scattering-point leg, a scattering event, and a scattering-point-to-receiver leg:

\[\text{TX} \rightarrow \dots \rightarrow \text{SP} \rightarrow \dots \rightarrow \text{RX}\]

Both legs can undergo line-of-sight propagation, specular reflection, and refraction, i.e., the same interaction types as PathSolver except for diffuse reflection and diffraction which are not supported. The scattering event is described by the radar cross-section (RCS) and the cross-polarization matrix (CPM) of the scattering point, evaluated for the incident and scattered directions of the path.

Paths that do not interact with a sensing target are not computed by this solver; use PathSolver to compute them.

The sensing targets are part of the environment through which the paths are traced, and are seen as absorbers by the PathSolver: a target shadows the scattering points of the other targets and blocks the legs of the computed paths. A target does however not occlude the scattering points it contains, i.e., the ones which lie within its bounding box. This is because the scattering response of a target is entirely described by its scattering model: a leg which starts from such a point is only tested for occlusion once it has left that bounding box. A scattering point placed outside of the bounding box of its target, on the other hand, is occluded by that target as it is by any other object of the scene.

As with PathSolver, if synthetic arrays are used (synthetic_array is True), transmitters and receivers are modelled as if they had a single antenna located at their position, and the channel responses of the individual antennas are computed “synthetically” by applying appropriate phase shifts.

The Doppler shifts of the computed paths account for the mobility of the transmitters, receivers, scene objects, and sensing targets. Only the rigid translation of a sensing target is modelled: all its scattering points move with its velocity, so the Doppler shifts do not reflect the rotation of a target.

Example#

import drjit as dr
import mitsuba as mi
import sionna
from sionna.rt import load_scene, Transmitter, Receiver, PlanarArray
from sionna.rt.rcs import (ConstantCPM, RCSSolver, ScatteringModel,
                           SensingTarget)

# Load example scene
scene = load_scene(sionna.rt.scene.simple_street_canyon)

# Configure antenna arrays for all transmitters and receivers
scene.tx_array = PlanarArray(num_rows=1, num_cols=1, pattern="iso",
                             polarization="V")
scene.rx_array = scene.tx_array

scene.add(Transmitter(name="tx", position=[-32,-9,25]))
scene.add(Receiver(name="rx", position=[-32,11,31]))

# Cross-section of 1 square meter, independent of the incident and
# scattered directions. The seed is only used by the models with
# random components.
def rcs(k_i, k_s, seed):
    return dr.ones(mi.Float, dr.width(k_i))

# Sensing target shaped as a cuboid, with a single scattering point
# 2m below it which does not depolarize
model = ScatteringModel([0,0,-2], rcs=rcs,
                        cpm=ConstantCPM())
target = SensingTarget(name="st", scattering_model=model,
                       length=4., width=2., height=1.5,
                       position=[-16,-10,60])
scene.add(target)

# Compute paths
solver = RCSSolver()
paths = solver(scene)

# Open preview showing paths
scene.preview(paths=paths)
__call__(scene: sionna.rt.scene.Scene, max_depth: int = 3, buffer_size_per_sp: int = 1000000, samples_per_sp: int = 1000000, synthetic_array: bool = True, los: bool = True, specular_reflection: bool = True, refraction: bool = True, seed: int | None = None) → sionna.rt.path_solvers.paths.Paths[source]#

Executes the solver

Paths are traced from the scattering points of the sensing targets, which are therefore the sources of the underlying path tracing. The buffer_size_per_sp and samples_per_sp parameters consequently apply to each scattering point, and the legs of a scattering point towards the transmitters and towards the receivers share these budgets.

Parameters:
  • scene (sionna.rt.scene.Scene) – Scene for which to compute paths

  • max_depth (int) – Maximum depth of the paths, i.e., maximum total number of interactions including the scattering event on the sensing target. Each of the two legs can therefore undergo at most max_depth - 1 interactions with the scene, and a value of 1 restricts the computed paths to those for which both legs are unobstructed.

  • buffer_size_per_sp (int) – Maximum number of legs stored per scattering point

  • samples_per_sp (int) – Number of samples per scattering point

  • synthetic_array (bool) – If set to True (default), then the antenna arrays are applied synthetically

  • los (bool) – Enable unobstructed legs, i.e., legs without any interaction with the scene

  • specular_reflection (bool) – Enables specular reflection

  • refraction (bool) – Enables refraction

  • seed (int | None) – Non-negative seed. If set to None (default), a seed is drawn at random, so that every call draws new random components. Reproducing a call therefore requires passing an explicit seed. A fixed seed does not guarantee deterministic results unless the solver is constructed with deterministic=True. The seed is also given to the RCS and CPM of the scattering points, which the models with random components use to draw them, e.g. TR38901RCS and TR38901CPM.

Returns:

Computed paths, as an instance of Paths

property loop_mode#

Get/set the Dr.Jit mode used to evaluate the loops that implement the solver. Should be one of “evaluated” or “symbolic”. Symbolic mode (default) is the fastest one but does not support automatic differentiation. For more details, see the corresponding Dr.Jit documentation.

Type:

“evaluated” | “symbolic”

Parameters:

deterministic (bool)

Sensing Targets#

class sionna.rt.rcs.SensingTarget(name: str, scattering_model: sionna.rt.rcs.scattering_model.ScatteringModel, mi_mesh: mitsuba.Mesh | None = None, fname: str | None = None, length: float | None = None, width: float | None = None, height: float | None = None, color: Tuple[float, float, float] = (0.2, 0.4, 1.0), display_opacity: float = 0.5, position: mitsuba.Point3f | None = None, orientation: mitsuba.Point3f | None = None, look_at: mitsuba.Point3f | sionna.rt.scene_object.SceneObject | sionna.rt.radio_devices.radio_device.RadioDevice | None = None, velocity: mitsuba.Vector3f | None = None)[source]#

Class defining a sensing target

A sensing target is a scene object whose scattering response is described by a scattering model, i.e., by a collection of scattering points in its local coordinate system (LCS), rather than by a radio material. Its radio material is therefore always an AbsorberRadioMaterial, which cannot be changed: no energy is scattered by the surface of the target itself.

The shape of a sensing target can be specified in three mutually exclusive ways: from a Mitsuba shape (mi_mesh), from a mesh file (fname), or as a cuboid of the given dimensions (length, width, and height).

To create a sensing target shaped as a cuboid of 4m x 2m x 1.5m, with a single scattering point at the center of its roof, i.e., 0.75m above its center:

model = ScatteringModel([0, 0, 0.75], rcs="my_rcs",
                        cpm="my_cpm")
target = SensingTarget(name="car", scattering_model=model,
                       length=4., width=2., height=1.5)

As with any other scene object, a sensing target is added to a scene using add() or edit(). Its position and orientation can be set at construction, or through the corresponding properties:

target.position = [10, 0, 0]
scene.add(target)
target.orientation = [dr.pi/2, 0, 0]

The scattering points of a target are given in its unscaled LCS, and are scaled along with its geometry by its scaling, so that a point keeps its place relative to the shape it describes.

Both RCSSolver and PathSolver trace paths through the shapes of the sensing targets and see them as absorbers, so that a target casts a radio shadow. As the scattering response of a target is entirely described by its scattering model, RCSSolver makes an exception for the scattering points a target contains, i.e., the ones which lie within its bounding box: a leg which starts from such a point is only tested for occlusion once it has left that bounding box. A scattering point placed outside of that box, e.g., above the roof of a vehicle, is on the other hand occluded by its own target as it is by any other object of the scene.

The velocity of a target is accounted for by RCSSolver when computing the Doppler shifts of the paths scattered by its scattering points. It must be set explicitly, as moving a target by updating its position does not set it:

target.velocity = [10, 0, 0]
Parameters:
  • name (str) – Name of the sensing target

  • scattering_model (ScatteringModel) – Scattering model of the target

  • mi_mesh (mi.Mesh | None) – Mitsuba shape. Mutually exclusive with fname and the cuboid dimensions.

  • fname (str | None) – Filename of a valid mesh ( “.ply” | “.obj”). Mutually exclusive with mi_mesh and the cuboid dimensions.

  • length (float | None) – Length, i.e., size along the x-axis of the LCS, of the cuboid representing the target [m]. Must be specified together with width and height, and is mutually exclusive with mi_mesh and fname.

  • width (float | None) – Width, i.e., size along the y-axis of the LCS, of the cuboid representing the target [m]

  • height (float | None) – Height, i.e., size along the z-axis of the LCS, of the cuboid representing the target [m]

  • color (Tuple[float, float, float]) – Defines the RGB (red, green, blue) color parameter for the target as displayed in the previewer and renderer. Each RGB component must have a value within the range \(\in [0,1]\).

  • display_opacity (float) – Defines the opacity with which the target is displayed in the previewer and renderer, within the range \(\in [0,1]\). Targets are displayed as semi-transparent by default, so that their scattering points remain visible.

  • position (mi.Point3f | None) – Position \((x,y,z)\) [m] of the center of the target. If set to None, the target keeps the position of its mesh.

  • orientation (mi.Point3f | None) – Orientation specified through three angles \((\alpha, \beta, \gamma)\) corresponding to a 3D rotation as defined in (3). Mutually exclusive with look_at; specifying both raises ValueError. Defaults to \((0,0,0)\) if both orientation and look_at are None.

  • look_at (mi.Point3f | SceneObject | RadioDevice | None) – A position, or the instance of a SceneObject or RadioDevice to look at. Mutually exclusive with orientation.

  • velocity (mi.Vector3f | None) – Velocity vector of the target [m/s]

Methods

clone(name: str | None = None, as_mesh: bool = False, props: mitsuba.Properties | None = None) → sionna.rt.rcs.sensing_target.SensingTarget | mitsuba.Mesh[source]#

Creates a clone of the current sensing target

The clone shares the scattering model of the original target and has the same geometry, color, and display opacity, but is assigned a new name.

Parameters:
  • name (str | None) – Name (id) of the cloned target. If None, the clone will be named as <original_name>-clone.

  • as_mesh (bool) – If set to True, the clone will be returned as a mitsuba.Mesh object. Otherwise, a sionna.rt.rcs.SensingTarget will be returned.

  • props (mitsuba.Properties | None) – Pre-populated properties to be used in the new Mitsuba shape. Allows overriding the BSDF, emitter, etc.

Returns:

A clone of the current sensing target

show(k_i: mitsuba.Vector3f, **kwargs) → None[source]#

In an interactive notebook environment, opens an interactive 3D viewer of the scattering model of this target

The target is shown in its local coordinate system (LCS), i.e., as it is before being positioned and oriented, since that is the frame in which its scattering points and their RCS and CPM are defined. The viewer displays the mesh of the target, the bounding box of that mesh as a wireframe, every scattering point with the triad of its local axes, the incident direction, and, around every scattering point, a surface showing the bistatic radar cross-section it scatters in every direction [dBsm].

Controls:

  • Mouse left: Rotate

  • Scroll wheel: Zoom

  • Mouse right: Move

Parameters:
  • k_i (mitsuba.Vector3f) – Incident direction of propagation, in the LCS of this target. As in eval_rcs(), this is a direction of propagation and therefore points towards the scattering points. A direction \(\mathbf{k}\) given in the global coordinate system is brought to the LCS with rotation_matrix(target.orientation).T @ k.

  • kwargs – Additional display options, as accepted by ScatteringModelViewer

Example#

import drjit as dr
from sionna.rt.rcs import TR38901SensingTarget
from sionna.rt.utils import r_hat

target = TR38901SensingTarget(name="st",
                              object_type="vehicle-multi-sp")

# Wave incident from the front of the car, i.e., from the +x-axis
# side of its LCS, at a zenith and an azimuth angle of 45 deg
target.show(k_i=-r_hat(dr.pi/4, dr.pi/4))

Attributes

property display_opacity#

float: Get/set the opacity with which this target is displayed in the previewer and renderer. A value of 1 makes the target fully opaque, and a value of 0 makes it invisible.

property radio_material#

(read-only) Radio material of the sensing target

The surface of a sensing target absorbs all the incident energy, as its scattering response is entirely described by its scattering_model. This material can therefore not be changed.

Type:

AbsorberRadioMaterial

property scattering_model#

Scattering model of the sensing target

Type:

ScatteringModel

class sionna.rt.rcs.ConstantRCSSensingTarget(name: str, sigma: float | drjit.cuda.ad.Float = 1.0, xpr_db: float | drjit.cuda.ad.Float | None = None, mi_mesh: mitsuba.Mesh | None = None, fname: str | None = None, length: float | None = None, width: float | None = None, height: float | None = None, color: Tuple[float, float, float] = (0.2, 0.4, 1.0), display_opacity: float = 0.5, position: mitsuba.Point3f | None = None, orientation: mitsuba.Point3f | None = None, look_at: mitsuba.Point3f | sionna.rt.scene_object.SceneObject | sionna.rt.radio_devices.radio_device.RadioDevice | None = None, velocity: mitsuba.Vector3f | None = None)[source]#

Sensing target with a single scattering point of constant radar cross-section

The target automatically creates its ScatteringModel; no scattering model is supplied by the user. The model consists of a single scattering point located at the center \((0,0,0)\) of the local coordinate system (LCS) of the target, whose RCS is a ConstantRCS and whose cross-polarization matrix is a ConstantCPM, so that neither depends on the incident and scattered directions.

If no mesh is provided, the target is represented by a cuboid whose omitted dimensions default to a cube of 0.3m. If a mesh is provided, its axis-aligned bounding box (AABB) determines the reported dimensions. The AABB is read before the target is posed, so the resulting dimensions are the ones of its LCS regardless of the requested orientation, and scaling the target afterwards scales them accordingly. As the scattering point sits at the center of the LCS, the dimensions only affect how the target is displayed and the geometry seen by PathSolver, not its scattering response.

To create a target of cross-section 0.1 \(\text{m}^2\) shaped as the default cube:

from sionna.rt.rcs import ConstantRCSSensingTarget

target = ConstantRCSSensingTarget(name="st", sigma=0.1)

The cross-section and cross-polarization ratio can also be changed after construction:

target.sigma = 20.
target.xpr_db = 3.
Parameters:
  • name (str) – Name of the sensing target

  • sigma (float | mi.Float) – Bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)] of the scattering point

  • xpr_db (float | mi.Float | None) – Cross-polarization ratio \(\text{XPR}_{dB}\) [dB] of the scattering point, as defined in ConstantCPM. Set to None for a target which does not depolarize.

  • mi_mesh (mi.Mesh | None) – Mitsuba shape. Mutually exclusive with fname and the cuboid dimensions.

  • fname (str | None) – Filename of a valid mesh ( “.ply” | “.obj”). Mutually exclusive with mi_mesh and the cuboid dimensions.

  • length (float | None) – Size along the x-axis of the LCS [m]. If omitted for a cuboid, defaults to 0.3m.

  • width (float | None) – Size along the y-axis of the LCS [m]. If omitted for a cuboid, defaults to 0.3m.

  • height (float | None) – Size along the z-axis of the LCS [m]. If omitted for a cuboid, defaults to 0.3m.

  • color (Tuple[float, float, float]) – RGB color used by the previewer and renderer

  • display_opacity (float) – Display opacity in the range \([0,1]\)

  • position (mi.Point3f | None) – Position \((x,y,z)\) [m] of the center of the target. If set to None, the target keeps the position of its mesh.

  • orientation (mi.Point3f | None) – Orientation specified through three angles \((\alpha, \beta, \gamma)\) corresponding to a 3D rotation as defined in (3). Mutually exclusive with look_at; specifying both raises ValueError. Defaults to \((0,0,0)\) if both orientation and look_at are None.

  • look_at (mi.Point3f | SceneObject | RadioDevice | None) – A position, or the instance of a SceneObject or RadioDevice to look at. Mutually exclusive with orientation.

  • velocity (mi.Vector3f | None) – Velocity vector of the target [m/s]

Methods

clone(name: str | None = None, as_mesh: bool = False, props: mitsuba.Properties | None = None) → sionna.rt.rcs.constant_rcs_sensing_target.ConstantRCSSensingTarget | mitsuba.Mesh[source]#

Creates a clone of the current constant-RCS sensing target

The clone shares the scattering model of the original target, and has the same dimensions, geometry, pose, color, and display opacity.

Parameters:

Attributes

property cpm: sionna.rt.rcs.cpm.ConstantCPM#

CPM callable of the scattering point of this target

Type:

ConstantCPM

property dimensions: Dict[str, float]#

Target dimensions as length, width, and height [m]

property height: float#

Size along the z-axis of the local coordinate system [m], scaled by the scaling of this target

property length: float#

Size along the x-axis of the local coordinate system [m], scaled by the scaling of this target

property rcs: sionna.rt.rcs.rcs.ConstantRCS#

RCS callable of the scattering point of this target

Type:

ConstantRCS

property sigma#

Get/set the bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)] of the scattering point

Type:

mi.Float

property width: float#

Size along the y-axis of the local coordinate system [m], scaled by the scaling of this target

property xpr_db#

Get/set the cross-polarization ratio \(\text{XPR}_{dB}\) [dB] of the scattering point, or None if it does not depolarize

Type:

mi.Float | None

class sionna.rt.rcs.ScatteringModel(lcs_positions: mitsuba.Point3f | None = None, lcs_orientations: mitsuba.Point3f | None = None, rcs: list[str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float]] | str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float] | None = None, cpm: list[str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]]] | str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]] | None = None)[source]#

Class defining the scattering model of a sensing target

A scattering model consists of a collection of scattering points, given in the local coordinate system (LCS) of the sensing target it is attached to. Scattering points can be added and removed at any time.

Predefined scattering models are built by deriving from this class and adding the scattering points of the model in the constructor:

class MyScatteringModel(ScatteringModel):
    def __init__(self):
        super().__init__()
        self.add_scattering_points(mi.Point3f([0, 1], [0, 0], [0, 0]),
                                   rcs="my_rcs", cpm="my_cpm")
Parameters:

Methods

add_scattering_points(lcs_positions: mitsuba.Point3f, lcs_orientations: mitsuba.Point3f | None = None, rcs: list[str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float]] | str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float] | None = None, cpm: list[str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]]] | str | Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]] | None = None)[source]#

Adds scattering points to this model

The new points are appended to the ones of this model.

Parameters:
remove_scattering_points(indices: int | list[int])[source]#

Removes scattering points from this model

The remaining points keep their relative order, and so do their callables, which are re-indexed accordingly.

Parameters:

indices (int | list[int]) – Indices of the scattering points to remove

Attributes

property spst#

Scattering points of the model

Type:

ScatteringPoints

class sionna.rt.rcs.ScatteringPoints(lcs_positions: mitsuba.Point3f = <factory>, lcs_orientations: mitsuba.Point3f = <factory>, rcs: dataclasses.InitVar[typing.Union[list[typing.Union[str, typing.Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float]]], str, typing.Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float], NoneType]] = None, cpm: dataclasses.InitVar[typing.Union[list[typing.Union[str, typing.Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], typing.Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]]]], str, typing.Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], typing.Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]], NoneType]] = None)[source]#

Collection of scattering points of a sensing target

Positions and orientations are stored in the local coordinate system (LCS) of the sensing target as Dr.Jit arrays.

Every scattering point has exactly one RCS callable and one CPM callable, both of which are required. They are stored in rcs_callables and cpm_callables, in the same order as the points, so the index of a point is also the index of its callables.

Parameters:

Methods

concat(other: Self | list[Self]) → Self[source]#

Returns a new collection that combines this one with other

The points of other are appended to the ones of this collection, and so are their callables. If other is a list, its collections are appended in the order in which they are given.

Parameters:

other (Self | list[Self]) – Scattering points to be concatenated

Returns:

Concatenated scattering points

eval_cpm(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, st_orientations: mitsuba.Point3f, st_indices: drjit.cuda.ad.UInt, spst_indices: drjit.cuda.ad.UInt, seed: int = 0) → Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f][source]#

Evaluates, for every sample, the CPM of the scattering point it is associated with

As with eval_rcs(), the directions are given in the GCS and are rotated to the local frame of the scattering point before the CPM is evaluated.

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions in the GCS

  • k_s (mitsuba.Vector3f) – Scattered directions in the GCS

  • st_orientations (mitsuba.Point3f) – Orientations of the sensing targets in the GCS, specified through three angles \((\alpha, \beta, \gamma)\)

  • st_indices (drjit.cuda.ad.UInt) – Index of the sensing target of each sample into st_orientations

  • spst_indices (drjit.cuda.ad.UInt) – Index of the scattering point of each sample into this collection

  • seed (int) – Seed given to the CPM callables, which the ones with random components use to draw them

Returns:

Real part of the cross-polarization matrix of each sample

Returns:

Imaginary part of the cross-polarization matrix of each sample

eval_jones_matrix(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, st_orientations: mitsuba.Point3f, st_indices: drjit.cuda.ad.UInt, spst_indices: drjit.cuda.ad.UInt, seed: int = 0) → Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f][source]#

Evaluates, for every sample, the Jones matrix of the scattering point it is associated with

The Jones matrix of the transfer function of a scattering point combines its RCS \(\sigma\) and its cross-polarization matrix \(\mathbf{W}\) as

\[\mathbf{J} = \sqrt{\sigma}\,\mathbf{W}\]

so this returns the real and imaginary parts of a complex \(2 \times 2\) matrix, with one matrix per sample. As with eval_rcs(), the directions are given in the GCS and are rotated to the local frame of the scattering point before the RCS and the CPM are evaluated.

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions in the GCS

  • k_s (mitsuba.Vector3f) – Scattered directions in the GCS

  • st_orientations (mitsuba.Point3f) – Orientations of the sensing targets in the GCS, specified through three angles \((\alpha, \beta, \gamma)\)

  • st_indices (drjit.cuda.ad.UInt) – Index of the sensing target of each sample into st_orientations

  • spst_indices (drjit.cuda.ad.UInt) – Index of the scattering point of each sample into this collection

  • seed (int) – Seed given to the RCS and CPM callables, which the ones with random components use to draw them

Returns:

Real part of the Jones matrix of each sample

Returns:

Imaginary part of the Jones matrix of each sample

eval_rcs(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, st_orientations: mitsuba.Point3f, st_indices: drjit.cuda.ad.UInt, spst_indices: drjit.cuda.ad.UInt, seed: int = 0) → drjit.cuda.ad.Float[source]#

Evaluates, for every sample, the RCS of the scattering point it is associated with

The directions k_i and k_s are given in the global coordinate system (GCS), whereas an RCS is defined in the local frame of its scattering point. The directions are therefore rotated to that frame before the RCS is evaluated, using the to-world transformation

\[\mathbf{R}(\text{st\_orientation}) \mathbf{R}(\text{lcs\_orientation})\]

where \(\mathbf{R}()\) is defined in (3).

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions in the GCS

  • k_s (mitsuba.Vector3f) – Scattered directions in the GCS

  • st_orientations (mitsuba.Point3f) – Orientations of the sensing targets in the GCS, specified through three angles \((\alpha, \beta, \gamma)\)

  • st_indices (drjit.cuda.ad.UInt) – Index of the sensing target of each sample into st_orientations

  • spst_indices (drjit.cuda.ad.UInt) – Index of the scattering point of each sample into this collection

  • seed (int) – Seed given to the RCS callables, which the ones with random components use to draw them

Returns:

Bistatic radar cross-section of each sample [\(\text{m}^2\)]

gcs_positions(st_positions: mitsuba.Point3f, st_orientations: mitsuba.Point3f, st_indices: drjit.cuda.ad.UInt, st_scalings: mitsuba.Vector3f | None = None) → mitsuba.Point3f[source]#

Returns the positions of the scattering points in the global coordinate system (GCS)

The positions of this collection are given in the local frame of the sensing targets, so they are scaled, rotated, and translated to the GCS using the to-world transformation of the sensing target of every point:

\[\mathbf{p} = \mathbf{p}_{\text{st}} + \mathbf{R}(\text{st\_orientation}) \left( \mathbf{s}_{\text{st}} \odot \mathbf{p}_{\text{lcs}} \right)\]

where \(\mathbf{R}()\) is defined in (3) and \(\odot\) is the element-wise product.

Parameters:
  • st_positions (mitsuba.Point3f) – Positions of the sensing targets in the GCS [m]

  • st_orientations (mitsuba.Point3f) – Orientations of the sensing targets in the GCS, specified through three angles \((\alpha, \beta, \gamma)\)

  • st_indices (drjit.cuda.ad.UInt) – Index of the sensing target of each scattering point of this collection

  • st_scalings (mitsuba.Vector3f | None) – Scalings of the sensing targets. If set to None, the targets are assumed to be unscaled.

Returns:

Positions of the scattering points in the GCS [m]

remove(indices: int | list[int]) → Self[source]#

Returns a new collection without the points at indices

The remaining points keep their relative order, and so do their callables, which are re-indexed accordingly.

Parameters:

indices (int | list[int]) – Indices of the scattering points to remove

Returns:

Scattering points without the removed ones

scaled_lcs_positions(st_scalings: mitsuba.Vector3f, st_indices: drjit.cuda.ad.UInt) → mitsuba.Point3f[source]#

Returns the positions of the scattering points in the local coordinate system (LCS) of their sensing target, scaled by the scaling of that target

The positions of this collection are given in the unscaled LCS of the sensing targets, i.e., in the frame in which the scattering model was defined, whereas scaling a target resizes its mesh. The positions are therefore scaled along with it, so that a scattering point keeps its place relative to the geometry of its target:

\[\mathbf{p} = \mathbf{s}_{\text{st}} \odot \mathbf{p}_{\text{lcs}}\]

where \(\odot\) is the element-wise product.

Parameters:
  • st_scalings (mitsuba.Vector3f) – Scalings of the sensing targets

  • st_indices (drjit.cuda.ad.UInt) – Index of the sensing target of each scattering point of this collection

Returns:

Scaled positions of the scattering points in the LCS [m]

Radar Cross-Sections#

class sionna.rt.rcs.ConstantRCS(sigma: float | drjit.cuda.ad.Float = 1.0)[source]#

Callable evaluating a radar cross-section that does not depend on the incident and scattered directions

The callable returns the bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)] of the scattering point for every pair of incident and scattered directions.

Parameters:

sigma (float | drjit.cuda.ad.Float) – Bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)]

Methods

__call__(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, seed: int = 0) → drjit.cuda.ad.Float[source]#

Evaluates the cross-section for the given directions

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

  • seed (int) – Ignored, as this cross-section is deterministic

Returns:

Bistatic radar cross-section [\(\text{m}^2\)]

Attributes

property sigma#

Get/set the bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)]

Type:

mi.Float

sionna.rt.rcs.register_rcs(name: str, rcs_callable: Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float])[source]#

Registers a new radar cross-section (RCS) callable

An RCS is defined in the local coordinate system of a sensing target and depends on the incident direction \(\mathbf{k}_i\) and the scattered direction \(\mathbf{k}_s\). It evaluates to the bistatic radar cross-section \(\sigma\) [\(\text{m}^2\)] of a scattering point for these directions.

The cross-section sets the power a scattering point scatters, whereas the cross-polarization matrix (CPM) \(\mathbf{W}\) of register_cpm() sets how that power is distributed over the polarization components. Together, the two characterize the scattering point completely through the Jones matrix

\[\mathbf{J} = \sqrt{\sigma}\,\mathbf{W}\]

of its transfer function, which eval_jones_matrix() assembles.

Following (41), a scattering point illuminated by an incident field \(\mathbf{E}_i\) scatters the field

\[\mathbf{E}_s = \frac{1}{r}\mathbf{J}\mathbf{E}_i\]

at a distance \(r\) from the point, the \(1/r\) and the spreading of the scattered power over the sphere being supplied by the propagation of the scattered field. The entries of \(\mathbf{J}\) therefore have units of meters, and those of \(\sigma\) units of square meters.

An RCS is also given the seed of the evaluation, which the models with random components use to draw them.

The following snippet registers an RCS which is largest in the backscattering direction and vanishes in the forward direction, and assigns it by name to a scattering point:

import drjit as dr
from sionna.rt.rcs import ConstantCPM, ScatteringModel, register_rcs

# 10 m^2 back towards the direction the wave comes from, i.e., for
# k_s = -k_i, decreasing to 0 m^2 in the forward direction k_s = k_i.
# The seed is ignored, as this cross-section is deterministic.
def backscattering_rcs(k_i, k_s, seed):
    return 5.*(1. - dr.dot(k_i, k_s))

register_rcs("backscattering", backscattering_rcs)

model = ScatteringModel([0, 0, 0], rcs="backscattering",
                        cpm=ConstantCPM())
Parameters:
sionna.rt.rcs.unregister_rcs(name: str)[source]#

Unregisters an RCS callable

Parameters:

name (str) – Name of the RCS callable

sionna.rt.rcs.get_rcs(name: str) → Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], drjit.cuda.ad.Float][source]#

Returns a registered RCS callable

Parameters:

name (str) – Name of the RCS callable

Returns:

Registered RCS callable

Cross-Polarization Matrices#

class sionna.rt.rcs.ConstantCPM(xpr_db: float | drjit.cuda.ad.Float | None = None)[source]#

Callable evaluating a cross-polarization matrix that does not depend on the incident and scattered directions

The callable returns the real matrix

\[\begin{split}\mathbf{W} = \frac{1}{\sqrt{1+\beta^2}} \begin{bmatrix} 1 & -\beta\\ \beta & 1 \end{bmatrix}, \qquad \beta = 10^{-\text{XPR}_{dB}/20}\end{split}\]

where \(\text{XPR}_{dB}\) is the cross-polarization ratio [dB] of the scattering point, i.e., the ratio of the co-polarized to the cross-polarized scattered power. The matrix is a rotation and hence unitary, so it satisfies the normalization \(\lVert\mathbf{W}\rVert_F^2 = 2\).

Its entries are the ones of the diffuse scattering matrix of (41), with the random phase shifts dropped and the cross-polarization discrimination coefficient

\[K_x = \frac{1}{1 + 10^{\text{XPR}_{dB}/10}}\in[0,1]\]

of (42) written in terms of the XPR, as \(\sqrt{1-K_x}\) and \(\sqrt{K_x}\) are the co-polarized and cross-polarized entries above. With an infinite XPR, the scattering point preserves the polarization of the incident field, with \(\text{XPR}_{dB} = 0\) it splits the scattered power evenly over both polarization components, and as the XPR tends to \(-\infty\) it scatters the power entirely on the cross-polarized component.

Parameters:

xpr_db (float | drjit.cuda.ad.Float | None) – Cross-polarization ratio \(\text{XPR}_{dB}\) [dB]. Set to None for a scattering point which does not depolarize, i.e., an infinite XPR.

Methods

__call__(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, seed: int = 0) → Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f][source]#

Evaluates the CPM for the given directions

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

  • seed (int) – Ignored, as this matrix is deterministic

Returns:

Real part of the cross-polarization matrix

Returns:

Imaginary part of the cross-polarization matrix

Attributes

property xpr_db#

Get/set the cross-polarization ratio \(\text{XPR}_{dB}\) [dB], or None for a scattering point which does not depolarize

Type:

mi.Float | None

sionna.rt.rcs.register_cpm(name: str, cpm_callable: Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]])[source]#

Registers a new cross-polarization matrix (CPM) callable

A CPM is defined in the local coordinate system of a sensing target and depends on the incident direction \(\mathbf{k}_i\) and the scattered direction \(\mathbf{k}_s\). It evaluates to the complex \(2 \times 2\) matrix \(\mathbf{W}\), returned as the real and imaginary parts of that matrix.

The CPM describes how a scattering point transforms the polarization of the incident field, whereas the radar cross-section \(\sigma\) of register_rcs() sets the power it scatters. Together, the two define the Jones matrix \(\mathbf{J} = \sqrt{\sigma}\,\mathbf{W}\) of the transfer function of the scattering point, which eval_jones_matrix() assembles.

A CPM is also given the seed of the evaluation, which the models with random components use to draw them.

The following snippet registers a CPM which turns each linearly polarized component of the incident field into a circularly polarized one, and assigns it by name to a scattering point:

import drjit as dr
import mitsuba as mi
from sionna.rt.rcs import ConstantRCS, ScatteringModel, register_cpm

# W = [[1, j], [j, 1]]/sqrt(2), a unitary matrix which leaves the
# scattered power set by the RCS unchanged. The seed is ignored, as
# this matrix is deterministic.
def circular_cpm(k_i, k_s, seed):
    zero = dr.zeros(mi.Float, dr.width(k_i))
    a = zero + 0.5**0.5
    return mi.Matrix2f(a, zero, zero, a), mi.Matrix2f(zero, a, a, zero)

register_cpm("circular", circular_cpm)

model = ScatteringModel([0, 0, 0], rcs=ConstantRCS(sigma=1.),
                        cpm="circular")
Parameters:
sionna.rt.rcs.unregister_cpm(name: str)[source]#

Unregisters a CPM callable

Parameters:

name (str) – Name of the CPM callable

sionna.rt.rcs.get_cpm(name: str) → Callable[[mitsuba.Vector3f, mitsuba.Vector3f, int], Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f]][source]#

Returns a registered CPM callable

Parameters:

name (str) – Name of the CPM callable

Returns:

Registered CPM callable

3GPP TR 38.901 Models#

Sionna implements the sensing target models specified in [TR38901_RT], clause 7.9.2. The type of target (object_type) and the RCS model (model_type) determine both the number of scattering points and the parameters of every point, which are taken from Tables 7.9.2.1-1 to 7.9.2.1-7. The supported combinations are listed in the documentation of TR38901ScatteringModel.

Every scattering point depolarizes according to the cross-polarization matrix of clause 7.9.2.2, whose cross-polarized entries are set by the XPR of Table 7.9.2.2-1. That matrix is taken as eq. 7.9.2-5 defines it, i.e., with co-polarized entries of unit modulus rather than normalized, so the tabulated cross-section is the co-polarized one and the depolarized power adds to it.

The models have three random components, all of which are disabled by default, so that a scattering point evaluates deterministically unless they are enabled:

Flag

Random component

random_sigma_s

The log-normal RCS component \(\sigma_S\) of clause 7.9.2.1, which is otherwise fixed to 1, exactly its linear mean per eq. 7.9.2-1

random_xpr

The XPR of eq. 7.9.2-5, which is otherwise fixed to its tabulated mean in dB

random_phases

The four initial phases of eq. 7.9.2-5, which are otherwise zero, so that a scattering point does not randomize the phase of a path

Two runs of the solver on the same scene with the same seed therefore give every path the same draws, and exchanging the two directions leaves the cross-section unchanged and transposes the cross-polarization matrix, as clause 7.9.4 requires for monostatic sensing. TR38901RCS and TR38901CPM detail the draws and the limits of their reproducibility.

TR38901SensingTarget is the entry point of these models: it builds its own TR38901ScatteringModel, which in turn equips every scattering point with a TR38901RCS and a TR38901CPM callable, and carries the three flags. A target following the specifications is therefore created as follows:

from sionna.rt.rcs import TR38901SensingTarget

target = TR38901SensingTarget(name="st", object_type="vehicle-multi-sp")

# Draw the random components of the specifications
target.scattering_model.random_sigma_s = True
target.scattering_model.random_xpr = True
target.scattering_model.random_phases = True
class sionna.rt.rcs.TR38901SensingTarget(name: str, object_type: str, model_type: int = 2, mi_mesh: mitsuba.Mesh | None = None, fname: str | None = None, length: float | None = None, width: float | None = None, height: float | None = None, color: Tuple[float, float, float] = (0.2, 0.4, 1.0), display_opacity: float = 0.5, position: mitsuba.Point3f | None = None, orientation: mitsuba.Point3f | None = None, look_at: mitsuba.Point3f | sionna.rt.scene_object.SceneObject | sionna.rt.radio_devices.radio_device.RadioDevice | None = None, velocity: mitsuba.Vector3f | None = None, random_sigma_s: bool | None = None, random_phases: bool | None = None, random_xpr: bool | None = None)[source]#

Sensing target following 3GPP TR 38.901, clause 7.9.2

The target automatically creates its TR38901ScatteringModel; no scattering model is supplied by the user. If no mesh is provided, the target is represented by a cuboid whose omitted dimensions default independently to the values specified for object_type. If a mesh is provided, its axis-aligned bounding box (AABB) determines the dimensions used to place the scattering points. The AABB is read before the target is posed, so the resulting dimensions are the ones of its local coordinate system (LCS) regardless of the requested orientation. Scaling the target afterwards resizes its geometry and its scattering points alike, and the reported dimensions follow.

The random components of the model, i.e., the RCS component \(\sigma_S\) of clause 7.9.2.1 and the XPR and initial phases of clause 7.9.2.2, are enabled through random_sigma_s, random_xpr and random_phases, which the target forwards to its TR38901ScatteringModel. They can also be changed afterwards through the properties of the same names of its scattering_model:

target = TR38901SensingTarget(name="st",
                              object_type="vehicle-multi-sp",
                              random_sigma_s=True)
target.scattering_model.random_sigma_s = False
Parameters:
  • name (str) – Name of the sensing target

  • object_type (str) – Type of sensing target, one of "uav-small-size", "uav-large-size", "human", "vehicle-single-sp", "vehicle-multi-sp", "agv-single-sp", "agv-multi-sp"

  • model_type (int) – RCS model of clause 7.9.2.1, either 1 or 2

  • mi_mesh (mi.Mesh | None) – Mitsuba shape. Mutually exclusive with fname and the cuboid dimensions.

  • fname (str | None) – Filename of a valid mesh ( “.ply” | “.obj”). Mutually exclusive with mi_mesh and the cuboid dimensions.

  • length (float | None) – Size along the x-axis of the LCS [m]. If omitted for a cuboid, defaults to the specification value for object_type.

  • width (float | None) – Size along the y-axis of the LCS [m]. If omitted for a cuboid, defaults to the specification value for object_type.

  • height (float | None) – Size along the z-axis of the LCS [m]. If omitted for a cuboid, defaults to the specification value for object_type.

  • color (Tuple[float, float, float]) – RGB color used by the previewer and renderer

  • display_opacity (float) – Display opacity in the range \([0,1]\)

  • position (mi.Point3f | None) – Position \((x,y,z)\) [m] of the center of the target. If set to None, the target keeps the position of its mesh.

  • orientation (mi.Point3f | None) – Orientation specified through three angles \((\alpha, \beta, \gamma)\) corresponding to a 3D rotation as defined in (3). Mutually exclusive with look_at; specifying both raises ValueError. Defaults to \((0,0,0)\) if both orientation and look_at are None.

  • look_at (mi.Point3f | SceneObject | RadioDevice | None) – A position, or the instance of a SceneObject or RadioDevice to look at. Mutually exclusive with orientation.

  • velocity (mi.Vector3f | None) – Velocity vector of the target [m/s]

  • random_sigma_s (bool | None) – If set to True, the RCS component \(\sigma_S\) of clause 7.9.2.1 is drawn for every pair of directions. If set to None, the default of TR38901ScatteringModel is used.

  • random_phases (bool | None) – If set to True, the four initial phases of eq. 7.9.2-5 are drawn for every pair of directions. If set to None, the default of TR38901ScatteringModel is used.

  • random_xpr (bool | None) – If set to True, the XPR of eq. 7.9.2-5 is drawn for every pair of directions. If set to None, the default of TR38901ScatteringModel is used.

Methods

clone(name: str | None = None, as_mesh: bool = False, props: mitsuba.Properties | None = None) → sionna.rt.rcs.tr38901.sensing_target.TR38901SensingTarget | mitsuba.Mesh[source]#

Creates a clone of the current TR 38.901 sensing target

The clone shares the scattering model of the original target, and has the same dimensions, geometry, pose, color, and display opacity.

Parameters:

Attributes

property dimensions: Dict[str, float]#

Target dimensions as length, width, and height [m]

property height: float#

Size along the z-axis of the local coordinate system [m], scaled by the scaling of this target

property length: float#

Size along the x-axis of the local coordinate system [m], scaled by the scaling of this target

property model_type: int#

RCS model of clause 7.9.2.1

Type:

int

property object_type: str#

Type of sensing target

Type:

str

property width: float#

Size along the y-axis of the local coordinate system [m], scaled by the scaling of this target

class sionna.rt.rcs.TR38901ScatteringModel(object_type: str, model_type: int = 2, lcs_positions: mitsuba.Point3f | None = None, random_sigma_s: bool = False, random_phases: bool = False, random_xpr: bool = False)[source]#

Scattering model of a sensing target, as specified in 3GPP TR 38.901, clause 7.9.2

The type of sensing target determines both the number of scattering points of the model and the sets of parameters of every point, which are taken from Tables 7.9.2.1-1 to 7.9.2.1-7. A table row is a set of parameters rather than a scattering point: the models with a single scattering point hold every row as a lobe of that point and select one of them from the bisector angle, whereas the models with multiple scattering points give one row to every point, all of them contributing simultaneously.

The specifications only leave a choice between the two for the vehicle and the AGV, hence the -single-sp and -multi-sp object types:

object_type

model_type

Scattering points

Table

"uav-small-size"

1

1

7.9.2.1-1

"human"

1 or 2

1

7.9.2.1-1 or 7.9.2.1-3

"uav-large-size"

2

1

7.9.2.1-2

"vehicle-single-sp"

2

1

7.9.2.1-4

"vehicle-multi-sp"

2

5

7.9.2.1-5

"agv-single-sp"

2

1

7.9.2.1-6

"agv-multi-sp"

2

5

7.9.2.1-7

Every scattering point depolarizes according to the cross-polarization matrix of clause 7.9.2.2, with the XPR of Table 7.9.2.2-1, as detailed in TR38901CPM.

The random components of the two models, i.e., the RCS component \(\sigma_S\) of clause 7.9.2.1 and the XPR and initial phases of clause 7.9.2.2, are disabled by default and are enabled through random_sigma_s, random_xpr and random_phases. They are drawn per pair of incident and scattered directions from the seed given to __call__(), as detailed in TR38901RCS and TR38901CPM.

This model is created by TR38901SensingTarget, which determines the target dimensions and places the scattering points. Its flags can be set when constructing that target, which forwards them to the model, and changed at any time afterwards through the scattering_model of the target.

Parameters:
  • object_type (str) – Type of sensing target, one of "uav-small-size", "uav-large-size", "human", "vehicle-single-sp", "vehicle-multi-sp", "agv-single-sp", "agv-multi-sp"

  • model_type (int) – RCS model of clause 7.9.2.1, either 1 or 2. RCS model 1 fixes the angular component \(\sigma_D\) of the monostatic RCS to 1, and is only defined for the small UAV and the human.

  • lcs_positions (mitsuba.Point3f | None) – Positions of the scattering points, resolved from the geometry of the owning target [m]

  • random_sigma_s (bool) – If set to True, the RCS component \(\sigma_S\) of clause 7.9.2.1 is drawn for every pair of directions. Defaults to False.

  • random_phases (bool) – If set to True, the four initial phases of eq. 7.9.2-5 are drawn for every pair of directions. Defaults to False.

  • random_xpr (bool) – If set to True, the XPR of eq. 7.9.2-5 is drawn for every pair of directions. Defaults to False.

Example#

from sionna.rt.rcs import TR38901SensingTarget

# Enable the random initial phases when constructing the target
target = TR38901SensingTarget(name="st",
                              object_type="vehicle-multi-sp",
                              random_phases=True)

# Enable the random XPR afterwards, through the scattering model
target.scattering_model.random_xpr = True
property model_type: int#

RCS model of clause 7.9.2.1

Type:

int

property object_type: str#

Type of sensing target

Type:

str

property random_phases: bool#

Get/set whether the four initial phases of eq. 7.9.2-5 are drawn for every pair of directions

Type:

bool

property random_sigma_s: bool#

Get/set whether the RCS component \(\sigma_S\) of clause 7.9.2.1 is drawn for every pair of directions

Type:

bool

property random_xpr: bool#

Get/set whether the XPR of eq. 7.9.2-5 is drawn for every pair of directions

Type:

bool

class sionna.rt.rcs.TR38901RCS(lobes: Sequence[sionna.rt.rcs.tr38901.parameters.LobeParameters], k1: float = 0.0, k2: float = 0.0, sigma_m_db: float = 0.0, sigma_s_std_db: float = 0.0, random_sigma_s: bool = False)[source]#

Callable evaluating the RCS of a scattering point of a sensing target, as specified in 3GPP TR 38.901, clause 7.9.2.1

The callable returns the bistatic radar cross-section \(\sigma_M\sigma_D\sigma_S\) [\(\text{m}^2\)], where \(10\lg(\sigma_M\sigma_D)\) is given by eq. 7.9.2-2 for RCS model 1 and by eq. 7.9.2-3 for RCS model 2, and \(\sigma_S\) is the third RCS component of clause 7.9.2.1.

How the scattered power is distributed over the polarization components is set by the cross-polarization matrix of clause 7.9.2.2, which TR38901CPM implements, and not by this callable.

The component \(\sigma_S\) is random, and is only drawn if random_sigma_s is set. It is otherwise fixed to 1, which eq. 7.9.2-1 makes exactly its linear mean. When drawn, \(10\lg(\sigma_S)\) is Gaussian with the standard deviation sigma_s_std_db of Tables 7.9.2.1-1 to 7.9.2.1-7 and the mean of eq. 7.9.2-1, which is what makes the linear mean 1, and is truncated three standard deviations above its mean as in eq. 7.9.4-1.

The draw is keyed by a hash of the pair of incident and scattered directions and of the seed the callable is evaluated with, so it is a function of its inputs alone. Two evaluations of the same pair of directions with the same seed therefore give the same cross-section, and two runs of RCSSolver on the same scene with the same seed give every path the same cross-section. Exchanging the two directions also leaves it unchanged, as clause 7.9.4 requires for monostatic sensing.

With several lobes, the bisector angle indexes one of them as specified by the theta_range and phi_range of every lobe, which tile the sphere. The selection is branch-free, as every lobe is evaluated.

Parameters:
  • lobes (Sequence[sionna.rt.rcs.tr38901.parameters.LobeParameters]) – Sets of parameters of the scattering point. An empty sequence selects RCS model 1, which has no lobe.

  • k1 (float) – \(k_1\) of eq. 7.9.2-3

  • k2 (float) – \(k_2\) of eq. 7.9.2-3

  • sigma_m_db (float) – \(10\lg(\sigma_M)\) [dBsm], used by RCS model 1 only

  • sigma_s_std_db (float) – Standard deviation of \(10\lg(\sigma_S)\) [dB], from the tables of clause 7.9.2.1. Only used if random_sigma_s is set.

  • random_sigma_s (bool) – If set to True, the component \(\sigma_S\) is drawn for every pair of directions. It is otherwise fixed to 1.

Methods

__call__(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, seed: int = 0) → drjit.cuda.ad.Float[source]#

Evaluates the RCS for the given directions

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

  • seed (int) – Seed of the draw of \(\sigma_S\), unused if random_sigma_s is not set

Returns:

Bistatic radar cross-section \(\sigma_M\sigma_D\sigma_S\) [\(\text{m}^2\)]

sigma_md_db(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f) → drjit.cuda.ad.Float[source]#

Evaluates \(10\lg(\sigma_M\sigma_D)\) [dBsm] for the given directions

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

Returns:

\(10\lg(\sigma_M\sigma_D)\) [dBsm]

sigma_s_db(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, seed: int = 0) → drjit.cuda.ad.Float[source]#

Draws \(10\lg(\sigma_S)\) [dB] for the given directions

The draw is the truncated Gaussian of clause 7.9.2.1, and is 0, i.e., \(\sigma_S = 1\), if random_sigma_s is not set.

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

  • seed (int) – Seed of the draw

Returns:

\(10\lg(\sigma_S)\) [dB]

Attributes

property lobes: Tuple[sionna.rt.rcs.tr38901.parameters.LobeParameters, ...]#

Sets of parameters of the scattering point

Type:

tuple [ LobeParameters ]

property random_sigma_s: bool#

Get/set whether the component \(\sigma_S\) is drawn for every pair of directions, rather than fixed to its linear mean of 1

Type:

bool

property sigma_s_std_db: float#

Standard deviation of \(10\lg(\sigma_S)\) [dB], from the tables of clause 7.9.2.1

Type:

float

class sionna.rt.rcs.TR38901CPM(xpr_db: float | None = None, xpr_std_db: float = 0.0, random_phases: bool = False, random_xpr: bool = False)[source]#

Callable evaluating the cross-polarization matrix (CPM) of a scattering point of a sensing target, as specified in 3GPP TR 38.901, clause 7.9.2.2

The callable returns the matrix

\[\begin{split}\mathbf{W} = \begin{bmatrix} e^{j\Phi^{\theta\theta}} & \beta e^{j\Phi^{\theta\varphi}}\\ \beta e^{j\Phi^{\varphi\theta}} & e^{j\Phi^{\varphi\varphi}} \end{bmatrix}, \qquad \beta = \sqrt{\kappa^{-1}} = 10^{-\text{XPR}_{dB}/20}\end{split}\]

which is the cross-polarization matrix of eq. 7.9.2-5, whose cross-polarized entries are set by the XPR \(\kappa\) of Table 7.9.2.2-1 and whose four initial phases are the ones of that equation. The cross-section the scattering point scatters is given separately by TR38901RCS.

Both the XPR and the phases are random, and are only drawn if random_xpr and random_phases are set, respectively:

  • When drawn, \(10\lg(\kappa)\) is Gaussian with the mean xpr_db and the standard deviation xpr_std_db of Table 7.9.2.2-1, as in eq. 7.9.4-3. It is otherwise fixed to xpr_db, i.e., to its mean in dB.

  • When drawn, the four phases are uniform over \((-\pi, \pi)\). They are otherwise zero, so the matrix is real and a scattering point does not randomize the phase of a path.

Two evaluations of the same pair of directions with the same seed give the same matrix, and two runs of RCSSolver on the same scene with the same seed give every path the same matrix. Exchanging the two directions transposes it, as clause 7.9.4 requires for monostatic sensing.

Parameters:
  • xpr_db (float | None) – \(10\lg(\kappa)\) [dB], the cross-polarization ratio of eq. 7.9.2-5, and its mean in dB if random_xpr is set. Set to None for a scattering point which does not depolarize, i.e., an infinite XPR.

  • xpr_std_db (float) – Standard deviation of \(10\lg(\kappa)\) [dB], from Table 7.9.2.2-1. Only used if random_xpr is set.

  • random_phases (bool) – If set to True, the four initial phases of eq. 7.9.2-5 are drawn for every pair of directions. They are otherwise zero.

  • random_xpr (bool) – If set to True, the XPR is drawn for every pair of directions. It is otherwise fixed to xpr_db.

Methods

__call__(k_i: mitsuba.Vector3f, k_s: mitsuba.Vector3f, seed: int = 0) → Tuple[drjit.cuda.ad.Matrix2f, drjit.cuda.ad.Matrix2f][source]#

Evaluates the CPM for the given directions

Parameters:
  • k_i (mitsuba.Vector3f) – Incident directions of propagation, in the local coordinate system of the scattering point

  • k_s (mitsuba.Vector3f) – Scattered directions of propagation, in the local coordinate system of the scattering point

  • seed (int) – Seed of the draws of the XPR and of the phases, unused if neither random_xpr nor random_phases is set

Returns:

Real part of the cross-polarization matrix

Returns:

Imaginary part of the cross-polarization matrix

Attributes

property random_phases: bool#

Get/set whether the four initial phases of eq. 7.9.2-5 are drawn for every pair of directions, rather than zero

Type:

bool

property random_xpr: bool#

Get/set whether the XPR is drawn for every pair of directions, rather than fixed to its mean in dB

Type:

bool

property xpr_db: float | None#

\(10\lg(\kappa)\) [dB] of eq. 7.9.2-5, or None for a scattering point which does not depolarize

Type:

float | None

property xpr_std_db: float#

Standard deviation of \(10\lg(\kappa)\) [dB], from Table 7.9.2.2-1

Type:

float