Source code for swarmsim.Loggers.shepherding_logger

from swarmsim.Loggers import BaseLogger
from swarmsim.Utils import add_entry, get_done_shepherding, xi_shepherding


[docs] class ShepherdingLogger(BaseLogger): """ Specialized logger for shepherding simulations with task-specific metrics. This logger extends the BaseLogger to capture and analyze shepherding-specific metrics such as target capture rates, completion status, and task progression. It monitors the effectiveness of shepherding algorithms by tracking how many targets are successfully guided to goal regions. The logger computes the shepherding metric xi (ξ), which represents the fraction of targets successfully captured, and monitors task completion to enable early termination when all targets reach the goal region. Parameters ---------- populations : list of Population List of population objects in the shepherding simulation. Typically includes target agents (index 0) and optionally shepherd agents. environment : Environment Shepherding environment object containing goal regions and spatial boundaries. Must support shepherding-specific geometric calculations. config_path : str Path to the YAML configuration file containing logger parameters. Attributes ---------- populations : list of Population Population objects being monitored, inherited from BaseLogger. First population (index 0) is typically the target agents. environment : Environment Shepherding environment with goal regions, inherited from BaseLogger. xi : float Current shepherding metric (fraction of captured targets). Range: [0.0, 1.0] where 1.0 indicates all targets captured. done : bool Task completion flag indicating whether all targets are captured. current_info : dict Current timestep information including shepherding metrics. global_info : dict Accumulated simulation data across all timesteps. Config Requirements ------------------- The YAML configuration file must contain logger parameters under the class section: ShepherdingLogger : dict Configuration section for the shepherding logger: - ``activate`` : bool, optional Enable/disable logging. Default: ``True`` - ``log_freq`` : int, optional Print frequency (0 = never). Default: ``0`` - ``save_freq`` : int, optional Save frequency (0 = never). Default: ``1`` - ``save_data_freq`` : int, optional Data save frequency. Default: ``0`` - ``save_global_data_freq`` : int, optional Global data save frequency. Default: ``0`` - ``log_path`` : str, optional Output directory path. Default: ``"./logs"`` - ``log_name`` : str, optional Log file name suffix. Default: ``""`` - ``comment_enable`` : bool, optional Enable experiment comments. Default: ``False`` Notes ----- **Shepherding Metrics:** The logger computes several task-specific metrics: - **Xi (ξ)**: Fraction of targets successfully captured in goal region - **Task Completion**: Boolean flag indicating complete task success - **Temporal Progression**: Evolution of capture rate over time **Early Termination:** The logger can trigger early simulation termination when all targets are successfully shepherded to the goal region, improving computational efficiency for successful trials. **Integration with Shepherding Utils:** Uses specialized utility functions: - ``xi_shepherding()``: Computes capture fraction metric - ``get_done_shepherding()``: Determines task completion status Examples -------- **Basic Configuration:** .. code-block:: yaml ShepherdingLogger: activate: true log_freq: 10 save_freq: 1 log_path: "./shepherding_logs" log_name: "shepherding_experiment" """ def __init__(self, populations: list, environment: object, config_path: str) -> None: super().__init__(populations, environment, config_path) self.xi = 0
[docs] def log(self, data: dict = None) -> bool: """ A function that defines the information to log. Parameters ---------- data: dict composed of {name_variabile: value} to log Returns ------- done: bool flag to truncate a simulation early. Default value=False. Notes ------- In the configuration file (a yaml file) there should be a namespace with the name of the log you are creating. By default, it does not truncate episode early. See add_data from Utils/logger_utils.py to quickly add variables to log. """ if self.activate: # Get metrics self.xi = self.get_xi() self.done = self.get_event() super().log(data) return self.done
[docs] def log_internal_data(self, save_mode=['print', 'txt']): super().log_internal_data(save_mode) add_entry(self.current_info, save_mode, xi=self.xi)
[docs] def get_xi(self) -> float: """ Get metric for shepherding xi, i.e., fraction of captured targets. Returns ------- float: fraction of captured targets """ return xi_shepherding(self.populations[0], self.environment)
[docs] def get_event(self) -> bool: """ Verify if every target is inside the goal region Returns ------- bool: true is every target is inside the goal region, false otherwise """ return get_done_shepherding(self.populations[0], self.environment)