Interpreting Lidar PointClouds
When to Use
Use this skill when the user asks what already-read lidar Coordinates, Intensity, TimeOffsetNs, Flags, IDs, normals, velocity, or other PointCloud tensors mean. Use reading-sensor-pointclouds instead when the user needs map/read code to obtain the tensors.
Inputs
Resolve inputs in this order: existing repository files and referenced snippets, explicit user request, then broader agent context.
- Lidar channel names and tensor values or summaries already available to the caller.
- Authored lidar settings that affect interpretation, especially
elementsCoordsType, outputFrameOfReference, and includeInvalidPoints.
- Validity context:
Counts, Flags, requested visualization, and whether invalid points should be included or filtered.
- Repository source snippets referenced below. Treat these snippets as the API source of truth.
Prerequisites
- Use an ovrtx checkout that contains the referenced examples and docs tests.
- Read the relevant
> **Source:** snippet before writing or explaining API usage.
- Start from tensors the caller has already read, or a conceptual question about channel meaning. Use
reading-sensor-pointclouds if the user needs code to access the tensors.
- Use
configuring-lidar-sensors when the requested channel is missing because it was not authored in the lidar PointCloud RenderVar.
Instructions
- Identify the lidar channels being interpreted and the settings that define their coordinate frame, units, and validity behavior.
- Read the matching interpretation source snippet before explaining channel behavior or visualization choices.
- Use
Counts[0] for tensor bounds and Flags bit tests for per-point validity when invalid points may be present.
- Explain channel meaning without adding mapping boilerplate unless the user also asks how to read the tensors.
- Combine configuration, reading, and interpretation skills only when the user asks for an end-to-end sensor workflow.
- When changing code, run the narrow docs test or example that owns the snippet whenever practical.
Output Format
- For explanations, cite the relevant API names, source snippets, and caveats.
- For code changes, summarize the files changed, snippets affected, and validation run.
Scripts
This skill has no scripts.
Limitations
- The referenced snippets remain the source of truth; update or add tested snippets before documenting new API usage.
Overview
Lidar PointCloud output is a composite render var with per-point tensors. Use Counts[0] to bound the delivered point entries before interpreting any channel, and use the Flags VALID bit for per-entry validity when invalid points may be present.
Source: examples/python/sensors/lidar/main.py snippet read-lidar-pointcloud
Source: examples/c/sensors/lidar/main.cpp snippet read-lidar-pointcloud
The lidar examples demonstrate a minimal interpretation path: read Coordinates, Counts, Intensity, and TimeOffsetNs, slice each per-point tensor to the valid range, and summarize or visualize the result.
Channels
These are the available lidar PointCloud channels from omni.sensors.nv.lidar.
| Channel |
Type / Shape |
Unit |
Meaning |
Counts |
int32 scalar |
points |
Model-delivered point entry count; use it to bound every per-point tensor. With default invalid-point dropping this is the valid point count, but includeInvalidPoints = true can preserve invalid entries inside the range. |
Coordinates |
float 2D, 3 x N |
m, rad |
Point coordinates. Representation is controlled by elementsCoordsType: Cartesian positions or spherical components. Frame is controlled by outputFrameOfReference. |
Intensity |
float 1D, N |
unitless |
Processed return strength, normalized by the lidar intensity processing mode. Range depends on scaling and mapping attribute, base is [0,1] |
TimeOffsetNs |
int32 1D, N |
ns |
Per-point time offset relative to the sensor frame timestamp. |
Flags |
uint8 1D, N |
unitless |
Model-delivered point status flags. VALID (1 << 6, 0x40) marks a valid point. Lidar also uses FLAG_7 (1 << 5, 0x20) to mark that the point starts a new scan. |
EmitterId |
uint32 1D, N |
unitless |
Internal emitter or laser index in the emitter state array. |
ChannelId |
uint32 1D, N |
unitless |
Detector/channel index. This can differ from emitter index for complex channel configurations. |
TickId |
uint32 1D, N |
unitless |
Tick or scan-step index for the hit. |
EchoId |
uint8 1D, N |
unitless |
Return index for multi-echo lidar beams. |
TickState |
uint8 1D, N |
unitless |
Active scan pattern state for the tick that produced the point. |
MaterialId |
uint32 1D, N |
unitless |
Encoded nonvisual material ID of the hit surface. |
ObjectId |
uint32 2D, N x 4 |
unitless |
128-bit stable object ID for the hit object, packed as four uint32 values per point. |
HitNormal |
float 2D, N x 3 |
unitless |
Surface normal at the hit point, in the configured output frame. |
Velocity |
float 2D, N x 3 |
m/s |
Velocity vector at the hit point. |
The model auto-enables Counts and Flags, and they are delivered as ordinary PointCloud channel tensors. Other channels are present only when requested and supported by the sensor configuration.
Validity
Within the first Counts[0] entries, a point is valid when (Flags[i] & VALID) != 0. A point is invalid when that bit is clear. Do not compare Flags[i] == VALID, because lidar can set additional bits such as FLAG_7 on the same point.
With the default omni:sensor:Core:includeInvalidPoints = false, invalid lidar returns are dropped before output, so entries up to Counts[0] are expected to be valid. With includeInvalidPoints = true, invalid returns are preserved; filter by Flags before using channels such as Coordinates, Intensity, HitNormal, or Velocity as real returns.
Interpretation Notes
Coordinates may be Cartesian or spherical. Check the authored elementsCoordsType before treating components as XYZ.
- Lidar sensor-frame output is often easiest for sensor algorithms and visualization in sensor coordinates; world-frame output is useful for scene-level fusion.
Intensity is processing-mode dependent, so compare values only across runs with compatible lidar intensity settings and materials.
TimeOffsetNs matters for scanning sensors because different points in one reported frame can come from different firing times.
EmitterId, ChannelId, TickId, EchoId, and TickState are useful for reconstructing scan pattern behavior or filtering by beam/return.
MaterialId, ObjectId, HitNormal, and Velocity are richer attribution channels and may need additional sensor/material settings.
- Use
Counts for tensor bounds and Flags for per-point validity; these are different concepts when invalid points are included.
Visualization
Source: examples/python/sensors/lidar/main.py snippet intensity-colors
Source: examples/python/sensors/lidar/main.py snippet log-lidar-points
Coloring by Intensity is a useful default for public examples. For debugging scan timing, color by TimeOffsetNs; for material validation, color or group by MaterialId.
Related Skills
reading-sensor-pointclouds for mapping and slicing composite PointCloud tensors.
configuring-lidar-sensors for authoring lidar output channels.
nonvisual-materials for interpreting MaterialId values.
Troubleshooting
- If source snippets do not cover the requested variant, add or update a focused docs test or example before documenting the new pattern.
- If behavior differs between Python and C/C++, prefer the language-specific snippet and call out the difference explicitly.
References
- Use the
> **Source:** directives in this skill to locate tested snippets before reusing API patterns.
- Keep related skills, docs, and snippets synchronized when changing the workflow.
1---2name: interpreting-lidar-pointclouds3description: Interpreting already-read lidar PointCloud tensors: channel meanings, units, valid point ranges, coordinate-frame implications, flags, IDs, normals, velocity, and visualization values. Use reading-sensor-pointclouds when the user needs to map or fetch the tensors first.4license: LicenseRef-NvidiaProprietary5---67# Interpreting Lidar PointClouds89## When to Use1011Use this skill when the user asks what already-read lidar Coordinates, Intensity, TimeOffsetNs, Flags, IDs, normals, velocity, or other PointCloud tensors mean. Use `reading-sensor-pointclouds` instead when the user needs map/read code to obtain the tensors.1213## Inputs1415Resolve inputs in this order: existing repository files and referenced snippets, explicit user request, then broader agent context.1617- Lidar channel names and tensor values or summaries already available to the caller.18- Authored lidar settings that affect interpretation, especially `elementsCoordsType`, `outputFrameOfReference`, and `includeInvalidPoints`.19- Validity context: `Counts`, `Flags`, requested visualization, and whether invalid points should be included or filtered.20- Repository source snippets referenced below. Treat these snippets as the API source of truth.2122## Prerequisites2324- Use an ovrtx checkout that contains the referenced examples and docs tests.25- Read the relevant `> **Source:**` snippet before writing or explaining API usage.26- Start from tensors the caller has already read, or a conceptual question about channel meaning. Use `reading-sensor-pointclouds` if the user needs code to access the tensors.27- Use `configuring-lidar-sensors` when the requested channel is missing because it was not authored in the lidar `PointCloud` RenderVar.2829## Instructions30311. Identify the lidar channels being interpreted and the settings that define their coordinate frame, units, and validity behavior.322. Read the matching interpretation source snippet before explaining channel behavior or visualization choices.333. Use `Counts[0]` for tensor bounds and `Flags` bit tests for per-point validity when invalid points may be present.344. Explain channel meaning without adding mapping boilerplate unless the user also asks how to read the tensors.355. Combine configuration, reading, and interpretation skills only when the user asks for an end-to-end sensor workflow.366. When changing code, run the narrow docs test or example that owns the snippet whenever practical.3738## Output Format3940- For explanations, cite the relevant API names, source snippets, and caveats.41- For code changes, summarize the files changed, snippets affected, and validation run.4243## Scripts4445This skill has no scripts.4647## Limitations4849- The referenced snippets remain the source of truth; update or add tested snippets before documenting new API usage.5051## Overview5253Lidar `PointCloud` output is a composite render var with per-point tensors. Use `Counts[0]` to bound the delivered point entries before interpreting any channel, and use the `Flags` `VALID` bit for per-entry validity when invalid points may be present.5455> **Source:** `examples/python/sensors/lidar/main.py` snippet `read-lidar-pointcloud`5657> **Source:** `examples/c/sensors/lidar/main.cpp` snippet `read-lidar-pointcloud`5859The lidar examples demonstrate a minimal interpretation path: read `Coordinates`, `Counts`, `Intensity`, and `TimeOffsetNs`, slice each per-point tensor to the valid range, and summarize or visualize the result.6061## Channels6263These are the available lidar `PointCloud` channels from `omni.sensors.nv.lidar`.6465| Channel | Type / Shape | Unit | Meaning |66|---|---|---|---|67| `Counts` | `int32` scalar | points | Model-delivered point entry count; use it to bound every per-point tensor. With default invalid-point dropping this is the valid point count, but `includeInvalidPoints = true` can preserve invalid entries inside the range. |68| `Coordinates` | `float` 2D, `3 x N` | m, rad | Point coordinates. Representation is controlled by `elementsCoordsType`: Cartesian positions or spherical components. Frame is controlled by `outputFrameOfReference`. |69| `Intensity` | `float` 1D, `N` | unitless | Processed return strength, normalized by the lidar intensity processing mode. Range depends on scaling and mapping attribute, base is [0,1] |70| `TimeOffsetNs` | `int32` 1D, `N` | ns | Per-point time offset relative to the sensor frame timestamp. |71| `Flags` | `uint8` 1D, `N` | unitless | Model-delivered point status flags. `VALID` (`1 << 6`, `0x40`) marks a valid point. Lidar also uses `FLAG_7` (`1 << 5`, `0x20`) to mark that the point starts a new scan. |72| `EmitterId` | `uint32` 1D, `N` | unitless | Internal emitter or laser index in the emitter state array. |73| `ChannelId` | `uint32` 1D, `N` | unitless | Detector/channel index. This can differ from emitter index for complex channel configurations. |74| `TickId` | `uint32` 1D, `N` | unitless | Tick or scan-step index for the hit. |75| `EchoId` | `uint8` 1D, `N` | unitless | Return index for multi-echo lidar beams. |76| `TickState` | `uint8` 1D, `N` | unitless | Active scan pattern state for the tick that produced the point. |77| `MaterialId` | `uint32` 1D, `N` | unitless | Encoded nonvisual material ID of the hit surface. |78| `ObjectId` | `uint32` 2D, `N x 4` | unitless | 128-bit stable object ID for the hit object, packed as four `uint32` values per point. |79| `HitNormal` | `float` 2D, `N x 3` | unitless | Surface normal at the hit point, in the configured output frame. |80| `Velocity` | `float` 2D, `N x 3` | m/s | Velocity vector at the hit point. |8182The model auto-enables `Counts` and `Flags`, and they are delivered as ordinary `PointCloud` channel tensors. Other channels are present only when requested and supported by the sensor configuration.8384## Validity8586Within the first `Counts[0]` entries, a point is valid when `(Flags[i] & VALID) != 0`. A point is invalid when that bit is clear. Do not compare `Flags[i] == VALID`, because lidar can set additional bits such as `FLAG_7` on the same point.8788With the default `omni:sensor:Core:includeInvalidPoints = false`, invalid lidar returns are dropped before output, so entries up to `Counts[0]` are expected to be valid. With `includeInvalidPoints = true`, invalid returns are preserved; filter by `Flags` before using channels such as `Coordinates`, `Intensity`, `HitNormal`, or `Velocity` as real returns.8990## Interpretation Notes9192- `Coordinates` may be Cartesian or spherical. Check the authored `elementsCoordsType` before treating components as XYZ.93- Lidar sensor-frame output is often easiest for sensor algorithms and visualization in sensor coordinates; world-frame output is useful for scene-level fusion.94- `Intensity` is processing-mode dependent, so compare values only across runs with compatible lidar intensity settings and materials.95- `TimeOffsetNs` matters for scanning sensors because different points in one reported frame can come from different firing times.96- `EmitterId`, `ChannelId`, `TickId`, `EchoId`, and `TickState` are useful for reconstructing scan pattern behavior or filtering by beam/return.97- `MaterialId`, `ObjectId`, `HitNormal`, and `Velocity` are richer attribution channels and may need additional sensor/material settings.98- Use `Counts` for tensor bounds and `Flags` for per-point validity; these are different concepts when invalid points are included.99100## Visualization101102> **Source:** `examples/python/sensors/lidar/main.py` snippet `intensity-colors`103104> **Source:** `examples/python/sensors/lidar/main.py` snippet `log-lidar-points`105106Coloring by `Intensity` is a useful default for public examples. For debugging scan timing, color by `TimeOffsetNs`; for material validation, color or group by `MaterialId`.107108## Related Skills109110- `reading-sensor-pointclouds` for mapping and slicing composite PointCloud tensors.111- `configuring-lidar-sensors` for authoring lidar output channels.112- `nonvisual-materials` for interpreting `MaterialId` values.113114## Troubleshooting115116- If source snippets do not cover the requested variant, add or update a focused docs test or example before documenting the new pattern.117- If behavior differs between Python and C/C++, prefer the language-specific snippet and call out the difference explicitly.118119## References120121- Use the `> **Source:**` directives in this skill to locate tested snippets before reusing API patterns.122- Keep related skills, docs, and snippets synchronized when changing the workflow.