API Reference

ambiegen

executors

abstract_executor

AbstractExecutor
AbstractExecutor(
    generator, results_path=None, min_fitness=0.0
)

Bases: ABC

AbstractExecutor is an abstract base class for evaluating the fitness of test scenarios.

Attributes:
  • results_path (str) –

    Path to store simulation results. If provided, the directory is created if it does not exist.

  • test_dict (dict) –

    Dictionary storing information about each executed test, including test data, fitness, info, and timestamp.

  • generator (AbstractGenerator) –

    Generator object responsible for converting genotypes to phenotypes and validating tests.

  • _name (str) –

    Name identifier for the executor.

  • min_fitness (float) –

    Minimum fitness threshold for test evaluation.

  • exec_counter (int) –

    Counter tracking the number of executed tests.

Methods:

Name Description
execute_test

Executes a test scenario, evaluates its fitness, and returns the fitness score and additional information. Handles test validity, execution timing, and error logging.

_execute

Abstract method to be implemented by subclasses, defining how a test is executed and its fitness is computed. This method should be implemented for a specific system under test.

name -> int

Property returning the name identifier of the executor.

Source code in ambiegen/executors/abstract_executor.py
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
def __init__(
    self,
    generator: AbstractGenerator,
    results_path: str = None,
    min_fitness: float = 0.0
):
    self.results_path = results_path
    self.test_dict = {}
    self.generator = generator
    self._name = "AbstractExecutor"
    self.min_fitness = min_fitness

    if results_path:
        #logger.debug("Creating folder for storing simulation results.")
        os.makedirs(results_path, exist_ok=True)

    self.exec_counter = -1  # counts how many executions have been
name property
name

Size of the phenotype.

Returns:
  • int( int ) –

    Size of the phenotype.

execute_test
execute_test(test)

Executes a given test, evaluates its fitness, and logs execution details.

Parameters:
  • test

    The test input to be executed, typically a genotype representation.

Returns:
  • Tuple[float, str]

    Tuple[float, str]: A tuple containing the fitness value (as a float) and additional information (as a string).

Notes
  • Converts the genotype to phenotype using the generator.
  • Validates the test before execution; if invalid, returns a fitness of 0.
  • If an exception occurs during execution, logs the error and updates the test info accordingly.
Source code in ambiegen/executors/abstract_executor.py
 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
def execute_test(self, test) -> Tuple[float, str]:
    """
    Executes a given test, evaluates its fitness, and logs execution details.

    Arguments:
        test: The test input to be executed, typically a genotype representation.

    Returns:
        Tuple[float, str]: A tuple containing the fitness value (as a float) and additional information (as a string).

    Notes:
        - Converts the genotype to phenotype using the generator.
        - Validates the test before execution; if invalid, returns a fitness of 0.
        - If an exception occurs during execution, logs the error and updates the test info accordingly.
    """

    self.exec_counter += 1  # counts how many executions have been

    fitness = 0

    self.test_dict[self.exec_counter] = {"test": list(test), "fitness": None, "info": None, "timestamp": time.time() }

    test = self.generator.genotype2phenotype(test)

    valid, info = self.generator.is_valid(test)
    if not valid:
        log.debug("The generated road is invalid")
        self.test_dict[self.exec_counter]["fitness"] = fitness
        self.test_dict[self.exec_counter]["info"] = info
        return float(fitness)

    try:
        start = time.time()
        fitness = self._execute(test)
        end = time.time()
        self.test_dict[self.exec_counter]["execution_time"] = end - start
        log.debug(f"Execution time: {end - start} seconds")
        self.test_dict[self.exec_counter]["fitness"] = fitness
        self.test_dict[self.exec_counter]["info"] = info

    except Exception as e:
        log.info(f"Error {e} found")
        log.info(f"Error {traceback.format_exc()} found")
        log.error("Error during execution of test.", exc_info=True)
        self.test_dict[self.exec_counter]["info"] = f"ERROR: {e}"


    return float(fitness)

ambiegen_uav_executor

AmbieGenUAVExecutor
AmbieGenUAVExecutor(generator)

Bases: AbstractExecutor

AmbieGenUAVExecutor executes UAV test scenarios using the RRT (Rapidly-exploring Random Tree) algorithm to evaluate test fitness. This executor integrates with a generator to define the environment and obstacles, runs the RRT path planning algorithm, and computes a fitness score based on the path length and simulation results. If the RRT fails to find a path or the fitness is below a threshold, it executes the test in simulation, evaluates the minimum distance to obstacles, and applies additional fitness bonuses or penalties. The outcome and metrics are logged for each execution.

Attributes:
  • n_sim_evals (int) –

    Counter for the number of simulation evaluations performed.

  • _name (str) –

    Name identifier for the executor.

  • min_fitness (int) –

    Minimum fitness threshold.

  • generator (AbstractGenerator) –

    The generator object providing environment boundaries and obstacle information.

Methods:

Name Description
_execute

Executes the test scenario using RRT, evaluates the path, and computes the fitness value.

Source code in ambiegen/executors/ambiegen_uav_executor.py
23
24
25
26
27
def __init__(self, generator: AbstractGenerator):
    super().__init__(generator)
    self.n_sim_evals = 0
    self._name = "RRTExecutor"
    self.min_fitness = 25

fake_executor

FakeExecutor
FakeExecutor(generator)

Bases: AbstractExecutor

A fake executor class for testing purposes, inheriting from AbstractExecutor. It generates a fitness value of 0 for any test executed, simulating the behavior of an executor without actual execution logic.

Attributes:
  • n_sim_evals (int) –

    Counter for the number of simulated evaluations.

Parameters:

Methods:

Name Description
_execute

Simulates the execution of a test and returns a fitness value (always 0 in this fake implementation).

Source code in ambiegen/executors/fake_executor.py
21
22
23
def __init__(self, generator:AbstractGenerator):
    super().__init__(generator)
    self.n_sim_evals = 0

obstacle_scene_executor

ObstacleSceneExecutor
ObstacleSceneExecutor(generator, min_fitness=0.0)

Bases: AbstractExecutor

Executes obstacle scene tests using a provided generator and evaluates their fitness. This executor runs UAV (Unmanned Aerial Vehicle) simulation tests, tracks their outcomes, and computes a fitness score based on the minimum distance to obstacles encountered during the test. It maintains dictionaries to store test results and statistics, such as the number of simulation evaluations and failures.

Parameters:
  • generator (AbstractGenerator) –

    The generator used to create test scenarios.

  • min_fitness (float, default: 0.0 ) –

    The minimum fitness threshold. Defaults to 0.0.

Attributes:
  • uav_test_dict (dict) –

    Stores detailed information about each UAV test execution.

  • n_sim_evals (int) –

    Counter for the number of simulation evaluations performed.

  • num_failures (int) –

    Counter for the number of failed tests.

Methods:

Name Description
_execute

Executes a single test, records its results, and returns a fitness value. The fitness is calculated as the negative inverse of the minimum distance to obstacles. Handles exceptions during test execution and logs errors.

Source code in ambiegen/executors/obstacle_scene_executor.py
26
27
28
29
30
def __init__(self, generator: AbstractGenerator, min_fitness: float = 0.0):
    super().__init__(generator, min_fitness)
    self.uav_test_dict = {}
    self.n_sim_evals = 0
    self.num_failures = 0

rrt_executor

RRTExecutor
RRTExecutor(generator, min_fitness=25.0)

Bases: AbstractExecutor

RRTExecutor executes test scenarios using the Rapidly-exploring Random Tree (RRT) algorithm to evaluate their fitness. This executor interfaces with a generator to obtain environment boundaries and obstacles, then attempts to find a path from a fixed start position to a goal using RRT. The fitness of a test scenario is determined by the length of the path found (shorter paths yield higher fitness), or zero if no path is found.

Attributes:
  • n_sim_evals (int) –

    Counter for the number of simulation evaluations performed.

  • _name (str) –

    Name identifier for the executor.

  • min_fitness (float) –

    Minimum fitness threshold for test scenarios.

  • generator

    An object providing environment boundaries and obstacle information.

  • min_fitness (float) –

    Minimum fitness threshold. Defaults to 25.0.

Methods:

Name Description
_execute

Executes the RRT algorithm on the provided test scenario and returns its fitness value.

Source code in ambiegen/executors/rrt_executor.py
23
24
25
26
27
def __init__(self, generator, min_fitness: float = 25.0):
    super().__init__(generator)
    self.n_sim_evals = 0
    self._name = "RRTExecutor"
    self.min_fitness = 25

generators

abstract_generator

AbstractGenerator
AbstractGenerator(name='AbstractGenerator')

Bases: ABC

Abstract base class for genotype-phenotype generators. This class defines the interface for generators that map between genotype and phenotype representations, provide bounds for genotypes, generate random samples, validate tests, and visualize them. Subclasses must implement all abstract properties and methods. In other words, when adding a new generator, you should implement all the abstract methods defined in this class

Attributes:
  • name (str) –

    Name identifier for the generator.

  • size (int) –

    Number of elements in the genotype representation.

  • lower_bound (List[float]) –

    Lower bounds for each element in the genotype.

  • upper_bound (List[float]) –

    Upper bounds for each element in the genotype.

Methods:

Name Description
cmp_func

List[float], test2: List[float]) -> float: Compare two tests and return -1, 0, or 1.

genotype2phenotype

List[float]) -> List[float]: Convert a genotype to its phenotype representation.

generate_random_test

Generate a random valid test (genotype).

is_valid

List[float]) -> bool: Check if a test is valid.

visualize_test

List[float], save_path: str = None): Visualize a test.

phenotype2genotype

List[float]) -> List[float]: Convert a phenotype to its genotype representation.

Initialize the generator.

Parameters:
  • name (str, default: 'AbstractGenerator' ) –

    Name identifier for the generator

  • config

    Optional configuration dictionary containing parameters

Source code in ambiegen/generators/abstract_generator.py
35
36
37
38
39
40
41
42
43
def __init__(self, name: str = "AbstractGenerator"):
    """
    Initialize the generator.

    Args:
        name: Name identifier for the generator
        config: Optional configuration dictionary containing parameters
    """
    self._name = name
lower_bound abstractmethod property
lower_bound

Lower bound of the genotype.

This is the minimum value for each element in the genotype.

Returns:
  • List[float]

    List of lower bounds for each element in the genotype

name property
name

Get the name of the generator.

Returns:
  • str

    Name of the generator

size abstractmethod property
size

Size of the genotype representation.

The genotype is the internal representation used by the optimization algorithm. This is typically a list/array of floating-point values.

Returns:
  • int

    Number of elements in the genotype

upper_bound abstractmethod property
upper_bound

Upper bound of the genotype.

This is the maximum value for each element in the genotype.

Returns:
  • List[float]

    List of upper bounds for each element in the genotype

__str__
__str__()

String representation of the generator.

Source code in ambiegen/generators/abstract_generator.py
162
163
164
def __str__(self) -> str:
    """String representation of the generator."""
    return f"{self.__class__.__name__}(name='{self.name}', genotype_size={self.genotype_size})"
cmp_func abstractmethod
cmp_func(test1, test2)

Compare two tests.

Parameters:
  • test1 (array) –

    First test to compare.

  • test2 (array) –

    Second test to compare.

Returns:
  • float( int ) –

    the degree of similarity between the two tests based on the distance function (cosine similarity by default)

Source code in ambiegen/generators/abstract_generator.py
 97
 98
 99
100
101
102
103
104
105
106
107
108
@abc.abstractmethod
def cmp_func(self, test1: typing.List[float], test2: typing.List[float]) -> int:
    """Compare two tests.

    Args:
        test1 (np.array): First test to compare.
        test2 (np.array): Second test to compare.

    Returns:
        float: the degree of similarity between the two tests based on the distance function (cosine similarity by default)
    """
    pass
generate_random_test abstractmethod
generate_random_test()

Generate samples from the generator

Returns:
  • List[float]

    np.array: Generated samples.

Source code in ambiegen/generators/abstract_generator.py
133
134
135
136
137
138
139
140
@abc.abstractmethod
def generate_random_test(self) -> (typing.List[float]):
    """Generate samples from the generator

    Returns:
        np.array: Generated samples.
    """
    pass
genotype2phenotype abstractmethod
genotype2phenotype(genotype)

Convert a genotype to a phenotype.

Parameters:
  • genotype (array) –

    Genotype to convert.

Returns:
  • List[float]

    np.array: Phenotype representation of the genotype.

Source code in ambiegen/generators/abstract_generator.py
121
122
123
124
125
126
127
128
129
130
131
@abc.abstractmethod
def genotype2phenotype(self, genotype: typing.List[float]) -> typing.List[float]:
    """Convert a genotype to a phenotype.

    Args:
        genotype (np.array): Genotype to convert.

    Returns:
        np.array: Phenotype representation of the genotype.
    """
    pass
is_valid abstractmethod
is_valid(test)

Check if a test is valid.

Parameters:
  • test (array) –

    Test to check.

Returns:
  • bool( bool ) –

    True if the test is valid, False otherwise.

Source code in ambiegen/generators/abstract_generator.py
141
142
143
144
145
146
147
148
149
150
151
@abc.abstractmethod
def is_valid(self, test: typing.List[float]) -> bool:
    """Check if a test is valid.

    Args:
        test (np.array): Test to check.

    Returns:
        bool: True if the test is valid, False otherwise.
    """
    pass
phenotype2genotype
phenotype2genotype(phenotype)

Convert a phenotype to a genotype.

Parameters:
  • phenotype (array) –

    Phenotype to convert.

Returns:
  • List[float]

    np.array: Genotype representation of the phenotype.

Source code in ambiegen/generators/abstract_generator.py
110
111
112
113
114
115
116
117
118
119
def phenotype2genotype(self, phenotype: typing.List[float]) -> typing.List[float]:
    """Convert a phenotype to a genotype.

    Args:
        phenotype (np.array): Phenotype to convert.

    Returns:
        np.array: Genotype representation of the phenotype.
    """
    pass
visualize_test abstractmethod
visualize_test(test, save_path=None)

Visualize a test.

Parameters:
  • test (array) –

    Test to visualize.

Source code in ambiegen/generators/abstract_generator.py
153
154
155
156
157
158
159
160
@abc.abstractmethod
def visualize_test(self, test: typing.List[float], save_path: str = None):
    """Visualize a test.

    Args:
        test (np.array): Test to visualize.
    """
    pass

obstacle_generator

ObstacleGenerator
ObstacleGenerator(case_study_file, max_box_num=3)

Bases: AbstractGenerator

ObstacleGenerator is a generator class for creating and manipulating obstacle configurations for drone test cases. This class provides methods to randomly generate, normalize, denormalize, and validate obstacle test cases within specified bounds. It supports conversion between phenotype (test case with obstacles) and genotype (flattened, normalized representation), as well as visualization of generated test cases.

Attributes:
  • min_size (Size) –

    Minimum allowed size for obstacles.

  • max_size (Size) –

    Maximum allowed size for obstacles.

  • min_position (Position) –

    Minimum allowed position for obstacles.

  • max_position (Position) –

    Maximum allowed position for obstacles.

  • case_study (DroneTest) –

    The drone test case loaded from a YAML file.

  • max_box_num (int) –

    Maximum number of obstacles allowed in a test case.

  • _l_b (ndarray) –

    Lower bounds for the flattened test case.

  • _u_b (ndarray) –

    Upper bounds for the flattened test case.

  • _size (int) –

    Size of the genotype vector.

  • size (int) –

    Returns the size of the genotype vector.

  • lower_bound (list) –

    Returns the lower bound for the genotype vector.

  • upper_bound (list) –

    Returns the upper bound for the genotype vector.

Methods:

Name Description
cmp_func

Computes the cosine similarity difference between two vectors.

get_bounds

Returns the lower and upper bounds for the genotype vector.

flatten_test_case

Flattens a nested test case structure into a 1D numpy array.

generate_random_test

Generates a random, valid obstacle test case and returns its genotype.

normalize_flattened_test

Normalizes a flattened test case using min and max bounds.

denormalize_flattened_test

Denormalizes a normalized test case back to original scale.

phenotype2genotype

Converts a phenotype (TestCase) to a normalized genotype vector.

genotype2phenotype

Converts a genotype vector back to a phenotype (TestCase).

resize_test

Reshapes a flattened test case into the expected structure.

is_valid

Checks if a given test case is valid (no overlaps, within bounds).

obstacles_fit

Checks if a list of obstacles fit within the defined area and do not overlap.

get_random_box_vals

Generates random values for a single obstacle's parameters.

visualize_test

Visualizes a test case and saves the plot to a file.

Initialize the generator.

Parameters:
  • config (dict) –

    Dictionary containing the configuration parameters.

Source code in ambiegen/generators/obstacle_generator.py
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
def __init__(self,  case_study_file: str, max_box_num:int=3):
    """Initialize the generator.

    Args:
        config (dict): Dictionary containing the configuration parameters.
    """
    super().__init__()
    self.min_size = Obstacle.Size(2, 2, 15)
    self.max_size = Obstacle.Size(20, 20, 25)
    self.min_position = Obstacle.Position(-40, 10, 0, 0)
    self.max_position = Obstacle.Position(30, 40, 0, 90)
    self.case_study = DroneTest.from_yaml(case_study_file)
    self.max_box_num = max_box_num
    self._l_b, self._u_b = self.get_bounds()
    self._size = self.max_box_num*6 + 1 
denormalize_flattened_test
denormalize_flattened_test(norm_test)

Use min and max values to denormalize the test case. Args: norm_test (list): Flattened normalized test case to denormalize.

Source code in ambiegen/generators/obstacle_generator.py
158
159
160
161
162
163
164
165
166
167
168
def denormalize_flattened_test(self, norm_test: typing.List[float]) -> typing.List[float]:
    '''
    Use min and max values to denormalize the test case.
    Args:
        norm_test (list): Flattened normalized test case to denormalize.
    '''
    result = norm_test*(self._u_b - self._l_b) + self._l_b
    result =  np.array(result, dtype=object)
    result[0] = int(round(result[0]))  # Ensure the first element is an integer (number of boxes)

    return result
is_valid
is_valid(test)

Check if the given test is valid.

Parameters:
  • test

    The test to be validated.

Returns:
  • tuple[bool, str]

    A tuple containing a boolean indicating the validity of the test and a string with additional information.

Source code in ambiegen/generators/obstacle_generator.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
def is_valid(self, test) -> tuple[bool, str]:
    """
    Check if the given test is valid.

    Args:
        test: The test to be validated.

    Returns:
        A tuple containing a boolean indicating the validity of the test and a string with additional information.
    """
    #log.info(f"test {test}")
    boxes  = test.test.simulation.obstacles

    valid, info  = self.obstacles_fit(boxes)

    return valid, info
normalize_flattened_test
normalize_flattened_test(test)

Use min and max values to normalize the test case. Args: test (list): Flattened test case to normalize.

Source code in ambiegen/generators/obstacle_generator.py
150
151
152
153
154
155
156
def normalize_flattened_test(self, test: typing.List[float]) -> typing.List[float]:
    '''
    Use min and max values to normalize the test case.
    Args:
        test (list): Flattened test case to normalize.'''
    result = (test - self._l_b)/(self._u_b - self._l_b)
    return result
obstacles_fit
obstacles_fit(box_list)

Check if the boxes in the given list fit within the defined bounds.

Parameters:
  • box_list (List[Obstacle]) –

    A list of boxes to be checked.

Returns:
  • tuple[bool, str]

    A tuple containing a boolean indicating if the boxes fit within the bounds and a string with additional information.

Source code in ambiegen/generators/obstacle_generator.py
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
def obstacles_fit(self, box_list: typing.List[Obstacle]) -> tuple[bool, str]:
    """
    Check if the boxes in the given list fit within the defined bounds.

    Args:
        box_list: A list of boxes to be checked.

    Returns:
        A tuple containing a boolean indicating if the boxes fit within the bounds and a string with additional information.
    """
    existing_boxes_geometry_list = [obstacle.geometry for obstacle in box_list]#[obstacle.position.x, obstacle.position.y, obstacle.position.r]

    min_pos = [self.min_position.x, self.min_position.y]
    max_pos = [self.max_position.x, self.max_position.y]

    outer_polygon = geometry.Polygon([min_pos, [min_pos[0], max_pos[1]], max_pos, [max_pos[0], min_pos[1]]])

    n = len(existing_boxes_geometry_list)

    for i in range(n):
        for j in range(i + 1, n):
            poly1 = existing_boxes_geometry_list[i]
            poly2 = existing_boxes_geometry_list[j]

            # Check if polygons intersect
            if poly1.intersects(poly2):

                return False, f"Obstacles {i} and {j} intersect."

    for inner_polygon in existing_boxes_geometry_list:
        if not(inner_polygon.within(outer_polygon)):
            return False, "Obstacle out of the defined bounds"


    return True, "Valid test"

mutation

abstract_mutation

AbstractMutation
AbstractMutation(mut_prob=0.4)

Bases: Mutation, ABC

Abstract base class for mutation operators in evolutionary algorithms. This class defines the interface and basic behavior for mutation operations, including a mutation rate and the mechanism to apply mutation to a population. Subclasses must implement the _do_mutation method to specify the mutation logic.

Attributes:
  • mut_rate (float) –

    Probability of mutating an individual (default: 0.4).

Methods:

Name Description
_do

Applies mutation to each individual in the population X with probability mut_rate.

_do_mutation

Abstract method to perform mutation on a single individual. Must be implemented by subclasses.

Args: mut_rate (float, optional): Mutation rate, probability of mutating an individual. Defaults to 0.4.

Source code in ambiegen/mutation/abstract_mutation.py
27
28
29
def __init__(self, mut_prob: float = 0.4):
    super().__init__()
    self.mut_prob = mut_prob
do_mutation abstractmethod
do_mutation(x)

Apply a mutation operation to the input array.

Parameters:
  • x

    array-like The input data to be mutated.

Returns:
  • ndarray

    np.ndarray The mutated version of the input array.

Source code in ambiegen/mutation/abstract_mutation.py
72
73
74
75
76
77
78
79
80
81
82
83
84
85
@abc.abstractmethod
def do_mutation(self, x) -> np.ndarray:
    """
    Apply a mutation operation to the input array.

    Parameters:
        x: array-like
            The input data to be mutated.

    Returns:
        np.ndarray
            The mutated version of the input array.
    """
    pass

obstacle_mutation

ObstacleMutation
ObstacleMutation(mut_prob=0.4, generator=None)

Bases: AbstractMutation

ObstacleMutation applies mutation operations to obstacle-based test configurations. This class provides mutation strategies for modifying, adding, or removing obstacles in a test configuration. It is designed to work with a generator that supplies obstacle parameters and normalization/denormalization methods for the test representation.

Parameters:
  • mut_prob (float, default: 0.4 ) –

    Probability of mutation being applied. Defaults to 0.4.

  • generator (AbstractGenerator, default: None ) –

    Generator instance for obstacle parameter generation and test normalization.

Methods:

Name Description
do_mutation

Applies a random mutation (modification, addition, or removal of an obstacle) to the input solution x. Returns the mutated solution if valid, otherwise returns the original solution.

_random_modification

Randomly modifies three parameters of a randomly selected obstacle in the test configuration.

_add_obstacle

Adds a new randomly generated obstacle to the test configuration, if the maximum number is not exceeded.

_remove_obstacle

Removes a randomly selected obstacle from the test configuration, if more than one obstacle exists.

Source code in ambiegen/mutation/obstacle_mutation.py
30
31
32
def __init__(self, mut_prob: float = 0.4, generator: AbstractGenerator = None):
    self.generator = generator # this allows to reuse mutation with differet frameworks
    super().__init__(mut_prob)
do_mutation
do_mutation(x)

Applies a random mutation to the given solution x and returns the mutated solution if it is valid. The mutation is selected randomly from the following options: - Random modification of the solution. - Addition of an obstacle. - Removal of an obstacle. If the mutated solution is not valid according to the validator, the original solution is returned. Args: x: The solution to be mutated. Returns: np.ndarray: The mutated solution if valid, otherwise the original solution.

Source code in ambiegen/mutation/obstacle_mutation.py
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
def do_mutation(self, x) -> np.ndarray:
    """
    Applies a random mutation to the given solution `x` and returns the mutated solution if it is valid.
    The mutation is selected randomly from the following options:
        - Random modification of the solution.
        - Addition of an obstacle.
        - Removal of an obstacle.
    If the mutated solution is not valid according to the validator, the original solution is returned.
    Args:
        x: The solution to be mutated.
    Returns:
        np.ndarray: The mutated solution if valid, otherwise the original solution.
    """
    if not self.generator:
        raise ValueError("Generator not set.")

    possible_mutations = [
        self._random_modification, 
        self._add_obstacle,
        self._remove_obstacle
    ]

    x = self.generator.denormalize_flattened_test(x)

    mutator = np.random.choice(possible_mutations)

    mutated_x = mutator(x)
    mutated_x = self.generator.normalize_flattened_test(mutated_x)

    return mutated_x

uniform_mutation

UniformMutation
UniformMutation(mut_prob=0.4)

Bases: AbstractMutation

UniformMutation applies uniform mutation to individuals in an evolutionary algorithm. This mutation operator randomly selects genes in the input array and replaces them with new values sampled uniformly within the allowed bounds for each gene. The probability of mutation for each gene is controlled by un_mut_rate.

Parameters:
  • mut_prob (float, default: 0.4 ) –

    The overall mutation rate for the operator. Defaults to 0.4.

Attributes:
  • un_mut_rate (float) –

    The probability of mutating each gene during uniform modification.

Methods:

Name Description
_do_mutation

Applies the mutation operator to the input array x by randomly selecting a mutation method.

_uniform_modification

Performs uniform mutation on the input array kappas, replacing each gene with a new value sampled uniformly within its bounds with probability un_mut_rate.

Source code in ambiegen/mutation/uniform_mutation.py
27
28
def __init__(self, mut_prob: float = 0.4):
    super().__init__(mut_prob)

problems

abstract_problem

AbstractProblem
AbstractProblem(
    executor_list,
    generator,
    n_var=10,
    xl=None,
    xu=None,
    name="AbstractProblem",
)

Bases: ElementwiseProblem, ABC

AbstractProblem is a base class for defining optimization problems that evaluate solutions using a set of executors and a generator.

Parameters:
  • executor_list (List[AbstractExecutor]) –

    A list of executor objects responsible for evaluating solutions.

  • generator (AbstractGenerator) –

    An object responsible for generating solutions.

  • n_var (int, default: 10 ) –

    Number of decision variables. Defaults to 10.

  • xl (optional, default: None ) –

    Lower bounds for the variables.

  • xu (optional, default: None ) –

    Upper bounds for the variables.

  • name (str, default: 'AbstractProblem' ) –

    Name of the problem. Defaults to "AbstractProblem".

Attributes:
  • executors (List[AbstractExecutor]) –

    List of executors used for evaluation.

  • generator (AbstractGenerator) –

    Generator for creating solutions.

  • _name (str) –

    Name of the problem.

  • min_fitness_list (List[float]) –

    Minimum fitness values for each executor.

Methods:

Name Description
_evaluate

Evaluates the given solution(s) using all executors and stores the results in the output dictionary.

name

Returns the name of the problem.

Source code in ambiegen/problems/abstract_problem.py
34
35
36
37
38
39
40
41
42
43
44
45
def __init__(self, executor_list: List[AbstractExecutor], generator: AbstractGenerator, n_var: int=10, xl=None, xu=None, name: str = "AbstractProblem"):
    """
    """
    self.executors = executor_list
    self.generator = generator
    self._name = name
    n_obj = len(executor_list)
    n_ieq_constr = len(executor_list)
    self.min_fitness_list = [
        executor.min_fitness for executor in self.executors]

    super().__init__(n_var=n_var, n_obj=n_obj, n_ieq_constr=n_ieq_constr, xl=xl, xu=xu)
name property
name

Size of the phenotype.

Returns:
  • int( int ) –

    Size of the phenotype.

sampling

abstract_sampling

AbstractSampling
AbstractSampling(generator)

Bases: Sampling, ABC

Abstract base class for sampling strategies using a provided generator. This the basic class to be use used for sampling strategies in the evolutionary based search.

Parameters:
  • generator (AbstractGenerator) –

    An instance of a generator used to produce random tests.

Methods:

Name Description
_do

Generates a specified number of samples using the generator.

Source code in ambiegen/sampling/abstract_sampling.py
20
21
22
def __init__(self, generator:AbstractGenerator) -> None:
    super().__init__()
    self.generator = generator

greedy_sampling

GreedySampling
GreedySampling(generator, greedy_executor)

Bases: AbstractSampling

GreedySampling implements a sampling strategy that selects the best candidate out of k randomly generated tests based on their fitness, using a greedy approach.

Parameters:
  • generator (AbstractGenerator) –

    An object capable of generating random tests and converting genotypes to phenotypes.

  • greedy_executor (AbstractExecutor) –

    An object capable of evaluating the fitness of a phenotype.

Methods:

Name Description
_do

Generates n_samples test cases by repeatedly selecting the best out of k randomly generated candidates.

_select_best_of_k

Generates k random test cases and selects the one with the best (lowest) fitness value.

Source code in ambiegen/sampling/greedy_sampling.py
20
21
22
def __init__(self, generator:AbstractGenerator, greedy_executor:AbstractExecutor) -> None:
    super().__init__(generator)
    self.executor = greedy_executor

lhs_sampling

LHSSampling
LHSSampling(generator)

Bases: Sampling, ABC

LHSSampling implements a Latin Hypercube Sampling (LHS) strategy with additional validity checking. This class generates samples using LHS and filters them through a user-provided generator's validity function. Only samples that are considered valid by the generator are retained.

Parameters:
  • generator (AbstractGenerator) –

    An instance responsible for genotype-to-phenotype conversion and validity checking.

Methods:

Name Description
_do

Generates up to n_samples valid samples for the given problem using LHS. Returns: np.ndarray: An array of valid samples.

Source code in ambiegen/sampling/lhs_sampling.py
23
24
25
def __init__(self, generator:AbstractGenerator) -> None:
    super().__init__()
    self.generator = generator

testers

abstract_bayes_opt_tester

AbstractBayesOptTester
AbstractBayesOptTester(name='bayes_opt_test_generator')

Bases: AbstractTester

AbstractBayesOptTester provides a base structure for Bayesian optimization test generators. This abstract class defines the essential methods and initialization required for implementing Bayesian optimization testers. Subclasses should implement the abstract methods to specify problem initialization and executor setup.

Attributes:
  • name (str) –

    The name of the test generator.

Methods:

Name Description
configure_algorithm

Configure the optimization algorithm. To be implemented by subclasses if needed.

initialize_parameters

Initialize parameters for the optimization process. To be implemented by subclasses if needed.

run_optimization

Run the optimization process. To be implemented by subclasses if needed.

initialize_problem

Abstract method. Initialize the optimization problem. Must be implemented by subclasses.

initialize_executor

Abstract method. Initialize the executor for running the optimization. Must be implemented by subclasses.

Source code in ambiegen/testers/abstract_bayes_opt_tester.py
31
32
def __init__(self, name="bayes_opt_test_generator"):
    self.super().__init__(name)

abstract_evolutionary_tester

AbstractEvolutionaryTester
AbstractEvolutionaryTester(
    name="evlutionary_test_generator", config_file=None
)

Bases: AbstractTester

Abstract base class for evolutionary test generators.

This class provides a structure for initializing and configuring evolutionary search algorithms used in test generation.

Parameters:
  • name (str, default: 'evlutionary_test_generator' ) –

    name of the test generator.

  • config_file (yaml | None, default: None ) –

    loaded configuration file.

Methods:

Name Description
set_up_search_algorithm

Initializes the search algorithm.

initialize_parameters

Sets up the parameters for the evolutionary algorithm.

configure_algorithm

Sets up the evolutionary algorithm

initialize_problem

Initializes the pymoo optimization problem.

run_optimization

Executes the optimization process using the configured algorithm.

initialize_test_generator

Abstract method to initialize the test generator, should be implemented specifically for the target problem.

initialize_test_executors

Abstract method to initialize the test executors, should be implemented specifically for the target problem.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
34
35
def __init__(self, name="evlutionary_test_generator", config_file=None):
    super().__init__(name, config_file)
configure_algorithm
configure_algorithm()

Configures and initializes the evolutionary algorithm with the specified crossover, mutation, and sampling strategies based on the current config file. This method also sets the DuplicateElimination strategy to remove duplicates during the optimization process. Experimentally obtained threshold should be used, 0.025 by default.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
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
def configure_algorithm(self):
    """
    Configures and initializes the evolutionary algorithm with the specified crossover, mutation,
    and sampling strategies based on the current config file.
    This method also sets the DuplicateElimination strategy to remove duplicates
    during the optimization process. Experimentally obtained threshold should be used, 0.025 by default.
    """
    cross_prob = self.config["search_based"]["crossover_prob"]
    mut_prob = self.config["search_based"]["mutation_prob"]
    if self.crossover == "sbx":
        crossover = CROSSOVERS[self.crossover](prob_var=cross_prob, eta=3.0, vtype=float) # crossover defined by pymoo
    else:
        crossover = CROSSOVERS[self.crossover](cross_prob=cross_prob)
    if self.mutation == "pm":
        mutation = MUTATIONS[self.mutation](prob=mut_prob, eta=3.0, vtype=float) # mutation defined by pymoo
    else:
        mutation = MUTATIONS[self.mutation](mut_prob=mut_prob)

    self.method = ALGORITHMS[self.alg](
        pop_size=self.pop_size,
        n_offsprings=int(round(self.pop_size / 2)),
        sampling=SAMPLERS[self.sampling](self.generator),
        n_points_per_iteration=int(round(self.pop_size / 2)),
        crossover=crossover,
        mutation=mutation,
        eliminate_duplicates=AbstractDuplicateElimination(
            generator=self.generator, threshold=0.025
        ),
    )
initialize_parameters
initialize_parameters()

Initializes the parameters required for the test generation process. This method sets up the random seed, population size, algorithm, sampling method, crossover, and mutation strategy based on the provided configuration. If a seed is not specified in the configuration, a random seed is generated.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
def initialize_parameters(self):
    """
    Initializes the parameters required for the test generation process.
    This method sets up the random seed, population size, algorithm, sampling method,
    crossover, and mutation strategy based on the provided configuration. If a seed is
    not specified in the configuration, a random seed is generated.
    """
    log.info("Starting test generation, initializing parameters")

    if self.config["common"]["seed"] != "None":
        self.seed = self.config["common"]["seed"]
        log.info(f"Using provided seed: {self.seed}")
    else:
        log.info("No seed provided, generating a random seed")
        # Generate a random seed if not provided in the config
        self.seed = get_random_seed()
    self.pop_size = self.config["search_based"]["pop_size"]
    log.info(f"Population size: {self.pop_size}")
    self.alg = self.config["search_based"]["algorithm"]
    self.sampling = "abstract"
    self.crossover = self.config["search_based"]["crossover"]
    self.mutation = self.config["search_based"]["mutation"]
initialize_problem
initialize_problem()

Initializes the pymoo optimization problem by creating an instance of AbstractProblem.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
101
102
103
104
105
106
107
108
109
110
111
def initialize_problem(self):
    """
    Initializes the pymoo optimization problem by creating an instance of AbstractProblem.
    """
    self.problem = AbstractProblem(
        self.executors,
        self.generator, 
        n_var=self.generator.size, # number of variables in the genotype
        xl=self.generator.lower_bound,
        xu=self.generator.upper_bound
    )
initialize_test_executors abstractmethod
initialize_test_executors()

To be implemented specifically for your problem.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
139
140
141
142
143
@abc.abstractmethod
def initialize_test_executors(self):
    """
    To be implemented specifically for your problem."""
    pass
initialize_test_generator abstractmethod
initialize_test_generator()

To be implemented specifically for your problem.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
132
133
134
135
136
@abc.abstractmethod
def initialize_test_generator(self):
    '''
    To be implemented specifically for your problem.'''
    pass
run_optimization
run_optimization()

This method initializes and executes the optimization algorithm with the provided settings, including termination criteria, random seed, verbosity, duplicate elimination, and history saving. The optimization result is stored in the self.res attribute.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
def run_optimization(self):
    """
    This method initializes and executes the optimization algorithm with the provided settings,
    including termination criteria, random seed, verbosity, duplicate elimination, and history saving.
    The optimization result is stored in the `self.res` attribute.
    """
    self.res = minimize(
        self.problem,
        self.method,
        termination=get_termination(
            self.config["common"]["termination"], self.config["common"]["budget"]
        ),
        seed=self.seed,
        verbose=True,
        eliminate_duplicates=True,
        save_history=True,
    )
    return self.res
set_up_search_algorithm
set_up_search_algorithm()

Sets up the search algorithm by initializing parameters, configuring the algorithm, and initializing the problem.

Source code in ambiegen/testers/abstract_evolutionary_tester.py
37
38
39
40
41
42
43
44
def set_up_search_algorithm(self):
    """
    Sets up the search algorithm by initializing parameters, configuring the algorithm,
    and initializing the problem. 
    """
    self.initialize_parameters()
    self.configure_algorithm()
    self.initialize_problem()

abstract_evolutionary_tester_ask_tell

AbstractEvolutionaryTesterAskTell
AbstractEvolutionaryTesterAskTell(
    name="evlutionary_test_generator", config_file=None
)

Bases: AbstractEvolutionaryTester

Abstract base class for evolutionary test generators.

This class provides a structure for initializing and configuring evolutionary search algorithms used in test generation.

Parameters:
  • name (str, default: 'evlutionary_test_generator' ) –

    name of the test generator.

  • config_file (yaml | None, default: None ) –

    loaded configuration file.

Methods:

Name Description
set_up_search_algorithm

Initializes the search algorithm.

initialize_parameters

Sets up the parameters for the evolutionary algorithm.

configure_algorithm

Sets up the evolutionary algorithm

initialize_problem

Initializes the pymoo optimization problem.

run_optimization

Executes the optimization process using the configured algorithm.

initialize_test_generator

Abstract method to initialize the test generator, should be implemented specifically for the target problem.

initialize_test_executors

Abstract method to initialize the test executors, should be implemented specifically for the target problem.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
38
39
40
41
42
def __init__(self, name="evlutionary_test_generator", config_file=None):
    super().__init__(name, config_file)

    self.exec_counter = 0
    self.test_dict = {}
ask
ask()

Generates and returns a new population of candidate solutions using the underlying evolutionary method.

Returns:
  • list( List ) –

    A list representing the new population of candidate solutions.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
87
88
89
90
91
92
93
94
95
96
def ask(self) -> List:
    """
    Generates and returns a new population of candidate solutions using the underlying evolutionary method.

    Returns:
        list: A list representing the new population of candidate solutions.
    """
    pop = self.method.ask()

    return pop
initialize_test_executors
initialize_test_executors()

To be implemented specifically for your problem.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
129
130
131
132
def initialize_test_executors(self):
    """
    To be implemented specifically for your problem."""
    pass
initialize_test_generator abstractmethod
initialize_test_generator()

To be implemented specifically for your problem.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
121
122
123
124
125
@abc.abstractmethod
def initialize_test_generator(self):
    '''
    To be implemented specifically for your problem.'''
    pass
set_up_search_algorithm
set_up_search_algorithm()

Sets up the search algorithm by initializing parameters, configuring the algorithm, and initializing the problem.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
def set_up_search_algorithm(self):
    """
    Sets up the search algorithm by initializing parameters, configuring the algorithm,
    and initializing the problem. 
    """
    self.initialize_parameters()
    self.configure_algorithm()
    self.initialize_problem()
    termination  = get_termination(
            self.config["common"]["termination"], self.config["common"]["budget"]
        )
    self.method.setup(self.problem, termination=termination, verbose=True, eliminate_duplicates=True, save_history=True)
    np.random.seed(self.seed)
    self.current_individual = self.pop_size
    self.ind_num = self.pop_size
    self.pop = None
tell
tell(population)

Provides the test results back to the tester.

Source code in ambiegen/testers/abstract_evolutionary_tester_ask_tell.py
 98
 99
100
def tell(self, population: List):
    """Provides the test results back to the tester."""
    self.method.tell(population)

abstract_fuzzing_tester

AbstractFuzzingTester
AbstractFuzzingTester(name='fuzzing_test_generator')

Bases: AbstractTester

Abstract base class for fuzzing testers, extending AbstractTester. This class provides a template for implementing fuzzing-based testing strategies. It defines the structure for configuring algorithms, initializing parameters, and running optimization routines. Subclasses must implement the abstract methods for initializing executors and test generators.

Args:

name (str): The name of the fuzzing tester instance. Defaults to "fuzzing_test_generator".

Methods:

Name Description
configure_algorithm

Configure the fuzzing algorithm. To be implemented by subclasses if needed.

initialize_parameters

Initialize parameters required for fuzzing. To be implemented by subclasses if needed.

run_optimization

Run the optimization process for fuzzing. To be implemented by subclasses if needed.

initialize_executors

Abstract method. Initialize the executors responsible for running tests. Must be implemented by subclasses.

initialize_test_generator

Abstract method. Initialize the test generator for producing test cases. Must be implemented by subclasses.

Source code in ambiegen/testers/abstract_fuzzing_tester.py
35
36
def __init__(self, name="fuzzing_test_generator"):
    self.super().__init__(name)

abstract_tester

AbstractTester
AbstractTester(
    name="abstract_test_generator", config_file=None
)

Bases: ABC

Abstract base class for test generation and execution workflows. This class defines the interface for creating test generators, executors, and search algorithms, as well as running optimization processes for automated testing. Subclasses must implement the abstract methods to provide concrete functionality for initializing test generators, executors, search algorithms, and running the optimization process.

Parameters:
  • _name (str) –

    Name of the test generator instance.

  • config (Any) –

    Configuration file or object for the test generator.

Methods:

Name Description
initialize_test_generator

Main purpose of this method is to generate random tests. Must be implemented by subclasses.

initialize_test_executors

This method should launch and evalute the target system or function. Must be implemented by subclasses.

set_up_search_algorithm

Abstract method to set up the search algorithm. Must be implemented by subclasses.

run_optimization

Abstract method to run the optimization process. Must be implemented by subclasses.

start

Orchestrates the initialization and execution of the test generation and optimization process by calling the respective methods in sequence.

Source code in ambiegen/testers/abstract_tester.py
35
36
37
def __init__(self, name="abstract_test_generator", config_file:dict=None):
    self._name = name
    self.config = config_file
get_results
get_results()

Retrieves the results of the test generation and optimization process. To be used with ask and tell interface.

Source code in ambiegen/testers/abstract_tester.py
106
107
108
109
110
def get_results(self):
    """
    Retrieves the results of the test generation and optimization process. To be used with ask and tell interface.
    """
    return self.test_dict, self.method.result()
initialize
initialize()

Initializes the tester by setting up the necessary components. To be used with ask and tell interface.

Source code in ambiegen/testers/abstract_tester.py
 97
 98
 99
100
101
102
103
def initialize(self):
    """
    Initializes the tester by setting up the necessary components. To be used with ask and tell interface.
    """
    self.initialize_test_generator()
    self.initialize_test_executors()
    self.set_up_search_algorithm()
initialize_test_executors abstractmethod
initialize_test_executors()

Initializes the test executor. This method should be implemented specifically for your problem. It should launch and evaluate the target system or function.

Source code in ambiegen/testers/abstract_tester.py
55
56
57
58
59
60
61
62
@abc.abstractmethod
def initialize_test_executors(self) -> AbstractExecutor:
    """
    Initializes the test executor. This method should be implemented
    specifically for your problem. It should launch and evaluate the target
    system or function. 
    """
    pass
initialize_test_generator abstractmethod
initialize_test_generator()

Initializes the test generator. This method should be implemented specifically for your your problem. It should generate random tests, check their validity, do conversion between genotype and phenotype representations. For more details, refer to the AbstractGenerator class.

Raises:
  • NotImplementedError

    If the method is not overridden by a subclass.

Source code in ambiegen/testers/abstract_tester.py
40
41
42
43
44
45
46
47
48
49
50
51
52
@abc.abstractmethod
def initialize_test_generator(self) -> AbstractGenerator:
    """
    Initializes the test generator. 
    This method should be implemented specifically for your your problem.
    It should generate random tests, check their validity, do conversion 
    between genotype and phenotype representations. For more details,
    refer to the ```AbstractGenerator``` class.

    Raises:
        NotImplementedError: If the method is not overridden by a subclass.
    """
    pass
run_optimization abstractmethod
run_optimization()

Runs the optimization process to generate test cases.

This method should be implemented by subclasses to execute the optimization algorithm.

Source code in ambiegen/testers/abstract_tester.py
73
74
75
76
77
78
79
80
@abc.abstractmethod
def run_optimization(self):
    """
    Runs the optimization process to generate test cases.

    This method should be implemented by subclasses to execute the optimization algorithm.
    """
    pass
set_up_search_algorithm abstractmethod
set_up_search_algorithm()

Initializes or configures the search algorithm to be used in the testing process.

This method should be implemented by subclasses.

Source code in ambiegen/testers/abstract_tester.py
64
65
66
67
68
69
70
71
@abc.abstractmethod
def set_up_search_algorithm(self):
    """
    Initializes or configures the search algorithm to be used in the testing process.

    This method should be implemented by subclasses.
    """
    pass
start
start()

Function to start the test generation and optimization process. To be used when evaluation happens within the optimization process.

Returns:
  • tuple

    A tuple containing the test results (self.res) and the test executor (self.executor).

Source code in ambiegen/testers/abstract_tester.py
82
83
84
85
86
87
88
89
90
91
92
93
94
def start(self):
    """
    Function to start the test generation and optimization process. To be used when evaluation happens within the optimization process.

    Returns:
        tuple: A tuple containing the test results (`self.res`) and the test executor (`self.executor`).
    """

    self.initialize_test_generator()
    self.initialize_test_executors()
    self.set_up_search_algorithm()
    self.run_optimization()
    return self.executors[0].test_dict, self.res

uav_tester

UAVTester
UAVTester(config_file=None)

Bases: AbstractEvolutionaryTester

UAVTester is a specialized tester class for generating and executing UAV (Unmanned Aerial Vehicle) test datasets using obstacle scenes.

Attributes:
  • generator (ObstacleGenerator) –

    Instance responsible for generating obstacle scenes based on a specified case study.

  • executors (list) –

    List of test executors, for evaluating the test.

Methods:

Name Description
initialize_test_generator

Sets up the obstacle scene generator using a predefined case study and a maximum number of obstacles.

initialize_test_executors

Initializes the test executors for the UAV test generator, specifically using RRTExecutor.

Source code in ambiegen/testers/uav_tester.py
26
27
28
def __init__(self, config_file=None):
    name  = "uav_test_generator"
    super().__init__(name, config_file)
initialize_test_executors
initialize_test_executors()

Initializes the executor for the UAV test generator. The number of executors in the list corresponds to the number of search objectives. Minimum fitness is set to 25.0, which is the minimum path length for the RRT algorithm to identify to count the test as challenging

Source code in ambiegen/testers/uav_tester.py
42
43
44
45
46
47
48
def initialize_test_executors(self):
    """Initializes the executor for the UAV test generator.
    The number of executors in the list corresponds to the number of search objectives.
    Minimum fitness is set to 25.0, which is the minimum path length for the RRT algorithm to identify to count the test as challenging"""

    #self.executor = ObstacleSceneExecutor(self.generator)
    self.executors = [RRTExecutor(self.generator, min_fitness=25.0)]
initialize_test_generator
initialize_test_generator()

Initializes the test generator for UAV testing. This method sets up an ObstacleGenerator instance.

Source code in ambiegen/testers/uav_tester.py
30
31
32
33
34
35
36
37
38
39
40
def initialize_test_generator(self):
    """
    Initializes the test generator for UAV testing.
    This method sets up an ```ObstacleGenerator``` instance. 
    """

    case_study = "case_studies/mission1.yaml"
    self.generator = ObstacleGenerator(
        case_study_file=case_study,
        max_box_num=3,
    )