Omniverse Lidar Extension

Introduction

The Lidar extension consists of RtxSensor based Lidar simulation plugins (currently only one), several plugins and different Omnigraph Nodes. The simulation plugin is a generic lidar model, which can be configured via a sensor profile json file.

LidarPointCloud

The Lidar extension uses the GenericModelOutput as output format. See the documentation of the common extension for more information on the GenericModelOutput.

LidarProfile

The lidar profile parameters affect the behavior of the lidar sensor. It consists of mandatory basic parameters and optional ones. Examples are the Example_Rotary and Example_Solid_State profiles.

Basic Parameters

  • scanType: The type of the lidar sensor (rotary for rotating and solidState for non-moving sensors)

  • nearRangeM/farRangeM: The min/max range of the lidar sensor in meters

  • rangeResolutionM: The resolution of the range in meters

  • rangeAccuracyM: The accuracy of the range in meters

  • wavelengthNm: The wavelength of the lidar sensor in nanometers

  • maxReturns: Number of max returns per emitter (e.g., 2 for dual return mode)

  • reportRateBaseHz: Number of times the firing pattern is applied per second, this is defined as a “tick”

  • numberOfEmitters: Number of emitters in the lidar sensor per scan

  • scanRateBaseHz: Number of full point cloud scans per second

  • numLines (Solid State): Number of rows per scan

  • numRaysPerLine (Solid State): Number of rays per line/row, array with numLines elements

  • Firing Pattern Parameter (see Emitter State Parameters for detailed information):
    • emitters: Array of emitters if emitterStateCount is not defined

    • emitterStateCount: Number of states per emitter

    • emitterStates: Array of states for each emitter

Optional Parameters

  • avgPowerW: Average power of one lidar emitter pulse in watts (default: 0.002)

  • pulseTimeNs: Pulse time of one lidar emitter pulse in nanoseconds (default: 6)

  • validStartAzimuthDeg: Start azimuth of the valid range in degrees (default: 0)

  • validEndAzimuthDeg: End azimuth of the valid range in degrees (default: 360)

  • minDistBetweenEchos: Minimum distance between two echoes in meters (default: min(nearRangeM,0.4))

  • rangeOffset: Range offset in meters (default: 0) – useful for not hitting the prop

  • numberOfChannels: Number of channels/detectors in the lidar sensor (default: numberOfEmitters)

  • minReflectance: Minimum reflectance expected to see at minReflectanceRangeM (default: 0.1) – not the overall min reflectance

  • minReflectanceRange: Maximum range at which the minimum reflectance is expected to generate a valid return (default: 200)

  • intensityProcessing: Processing to get final intensity (supported right now: “normalization” and “correction”)

  • rayType: Type of ray in geometrical sense (e.g., “IDEALIZED”, “GAUSSIAN_BEAM”)

  • Detector Parameters:
    • effectiveApertureSize: Effective aperture size of the detector in meters (default: 0.01)

    • quantumEfficiency: Quantum efficiency of the detector (default: 0.9)

    • pixelPitch: Pixel pitch of the detector (default: 40.0)

    • calibrationGain: Calibration gain of the detector (default: 40.0)

    • bitDepthResolution: Bit depth resolution of the detector (default: 65536)

  • intensityMapping:
    • intensityMappingType: Type of intensity mapping (e.g., “LINEAR”, “NONLINEAR” – intensityMappingDecoding/Encoding)

    • intensityMappingDecoding: Decoding function values for intensity mapping

    • intensityScalePercent: Intensity scale in percent (default: 255)

  • Range Parameter: For setting a per emitter range (nearRangeM,farRangeM will be used as default)
    • rangeCount: Number of ranges in array

    • ranges: Array of ranges for each emitter e.g., [{“min”: 0, “max”: 100}, {“min”: 3, “max”: 200}]

  • Beam Parameter: Parameter of laser beam
    • beamWaistHorM: Horizontal beam waist in meters (default: 0.002)

    • beamWaistVerM: Vertical beam waist in meters (default: 0.002)

    • divergenceHorDeg: Horizontal divergence of the laser beam in degrees (default: calculated from beam waist)

    • divergenceVerDeg: Vertical divergence of the laser beam in degrees (default: calculated from beam waist)

    • focusDist: Focus distance of the laser beam in meters (default: 0.15)

    • Msquared: M squared value of the laser beam (default: 1.4)

Emitter State Parameters

The firing pattern, potentially, consists of multiple emitter states, whereas one emitter state is a full firing of all emitters. The minimum emitter parameters which have to be set are the following:

  • azimuthDeg: Azimuth of the emitter in degrees relative to the tick azimuth (see reportRateBaseHz)

  • elevationDeg: Elevation of the emitter in degrees

  • fireTimeNs: Time of the emitter firing in nanoseconds relative to the tick time (see reportRateBaseHz), should be inside the tick delta time

Additionally, the following optional parameters can be set:

  • channelId: Channel id of the emitter, to map specific emitter to channels (default: emitterId)

  • rangeId: Range id of the emitter, to map specific emitter to specified ranges (default: 0)

  • bank: Bank id of the emitter, to map specific emitter to banks/lines for solid state lidar (default: 0)

  • vertOffsetM: Vertical offset of the emitter in meters (default: 0)

  • horOffsetM: Horizontal offset of the emitter in meters (default: 0)

  • distanceCorrectionM: Distance correction of the emitter in meters (default: 0)

  • reportRateDiv: Report rate divisor of the emitter, to reduce the report rate of the emitter (default: 1)

  • focalSlope: Focal slope of the emitter, to correct the focal point of the emitter (default: 0)

  • focalDistM: Focal distance of the emitter in meters, to correct the focal point of the emitter (default: 0)

LidarPCConverter

The LidarPCConverter converts the RTXSensor Lidar data stream to an easily usable point cloud (GenericModelOutput format). The interface is defined in (include/omni/sensors/lidar/ILidarPCConverter.h).

Users can create objects that implement this interface by acquiring the ILidarPCConverterFactory (include/omni/sensors/lidar/ILidarPCConverterFactory.h) carbonite interface and using the createInstance() method.

Instantiation

To instantiate the LidarPCConverter the user needs to acquire the carbonite ILidarPCConverterFactory interface, and use the create instance method:

ILidarPCConverterPtr m_pcConverter = carb::getFramework()->acquireInterface<omni::sensors::lidar::ILidarPCConverterFactory>()->createInstance();

Initialization

The user has to initialize the converter, with the corresponding converter cfg (omni::sensors::lidar::LidarPCConverterCfg) like this:

m_pcConverter->init(cfg);

Conversion

The conversion of the buffer differs with the conversion buffer type (PACKETS, GENERIC_FILE (HDF5) or live sensor buffer). In the live sensor buffer the user calls the following function

m_pcConverter->convertBuffer(sensorBuffer, dataSize, numPoints, scanComplete, cudaStream);

Next he can get the point cloud:

LidarPointCloud pc = m_pcConverter->getPointCloud(cudaStream);

The user has to keep in mind, that in live CPU mode the getPointCloud function has to be called in a cudaLaunchHostFunc with the appropriate cudaStream, as every work is scheduled asynchronously.

LidarCorePlugin

Introduction

The Lidar core plugin is a generic Lidar simulation utilizing RtxSensor. It can be configured through sensor config file (json format) and it supports rotary as well as solid state lidars.

Plugin Name

omni.sensors.nv.lidar.lidar_core.plugin

Parameters & Attributes

The attributes are specified through a sensor config JSON file, which are placed in “data/sensors/lidar”. The desired sensor profile is set via the USDA attribute “custom token rtxsensor:modelConfig” (see Example in USDA for an example). This JSON file can be read with the ProfileReader utility plugin.

Available Parameterizations

The following parameterization to support specific Lidar already exists:

Lidar Type

Params File name

Model Config Entry

Variant

Generic Rotary

Example_Rotary.json

“Example_Rotary”

Generic Solid State

Example_Solid_State.json

“Example_Solid_State”

Atmospheric Modeling

The Lidar model includes a mie scattering based atmospheric simulation model, which currently supports rain. It is planned to add fog, haze and snow at a later time.

Besides the wavelength dependency, the rain model has one basic parameter: the rain rate in mm/h (configurable as a carb::setting: “/app/sensors/nv/atmospherics/rainRate”). For instance, a rain rate of 0.25mm/h is light rain, whereas a rain rate of 25mm/h corresponds to a very heavy rain. Every other parameter for the mie scattering (e.g., rain drop size distribution) is derived from the rain rate.

Additionally, the rain model provides the possibility to simulate rain drop hits as false positive. The amount of false positives can be set via a rain drop hit threshold (configurable as a carb::setting: “/app/sensors/nv/atmospherics/rainDropHitThresh”). This threshold is related to the mie back scattering efficiency parameter and a distance dependent rain drop hit probability distribution.

Both parameter can be set via command line are dynamically via the script editor, as both parameter are defined as a carb::setting. In example you can start the simulation with a rain rate of 25mm/h if you’re adding “–/app/sensors/nv/atmospherics/rainRate=25.” to the startup command of kit. It is important to activate the material framework to get accurate readings from wet roads (point drops) and false positives due to back scattering (under the ground).

Omnigraph Nodes

One example of the current nodes in the Lidar extension is the TranscoderLidar. A dumping transcoder, which encodes the Lidar data into vendor specific udp packets and dumps them into a bin-file.

TranscoderLidar

Introduction

The Transcoder node encodes the Lidar data stream into vendor specific packets and records them via binary file writing.

Omnigraph Node Name

omni.sensors.nv.lidar.TranscoderLidar

Parameters & Attributes

Parameter Name

Description

Value Type

Value Range

Default Value

Example

sensorProfileName

Filename of sensor profile (excluding directory and .json)

string

“GENERIC”

returnType

Indicates the desired return (first,last,dual,etc.,)

int

0

runMode

CPU = 0 or GPU = 1

int

0

dumpPackets

Dump packets as file

bool

false

decoderPath

Optional path to ndas decoder

string

“”

fileName

Filename of the dumped bin file

string

“”

Python Bindings and Scripts

The Lidar extension offers a variety of python bindings and scripts for the Lidar. These can be used for easy post-processing of the simulated Lidar point cloud.

Python Bindings

The python bindings make it possible to use the Lidar utilities and specific classes in python code. For instance, the user can import the Lidar python bindings in the following way:

import omni.sensors.nv.lidar.bindings._lidar as lidar

Furthermore, there exist the LidarUtilities script, containing some helper functions for ease of use of the Lidar bindings. The script can be imported, e.g., the following way:

import omni.sensors.nv.lidar.scripts.LidarUtilities as lutil

There are binding definitions for all basic classes and structs of the Lidar and lidar Tools extension. See the following (incomplete) list of the most basic classes:

  • LidarProfile

Furthermore, there are bindings for the following utilities:

  • LidarPCConverter

The binding exists for the LidarPCConverter, which accumulates and converts Lidar sensor buffers to the LidarPointCloud. There is a mode to accumulate and convert udp packets to a Lidar point cloud, but not every sensor is supported. To get a LidarPCConverter object the user can call the following helper function of the LidarUtilities script

cfg = lutil.PCGeneratorConfig(bin_file) # or (bin_file,"",sensor_name) for reading a HDF5 file (only supported in linux for now)
converter = lutil.get_pc_converter(cfg)

For more options of the PCGeneratorConfig see the LidarUtilities script.

Currently, only host side conversion of the buffer is supported, but GPU accelerated conversion will be added in the near future. An example conversion is as follows

# convert buffer
# File is specified in the cfg
converter.convertBuffer()
# or this for a GenericModelOutput binary buffer
# converter.convertBuffer(buffer,data_size, num_points, scan_complete)
pc = converter.getPointCloud()