Unverified Commit 1ad83e1b authored by Özhan Özen's avatar Özhan Özen Committed by GitHub

Updates `NoiseModelWithAdditiveBias` to apply per-feature bias sampling (#2760)

# Description

This PR updates the `NoiseModelWithAdditiveBias` to apply per-feature
bias sampling.

Previously, the model sampled a single scalar bias per episode and
applied it uniformly across all feature dimensions (i.e., axis 1 of a
(`num_env`, `feature_dim`) tensor). This PR changes the behavior to
instead sample a separate bias value for each feature dimension, making
the model more suitable for structured inputs such as positions,
velocities, or multi-DOF actions.

### Notes

Structured inputs typically contain semantically distinct components,
like [x, y, z] coordinates, where applying the same bias across all
components introduces unrealistic, fully correlated noise. Independent
per-dimension bias sampling leads to more realistic and robust policy
training, especially for sim-to-real transfer.

I’ve replaced the previous behavior with this new default, as I believe
the original implementation could be misleading and not well-suited for
many practical scenarios. However, if desired, I can make both behaviors
available via a configuration flag (e.g., `per_feature_bias=True`), to
retain backward compatibility.

Fixes #2759.

## Type of change

- Bug fix (non-breaking change which fixes an issue)
- New feature (non-breaking change which adds functionality)

## Checklist

- [x] I have run the [`pre-commit` checks](https://pre-commit.com/) with
`./isaaclab.sh --format`
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] I have updated the changelog and the corresponding version in the
extension's `config/extension.toml` file
- [x] I have added my name to the `CONTRIBUTORS.md` or my name already
exists there

---------
Co-authored-by: 's avatarKelly Guo <kellyg@nvidia.com>
parent 34cda4f7
[package] [package]
# Note: Semantic Versioning is used: https://semver.org/ # Note: Semantic Versioning is used: https://semver.org/
version = "0.40.8" version = "0.40.9"
# Description # Description
title = "Isaac Lab framework for Robot Learning" title = "Isaac Lab framework for Robot Learning"
......
Changelog Changelog
--------- ---------
0.40.9 (2025-06-25)
~~~~~~~~~~~~~~~~~~~
Added
^^^^^
* Added ``sample_bias_per_component`` flag to :class:`~isaaclab.utils.noise.noise_model.NoiseModelWithAdditiveBias` to enable independent per-component bias
sampling, which is now the default behavior. If set to False, the previous behavior of sharing the same bias value across all components is retained.
0.40.8 (2025-06-18) 0.40.8 (2025-06-18)
~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~
......
...@@ -103,3 +103,9 @@ class NoiseModelWithAdditiveBiasCfg(NoiseModelCfg): ...@@ -103,3 +103,9 @@ class NoiseModelWithAdditiveBiasCfg(NoiseModelCfg):
Based on this configuration, the bias is sampled at every reset of the noise model. Based on this configuration, the bias is sampled at every reset of the noise model.
""" """
sample_bias_per_component: bool = True
"""Whether to sample a separate bias for each data component.
Defaults to True.
"""
...@@ -154,6 +154,8 @@ class NoiseModelWithAdditiveBias(NoiseModel): ...@@ -154,6 +154,8 @@ class NoiseModelWithAdditiveBias(NoiseModel):
# store the bias noise configuration # store the bias noise configuration
self._bias_noise_cfg = noise_model_cfg.bias_noise_cfg self._bias_noise_cfg = noise_model_cfg.bias_noise_cfg
self._bias = torch.zeros((num_envs, 1), device=self._device) self._bias = torch.zeros((num_envs, 1), device=self._device)
self._num_components: int | None = None
self._sample_bias_per_component = noise_model_cfg.sample_bias_per_component
def reset(self, env_ids: Sequence[int] | None = None): def reset(self, env_ids: Sequence[int] | None = None):
"""Reset the noise model. """Reset the noise model.
...@@ -179,4 +181,11 @@ class NoiseModelWithAdditiveBias(NoiseModel): ...@@ -179,4 +181,11 @@ class NoiseModelWithAdditiveBias(NoiseModel):
Returns: Returns:
The data with the noise applied. Shape is the same as the input data. The data with the noise applied. Shape is the same as the input data.
""" """
# if sample_bias_per_component, on first apply, expand bias to match last dim of data
if self._sample_bias_per_component and self._num_components is None:
*_, self._num_components = data.shape
# expand bias from (num_envs,1) to (num_envs, num_components)
self._bias = self._bias.repeat(1, self._num_components)
# now re-sample that expanded bias in-place
self.reset()
return super().__call__(data) + self._bias return super().__call__(data) + self._bias
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment