Skip to content

Uncertainty Models

commonroad_control.simulation.uncertainty_model.uncertainty_interface

UncertaintyInterface dataclass

Bases: ABC

Interface for dataclasses storing noise/disturbances.

Source code in commonroad_control/simulation/uncertainty_model/uncertainty_interface.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
@dataclass
class UncertaintyInterface(ABC):
    """
    Interface for dataclasses storing noise/disturbances.
    """

    @property
    def dim(self):
        """
        :return: uncertainty dimension - int
        """
        return UncertaintyInterfaceIndex.dim

    @abstractmethod
    def convert_to_array(self) -> np.ndarray:
        """
        Converts instance of class to numpy array.
        :return: np.ndarray of dimension (self.dim,1)
        """
        pass
dim property

Returns:

Type Description

uncertainty dimension - int

convert_to_array() abstractmethod

Converts instance of class to numpy array.

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,1)

Source code in commonroad_control/simulation/uncertainty_model/uncertainty_interface.py
29
30
31
32
33
34
35
@abstractmethod
def convert_to_array(self) -> np.ndarray:
    """
    Converts instance of class to numpy array.
    :return: np.ndarray of dimension (self.dim,1)
    """
    pass

UncertaintyInterfaceIndex dataclass

Bases: ABC

Indices of the uncertainties.

Source code in commonroad_control/simulation/uncertainty_model/uncertainty_interface.py
 7
 8
 9
10
11
12
13
@dataclass(frozen=True)
class UncertaintyInterfaceIndex(ABC):
    """
    Indices of the uncertainties.
    """

    dim: int

commonroad_control.simulation.uncertainty_model.uncertainty_model_interface

UncertaintyModelInterface

Bases: ABC

Interface for uncertainty models for modeling disturbances or sensor noise. Examples include the gaussian or uniform distribution.

Source code in commonroad_control/simulation/uncertainty_model/uncertainty_model_interface.py
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
class UncertaintyModelInterface(ABC):
    """
    Interface for uncertainty models for modeling disturbances or sensor noise. Examples include the gaussian or uniform distribution.
    """

    def __init__(
        self,
        dim: int,
        nominal_value: Union[np.ndarray, List[float], UncertaintyInterface],
    ) -> None:
        """
        Initialize uncertainty model.
        :param dim: dimension of the uncertainty - int
        :param nominal_value: (optinally user-defined) nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
        """

        self._dim: int = dim

        # set nominal value
        if isinstance(nominal_value, UncertaintyInterface):
            nominal_value_np = nominal_value.convert_to_array()
        else:
            nominal_value_np: np.ndarray = np.array(nominal_value)
        self._nominal_value = nominal_value_np

    @property
    def dim(self) -> int:
        """
        :return: dimension of the uncertainty
        """
        return self._dim

    @property
    @abstractmethod
    def nominal_value(self) -> np.ndarray:
        """
        Returns the nominal value of uncertainty model (the expected value of the underlying distribution or a user-defined nominal value).
        :return: np.ndarray of dimension (self.dim,)
        """
        pass

    @abstractmethod
    def sample_uncertainty(self):
        pass
dim property

Returns:

Type Description
int

dimension of the uncertainty

nominal_value abstractmethod property

Returns the nominal value of uncertainty model (the expected value of the underlying distribution or a user-defined nominal value).

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

__init__(dim, nominal_value)

Initialize uncertainty model.

Parameters:

Name Type Description Default
dim int

dimension of the uncertainty - int

required
nominal_value Union[ndarray, List[float], UncertaintyInterface]

(optinally user-defined) nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface

required
Source code in commonroad_control/simulation/uncertainty_model/uncertainty_model_interface.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
def __init__(
    self,
    dim: int,
    nominal_value: Union[np.ndarray, List[float], UncertaintyInterface],
) -> None:
    """
    Initialize uncertainty model.
    :param dim: dimension of the uncertainty - int
    :param nominal_value: (optinally user-defined) nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
    """

    self._dim: int = dim

    # set nominal value
    if isinstance(nominal_value, UncertaintyInterface):
        nominal_value_np = nominal_value.convert_to_array()
    else:
        nominal_value_np: np.ndarray = np.array(nominal_value)
    self._nominal_value = nominal_value_np

commonroad_control.simulation.uncertainty_model.no_uncertainty

NoUncertainty

Bases: UncertaintyModelInterface

Dummy uncertainty model, e.g., if no disturbance or noise models are employed for simulation.

Source code in commonroad_control/simulation/uncertainty_model/no_uncertainty.py
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
class NoUncertainty(UncertaintyModelInterface):
    """
    Dummy uncertainty model, e.g., if no disturbance or noise models are employed for simulation.
    """

    def __init__(
        self,
        dim: int,
        *args,
        nominal_value: Union[np.ndarray, List[float], UncertaintyInterface, None] = None,
        **kwargs,
    ):
        """
        Initialize no-uncertainty model. If no user-defined nominal value is provided, the nominal value is set to zero.
        :param dim: dimension of the uncertainty - int
        :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
        """

        # if nominal_value is None, set default value
        if nominal_value is None:
            nominal_value = np.zeros(shape=(dim,))

        super().__init__(dim=dim, nominal_value=nominal_value)

    @property
    def nominal_value(self) -> np.ndarray:
        """
        Returns the nominal value of uncertainty model.
        :return: np.ndarray of dimension (self.dim,)
        """
        return self._nominal_value

    def sample_uncertainty(self) -> np.ndarray:
        """
        Since this model features no uncertainty, the nominal value is returned.
        :return:  np.ndarray of dimension (self.dim,)
        """
        return self.nominal_value
nominal_value property

Returns the nominal value of uncertainty model.

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

__init__(dim, *args, nominal_value=None, **kwargs)

Initialize no-uncertainty model. If no user-defined nominal value is provided, the nominal value is set to zero.

Parameters:

Name Type Description Default
dim int

dimension of the uncertainty - int

required
nominal_value Union[ndarray, List[float], UncertaintyInterface, None]

if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface

None
Source code in commonroad_control/simulation/uncertainty_model/no_uncertainty.py
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
def __init__(
    self,
    dim: int,
    *args,
    nominal_value: Union[np.ndarray, List[float], UncertaintyInterface, None] = None,
    **kwargs,
):
    """
    Initialize no-uncertainty model. If no user-defined nominal value is provided, the nominal value is set to zero.
    :param dim: dimension of the uncertainty - int
    :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
    """

    # if nominal_value is None, set default value
    if nominal_value is None:
        nominal_value = np.zeros(shape=(dim,))

    super().__init__(dim=dim, nominal_value=nominal_value)
sample_uncertainty()

Since this model features no uncertainty, the nominal value is returned.

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

Source code in commonroad_control/simulation/uncertainty_model/no_uncertainty.py
45
46
47
48
49
50
def sample_uncertainty(self) -> np.ndarray:
    """
    Since this model features no uncertainty, the nominal value is returned.
    :return:  np.ndarray of dimension (self.dim,)
    """
    return self.nominal_value

commonroad_control.simulation.uncertainty_model.uniform_distribution

UniformDistribution

Bases: UncertaintyModelInterface

Uncertainty model for generating uniformly distributed noise or disturbances.

Source code in commonroad_control/simulation/uncertainty_model/uniform_distribution.py
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
class UniformDistribution(UncertaintyModelInterface):
    """
    Uncertainty model for generating uniformly distributed noise or disturbances.
    """

    def __init__(
        self,
        dim: int,
        lower_bound: Union[np.ndarray, list[float], UncertaintyInterface],
        upper_bound: Union[np.ndarray, list[float], UncertaintyInterface],
        *args,
        nominal_value: Union[np.ndarray, list[float], UncertaintyInterface] = None,
        **kwargs,
    ) -> None:
        """
        Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the uniform distribution serves as the nominal value.
        :param dim: dimension of the uncertainty - int
        :param lower_bound: lower bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface
        :param upper_bound: upper bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface
        :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
        """

        # if nominal_value is None, set default value (requires bounds to be represented as arrays)
        if isinstance(lower_bound, UncertaintyInterface):
            lower_bound_np = lower_bound.convert_to_array()
        else:
            lower_bound_np: np.ndarray = np.array(lower_bound)

        if isinstance(upper_bound, UncertaintyInterface):
            upper_bound_np = upper_bound.convert_to_array()
        else:
            upper_bound_np: np.ndarray = np.array(upper_bound)
        if nominal_value is None:
            nominal_value = 0.5 * (lower_bound_np + upper_bound_np)

        super().__init__(dim=dim, nominal_value=nominal_value)

        # set bounds
        self._lower_bound: np.ndarray = lower_bound_np
        self._upper_bound: np.ndarray = upper_bound_np

        self._sanity_check()

    def _sanity_check(self) -> None:
        """
        Check args.
        """
        # check dimension
        if len(self._lower_bound) != self._dim or len(self._upper_bound) != self._dim:
            logger.error(
                f"Dimension mismatch: "
                f"expected dimension:{self._dim}, "
                f"lower bound:{len(self._lower_bound)}, upper bound:{len(self._upper_bound)}"
            )
            raise ValueError(
                f"Dimension mismatch: "
                f"expected dimension:{self._dim}, "
                f"lower bound:{len(self._lower_bound)}, upper bound:{len(self._upper_bound)}"
            )
        # check bounds (lb <= ub)
        if any(self._upper_bound < self._lower_bound):
            logger.error("Upper bound must be greater than lower bound.")
            raise ValueError("Upper bound must be greater than lower bound.")
        # check nominal value (must be between bounds)
        if any(self._nominal_value < self._lower_bound) or any(self._upper_bound < self._nominal_value):
            logger.error("Nominal value must be contained within bounds.")
            raise ValueError("Nominal value must be contained within bounds.")

    @property
    def nominal_value(self) -> np.ndarray:
        """
        Returns the nominal value, which is either the user-defined nominal value (passed as an input argument) or the mean of the uniform distribution
        :return: np.ndarray of dimension (self.dim,)
        """
        return self._nominal_value

    def sample_uncertainty(self) -> np.ndarray:
        """
        Generates a random sample from the uniform distribution.
        :return: np.ndarray of dimension (self.dim,)
        """
        return np.random.uniform(self._lower_bound, self._upper_bound)
nominal_value property

Returns the nominal value, which is either the user-defined nominal value (passed as an input argument) or the mean of the uniform distribution

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

__init__(dim, lower_bound, upper_bound, *args, nominal_value=None, **kwargs)

Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the uniform distribution serves as the nominal value.

Parameters:

Name Type Description Default
dim int

dimension of the uncertainty - int

required
lower_bound Union[ndarray, list[float], UncertaintyInterface]

lower bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface

required
upper_bound Union[ndarray, list[float], UncertaintyInterface]

upper bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface

required
nominal_value Union[ndarray, list[float], UncertaintyInterface]

if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface

None
Source code in commonroad_control/simulation/uncertainty_model/uniform_distribution.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
def __init__(
    self,
    dim: int,
    lower_bound: Union[np.ndarray, list[float], UncertaintyInterface],
    upper_bound: Union[np.ndarray, list[float], UncertaintyInterface],
    *args,
    nominal_value: Union[np.ndarray, list[float], UncertaintyInterface] = None,
    **kwargs,
) -> None:
    """
    Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the uniform distribution serves as the nominal value.
    :param dim: dimension of the uncertainty - int
    :param lower_bound: lower bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface
    :param upper_bound: upper bound of the uncertainty values - array/ list of floats/ instance of class UncertaintyInterface
    :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
    """

    # if nominal_value is None, set default value (requires bounds to be represented as arrays)
    if isinstance(lower_bound, UncertaintyInterface):
        lower_bound_np = lower_bound.convert_to_array()
    else:
        lower_bound_np: np.ndarray = np.array(lower_bound)

    if isinstance(upper_bound, UncertaintyInterface):
        upper_bound_np = upper_bound.convert_to_array()
    else:
        upper_bound_np: np.ndarray = np.array(upper_bound)
    if nominal_value is None:
        nominal_value = 0.5 * (lower_bound_np + upper_bound_np)

    super().__init__(dim=dim, nominal_value=nominal_value)

    # set bounds
    self._lower_bound: np.ndarray = lower_bound_np
    self._upper_bound: np.ndarray = upper_bound_np

    self._sanity_check()
_sanity_check()

Check args.

Source code in commonroad_control/simulation/uncertainty_model/uniform_distribution.py
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
def _sanity_check(self) -> None:
    """
    Check args.
    """
    # check dimension
    if len(self._lower_bound) != self._dim or len(self._upper_bound) != self._dim:
        logger.error(
            f"Dimension mismatch: "
            f"expected dimension:{self._dim}, "
            f"lower bound:{len(self._lower_bound)}, upper bound:{len(self._upper_bound)}"
        )
        raise ValueError(
            f"Dimension mismatch: "
            f"expected dimension:{self._dim}, "
            f"lower bound:{len(self._lower_bound)}, upper bound:{len(self._upper_bound)}"
        )
    # check bounds (lb <= ub)
    if any(self._upper_bound < self._lower_bound):
        logger.error("Upper bound must be greater than lower bound.")
        raise ValueError("Upper bound must be greater than lower bound.")
    # check nominal value (must be between bounds)
    if any(self._nominal_value < self._lower_bound) or any(self._upper_bound < self._nominal_value):
        logger.error("Nominal value must be contained within bounds.")
        raise ValueError("Nominal value must be contained within bounds.")
sample_uncertainty()

Generates a random sample from the uniform distribution.

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

Source code in commonroad_control/simulation/uncertainty_model/uniform_distribution.py
92
93
94
95
96
97
def sample_uncertainty(self) -> np.ndarray:
    """
    Generates a random sample from the uniform distribution.
    :return: np.ndarray of dimension (self.dim,)
    """
    return np.random.uniform(self._lower_bound, self._upper_bound)

commonroad_control.simulation.uncertainty_model.gaussian_distribution

GaussianDistribution

Bases: UncertaintyModelInterface

Uncertainty model for generating Gaussian noise or disturbances.

Source code in commonroad_control/simulation/uncertainty_model/gaussian_distribution.py
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
class GaussianDistribution(UncertaintyModelInterface):
    """
    Uncertainty model for generating Gaussian noise or disturbances.
    """

    def __init__(
        self,
        dim: int,
        mean: Union[np.ndarray, List[float], UncertaintyInterface],
        std_deviation: Union[np.ndarray, List[float], UncertaintyInterface],
        *args,
        nominal_value: Union[np.ndarray, List[float], UncertaintyInterface, None] = None,
        **kwargs,
    ) -> None:
        """
        Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the Gaussian distribution serves as the nominal value.
        :param dim: dimension of the uncertainty - int
        :param mean: mean value - array/ list of floats/ instance of class UncertaintyInterface
        :param std_deviation: standard deviations (component-wise) -  array/ list of floats/ instance of class UncertaintyInterface
        :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
        """

        # if nominal_value is None, set default value
        if nominal_value is None:
            nominal_value = mean

        super().__init__(dim=dim, nominal_value=nominal_value)

        if isinstance(mean, UncertaintyInterface):
            mean_np = mean.convert_to_array()
        else:
            mean_np: np.ndarray = np.array(mean)
        self._mean: np.ndarray = mean_np

        if isinstance(std_deviation, UncertaintyInterface):
            std_deviation_np = std_deviation.convert_to_array()
        else:
            std_deviation_np = np.array(std_deviation)
        self._std_deviation: np.ndarray = std_deviation_np

        self._sanity_check()

    def _sanity_check(self) -> None:
        """
        Checks args
        """
        if len(self._mean) != len(self._std_deviation) != self._dim:
            logger.error(
                f"Dimension mismatch: "
                f"expected dimension:{self._dim}, mean:{len(self._mean)}, std:{len(self._std_deviation)}"
            )
            raise ValueError(
                f"Dimension mismatch: "
                f"expected dimension:{self._dim}, mean:{len(self._mean)}, std:{len(self._std_deviation)}"
            )
        if any(self._std_deviation < 0):
            logger.error("Standard deviation must be non-negative.")
            raise ValueError("Standard deviation must be non-negative.")

    @property
    def mean(self) -> np.ndarray:
        """
        :return: mean value
        """
        return self._mean

    @property
    def std_deviations(self) -> np.ndarray:
        """ "
        :return: standard deviations per entry
        """
        return self._std_deviation

    @property
    def nominal_value(self) -> np.ndarray:
        """
        Returns the nominal value, which is either the user-defined nominal value (passed as an input argument) or the mean of the Gaussian distribution
        :return: np.ndarray of dimension (self.dim,)
        """
        return self._nominal_value

    def sample_uncertainty(self) -> np.ndarray:
        """
        Generates a random sample from the Gaussian distribution.
        :return: np.ndarray of dimension (self.dim,)
        """
        return np.random.normal(loc=self._mean, scale=self._std_deviation, size=self._dim)
mean property

Returns:

Type Description
ndarray

mean value

nominal_value property

Returns the nominal value, which is either the user-defined nominal value (passed as an input argument) or the mean of the Gaussian distribution

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

std_deviations property

"

Returns:

Type Description
ndarray

standard deviations per entry

__init__(dim, mean, std_deviation, *args, nominal_value=None, **kwargs)

Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the Gaussian distribution serves as the nominal value.

Parameters:

Name Type Description Default
dim int

dimension of the uncertainty - int

required
mean Union[ndarray, List[float], UncertaintyInterface]

mean value - array/ list of floats/ instance of class UncertaintyInterface

required
std_deviation Union[ndarray, List[float], UncertaintyInterface]

standard deviations (component-wise) - array/ list of floats/ instance of class UncertaintyInterface

required
nominal_value Union[ndarray, List[float], UncertaintyInterface, None]

if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface

None
Source code in commonroad_control/simulation/uncertainty_model/gaussian_distribution.py
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
def __init__(
    self,
    dim: int,
    mean: Union[np.ndarray, List[float], UncertaintyInterface],
    std_deviation: Union[np.ndarray, List[float], UncertaintyInterface],
    *args,
    nominal_value: Union[np.ndarray, List[float], UncertaintyInterface, None] = None,
    **kwargs,
) -> None:
    """
    Initialize uncertainty model. If no user-defined nominal value is provided, the mean of the Gaussian distribution serves as the nominal value.
    :param dim: dimension of the uncertainty - int
    :param mean: mean value - array/ list of floats/ instance of class UncertaintyInterface
    :param std_deviation: standard deviations (component-wise) -  array/ list of floats/ instance of class UncertaintyInterface
    :param nominal_value: if not None: user-defined nominal value of the uncertainty - array/ list of floats/ instance of class UncertaintyInterface
    """

    # if nominal_value is None, set default value
    if nominal_value is None:
        nominal_value = mean

    super().__init__(dim=dim, nominal_value=nominal_value)

    if isinstance(mean, UncertaintyInterface):
        mean_np = mean.convert_to_array()
    else:
        mean_np: np.ndarray = np.array(mean)
    self._mean: np.ndarray = mean_np

    if isinstance(std_deviation, UncertaintyInterface):
        std_deviation_np = std_deviation.convert_to_array()
    else:
        std_deviation_np = np.array(std_deviation)
    self._std_deviation: np.ndarray = std_deviation_np

    self._sanity_check()
_sanity_check()

Checks args

Source code in commonroad_control/simulation/uncertainty_model/gaussian_distribution.py
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
def _sanity_check(self) -> None:
    """
    Checks args
    """
    if len(self._mean) != len(self._std_deviation) != self._dim:
        logger.error(
            f"Dimension mismatch: "
            f"expected dimension:{self._dim}, mean:{len(self._mean)}, std:{len(self._std_deviation)}"
        )
        raise ValueError(
            f"Dimension mismatch: "
            f"expected dimension:{self._dim}, mean:{len(self._mean)}, std:{len(self._std_deviation)}"
        )
    if any(self._std_deviation < 0):
        logger.error("Standard deviation must be non-negative.")
        raise ValueError("Standard deviation must be non-negative.")
sample_uncertainty()

Generates a random sample from the Gaussian distribution.

Returns:

Type Description
ndarray

np.ndarray of dimension (self.dim,)

Source code in commonroad_control/simulation/uncertainty_model/gaussian_distribution.py
 97
 98
 99
100
101
102
def sample_uncertainty(self) -> np.ndarray:
    """
    Generates a random sample from the Gaussian distribution.
    :return: np.ndarray of dimension (self.dim,)
    """
    return np.random.normal(loc=self._mean, scale=self._std_deviation, size=self._dim)