Skip to content

[Core] Fix image normals data type resolution - #8375

Merged
maxkra15 merged 4 commits into
isaac-sim:developfrom
kellyguo11:kellyg/fix-image-normals-data-type
Oct 14, 2026
Merged

maxkra15 merged 4 commits into
isaac-sim:developfrom
kellyguo11:kellyg/fix-image-normals-data-type

Conversation

@kellyguo11

@kellyguo11 kellyguo11 commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Description

Adds the missing data_type: str = "normals" parameter to image_normals and uses it to select the camera output. The new parameter is keyword-only so the existing positional order for normalize, channel_first, and frame_stack remains compatible.

Manager terms resolve callable defaults into cfg.params before construction. Unlike the other per-modality image terms, image_normals did not declare its data type in the callable signature, so the strict CameraImageBase constructor raised KeyError: 'data_type'. This change fixes the signature rather than adding a fallback to the base class, keeping default resolution consistent with #8127.

Fixes NVBUG 6886551

No new dependencies.

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Release backport

  • Backport this pull request to the active release branch after it merges into develop

The release-branch compatibility fix is already open as #8373, so an automated duplicate backport is not requested.

Screenshots

Not applicable; this fixes observation-term construction.

Validation

  • Confirmed the default-resolution regression test fails on the unmodified develop branch with KeyError: 'data_type'.
  • Confirmed the positional-compatibility regression test fails before the follow-up fix with KeyError: False and passes once data_type is keyword-only.
  • Camera-image unit tests: 26 passed.
  • uv run isaaclab -f: passed, including the changelog gate against upstream/develop.
  • uv run --isolated --extra dev --extra ov -- make -C docs current-docs: passed without warnings.

Checklist

  • I have read and understood the contribution guidelines
  • I have run the pre-commit checks with uv run isaaclab --format
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have validated the changed behavior with focused coverage and applied the test-audit criteria to the test change
  • I have added a changelog fragment under source/<pkg>/changelog.d/ for every touched package
  • I have added my name to the CONTRIBUTORS.md or my name already exists there

@kellyguo11
kellyguo11 requested a review from a team October 8, 2026 00:41
@github-actions github-actions Bot added bug Something isn't working isaac-lab Related to Isaac Lab team labels Oct 8, 2026

@isaaclab-review-bot isaaclab-review-bot Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Isaac Lab Review Bot

All reviewed code categories look good.

  • PR description: The description matches the signature fix, resulting manager behavior, three-file scope, and reported validation; no performance evidence is needed for this construction-time parameter change.
  • Design and architecture: Architecture looks good.
  • Scope and over-engineering: No over-engineering issues.
  • API: API changes look good.
  • Compatibility and deprecation: No breaking changes identified.
  • Implementation: Implementation looks good.
  • Style consistency: Style consistency looks good.
  • Test quality: Test quality looks good.

No blocking issues. No inline findings.

Automated review; human maintainers own approval decisions.

@greptile-apps

greptile-apps Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Fixes camera normals observation to accept configurable data type.

The PR appears safe to merge.

What we checked:

  • Normals fail during construction: The manager fills callable defaults before constructing the term. ManagerTermBase also fills them before CameraImageBase reads data_type.

Summary

Adds data_type="normals" to image_normals so omitted settings resolve before construction, fixing KeyError: 'data_type'.

  • Reads the camera output selected by data_type.
  • Adds a regression test for default construction and normalized values.
  • Adds a changelog entry.
  • No actionable issues found. Tests were inspected, not run.

Reviews (1) · Last reviewed commit: "Add image normals data type parameter" · Reviewed by Greptile

@kellyguo11

Copy link
Copy Markdown
Contributor Author

@StafaH not sure if this is the right fix, pls let me know

@AntoineRichard AntoineRichard left a comment

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.

🤖 AI-generated review (Claude Code). Please double-check before acting on it.

The fix is correct. ManagerTermBase.__init__ fills in keyword-only defaults through _populate_term_defaults (manager_base.py:465-468), so the new test goes through the same path the observation manager uses. My comments are about the design around it.

1. Remove CameraImageBase.default_data_type. On develop, nothing reads it anymore, and its own docstring calls it a "Legacy data-type alias". It is also what caused this bug: image_normals set default_data_type = "normals", which looked like enough, but the base ignores the attribute after #8127. Removing it from the base and the four subclasses leaves the __call__ signature as the only place a default is defined, so the next image term can't fall into the same trap.

2. This fix and the release fix take different approaches. #8373 (merged into release/3.0.0) falls back in the base with cfg.params.get("data_type", self.default_data_type) and does not add a data_type argument to image_normals. As a result, params={"data_type": "normals"} fails the manager's parameter check on 3.0 GA but works on develop. That split is probably fine for GA, but please state it in the PR description. If you apply (1), only apply it on develop, because the release fallback still reads the attribute.

Inline comments below cover the tests and the keyword-only argument.

class TestModalityTerms:
"""Per-modality reading, validation and normalization."""

def test_normals_uses_default_data_type(self):

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.

(AI-generated) This test only covers normals, but the bug is broader: any image term that doesn't declare data_type in its signature breaks. One test parametrized over all four terms would catch the next one, and it could replace both new tests:

@pytest.mark.parametrize(("term_cls", "data_type"), [
    (image_rgb, "rgb"), (image_depth, "distance_to_image_plane"),
    (image_normals, "normals"), (image_segmentation, "semantic_segmentation"),
])
def test_constructs_with_default_data_type(term_cls, data_type):
    """Each camera image term resolves its data type from its own signature when the cfg omits it."""
    _, observe = _make_term(term_cls, _make_env({data_type: _random_rgb()}), normalize=False)
    assert observe().shape[0] == NUM_ENVS

_, observe = _make_term(image_normals, _make_env({"normals": normals}))
torch.testing.assert_close(observe(), (normals + 1.0) * 0.5)

def test_normals_preserves_positional_normalize(self):

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.

(AI-generated) Do we need this test? The manager always calls terms with keyword arguments, so this checks a calling convention rather than behavior a user would hit. Under the test-audit criteria I'd drop it, or fold it into the parametrized test above.

channel_first: bool = False,
frame_stack: int = 1,
*,
data_type: str = "normals",

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.

(AI-generated) Making this keyword-only is fine, because release/3.0.0 keeps the old positional order. But the other image terms take data_type as their second positional argument, so please add a sentence to the PR description explaining the difference.

Since isaac-sim#8127 the base class reads data_type from the term parameters, which the manager fills from each subclass's __call__ signature. The default_data_type attribute was no longer read and suggested a fallback that does not exist, which is how image_normals ended up without a data_type argument.
Replace the normals-only regression and the positional-call test with a sweep over CameraImageBase subclasses, so a new image term that omits data_type from __call__ fails here. Keep the normals normalization check, which has no other coverage.
@AntoineRichard

Copy link
Copy Markdown
Collaborator

run-ci

@isaaclab-bot isaaclab-bot Bot added ci:run-docker Trigger the on-demand Docker and GPU CI workflow and removed ci:run-docker Trigger the on-demand Docker and GPU CI workflow labels Oct 13, 2026
@maxkra15
maxkra15 self-requested a review October 14, 2026 10:02
@maxkra15
maxkra15 merged commit d652aa9 into isaac-sim:develop Oct 14, 2026
58 of 59 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working isaac-lab Related to Isaac Lab team

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants