Skip to content

Commit bf3cc4e

Browse files
committed
fix device propogation for noise and add noise tests
1 parent 225a896 commit bf3cc4e

File tree

2 files changed

+177
-3
lines changed

2 files changed

+177
-3
lines changed

source/extensions/omni.isaac.lab/omni/isaac/lab/utils/noise/noise_model.py

Lines changed: 53 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,21 @@
1818

1919

2020
def constant_noise(data: torch.Tensor, cfg: noise_cfg.ConstantNoiseCfg) -> torch.Tensor:
21-
"""Constant noise."""
21+
"""Applies a constant noise bias to a given data set.
22+
23+
Args:
24+
data: The unmodified data set to apply noise to.
25+
cfg: The configuration parameters for constant noise.
26+
27+
Returns:
28+
The data modified by the noise parameters provided.
29+
"""
30+
31+
# fix tensor device for bias on first call and update config parameters
32+
if isinstance(cfg.bias,torch.Tensor):
33+
if cfg.bias.device is not data.device:
34+
cfg.bias = cfg.bias.to(data.device,)
35+
2236
if cfg.operation == "add":
2337
return data + cfg.bias
2438
elif cfg.operation == "scale":
@@ -30,7 +44,25 @@ def constant_noise(data: torch.Tensor, cfg: noise_cfg.ConstantNoiseCfg) -> torch
3044

3145

3246
def uniform_noise(data: torch.Tensor, cfg: noise_cfg.UniformNoiseCfg) -> torch.Tensor:
33-
"""Uniform noise."""
47+
"""Applies a uniform noise to a given data set.
48+
49+
Args:
50+
data: The unmodified data set to apply noise to.
51+
cfg: The configuration parameters for uniform noise.
52+
53+
Returns:
54+
The data modified by the noise parameters provided.
55+
"""
56+
57+
# fix tensor device for n_max on first call and update config parameters
58+
if isinstance(cfg.n_max,torch.Tensor):
59+
if cfg.n_max.device is not data.device:
60+
cfg.n_max = cfg.n_max.to(data.device)
61+
# fix tensor device for n_min on first call and update config parameters
62+
if isinstance(cfg.n_min,torch.Tensor):
63+
if cfg.n_min.device is not data.device:
64+
cfg.n_min = cfg.n_min.to(data.device)
65+
3466
if cfg.operation == "add":
3567
return data + torch.rand_like(data) * (cfg.n_max - cfg.n_min) + cfg.n_min
3668
elif cfg.operation == "scale":
@@ -42,7 +74,25 @@ def uniform_noise(data: torch.Tensor, cfg: noise_cfg.UniformNoiseCfg) -> torch.T
4274

4375

4476
def gaussian_noise(data: torch.Tensor, cfg: noise_cfg.GaussianNoiseCfg) -> torch.Tensor:
45-
"""Gaussian noise."""
77+
"""Applies a gaussian noise to a given data set.
78+
79+
Args:
80+
data: The unmodified data set to apply noise to.
81+
cfg: The configuration parameters for gaussian noise.
82+
83+
Returns:
84+
The data modified by the noise parameters provided.
85+
"""
86+
87+
# fix tensor device for mean on first call and update config parameters
88+
if isinstance(cfg.mean,torch.Tensor):
89+
if cfg.mean.device is not data.device:
90+
cfg.mean = cfg.mean.to(data.device)
91+
# fix tensor device for std on first call and update config parameters
92+
if isinstance(cfg.std,torch.Tensor):
93+
if cfg.std.device is not data.device:
94+
cfg.std = cfg.std.to(data.device)
95+
4696
if cfg.operation == "add":
4797
return data + cfg.mean + cfg.std * torch.randn_like(data)
4898
elif cfg.operation == "scale":
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
# Copyright (c) 2022-2024, The Isaac Lab Project Developers.
2+
# All rights reserved.
3+
#
4+
# SPDX-License-Identifier: BSD-3-Clause
5+
6+
"""Launch Isaac Sim Simulator first."""
7+
8+
from omni.isaac.lab.app import AppLauncher, run_tests
9+
10+
# launch omniverse app
11+
app_launcher = AppLauncher(headless=True)
12+
simulation_app = app_launcher.app
13+
14+
"""Rest everything follows."""
15+
16+
import time
17+
import torch
18+
import unittest
19+
from dataclasses import MISSING
20+
21+
import omni.isaac.lab.utils.noise as noise
22+
from omni.isaac.lab.utils import configclass
23+
24+
25+
26+
class TestNoise(unittest.TestCase):
27+
"""Test different noise implementations."""
28+
29+
def test_gaussian_noise(self):
30+
"""Test guassian_noise function."""
31+
32+
for device in ["cpu","cuda"]:
33+
for noise_device in ["cpu","cuda"]:
34+
for op in ["add","scale","abs"]:
35+
with self.subTest(device=device, noise_device=noise_device, operation=op):
36+
# create random data set
37+
data = torch.rand(10000, 3, device=device)
38+
# define standard deviation and mean
39+
std = torch.tensor([0.1,0.2,0.3],device=noise_device)
40+
mean = torch.tensor([0.4,0.5,0.6],device=noise_device)
41+
# create noise config
42+
noise_cfg = noise.GaussianNoiseCfg(std=std,
43+
mean=mean,
44+
operation=op)
45+
46+
for i in range(10):
47+
# apply noise
48+
noisy_data = noise_cfg.func(data,cfg=noise_cfg)
49+
# calculate resulting noise compared to original data set
50+
if op=="add":
51+
std_result, mean_result = torch.std_mean(noisy_data-data,dim=0)
52+
elif op=="scale":
53+
std_result, mean_result = torch.std_mean(noisy_data/data,dim=0)
54+
elif op=="abs":
55+
std_result, mean_result = torch.std_mean(noisy_data,dim=0)
56+
57+
self.assertTrue(noise_cfg.mean.device,device)
58+
self.assertTrue(noise_cfg.std.device,device)
59+
torch.testing.assert_close(noise_cfg.std,std_result,atol=1e-2,rtol=1e-2)
60+
torch.testing.assert_close(noise_cfg.mean,mean_result,atol=1e-2,rtol=1e-2)
61+
62+
63+
def test_uniform_noise(self):
64+
"""Test uniform_noise function."""
65+
for device in ["cpu","cuda"]:
66+
for noise_device in ["cpu","cuda"]:
67+
for op in ["add","scale","abs"]:
68+
with self.subTest(device=device, noise_device=noise_device,operation=op):
69+
# create random data set
70+
data = torch.rand(10000, 3, device=device)
71+
# define uniform minimum and maximum
72+
n_min = torch.tensor([0.1,0.2,0.3],device=noise_device)
73+
n_max = torch.tensor([0.4,0.5,0.6],device=noise_device)
74+
# create noise config
75+
noise_cfg = noise.UniformNoiseCfg(n_max=n_max, n_min=n_min,operation=op)
76+
77+
for i in range(10):
78+
# apply noise
79+
noisy_data = noise_cfg.func(data,cfg=noise_cfg)
80+
# calculate resulting noise compared to original data set
81+
if op=="add":
82+
min_result, _ = torch.min(noisy_data-data,dim=0)
83+
max_result, _ = torch.max(noisy_data-data,dim=0)
84+
elif op=="scale":
85+
min_result, _ = torch.min(torch.div(noisy_data,data),dim=0)
86+
max_result, _ = torch.max(torch.div(noisy_data,data),dim=0)
87+
elif op=="abs":
88+
min_result, _ = torch.min(noisy_data,dim=0)
89+
max_result, _ = torch.max(noisy_data,dim=0)
90+
91+
self.assertTrue(noise_cfg.n_min.device,device)
92+
self.assertTrue(noise_cfg.n_max.device,device)
93+
self.assertTrue(all(torch.le(noise_cfg.n_min, min_result).tolist()))
94+
self.assertTrue(all(torch.ge(noise_cfg.n_max, max_result).tolist()))
95+
96+
def test_constant_noise(self):
97+
"""Test constant_noise"""
98+
for device in ["cpu","cuda"]:
99+
for noise_device in ["cpu","cuda"]:
100+
for op in ["add","scale","abs"]:
101+
with self.subTest(device=device, noise_device=noise_device,operation=op):
102+
# create random data set
103+
data = torch.rand(10000, 3, device=device)
104+
# define a bias
105+
bias = torch.tensor([0.1,0.2,0.3],device=noise_device)
106+
# create noise config
107+
noise_cfg = noise.ConstantNoiseCfg(bias=bias, operation=op)
108+
109+
for i in range(10):
110+
# apply noise
111+
noisy_data = noise_cfg.func(data,cfg=noise_cfg)
112+
# calculate resulting noise compared to original data set
113+
if op=="add":
114+
bias_result = noisy_data-data
115+
elif op=="scale":
116+
bias_result = noisy_data/data
117+
elif op=="abs":
118+
bias_result = noisy_data
119+
120+
self.assertTrue(noise_cfg.bias.device,device)
121+
torch.testing.assert_close(noise_cfg.bias.repeat(data.shape[0],1),bias_result)
122+
123+
if __name__ == "__main__":
124+
run_tests()

0 commit comments

Comments
 (0)