Lidar Sensors#
An ovrtx lidar scene needs an OmniLidar sensor prim and a RenderProduct
whose PointCloud RenderVar requests the channels the application will read.
The same USDA pattern is used by C and Python; application code loads the scene,
steps the RenderProduct, and maps the output.
Configure the Lidar Prim#
def OmniLidar "Lidar" (
prepend apiSchemas = ["OmniSensorGenericLidarCoreAPI"]
)
{
token omni:sensor:Core:elementsCoordsType = "CARTESIAN"
double2 omni:sensor:frameRate = (10, 1)
double3 xformOp:translate = (0, 0, 1)
float3 xformOp:rotateXYZ = (90, 0, -90)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
}
def OmniLidar "Lidar" (
prepend apiSchemas = ["OmniSensorGenericLidarCoreAPI"]
)
{
token omni:sensor:Core:elementsCoordsType = "CARTESIAN"
double2 omni:sensor:frameRate = (10, 1)
double3 xformOp:translate = (0, 0, 1)
float3 xformOp:rotateXYZ = (90, 0, -90)
uniform token[] xformOpOrder = ["xformOp:translate", "xformOp:rotateXYZ"]
}
Use OmniSensorGenericLidarCoreAPI for the generic lidar model. In Z-up
scenes, keep the scene Z-up and rotate the lidar prim so sensor +X points in
the intended forward direction.
Important Output Attributes#
Attribute |
Values |
Use |
|---|---|---|
|
|
Coordinate representation for point tensors. |
|
|
Frame of reference for all outputs. |
|
|
Custom transform used when the output frame is |
|
|
Motion compensation state for outputs. |
|
|
Preserve invalid returns in the point tensors when true. |
|
|
Emit partial scans as the sensor sweeps. |
|
|
Emit a full scan every frame for simplified workflows. |
Configure PointCloud Output#
def "Render"
{
def "Products"
{
def RenderProduct "LidarProduct"
{
rel camera = </World/Lidar>
rel orderedVars = [<../../Vars/PointCloud>]
}
}
def "Vars"
{
def RenderVar "PointCloud"
{
uniform string sourceName = "PointCloud"
string[] channels = [
"Coordinates",
"Intensity",
"Counts",
"TimeOffsetNs"
]
}
}
}
def "Render"
{
def "Products"
{
def RenderProduct "LidarProduct"
{
rel camera = </World/Lidar>
rel orderedVars = [<../../Vars/PointCloud>]
}
}
def "Vars"
{
def RenderVar "PointCloud"
{
uniform string sourceName = "PointCloud"
string[] channels = [
"Coordinates",
"Intensity",
"Counts",
"TimeOffsetNs"
]
}
}
}
Request only the channels the consumer needs. Counts and Flags are
auto-enabled and delivered like ordinary channel tensors.
Lidar Channels#
Channel |
Meaning |
|---|---|
|
Number of delivered point entries. Use it to bound every per-point tensor. |
|
Point coordinates in the configured coordinate representation and frame. |
|
Processed return strength. |
|
Per-point time offset relative to the sensor timestamp. |
|
Per-point status bits. The |
|
Emitter, detector/channel, scan tick, and return identifiers. |
|
Active scan pattern state for the tick that produced the point. |
|
Hit material and object identifiers. |
|
Surface normal and velocity at the hit point. |
Interpreting Lidar Output#
Within the first Counts[0] entries, a point is valid when
Flags[i] & 0x40 is non-zero. Do not compare Flags[i] == 0x40 because
other lidar-specific bits can be set at the same time.
With includeInvalidPoints = false, invalid returns are dropped before output.
With includeInvalidPoints = true, invalid entries can be present inside the
Counts range and must be filtered by Flags before using channels such as
Coordinates, Intensity, HitNormal, or Velocity as real returns.
For map/read code, see Reading Sensor PointClouds.