Skip to content

Add light color temperature variation#885

Open
alexmillane wants to merge 8 commits into
mainfrom
alex/feature/light_color_temperature_variation
Open

Add light color temperature variation#885
alexmillane wants to merge 8 commits into
mainfrom
alex/feature/light_color_temperature_variation

Conversation

@alexmillane

Copy link
Copy Markdown
Collaborator

Summary

Adds a light color variation.

Detailed description

  • Light color plugs into an existing Lab parameter for all lights.

- Update test_arena_env_builder_cfg to the renamed --no_solve_relations flag
  (the hyphenated form was failing the no-camera CI job).
- Collapse set_intensity/set_orientation docstrings to a single line; drop the
  redundant explicit DistantLightCfg angle (0.53 is already the default).
- Remove RST double-backticks from the quaternion helper docstring.
- Inline the single-use test variation name; use non-zero test azimuth/elevation
  so the applied direction differs from the identity default.
- Revert the droid_pnp_variations_config.json eval config changes.

Signed-off-by: alex <amillane@nvidia.com>
- Inline single-use test constants and pass the color into build_test_light.
- Drop superfluous asserts and RST backticks in docstrings.

Signed-off-by: alex <amillane@nvidia.com>
- Sample a white-point color temperature (Kelvin) and apply it to the dome
  and directional lights via a new set_color_temperature on LightBase.

Signed-off-by: alex <amillane@nvidia.com>
@alexmillane alexmillane marked this pull request as ready for review July 9, 2026 16:39
"""Uniform distribution over color temperature in Kelvin, from warm (low) to cool (high)."""


class LightColorTemperatureVariation(BuildTimeVariationBase):

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.

🔵 This class is structurally identical to LightIntensityVariation (sample one scalar → call a setter), differing only in the cfg's default range and which setter it invokes. With intensity and now temperature following the same shape, is it worth collapsing the single-scalar cases into one generic variation parameterized by the setter + default range (thin Cfg subclasses, or just cfg instances)? Not a blocker — more a question of whether this family is now large enough to earn a shared base rather than a third near-copy.

@arena-review-bot

Copy link
Copy Markdown
Contributor

🤖 Isaac Lab-Arena Review Bot

Summary

Adds a build-time LightColorTemperatureVariation that samples a white-point color temperature (Kelvin) and applies it to dome and directional lights via a new LightBase.set_color_temperature. The change is small, self-consistent, and mirrors the existing LightColorVariation / LightIntensityVariation pattern faithfully. Variations default to enabled=False, so the new behavior is opt-in and does not change the default path — good.

Findings

🔵 Improvement: variations/light_color_temperature_variation.py — This class is structurally identical to LightIntensityVariation (sample one scalar → call a setter), differing only in the default range and the setter it calls. With two near-copies now, worth considering a shared generic single-scalar variation. Non-blocking.

Test Coverage

Strong. test_light_color_temperature_variation.py covers both the disabled (unchanged cfg) and enabled (mutated + compiled-into-scene) paths for both light and directional_light, using the inner/outer run_simulation_app_function pattern and a degenerate sampler range for determinism — consistent with the sibling test_light_color_variation.py.

Verdict

Ship it

@greptile-apps

greptile-apps Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a new LightColorTemperatureVariation build-time variation that randomizes the white-point color temperature (in Kelvin) on DomeLight and DirectionalLight assets. It follows the established pattern of LightColorVariation and LightIntensityVariation, plugging into the same BuildTimeVariationBase infrastructure.

  • Adds set_color_temperature() to LightBase, which also forces enable_color_temperature = True on the spawner config, and wires the new LightColorTemperatureVariation into both DomeLight and DirectionalLight constructors.
  • The default sampler range is [2000, 10000] K, but the valid range accepted by set_color_temperature is [1000, 10000] K, leaving the warmest candlelight tones (1000–2000 K) unreachable via the default configuration.

Confidence Score: 4/5

Safe to merge; the new variation correctly wires into both DomeLight and DirectionalLight using the established build-time pattern, and the tests cover the disabled and enabled paths end-to-end.

The implementation is consistent with sibling variations and correctly delegates to the validated set_color_temperature API. The only gap is that the default sampler range starts at 2000 K while the API it calls accepts values down to 1000 K, leaving the warmest tones unreachable via the default configuration without an explicit override.

isaaclab_arena/variations/light_color_temperature_variation.py — the default sampler lower bound.

Important Files Changed

Filename Overview
isaaclab_arena/variations/light_color_temperature_variation.py New variation class, cleanly mirrors LightColorVariation; default sampler lower bound (2000 K) is narrower than the valid range (1000 K) accepted by set_color_temperature.
isaaclab_arena/assets/object_library.py Adds set_color_temperature() to LightBase and wires LightColorTemperatureVariation into DomeLight and DirectionalLight; logic is correct and consistent with existing set_intensity/set_color patterns.
isaaclab_arena/tests/test_light_color_temperature_variation.py New test file covering both the disabled (no-mutation) and enabled (mutation + compiled cfg) paths for both DomeLight and DirectionalLight; degenerate-range sampler trick is a solid determinism pattern.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[LightColorTemperatureVariation.apply] --> B{sampler set?}
    B -- No --> C[AssertionError]
    B -- Yes --> D[sampler.sample num_samples=1]
    D --> E[color_temperature = float result 0,0]
    E --> F[LightBase.set_color_temperature]
    F --> G{1000 <= temp <= 10000?}
    G -- No --> H[AssertionError]
    G -- Yes --> I[spawner_cfg.enable_color_temperature = True]
    I --> J[spawner_cfg.color_temperature = value]
    J --> K[object_cfg = _init_object_cfg]

    subgraph Registration
        L[DomeLight.__init__] --> M[add_variation LightColorTemperatureVariation]
        N[DirectionalLight.__init__] --> M
    end
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[LightColorTemperatureVariation.apply] --> B{sampler set?}
    B -- No --> C[AssertionError]
    B -- Yes --> D[sampler.sample num_samples=1]
    D --> E[color_temperature = float result 0,0]
    E --> F[LightBase.set_color_temperature]
    F --> G{1000 <= temp <= 10000?}
    G -- No --> H[AssertionError]
    G -- Yes --> I[spawner_cfg.enable_color_temperature = True]
    I --> J[spawner_cfg.color_temperature = value]
    J --> K[object_cfg = _init_object_cfg]

    subgraph Registration
        L[DomeLight.__init__] --> M[add_variation LightColorTemperatureVariation]
        N[DirectionalLight.__init__] --> M
    end
Loading

Reviews (1): Last reviewed commit: "Add light color temperature variation" | Re-trigger Greptile

class LightColorTemperatureVariationCfg(VariationBaseCfg):
"""Configuration for LightColorTemperatureVariation."""

sampler_cfg: UniformSamplerCfg = field(default_factory=lambda: UniformSamplerCfg(low=[2000.0], high=[10000.0]))

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.

P2 The default sampler lower bound is 2000 K while set_color_temperature documents and validates the full range [1000, 10000] K. With this default, the warmest tones (1000–2000 K — candlelight, incandescent bulbs) can never be sampled unless the caller explicitly overrides sampler_cfg. Aligning the default to 1000 K makes the variation self-consistent with the API it calls.

Suggested change
sampler_cfg: UniformSamplerCfg = field(default_factory=lambda: UniformSamplerCfg(low=[2000.0], high=[10000.0]))
sampler_cfg: UniformSamplerCfg = field(default_factory=lambda: UniformSamplerCfg(low=[1000.0], high=[10000.0]))

Comment thread isaaclab_arena/assets/object_library.py Outdated
self.object_cfg = self._init_object_cfg()

def set_color_temperature(self, color_temperature: float) -> None:
"""Enable and set the light's white-point color temperature in Kelvin, in [1000, 10000]."""

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.

Is there a reason to constrain it to 1000, 10000?

@cvolkcvolk cvolkcvolk 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.

lgtm

@alexmillane alexmillane changed the base branch from alex/feature/light_color_variation to main July 15, 2026 07:52
@alexmillane alexmillane enabled auto-merge (squash) July 15, 2026 07:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants