Configure a Full-Circle Scan#

Sample a full azimuth circle with a specified firing order. Use the grid’s layout to choose which direction is visited next and its time offsets to choose when that sample is emitted within a capture.

Before you start. Author the base and depth patterns from Sample a Depth Grid; the USD Python tab modifies that existing stage.

Timed angular grid#

A 4 by 16 spherical grid represents four elevation rows scanned over a full azimuth circle. Matching transmitter/receiver grids and one Free ray per transmitter retain direct 1to1 pairing and produce 64 slots.

The override below uses columnMajor so all four elevations are visited before advancing azimuth. Transmitter offsets span 0 to 1,000,000 ns across all 64 elements, not a separate interval for each row. The inherited single-ray bundle has zero ray-local offset, so each ray fires at its transmitter’s offset. The sensor capture rate and these within-capture offsets are separate controls; see firing times. The layer below authors the scan geometry and timing together:

#usda 1.0
(
    defaultPrim = "World"
    metersPerUnit = 1
    upAxis = "Z"
    timeCodesPerSecond = 10
    subLayers = [@generic_wpm_depth.usda@]
)

over "World"
{
    over "Sensor"
    {
        # Full-circle azimuth excludes +180, which duplicates -180.
        uint[] omni:sensor:GenericWpm:gridPatterns:tx:numRows = [4]
        uint[] omni:sensor:GenericWpm:gridPatterns:tx:numCols = [16]
        float[] omni:sensor:GenericWpm:gridPatterns:tx:startColUnits = [-180]
        float[] omni:sensor:GenericWpm:gridPatterns:tx:endColUnits = [180]
        token[] omni:sensor:GenericWpm:gridPatterns:tx:layouts = ["columnMajor"]
        uint[] omni:sensor:GenericWpm:gridPatterns:rx:numRows = [4]
        uint[] omni:sensor:GenericWpm:gridPatterns:rx:numCols = [16]
        float[] omni:sensor:GenericWpm:gridPatterns:rx:startColUnits = [-180]
        float[] omni:sensor:GenericWpm:gridPatterns:rx:endColUnits = [180]
        token[] omni:sensor:GenericWpm:gridPatterns:rx:layouts = ["columnMajor"]
        # Times follow the 64-cell flattened traversal, including both endpoints.
        uint[] omni:sensor:GenericWpm:gridPatterns:tx:startTimeOffsetsNs = [0]
        uint[] omni:sensor:GenericWpm:gridPatterns:tx:endTimeOffsetsNs = [1000000]
    }
}
sensor = stage.GetPrimAtPath("/World/Sensor")
for role in ("tx", "rx"):
    grid = "omni:sensor:GenericWpm:gridPatterns:" + role + ":"
    # Full-circle azimuth excludes the duplicate +180-degree endpoint.
    sensor.GetAttribute(grid + "numRows").Set([4])
    sensor.GetAttribute(grid + "numCols").Set([16])
    sensor.GetAttribute(grid + "startColUnits").Set([-180])
    sensor.GetAttribute(grid + "endColUnits").Set([180])
    sensor.GetAttribute(grid + "layouts").Set(["columnMajor"])
tx = "omni:sensor:GenericWpm:gridPatterns:tx:"
sensor.CreateAttribute(tx + "startTimeOffsetsNs", Sdf.ValueTypeNames.UIntArray, custom=False).Set([0])
sensor.CreateAttribute(tx + "endTimeOffsetsNs", Sdf.ValueTypeNames.UIntArray, custom=False).Set([1000000])

The final azimuth column does not repeat the first direction. Timing still includes both endpoints. The enclosure supplies targets around the full circle; an open scene can leave invalid slots. The complete scan is traced each frame. This configures sampling and firing offsets, not a rotating-device scheduler or lidar detector. The static enclosure does not demonstrate motion distortion.

Attribute meanings are on USD Attributes; complete types and defaults are in Sensor API Schemas.

Verification#

  1. Confirm numTx = 64, raysPerTx = 1 and groupSize = 1 in the completed output.

  2. The reported transmitter grid has four rows, sixteen columns and column-major order.

  3. Inspect valid DeltaTimeNs values against the firing schedule.

  4. Compare the first and final azimuth directions: the final column must not repeat the first.

Potential issues#

Use the Generic wpm checks for confirming checks and recovery.

  • Some directions have no return. Open scene directions can leave allocated slots invalid. Refer to Outputs.

  • A scan does not extend into later captures. Firing offsets select motion samples inside one complete capture. Refer to firing times.