Skip to content

Add dictionary and single-tensor processors for cameras and observations - #8571

Closed
mataylor-nvidia wants to merge 23 commits into
isaac-sim:developfrom
mataylor-nvidia:feat/render-buffer-pipe
Closed

mataylor-nvidia wants to merge 23 commits into
isaac-sim:developfrom
mataylor-nvidia:feat/render-buffer-pipe

Conversation

@mataylor-nvidia

@mataylor-nvidia mataylor-nvidia commented Oct 14, 2026 •

Copy link
Copy Markdown
Contributor

Superseded by two stacked draft PRs:

  1. Rename modifiers to tensor processors and add dictionary processing (#8693), targeting upstream develop.
  2. Move PPISP processing from renderers into camera pipelines (mataylor-nvidia/IsaacLab#86), targeting the first PR's branch in the fork. Upstream repository rules prohibit creating the branch needed for a stacked base there. Once Rename modifiers and unify tensor processor APIs #8693 merges, the upper commit can be rebased onto develop and submitted upstream.

The cleanup defers the observation dictionary adapters, removes their preparation/teardown machinery, consolidates camera setup and duplicate tests, and retains deprecated modifier imports/configuration during migration. PPISP production changes are +627 / -629; tests and documentation account for the remaining net growth.

Both replacement branches are based on current develop and have passed focused tests, formatting/lint, changelog checks, and focused Sphinx validation. Full documentation is blocked by the installed Omniverse Kit EULA requirement; live OVRTX/Isaac RTX and remote GPU CI remain unrun. The original branch and review history are preserved.

temiroff and others added 16 commits October 6, 2026 17:10
Expose scene-linear RGB before camera exposure and response as a camera output on Isaac RTX,
OVRTX, and Newton Warp, without changing CameraCfg.isp_cfg or the renderer-owned PPISP path.

Isaac RTX and OVRTX read it from the HdrColor source and neutralize exposure on the camera prim,
using the exposure override now shared from isaaclab.renderers. Newton applies no exposure, so it
matches rgb_hdr. When both HDR outputs are requested they share one buffer. OVRTX also disables
Gaussian skip-tonemapping on HDR-consuming render products so Gaussian pixels reach HdrColor.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
Renderers import apply_rtx_exposure_overrides from isaaclab.renderers.rtx_camera_overrides, so isaaclab_ppisp no longer re-exports it.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
Camera no longer branches on the renderer type. IsaacRtxRendererCfg sets the RTX sensor and Gaussian HDR routing settings in a new RendererCfg.apply_pre_reset_settings hook, which cameras call before sim.reset().

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
OVRTX exports the stage once, when the first camera initializes, so overrides authored later by
other cameras, such as the neutral exposure for rgb_radiance, never reached it. Cameras now apply
their renderer overrides in a PHYSICS_READY callback that runs before any sensor initializes.

Also address review comments: map the exposure attribute types explicitly, merge the HDR case into
the existing OVRTX render-var test, state the expected HDR routing per test row, and point the
rtx_sensors comment at IsaacRtxRendererCfg.apply_pre_reset_settings.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
…upport in the matrix

SensorBase registers a PHYSICS_READY callback that runs every sensor's _prepare_initialize_impl()
before any sensor initializes, through its existing weak reference. Camera overrides the hook to
apply its renderer overrides, so it no longer registers its own callback or imports weakref.

The rgb_radiance enum docstring keeps only the definition. The camera documentation's renderer
support matrix now lists rgb_radiance as derived on Isaac RTX and OVRTX, with the note below it.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
Replace RendererCfg.apply_pre_reset_settings() with BaseRenderer.apply_camera_settings(), which cameras call right after creating their renderer in __init__, still before sim.reset(). Renderer configurations stay data only. IsaacRtxRenderer implements the hook.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
The neutral-exposure override is a temporary workaround until RTX provides a native radiance output (NVBug 6858736), so it is not public API: rename it to _apply_rtx_exposure_overrides, document the module as internal, and drop it from the changelog.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
…ethod

Isaac RTX marks RTX sensor rendering when it is created, which cameras do during scene construction, and enables Gaussian HDR routing in prepare_cameras for cameras that read HDR color. BaseRenderer.apply_camera_settings() and the Camera call to it are removed.

Signed-off-by: Alexander Temirov <atemirov@nvidia.com>
# Conflicts:
#	source/isaaclab_ov/isaaclab_ov/renderers/ovrtx_usd.py
#	source/isaaclab_ov/test/test_ovrtx_usd.py
Restore the em dash in two Camera comments, mark the exposure-override removal as breaking, and drop a fragment that described review iterations rather than a change against develop.
isaaclab_ppisp.apply_rtx_exposure_overrides shipped as public API. Keep it, and its submodule path, as a wrapper that raises a DeprecationWarning and applies the renderers' override, which now runs automatically for cameras with PPISP or rgb_radiance.
This reverts commit bcb22ec. Reviewers asked for a clean break without compatibility shims; the changelog marks the removal as breaking with its migration.
@github-actions github-actions Bot added documentation Improvements or additions to documentation isaac-lab Related to Isaac Lab team labels Oct 14, 2026
@mataylor-nvidia mataylor-nvidia changed the title Add a shared render buffer pipe for cameras and observations Add shared buffer processing for cameras and observations Oct 14, 2026
@mataylor-nvidia

Copy link
Copy Markdown
Contributor Author

Design proposal: Move image processing into RenderBufferPipe. Renderers supply raw buffers; cameras and observations decide when to process them and how to expose the results.

Draft: #8571

Renderer buffers → camera-owned pipe      → camera.data.output
Renderer buffers → observation-owned pipe → observation snapshot
Incoming tensor  → modifier-owned pipe    → observation snapshot

Buffers are ProxyArrays. Shape, dtype, and device come directly from storage.
PreparedBufferOperation describes executable processing:

output_specs
apply
reset
close

output_specs tells the pipe what to allocate. apply(inputs, outputs) writes into those allocations. Optional reset and close callbacks manage operation state and resources.
ProcessingBufferStepCfg connects that operation to named buffers:

prepare
inputs
outputs
params

Then map buffer names to operation roles. mechanism supports an operation with multiple inputs. Preparation happens once then execution loop looks like

current = dict(buffers)
for operation, inputs, outputs, destinations in self._operations:
    operation.apply({role: current[name] for role, name in inputs.items()}, destinations)
    current.update({name: destinations[role] for role, name in outputs.items()})
return current

The consumers have control over delivery

  • Cameras publish borrowed buffers; observations return snapshots that survive subsequent processing.

  • modifiers shouldn't know data names: The factory only gets arrays keyed by role, plus params. It never sees the step config (images.py:121)

  • one operation, several inputs (fog: rgb + depth → rgb) inputs={"color": "rgb", "depth": ...}, outputs={"color": "rgb"}

  • point Cosmos at specific outputs, each step names its inputs and outputs explicitly

  • hide rgb_radiance

  • The renderer is asked for it before it starts; it's in render_outputs but not in data.output unless listed

  • plain list as a shortcut pipeline=[PpispStepCfg()] with default names

  • Don't make every BaseModifier handle batches

  • ModifierBase is unchanged; steps are a separate type, connected through RenderBufferPipeModifier

  • scale before PPISP
    Works by putting RenderBufferPipeModifierCfg after a scale modifier, but only for single-input steps

  • PpispControllerWeights are different per controller

The current form used is a list:

CameraCfg(
    data_types=["rgb", "depth"],
    # PpispStepCfg defaults: inputs={"radiance": "rgb_radiance"}, outputs={"color": "rgb"}
    pipeline=[PpispStepCfg(params={"cfg": ppisp_cfg})],
)

# The dict form Octi and Mustafa proposed (not implemented)
CameraCfg(data_types=["rgb", "depth"], modifiers={"rgb": [PpispModifierCfg()]})

from isaaclab.envs import ManagerBasedEnv


class processed_sensor(ManagerTermBase):

@mataylor-nvidia mataylor-nvidia Oct 14, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isaac Lab’s existing convention for callable MDP terms: classes such as image_depth, image_features, and stacked_image also use snake_case. They’re configured through the same func field as ordinary functions:

ObservationTermCfg(func=mdp.processed_sensor, ...)

for _cfg, renderer in self._renderer_entries:
renderer.initialize()

def register_camera(self, camera: Camera) -> None:

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you sure this is needed for this pr?

@mataylor-nvidia mataylor-nvidia changed the title Add shared buffer processing for cameras and observations Add dictionary and single-tensor processors for cameras and observations Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants