Target Location Uncertainty

This tutorial demonstrates how to model uncertainty in target locations when imaging ground targets using a simple single-satellite BSK-RL environment. It also shows how target location uncertainty can grow over time when a target is not imaged.

Loading Modules

[1]:
from collections.abc import Iterable
from typing import Any, ClassVar, Union

import numpy as np
from Basilisk.architecture import bskLogging
from Basilisk.utilities import macros, orbitalMotion
from scipy.stats import norm

from bsk_rl import act, obs, sats
from bsk_rl.data.unique_image_data import UniqueImageData, UniqueImageReward
from bsk_rl.gym import SatelliteTasking
from bsk_rl.scene.targets import UniformTargets
from bsk_rl.sim import dyn, fsw
from bsk_rl.sim.fsw import action
from bsk_rl.utils.orbital import random_orbit

bskLogging.setDefaultLogLevel(bskLogging.BSK_WARNING)

Making a Scenario with Location Uncertain Targets

To account for location uncertainty in the simulation process, the following parameters are assigned to each target using UniformTargets as a base:

  • search_area represents a square region on the surface within which the estimated location is the center of the area.

  • acquiring_speed represents the apparent ground-track speed, sampled uniformly to reflect orbital geometry and latitude effects.

  • scan_width represents the fixed width of the imaging swath of the satellite.

  • search_duration represents the total imaging duration, proportional to the number of sensor swaths required to cover the area.

  • image_time represents the true imaging time within the duration window, drawn from a Gaussian distribution centered at the mid-point of \(T_i\) (\(\mu_i\)) with standard deviation \(0.3T_i\) (\(\sigma_i\)), truncated to nonnegative values. Approximately (4.8%) of samples occur after the window ends.

  • speed represents the target’s ground speed, sampled uniformly to reflect typical ship speeds and fixed for each target.

[2]:
class AreaTargets(UniformTargets):
    def regenerate_targets(self) -> None:
        super().regenerate_targets()
        for target in self.targets:
            side_length = np.random.uniform(10.0, 100.0) * 1e3  # m
            target.search_area = side_length**2  # m^2
            target.acquiring_speed = np.random.uniform(3.0, 6.0) * 1e3  # m/s
            scan_width = 20.0 * 1e3  # m
            search_duration = (
                side_length * np.ceil(side_length / scan_width) / target.acquiring_speed
            )
            target.search_duration = search_duration  # s

            mean_duration = search_duration / 2.0
            std_duration = search_duration * 0.3
            image_time = np.random.normal(loc=mean_duration, scale=std_duration)
            image_time = max(0.0, image_time)
            target.image_time = image_time  # s

            target.speed = np.random.uniform(22e3 / 3600, 46e3 / 3600)  # m/s

Making a Reward Function That Accounts for Target Uncertainty

When targets have location uncertainty, imaging the highest-priority target is not always the optimal choice. If a target is not imaged for some time, its uncertainty grows, which can reduce future imaging effectiveness. Therefore, the reward function should balance target priority and uncertainty. One approach is to multiply the target priority by its scaled uncertainty. Alternative reward formulations are explored in a forthcoming publication. The UncertainMultiplyReward is built on the UniqueImageReward base class and defines the reward function as

\[\begin{split}R(s, a, s') = \begin{cases} p_n \cdot \tilde{u}_n, & \text{if } a = a_{\text{image}, n} \text{ and } t_{\text{search}} = t_n^{\ast} \\ 0, & \text{otherwise} \end{cases}\end{split}\]

where \(p_n\) is the target priority, \(\tilde{u}_n\) is the scaled target uncertainty, \(t{\text{search}}\) is the time spent searching for the target, \(t_n^{\ast}\) is the true imaging duration, and \(a_{\text{image}, n}\) denotes the imaging action for the selected target \(n\). The scaled uncertainty \(\tilde{u}_n\) is calculated by normalizing the target’s search area by the maximum possible search area at the end of a three-orbit simulation (U_NORM²). The tunable parameter U_SCALE controls the relative contribution of normalized uncertainty to the reward. Unlike UniqueImageReward, this class removes the imaging list filter, allowing the same target to be imaged multiple times.

[3]:
from typing import TYPE_CHECKING

if TYPE_CHECKING:  # pragma: no cover
    from bsk_rl.sats import Satellite
    from bsk_rl.scene.targets import Target

ALTITUDE = 800  # altitude in km
T_ORBIT = (  # one orbital period in seconds
    2
    * np.pi
    * np.sqrt((orbitalMotion.REQ_EARTH + ALTITUDE) ** 3 / orbitalMotion.MU_EARTH)
)
U_NORM = (
    100.0 * 1e3 + 46e3 / 3600 * T_ORBIT * 3
)  # max search area in meters, for normalization
U_SCALE = 0.1  # scale factor for uncertainty reward


def _uncertainty(target: "Target") -> float:
    return target.search_area / (U_NORM**2)


def scaled_clipped_uncertainty(target: "Target", scale: float = 1.0) -> float:
    if scale <= 0.0:
        raise ValueError("reward_uncertainty_scale must be positive")
    return min(_uncertainty(target) / scale, 1.0)


class UncertainMultiplyReward(UniqueImageReward):
    def create_data_store(self, satellite: "Satellite") -> None:
        """Create a data store for a satellite.

        Args:
            satellite: Satellite to create a data store for.
        """
        satellite.data_store = self.data_store_type(
            satellite,
            initial_data=self.initial_data(satellite),
            **self.data_store_kwargs,
        )
        self.cum_reward[satellite.name] = 0.0

    def calculate_reward(
        self, new_data_dict: dict[str, UniqueImageData]
    ) -> dict[str, float]:
        """Reward images of targets based on their priority and current uncertainty.

        Targets may be imaged multiple times; each image earns reward based on
        ``self.reward_fn(target.priority * scaled_uncertainty)``, with the reward
        shared among all simultaneous images of the same target.

        Args:
            new_data_dict: Record of new images for each satellite

        Returns:
            reward: Cumulative reward across satellites for one step
        """
        reward = {}
        imaged_counts = {}
        for new_data in new_data_dict.values():
            for target in new_data.imaged:
                if target not in imaged_counts:
                    imaged_counts[target] = 0
                imaged_counts[target] += 1

        for sat_id, new_data in new_data_dict.items():
            reward[sat_id] = 0.0
            for target in new_data.imaged:
                uncertainty = scaled_clipped_uncertainty(target, scale=U_SCALE)
                reward[sat_id] += (
                    self.reward_fn(target.priority * uncertainty)
                    / imaged_counts[target]
                )
        return reward

Configuring the Satellite to Have Access to Target Uncertainty Information

The satellite has observations and actions associated with it that are relevant to the decision-making process. The observation space can be modified to include information about the targets and the uncertainty which allows better informed decision-making.

  • Observations:

    • SatProperties: Body angular velocity, instrument pointing direction, body position, and body velocity in dynamics model.

    • OpportunityProperties: Target priority, pointing error, pointing rate error, time until the target observation window opens and closes, scaled uncertainty, completion probability, and expected reward for each of the next 32 targets. The completion probability is calculated based on the available observation window duration and slew time, representing the probability of completing the search over the entire search area. The slew time is estimated using a regression model developed from simulation data.

    • Density: Upcoming target request density.

  • Actions:

    • RetaskImage: An extension of act.Image that allows the satellite to image the same target consecutively while selecting from the next 32 targets.

  • Dynamics model: FullFeaturedDynModel is used.

  • Flight software model: SteeringImagerFSWModel used as the base model and modified for duration-based imaging.

[4]:
class Density(obs.Observation):
    def __init__(
        self,
        interval_duration=60 * 3,
        intervals=10,
        norm=3,
    ):
        self.satellite: sats.ImagingSatellite
        super().__init__()
        self.interval_duration = interval_duration
        self.intervals = intervals
        self.norm = norm

    def get_obs(self):
        if self.intervals == 0:
            return []

        self.satellite.calculate_additional_windows(
            self.simulator.sim_time
            + (self.intervals + 1) * self.interval_duration
            - self.satellite.window_calculation_time
        )
        soonest = self.satellite.upcoming_opportunities_dict(types="target")
        rewards = np.array([opportunity.priority for opportunity in soonest])
        times = np.array([opportunities[0][1] for opportunities in soonest.values()])
        time_bins = np.floor((times - self.simulator.sim_time) / self.interval_duration)
        densities = [sum(rewards[time_bins == i]) for i in range(self.intervals)]
        return np.array(densities) / self.norm


def target_angle(sat_r_BN_P, sat_c_hat_P, opp_r_LP_P):
    vector_target_spacecraft_P = opp_r_LP_P - sat_r_BN_P
    vector_target_spacecraft_P_hat = vector_target_spacecraft_P / np.linalg.norm(
        vector_target_spacecraft_P
    )
    return np.arccos(np.dot(vector_target_spacecraft_P_hat, sat_c_hat_P))


def target_angle_rate(sat_r_BN_P, sat_v_BN_P, sat_omega_BP_P, opp_r_LP_P):
    r_BN_P = sat_r_BN_P
    v_BN_P = sat_v_BN_P
    r_LP_P = opp_r_LP_P
    omega_BP_P = sat_omega_BP_P
    omega_CP_ref = (
        omega_BP_P
        - np.cross(v_BN_P, r_LP_P - r_BN_P) / np.linalg.norm(r_LP_P - r_BN_P) ** 2
    )
    return np.linalg.norm(omega_CP_ref)


def regression_model(
    tgt_angle,
    tgt_angle_rate,
    x_0=0.4320,
    x_1=101.1396,
    x_2=641.8838,
    x_3=-45.9458,
    x_4=-7681.1881,
    x_5=-610.2113,
):
    slew_time = (
        x_0
        + x_1 * tgt_angle
        + x_2 * tgt_angle_rate
        + x_3 * tgt_angle**2
        + x_4 * tgt_angle_rate**2
        + x_5 * tgt_angle * tgt_angle_rate
    )
    return np.clip(slew_time, 1e-3, None)


def completion_probability(t_now, t_open, t_close, slew_time, search_duration):
    t_start = max(t_now + slew_time, t_open)
    t_avail = t_close - t_start

    if t_avail <= 0:
        return 0.0

    if search_duration <= 0:
        return 1.0

    mu = search_duration / 2.0
    sigma = max(search_duration * 0.3, 1e-6)

    return float(np.clip(norm.cdf(t_avail, loc=mu, scale=sigma), 0.0, 1.0))


def opportunity_completion_probability(sat, opp):
    target = opp["object"]
    r_LP_P = target.r_LP_P
    tgt_angle = target_angle(sat.dynamics.r_BN_P, sat.fsw.c_hat_P, r_LP_P)
    tgt_angle_rate = target_angle_rate(
        sat.dynamics.r_BN_P,
        sat.dynamics.v_BN_P,
        sat.dynamics.omega_BP_P,
        r_LP_P,
    )
    slew_time = regression_model(tgt_angle, tgt_angle_rate)

    t_open, t_close = opp["window"]
    return completion_probability(
        sat.simulator.sim_time, t_open, t_close, slew_time, target.search_duration
    )


def reward_value(target: "Target", scale: float = 1.0) -> float:
    """Calculate the reward value for a target.

    Args:
        target: Target to calculate reward for.
        scale: Scale factor for uncertainty reward.

    Returns:
        The reward value for the target.
    """
    return target.priority * scaled_clipped_uncertainty(target, scale=scale)


class RetaskImage(act.Image):
    """Image action that always reissues the task, even for same target consecutively."""

    def image(
        self,
        target: Union[int, "Target", str],
        prev_action_key: str | None = None,
        max_duration: float | None = None,
    ) -> str:
        target = self.satellite.parse_target_selection(target)
        self.satellite.task_target_for_imaging(target, max_duration=max_duration)
        return target.id


class CustomFswModel(fsw.SteeringImagerFSWModel):
    @action
    def action_image(
        self,
        r_LP_P: Iterable[float],
        data_name: str,
        acquisitionTime: float,
        allowedTime: float,
    ) -> None:
        """Attempt to image a target at a location.

        This action sets the target attitude to one tracking a ground location. If the
        target is within the imaging constraints for the specified time, an image will be taken and stored in
        the data buffer. The instrument power sink will be active as long as the task is
        enabled.

        Args:
            r_LP_P: [m] Planet-fixed planet relative target location.
            data_name: Data buffer to store image data to.
            acquisitionTime: [s] Time required to acquire the image.
            allowedTime: [s] Maximum time allowed to attempt to acquire the image.
        """
        self.insControl.controllerStatus = 1
        self.dynamics.instrumentPowerSink.powerStatus = 1
        self.dynamics.imagingTarget.r_LP_P_Init = r_LP_P
        self.dynamics.instrument.nodeDataName = data_name
        self.insControl.imaged = 0
        self.insControl.useDurationImaging = True
        self.insControl.acquisitionTime = macros.sec2nano(acquisitionTime)
        self.insControl.allowedTime = macros.sec2nano(allowedTime)
        self.simulator.enableTask(self.LocPointTask.name + self.satellite.name)


class CustomSatComposed(sats.ImagingSatellite):
    observation_spec: ClassVar[list[obs.Observation]] = [
        obs.SatProperties(
            dict(prop="omega_BN_B", norm=0.03),
            dict(prop="c_hat_H"),
            dict(prop="r_BN_P", norm=orbitalMotion.REQ_EARTH * 1e3),
            dict(prop="v_BN_P", norm=7616.5),
        ),
        Density(intervals=20, norm=5),
        obs.OpportunityProperties(
            dict(prop="priority"),
            dict(prop="r_LB_H", norm=orbitalMotion.REQ_EARTH * 1e3),
            dict(prop="target_angle", norm=np.pi / 2),
            dict(prop="target_angle_rate", norm=0.03),
            dict(prop="opportunity_open", norm=300.0),
            dict(prop="opportunity_close", norm=300.0),
            dict(
                prop="search_area",
                fn=lambda sat, opp: opp["object"].search_area,
                norm=(U_SCALE * (U_NORM) ** 2),
            ),
            dict(prop="completion_probability", fn=opportunity_completion_probability),
            dict(
                prop="reward_value",
                fn=lambda sat, opp: reward_value(opp["object"], scale=U_SCALE),
            ),
            type="target",
            n_ahead_observe=32,
        ),
    ]

    action_spec: ClassVar[list[act.Action]] = [
        RetaskImage(n_ahead_image=32),
    ]

    dyn_type = dyn.FullFeaturedDynModel
    fsw_type = CustomFswModel

    def task_target_for_imaging(
        self, target: "Target", max_duration: float | None = None
    ):
        """Task the satellite to image a target.

        Args:
            target: Selected target
            max_duration: [s] Maximum duration to wait for imaging. If None, wait until
                the end of the target's access window.
        """
        msg = f"{target} tasked for imaging, image_time: {target.image_time:.1f}, duration: {target.search_duration:.1f}"
        self.logger.info(msg)
        self.fsw.action_image(
            target.r_LP_P, self.buffer_name, target.image_time, target.search_duration
        )  # times in seconds
        self.enable_target_window(target, max_duration=max_duration)
        self.draw_imaging_line(target)
        self.latest_target = target

When instantiating a satellite, these parameters can be overriden with a constant or rerandomized every time the environment is reset using the sat_args dictionary.

[5]:
dataStorageCapacity = (
    20 * 8e6 * 100
)  # Large storage to avoid filling up in three orbits
batteryStorageCapacity = (
    1000.0 * 3600 * 2
)  # Large storage to avoid battery running out in three orbits

sat_args = CustomSatComposed.default_sat_args(
    oe=lambda: random_orbit(
        alt=ALTITUDE,  # 800 km altitude
        i=45,  # 45 degrees inclination
    ),
    imageAttErrorRequirement=0.01,
    imageRateErrorRequirement=0.01,
    batteryStorageCapacity=batteryStorageCapacity,
    storedCharge_Init=lambda: np.random.uniform(0.4, 1.0) * batteryStorageCapacity,
    u_max=0.4,
    K1=0.25,
    K3=3.0,
    servo_P=150 / 5,
    nHat_B=np.array([0, 0, -1]),
    omega_max=np.radians(5.0),  # Maximum rate command in degrees per second
    imageTargetMinimumElevation=np.arctan(800 / 500),  # 58 degrees minimum elevation
    rwBasePower=20,
    maxWheelSpeed=1500,
    storageInit=lambda: np.random.randint(
        0 * dataStorageCapacity,
        0.01 * dataStorageCapacity,
    ),  # Initialize storage use close to zero
    wheelSpeeds=lambda: np.random.uniform(
        -1, 1, 3
    ),  # Initialize reaction wheel speeds close to zero
    dataStorageCapacity=dataStorageCapacity,
)

Making Target Uncertainty Growing Environment

To model the growth of target location uncertainty over time, SatelliteUncertaintyTargets extends SatelliteTasking and overrides its step() method. The search-region side length grows according to the elapsed simulation time and the target’s speed, which is assigned in AreaTargets:

\[s_{\mathrm{new}} = \sqrt{A_{\mathrm{old}}} + v\Delta t, \qquad A_{\mathrm{new}} = s_{\mathrm{new}}^2.\]

Here, \(A_{\mathrm{old}}\) and \(A_{\mathrm{new}}\) are the old and updated search areas in m², \(s_{\mathrm{new}}\) is the updated side length in meters, \(v\) is the target’s speed in m/s, and \(\Delta t\) is the elapsed simulation time in seconds, returned as info["d_ts"].

The update order and modeling assumptions are:

  • The parent step() computes the reward before uncertainty is updated, using the target uncertainty available at the start of the step.

  • After every step, search areas and search durations are updated, and acquisition times (image_time) are sampled again for all known targets.

  • If imaging succeeds, the selected target’s search area, search duration, and acquisition time are then reset to zero at the step’s end. The returned observation is recomputed after these updates.

  • This implementation models growing uncertainty around fixed target coordinates. The target speed controls uncertainty growth; it does not move the target coordinates.

[6]:
class SatelliteUncertaintyTargets(SatelliteTasking):
    def step(self, action) -> tuple[Any, float, bool, bool, dict[str, Any]]:
        """Take a single-satellite action, run parent step, and update target uncertainties."""
        sat = self.satellites[0]
        target_selected = sat.parse_target_selection(action)
        old_stored_data = np.array(
            sat.dynamics.storageUnit.storageUnitDataOutMsg.read().storedData,
            dtype=float,
        )
        obs, reward, terminated, truncated, info = super().step(action)
        d_ts = info["d_ts"]
        new_stored_data = np.array(
            sat.dynamics.storageUnit.storageUnitDataOutMsg.read().storedData,
            dtype=float,
        )
        imaged_this_step = np.any(new_stored_data - old_stored_data > 0.0)

        targets = sat.data_store.data.known
        area_factor = 20e3  # scan width in meters (20 km)

        # Compute all new values in vectorized form
        search_areas = np.array([t.search_area for t in targets])
        side_lengths = np.sqrt(search_areas)
        acquiring_speeds = np.array([t.acquiring_speed for t in targets])
        speeds = np.array([t.speed for t in targets])

        new_side_lengths = side_lengths + speeds * d_ts
        new_search_areas = new_side_lengths**2
        new_search_durations = (
            new_side_lengths
            * np.ceil(new_side_lengths / area_factor)
            / acquiring_speeds
        )

        means = new_search_durations / 2.0
        stds = new_search_durations * 0.3
        new_image_times = np.maximum(0.0, np.random.normal(loc=means, scale=stds))

        # Update the target information
        for t, area, dur, time in zip(
            targets, new_search_areas, new_search_durations, new_image_times
        ):
            t.search_area = area
            t.search_duration = dur
            t.image_time = time

        # Reset the imaged target's uncertainty
        if imaged_this_step:
            target_selected.search_area = 0.0
            target_selected.search_duration = 0.0
            target_selected.image_time = 0.0

        sat.observation_builder.obs_dict_cache = None
        obs = sat.get_obs()

        return obs, reward, terminated, truncated, info

Initializing and Interacting with the Environment

For this example, the custom environment created above is used along with passing the satellite that is configured, the environment takes a scenario, which defines the environment the satellite is acting in, and a rewarder, which defines how data collected from the scenario is rewarded. The filter is added to prevent the satellite from reimaging recently observed targets with small search areas.

[7]:
threshold = (10e3) ** 2  # threshold for search area in m^2, (10 km)^2


def search_area_filter(opportunity, threshold=threshold):
    if opportunity["type"] == "target":
        return opportunity["object"].search_area > threshold
    return True


satellite = CustomSatComposed("EO", sat_args)
satellite.add_access_filter(search_area_filter, types="target")
n_targets = (1000, 10000)

env = SatelliteUncertaintyTargets(
    satellite=satellite,
    scenario=AreaTargets(n_targets=n_targets),
    rewarder=UncertainMultiplyReward(),
    sim_rate=0.5,
    max_step_duration=T_ORBIT,  # Duration long enough to prevent interruption of the imaging action
    time_limit=T_ORBIT * 3,  # three orbits
    log_level="INFO",
    failure_penalty=0.0,
)

First, reset the environment. It is possible to specify the seed when resetting the environment.

[8]:
observation, info = env.reset(seed=1)
2026-11-09 20:10:18,440 gym                            INFO       Resetting environment with seed=1
2026-11-09 20:10:18,441 utils.orbital                  WARNING    Ignoring a, e, and omega and using alt and r_body to generate a circular orbit.random_circular_orbit is preferred for this use case.
2026-11-09 20:10:18,442 scene.targets                  INFO       Generating 3877 targets
2026-11-09 20:10:18,515 sats.satellite.EO              INFO       <0.00> EO: Finding opportunity windows from 0.00 to 18600.00 seconds
2026-11-09 20:10:19,083 gym                            INFO       <0.00> Environment reset

It is possible to print out the actions and observations. The composed satellite action_description returns a human-readable action map. Each satellite has the same action space and similar observation space.

[9]:
print("Actions:", env.satellites[0].action_description, "\n")
print("States:", env.satellites[0].observation_description, "\n")

# Using the composed satellite features also provides a human-readable state:
for satellite in env.satellites:
    for k, v in satellite.observation_builder.obs_dict().items():
        print(f"{k}:  {v}")
Actions: ['action_image_0', 'action_image_1', 'action_image_2', 'action_image_3', 'action_image_4', 'action_image_5', 'action_image_6', 'action_image_7', 'action_image_8', 'action_image_9', 'action_image_10', 'action_image_11', 'action_image_12', 'action_image_13', 'action_image_14', 'action_image_15', 'action_image_16', 'action_image_17', 'action_image_18', 'action_image_19', 'action_image_20', 'action_image_21', 'action_image_22', 'action_image_23', 'action_image_24', 'action_image_25', 'action_image_26', 'action_image_27', 'action_image_28', 'action_image_29', 'action_image_30', 'action_image_31']

States: [np.str_('sat_props.omega_BN_B_normd[0]'), np.str_('sat_props.omega_BN_B_normd[1]'), np.str_('sat_props.omega_BN_B_normd[2]'), np.str_('sat_props.c_hat_H[0]'), np.str_('sat_props.c_hat_H[1]'), np.str_('sat_props.c_hat_H[2]'), np.str_('sat_props.r_BN_P_normd[0]'), np.str_('sat_props.r_BN_P_normd[1]'), np.str_('sat_props.r_BN_P_normd[2]'), np.str_('sat_props.v_BN_P_normd[0]'), np.str_('sat_props.v_BN_P_normd[1]'), np.str_('sat_props.v_BN_P_normd[2]'), np.str_('obs[0]'), np.str_('obs[1]'), np.str_('obs[2]'), np.str_('obs[3]'), np.str_('obs[4]'), np.str_('obs[5]'), np.str_('obs[6]'), np.str_('obs[7]'), np.str_('obs[8]'), np.str_('obs[9]'), np.str_('obs[10]'), np.str_('obs[11]'), np.str_('obs[12]'), np.str_('obs[13]'), np.str_('obs[14]'), np.str_('obs[15]'), np.str_('obs[16]'), np.str_('obs[17]'), np.str_('obs[18]'), np.str_('obs[19]'), np.str_('target.target_0.priority'), np.str_('target.target_0.r_LB_H_normd[0]'), np.str_('target.target_0.r_LB_H_normd[1]'), np.str_('target.target_0.r_LB_H_normd[2]'), np.str_('target.target_0.target_angle_normd'), np.str_('target.target_0.target_angle_rate_normd'), np.str_('target.target_0.opportunity_open_normd'), np.str_('target.target_0.opportunity_close_normd'), np.str_('target.target_0.search_area_normd'), np.str_('target.target_0.completion_probability'), np.str_('target.target_0.reward_value'), np.str_('target.target_1.priority'), np.str_('target.target_1.r_LB_H_normd[0]'), np.str_('target.target_1.r_LB_H_normd[1]'), np.str_('target.target_1.r_LB_H_normd[2]'), np.str_('target.target_1.target_angle_normd'), np.str_('target.target_1.target_angle_rate_normd'), np.str_('target.target_1.opportunity_open_normd'), np.str_('target.target_1.opportunity_close_normd'), np.str_('target.target_1.search_area_normd'), np.str_('target.target_1.completion_probability'), np.str_('target.target_1.reward_value'), np.str_('target.target_2.priority'), np.str_('target.target_2.r_LB_H_normd[0]'), np.str_('target.target_2.r_LB_H_normd[1]'), np.str_('target.target_2.r_LB_H_normd[2]'), np.str_('target.target_2.target_angle_normd'), np.str_('target.target_2.target_angle_rate_normd'), np.str_('target.target_2.opportunity_open_normd'), np.str_('target.target_2.opportunity_close_normd'), np.str_('target.target_2.search_area_normd'), np.str_('target.target_2.completion_probability'), np.str_('target.target_2.reward_value'), np.str_('target.target_3.priority'), np.str_('target.target_3.r_LB_H_normd[0]'), np.str_('target.target_3.r_LB_H_normd[1]'), np.str_('target.target_3.r_LB_H_normd[2]'), np.str_('target.target_3.target_angle_normd'), np.str_('target.target_3.target_angle_rate_normd'), np.str_('target.target_3.opportunity_open_normd'), np.str_('target.target_3.opportunity_close_normd'), np.str_('target.target_3.search_area_normd'), np.str_('target.target_3.completion_probability'), np.str_('target.target_3.reward_value'), np.str_('target.target_4.priority'), np.str_('target.target_4.r_LB_H_normd[0]'), np.str_('target.target_4.r_LB_H_normd[1]'), np.str_('target.target_4.r_LB_H_normd[2]'), np.str_('target.target_4.target_angle_normd'), np.str_('target.target_4.target_angle_rate_normd'), np.str_('target.target_4.opportunity_open_normd'), np.str_('target.target_4.opportunity_close_normd'), np.str_('target.target_4.search_area_normd'), np.str_('target.target_4.completion_probability'), np.str_('target.target_4.reward_value'), np.str_('target.target_5.priority'), np.str_('target.target_5.r_LB_H_normd[0]'), np.str_('target.target_5.r_LB_H_normd[1]'), np.str_('target.target_5.r_LB_H_normd[2]'), np.str_('target.target_5.target_angle_normd'), np.str_('target.target_5.target_angle_rate_normd'), np.str_('target.target_5.opportunity_open_normd'), np.str_('target.target_5.opportunity_close_normd'), np.str_('target.target_5.search_area_normd'), np.str_('target.target_5.completion_probability'), np.str_('target.target_5.reward_value'), np.str_('target.target_6.priority'), np.str_('target.target_6.r_LB_H_normd[0]'), np.str_('target.target_6.r_LB_H_normd[1]'), np.str_('target.target_6.r_LB_H_normd[2]'), np.str_('target.target_6.target_angle_normd'), np.str_('target.target_6.target_angle_rate_normd'), np.str_('target.target_6.opportunity_open_normd'), np.str_('target.target_6.opportunity_close_normd'), np.str_('target.target_6.search_area_normd'), np.str_('target.target_6.completion_probability'), np.str_('target.target_6.reward_value'), np.str_('target.target_7.priority'), np.str_('target.target_7.r_LB_H_normd[0]'), np.str_('target.target_7.r_LB_H_normd[1]'), np.str_('target.target_7.r_LB_H_normd[2]'), np.str_('target.target_7.target_angle_normd'), np.str_('target.target_7.target_angle_rate_normd'), np.str_('target.target_7.opportunity_open_normd'), np.str_('target.target_7.opportunity_close_normd'), np.str_('target.target_7.search_area_normd'), np.str_('target.target_7.completion_probability'), np.str_('target.target_7.reward_value'), np.str_('target.target_8.priority'), np.str_('target.target_8.r_LB_H_normd[0]'), np.str_('target.target_8.r_LB_H_normd[1]'), np.str_('target.target_8.r_LB_H_normd[2]'), np.str_('target.target_8.target_angle_normd'), np.str_('target.target_8.target_angle_rate_normd'), np.str_('target.target_8.opportunity_open_normd'), np.str_('target.target_8.opportunity_close_normd'), np.str_('target.target_8.search_area_normd'), np.str_('target.target_8.completion_probability'), np.str_('target.target_8.reward_value'), np.str_('target.target_9.priority'), np.str_('target.target_9.r_LB_H_normd[0]'), np.str_('target.target_9.r_LB_H_normd[1]'), np.str_('target.target_9.r_LB_H_normd[2]'), np.str_('target.target_9.target_angle_normd'), np.str_('target.target_9.target_angle_rate_normd'), np.str_('target.target_9.opportunity_open_normd'), np.str_('target.target_9.opportunity_close_normd'), np.str_('target.target_9.search_area_normd'), np.str_('target.target_9.completion_probability'), np.str_('target.target_9.reward_value'), np.str_('target.target_10.priority'), np.str_('target.target_10.r_LB_H_normd[0]'), np.str_('target.target_10.r_LB_H_normd[1]'), np.str_('target.target_10.r_LB_H_normd[2]'), np.str_('target.target_10.target_angle_normd'), np.str_('target.target_10.target_angle_rate_normd'), np.str_('target.target_10.opportunity_open_normd'), np.str_('target.target_10.opportunity_close_normd'), np.str_('target.target_10.search_area_normd'), np.str_('target.target_10.completion_probability'), np.str_('target.target_10.reward_value'), np.str_('target.target_11.priority'), np.str_('target.target_11.r_LB_H_normd[0]'), np.str_('target.target_11.r_LB_H_normd[1]'), np.str_('target.target_11.r_LB_H_normd[2]'), np.str_('target.target_11.target_angle_normd'), np.str_('target.target_11.target_angle_rate_normd'), np.str_('target.target_11.opportunity_open_normd'), np.str_('target.target_11.opportunity_close_normd'), np.str_('target.target_11.search_area_normd'), np.str_('target.target_11.completion_probability'), np.str_('target.target_11.reward_value'), np.str_('target.target_12.priority'), np.str_('target.target_12.r_LB_H_normd[0]'), np.str_('target.target_12.r_LB_H_normd[1]'), np.str_('target.target_12.r_LB_H_normd[2]'), np.str_('target.target_12.target_angle_normd'), np.str_('target.target_12.target_angle_rate_normd'), np.str_('target.target_12.opportunity_open_normd'), np.str_('target.target_12.opportunity_close_normd'), np.str_('target.target_12.search_area_normd'), np.str_('target.target_12.completion_probability'), np.str_('target.target_12.reward_value'), np.str_('target.target_13.priority'), np.str_('target.target_13.r_LB_H_normd[0]'), np.str_('target.target_13.r_LB_H_normd[1]'), np.str_('target.target_13.r_LB_H_normd[2]'), np.str_('target.target_13.target_angle_normd'), np.str_('target.target_13.target_angle_rate_normd'), np.str_('target.target_13.opportunity_open_normd'), np.str_('target.target_13.opportunity_close_normd'), np.str_('target.target_13.search_area_normd'), np.str_('target.target_13.completion_probability'), np.str_('target.target_13.reward_value'), np.str_('target.target_14.priority'), np.str_('target.target_14.r_LB_H_normd[0]'), np.str_('target.target_14.r_LB_H_normd[1]'), np.str_('target.target_14.r_LB_H_normd[2]'), np.str_('target.target_14.target_angle_normd'), np.str_('target.target_14.target_angle_rate_normd'), np.str_('target.target_14.opportunity_open_normd'), np.str_('target.target_14.opportunity_close_normd'), np.str_('target.target_14.search_area_normd'), np.str_('target.target_14.completion_probability'), np.str_('target.target_14.reward_value'), np.str_('target.target_15.priority'), np.str_('target.target_15.r_LB_H_normd[0]'), np.str_('target.target_15.r_LB_H_normd[1]'), np.str_('target.target_15.r_LB_H_normd[2]'), np.str_('target.target_15.target_angle_normd'), np.str_('target.target_15.target_angle_rate_normd'), np.str_('target.target_15.opportunity_open_normd'), np.str_('target.target_15.opportunity_close_normd'), np.str_('target.target_15.search_area_normd'), np.str_('target.target_15.completion_probability'), np.str_('target.target_15.reward_value'), np.str_('target.target_16.priority'), np.str_('target.target_16.r_LB_H_normd[0]'), np.str_('target.target_16.r_LB_H_normd[1]'), np.str_('target.target_16.r_LB_H_normd[2]'), np.str_('target.target_16.target_angle_normd'), np.str_('target.target_16.target_angle_rate_normd'), np.str_('target.target_16.opportunity_open_normd'), np.str_('target.target_16.opportunity_close_normd'), np.str_('target.target_16.search_area_normd'), np.str_('target.target_16.completion_probability'), np.str_('target.target_16.reward_value'), np.str_('target.target_17.priority'), np.str_('target.target_17.r_LB_H_normd[0]'), np.str_('target.target_17.r_LB_H_normd[1]'), np.str_('target.target_17.r_LB_H_normd[2]'), np.str_('target.target_17.target_angle_normd'), np.str_('target.target_17.target_angle_rate_normd'), np.str_('target.target_17.opportunity_open_normd'), np.str_('target.target_17.opportunity_close_normd'), np.str_('target.target_17.search_area_normd'), np.str_('target.target_17.completion_probability'), np.str_('target.target_17.reward_value'), np.str_('target.target_18.priority'), np.str_('target.target_18.r_LB_H_normd[0]'), np.str_('target.target_18.r_LB_H_normd[1]'), np.str_('target.target_18.r_LB_H_normd[2]'), np.str_('target.target_18.target_angle_normd'), np.str_('target.target_18.target_angle_rate_normd'), np.str_('target.target_18.opportunity_open_normd'), np.str_('target.target_18.opportunity_close_normd'), np.str_('target.target_18.search_area_normd'), np.str_('target.target_18.completion_probability'), np.str_('target.target_18.reward_value'), np.str_('target.target_19.priority'), np.str_('target.target_19.r_LB_H_normd[0]'), np.str_('target.target_19.r_LB_H_normd[1]'), np.str_('target.target_19.r_LB_H_normd[2]'), np.str_('target.target_19.target_angle_normd'), np.str_('target.target_19.target_angle_rate_normd'), np.str_('target.target_19.opportunity_open_normd'), np.str_('target.target_19.opportunity_close_normd'), np.str_('target.target_19.search_area_normd'), np.str_('target.target_19.completion_probability'), np.str_('target.target_19.reward_value'), np.str_('target.target_20.priority'), np.str_('target.target_20.r_LB_H_normd[0]'), np.str_('target.target_20.r_LB_H_normd[1]'), np.str_('target.target_20.r_LB_H_normd[2]'), np.str_('target.target_20.target_angle_normd'), np.str_('target.target_20.target_angle_rate_normd'), np.str_('target.target_20.opportunity_open_normd'), np.str_('target.target_20.opportunity_close_normd'), np.str_('target.target_20.search_area_normd'), np.str_('target.target_20.completion_probability'), np.str_('target.target_20.reward_value'), np.str_('target.target_21.priority'), np.str_('target.target_21.r_LB_H_normd[0]'), np.str_('target.target_21.r_LB_H_normd[1]'), np.str_('target.target_21.r_LB_H_normd[2]'), np.str_('target.target_21.target_angle_normd'), np.str_('target.target_21.target_angle_rate_normd'), np.str_('target.target_21.opportunity_open_normd'), np.str_('target.target_21.opportunity_close_normd'), np.str_('target.target_21.search_area_normd'), np.str_('target.target_21.completion_probability'), np.str_('target.target_21.reward_value'), np.str_('target.target_22.priority'), np.str_('target.target_22.r_LB_H_normd[0]'), np.str_('target.target_22.r_LB_H_normd[1]'), np.str_('target.target_22.r_LB_H_normd[2]'), np.str_('target.target_22.target_angle_normd'), np.str_('target.target_22.target_angle_rate_normd'), np.str_('target.target_22.opportunity_open_normd'), np.str_('target.target_22.opportunity_close_normd'), np.str_('target.target_22.search_area_normd'), np.str_('target.target_22.completion_probability'), np.str_('target.target_22.reward_value'), np.str_('target.target_23.priority'), np.str_('target.target_23.r_LB_H_normd[0]'), np.str_('target.target_23.r_LB_H_normd[1]'), np.str_('target.target_23.r_LB_H_normd[2]'), np.str_('target.target_23.target_angle_normd'), np.str_('target.target_23.target_angle_rate_normd'), np.str_('target.target_23.opportunity_open_normd'), np.str_('target.target_23.opportunity_close_normd'), np.str_('target.target_23.search_area_normd'), np.str_('target.target_23.completion_probability'), np.str_('target.target_23.reward_value'), np.str_('target.target_24.priority'), np.str_('target.target_24.r_LB_H_normd[0]'), np.str_('target.target_24.r_LB_H_normd[1]'), np.str_('target.target_24.r_LB_H_normd[2]'), np.str_('target.target_24.target_angle_normd'), np.str_('target.target_24.target_angle_rate_normd'), np.str_('target.target_24.opportunity_open_normd'), np.str_('target.target_24.opportunity_close_normd'), np.str_('target.target_24.search_area_normd'), np.str_('target.target_24.completion_probability'), np.str_('target.target_24.reward_value'), np.str_('target.target_25.priority'), np.str_('target.target_25.r_LB_H_normd[0]'), np.str_('target.target_25.r_LB_H_normd[1]'), np.str_('target.target_25.r_LB_H_normd[2]'), np.str_('target.target_25.target_angle_normd'), np.str_('target.target_25.target_angle_rate_normd'), np.str_('target.target_25.opportunity_open_normd'), np.str_('target.target_25.opportunity_close_normd'), np.str_('target.target_25.search_area_normd'), np.str_('target.target_25.completion_probability'), np.str_('target.target_25.reward_value'), np.str_('target.target_26.priority'), np.str_('target.target_26.r_LB_H_normd[0]'), np.str_('target.target_26.r_LB_H_normd[1]'), np.str_('target.target_26.r_LB_H_normd[2]'), np.str_('target.target_26.target_angle_normd'), np.str_('target.target_26.target_angle_rate_normd'), np.str_('target.target_26.opportunity_open_normd'), np.str_('target.target_26.opportunity_close_normd'), np.str_('target.target_26.search_area_normd'), np.str_('target.target_26.completion_probability'), np.str_('target.target_26.reward_value'), np.str_('target.target_27.priority'), np.str_('target.target_27.r_LB_H_normd[0]'), np.str_('target.target_27.r_LB_H_normd[1]'), np.str_('target.target_27.r_LB_H_normd[2]'), np.str_('target.target_27.target_angle_normd'), np.str_('target.target_27.target_angle_rate_normd'), np.str_('target.target_27.opportunity_open_normd'), np.str_('target.target_27.opportunity_close_normd'), np.str_('target.target_27.search_area_normd'), np.str_('target.target_27.completion_probability'), np.str_('target.target_27.reward_value'), np.str_('target.target_28.priority'), np.str_('target.target_28.r_LB_H_normd[0]'), np.str_('target.target_28.r_LB_H_normd[1]'), np.str_('target.target_28.r_LB_H_normd[2]'), np.str_('target.target_28.target_angle_normd'), np.str_('target.target_28.target_angle_rate_normd'), np.str_('target.target_28.opportunity_open_normd'), np.str_('target.target_28.opportunity_close_normd'), np.str_('target.target_28.search_area_normd'), np.str_('target.target_28.completion_probability'), np.str_('target.target_28.reward_value'), np.str_('target.target_29.priority'), np.str_('target.target_29.r_LB_H_normd[0]'), np.str_('target.target_29.r_LB_H_normd[1]'), np.str_('target.target_29.r_LB_H_normd[2]'), np.str_('target.target_29.target_angle_normd'), np.str_('target.target_29.target_angle_rate_normd'), np.str_('target.target_29.opportunity_open_normd'), np.str_('target.target_29.opportunity_close_normd'), np.str_('target.target_29.search_area_normd'), np.str_('target.target_29.completion_probability'), np.str_('target.target_29.reward_value'), np.str_('target.target_30.priority'), np.str_('target.target_30.r_LB_H_normd[0]'), np.str_('target.target_30.r_LB_H_normd[1]'), np.str_('target.target_30.r_LB_H_normd[2]'), np.str_('target.target_30.target_angle_normd'), np.str_('target.target_30.target_angle_rate_normd'), np.str_('target.target_30.opportunity_open_normd'), np.str_('target.target_30.opportunity_close_normd'), np.str_('target.target_30.search_area_normd'), np.str_('target.target_30.completion_probability'), np.str_('target.target_30.reward_value'), np.str_('target.target_31.priority'), np.str_('target.target_31.r_LB_H_normd[0]'), np.str_('target.target_31.r_LB_H_normd[1]'), np.str_('target.target_31.r_LB_H_normd[2]'), np.str_('target.target_31.target_angle_normd'), np.str_('target.target_31.target_angle_rate_normd'), np.str_('target.target_31.opportunity_open_normd'), np.str_('target.target_31.opportunity_close_normd'), np.str_('target.target_31.search_area_normd'), np.str_('target.target_31.completion_probability'), np.str_('target.target_31.reward_value')]

sat_props:  {'omega_BN_B_normd': array([ 0.00039127, -0.00239742, -0.00201266]), 'c_hat_H': array([-0.2553377 ,  0.34990175, -0.9013165 ]), 'r_BN_P_normd': array([ 0.27191488,  1.07952161, -0.15737657]), 'v_BN_P_normd': array([-0.58813816,  0.24710869,  0.67885361])}
obs:  [0.61613927 0.52590797 2.16525901 0.84111303 0.70704488 0.83069407
 0.91375432 0.46379506 1.23694842 0.1910646  0.55170474 0.96481464
 0.48085697 1.00094104 0.71199144 0.4284978  0.64232104 0.54620285
 1.24573418 0.85733118]
target:  {'target_0': {'priority': 0.5445075098554931, 'r_LB_H_normd': array([-0.12525147, -0.04207573, -0.0106086 ]), 'target_angle_normd': np.float64(0.8702928943366102), 'target_angle_rate_normd': np.float64(0.2654801533004988), 'opportunity_open_normd': np.float64(0.0), 'opportunity_close_normd': 0.08292947797901506, 'search_area_normd': np.float64(0.17639652161471076), 'completion_probability': 0.0, 'reward_value': np.float64(0.09604923073159681)}, 'target_1': {'priority': 0.1743742544301099, 'r_LB_H_normd': array([-0.12687985,  0.02258776,  0.06799816]), 'target_angle_normd': np.float64(1.0920125103542035), 'target_angle_rate_normd': np.float64(0.25057490589949355), 'opportunity_open_normd': 0.05040150384906402, 'opportunity_close_normd': 0.12564440578888758, 'search_area_normd': np.float64(0.574724155400884), 'completion_probability': 0.05861574859372087, 'reward_value': np.float64(0.10021709610100375)}, 'target_2': {'priority': 0.8850502421115217, 'r_LB_H_normd': array([-0.12851329,  0.07535018, -0.05207806]), 'target_angle_normd': np.float64(0.5305065959934344), 'target_angle_rate_normd': np.float64(0.20935374320771646), 'opportunity_open_normd': 0.11630077879695944, 'opportunity_close_normd': 0.37349055952818844, 'search_area_normd': np.float64(0.08269659424977034), 'completion_probability': 1.0, 'reward_value': np.float64(0.07319064076255752)}, 'target_3': {'priority': 0.38654071304501314, 'r_LB_H_normd': array([-0.12653241,  0.06289488, -0.02202203]), 'target_angle_normd': np.float64(0.6529037875000084), 'target_angle_rate_normd': np.float64(0.23455553442861315), 'opportunity_open_normd': np.float64(0.0), 'opportunity_close_normd': 0.4195773091508891, 'search_area_normd': np.float64(0.8403338408271099), 'completion_probability': 0.8456131848647674, 'reward_value': np.float64(0.3248232420291656)}, 'target_4': {'priority': 0.160400046327681, 'r_LB_H_normd': array([-0.12764433,  0.08121301, -0.00792819]), 'target_angle_normd': np.float64(0.7029376802932563), 'target_angle_rate_normd': np.float64(0.20772431686181247), 'opportunity_open_normd': 0.04768998270130857, 'opportunity_close_normd': 0.4965381588157784, 'search_area_normd': np.float64(0.8611054900374627), 'completion_probability': 0.7618806413964454, 'reward_value': np.float64(0.1381213604950295)}, 'target_5': {'priority': 0.9298235710096753, 'r_LB_H_normd': array([-0.13543875,  0.13300598,  0.06666277]), 'target_angle_normd': np.float64(0.9333107180048382), 'target_angle_rate_normd': np.float64(0.13589782408990939), 'opportunity_open_normd': 0.3535850480275377, 'opportunity_close_normd': 0.5695479314365876, 'search_area_normd': np.float64(0.21868930943349174), 'completion_probability': 0.9992861572814374, 'reward_value': np.float64(0.20334247463908917)}, 'target_6': {'priority': 0.19784830164759393, 'r_LB_H_normd': array([-0.14121145,  0.18307192,  0.00166498]), 'target_angle_normd': np.float64(0.7194885667331962), 'target_angle_rate_normd': np.float64(0.09871126021705368), 'opportunity_open_normd': 0.3931102732016974, 'opportunity_close_normd': 0.8461226548600663, 'search_area_normd': np.float64(0.800433237910146), 'completion_probability': 0.9987296842489407, 'reward_value': np.float64(0.15836435670280688)}, 'target_7': {'priority': 0.1386156538744331, 'r_LB_H_normd': array([-0.14421676,  0.1950004 ,  0.03732206]), 'target_angle_normd': np.float64(0.8120042994585247), 'target_angle_rate_normd': np.float64(0.09086432448805874), 'opportunity_open_normd': 0.45808051363667013, 'opportunity_close_normd': 0.8763201591907565, 'search_area_normd': np.float64(0.6172485827797024), 'completion_probability': 0.9978731675896372, 'reward_value': np.float64(0.08556031590507558)}, 'target_8': {'priority': 0.03109707545554785, 'r_LB_H_normd': array([-0.1484439 ,  0.21389199,  0.04400469]), 'target_angle_normd': np.float64(0.8214680638449257), 'target_angle_rate_normd': np.float64(0.08134972836561737), 'opportunity_open_normd': 0.5338063434209538, 'opportunity_close_normd': 0.933214069490803, 'search_area_normd': np.float64(0.665122718046666), 'completion_probability': 0.8892582946488108, 'reward_value': np.float64(0.02068337135029625)}, 'target_9': {'priority': 0.0695497171402839, 'r_LB_H_normd': array([-0.15331234,  0.2359342 , -0.03872249]), 'target_angle_normd': np.float64(0.6282113973002025), 'target_angle_rate_normd': np.float64(0.07501091508276823), 'opportunity_open_normd': 0.645420387199707, 'opportunity_close_normd': 0.9447857430085715, 'search_area_normd': np.float64(0.0426312811110133), 'completion_probability': 1.0, 'reward_value': np.float64(0.002964993542598903)}, 'target_10': {'priority': 0.39892285218107626, 'r_LB_H_normd': array([-0.16494202,  0.27105853,  0.07836564]), 'target_angle_normd': np.float64(0.8699006198557802), 'target_angle_rate_normd': np.float64(0.061877116675656665), 'opportunity_open_normd': 0.865717487751095, 'opportunity_close_normd': 1.0137336105810415, 'search_area_normd': np.float64(0.09585293751345156), 'completion_probability': 1.0, 'reward_value': np.float64(0.038237927222800575)}, 'target_11': {'priority': 0.7196578424919539, 'r_LB_H_normd': array([-0.16166115,  0.27044748, -0.01289104]), 'target_angle_normd': np.float64(0.6900733213222214), 'target_angle_rate_normd': np.float64(0.06183967641078823), 'opportunity_open_normd': 0.7101412232951995, 'opportunity_close_normd': 1.1281179840393234, 'search_area_normd': np.float64(0.45741232237357016), 'completion_probability': 0.9998629610836166, 'reward_value': np.float64(0.3291803650485976)}, 'target_12': {'priority': 0.5680690305779442, 'r_LB_H_normd': array([-0.17041572,  0.29741394, -0.04039145]), 'target_angle_normd': np.float64(0.6420852786239944), 'target_angle_rate_normd': np.float64(0.05661792188503003), 'opportunity_open_normd': 0.8818201667578486, 'opportunity_close_normd': 1.1380312903921965, 'search_area_normd': np.float64(0.8177917868144693), 'completion_probability': 0.783194052241575, 'reward_value': np.float64(0.4645621875503004)}, 'target_13': {'priority': 0.5057793867898664, 'r_LB_H_normd': array([-0.16405959,  0.27911921,  0.00352909]), 'target_angle_normd': np.float64(0.723225453739684), 'target_angle_rate_normd': np.float64(0.0588524493229975), 'opportunity_open_normd': 0.72730030328064, 'opportunity_close_normd': 1.1771145012276558, 'search_area_normd': np.float64(0.6060242667519132), 'completion_probability': 0.9997444348276265, 'reward_value': np.float64(0.3065145820175611)}, 'target_14': {'priority': 0.7794547743824966, 'r_LB_H_normd': array([-0.17311457,  0.30438612,  0.05076583]), 'target_angle_normd': np.float64(0.8082842065646286), 'target_angle_rate_normd': np.float64(0.052878172789729214), 'opportunity_open_normd': 0.8546166923118634, 'opportunity_close_normd': 1.2461696287280475, 'search_area_normd': np.float64(0.4205991209755788), 'completion_probability': 0.9999999916918995, 'reward_value': np.float64(0.3278379929454961)}, 'target_15': {'priority': 0.8867460123730111, 'r_LB_H_normd': array([-0.17418515,  0.31040792,  0.03017474]), 'target_angle_normd': np.float64(0.7707160815261936), 'target_angle_rate_normd': np.float64(0.051427752605200924), 'opportunity_open_normd': 0.8441449192515216, 'opportunity_close_normd': 1.2905109226773486, 'search_area_normd': np.float64(0.24914650562479035), 'completion_probability': 1.0, 'reward_value': np.float64(0.22092967035945282)}, 'target_16': {'priority': 0.7717322183449333, 'r_LB_H_normd': array([-0.17692929,  0.32010508, -0.00183004]), 'target_angle_normd': np.float64(0.7140198366407101), 'target_angle_rate_normd': np.float64(0.050054290832085374), 'opportunity_open_normd': 0.8766937350783157, 'opportunity_close_normd': 1.315058511625447, 'search_area_normd': np.float64(0.26712592728272655), 'completion_probability': 1.0, 'reward_value': np.float64(0.20614968443934592)}, 'target_17': {'priority': 0.5263757083871584, 'r_LB_H_normd': array([-0.18814282,  0.3494386 , -0.03852899]), 'target_angle_normd': np.float64(0.6561658054094747), 'target_angle_rate_normd': np.float64(0.04666420132441965), 'opportunity_open_normd': 1.0718797303870746, 'opportunity_close_normd': 1.3193467681755693, 'search_area_normd': np.float64(0.587524800335853), 'completion_probability': 0.8571781978287714, 'reward_value': np.float64(0.3092587829718084)}, 'target_18': {'priority': 0.9945607893457441, 'r_LB_H_normd': array([-0.19568387,  0.36839402, -0.04404732]), 'target_angle_normd': np.float64(0.6510663479345614), 'target_angle_rate_normd': np.float64(0.044193852684211866), 'opportunity_open_normd': 1.1833811914070207, 'opportunity_close_normd': 1.3437221754447435, 'search_area_normd': np.float64(0.017879810113325855), 'completion_probability': 1.0, 'reward_value': np.float64(0.01778255805966138)}, 'target_19': {'priority': 0.44649875552935225, 'r_LB_H_normd': array([-0.17901931,  0.32597214,  0.01298089]), 'target_angle_normd': np.float64(0.7394751192589574), 'target_angle_rate_normd': np.float64(0.04866272713553459), 'opportunity_open_normd': 0.8917368819972153, 'opportunity_close_normd': 1.3468321930704457, 'search_area_normd': np.float64(0.23881560830256143), 'completion_probability': 0.9999999999999997, 'reward_value': np.float64(0.1066308719080789)}, 'target_20': {'priority': 0.43235559476434404, 'r_LB_H_normd': array([-0.20035062,  0.37978416, -0.04542958]), 'target_angle_normd': np.float64(0.6510673764932378), 'target_angle_rate_normd': np.float64(0.0427684103682027), 'opportunity_open_normd': 1.2453267955652445, 'opportunity_close_normd': 1.3644435037746154, 'search_area_normd': np.float64(0.1791241255954302), 'completion_probability': 0.9997930820164433, 'reward_value': np.float64(0.07744531785845528)}, 'target_21': {'priority': 0.3298583471641354, 'r_LB_H_normd': array([-0.19140223,  0.35850189, -0.03406309]), 'target_angle_normd': np.float64(0.6646761316576539), 'target_angle_rate_normd': np.float64(0.04509704778794618), 'opportunity_open_normd': 1.0863690893463582, 'opportunity_close_normd': 1.3712759485187123, 'search_area_normd': np.float64(0.065404781694196), 'completion_probability': 1.0, 'reward_value': np.float64(0.02157431318627859)}, 'target_22': {'priority': 0.6517356566210931, 'r_LB_H_normd': array([-0.18789639,  0.35020645, -0.02204113]), 'target_angle_normd': np.float64(0.6825088147473989), 'target_angle_rate_normd': np.float64(0.04578434603652838), 'opportunity_open_normd': 1.017486739344078, 'opportunity_close_normd': 1.3833916362829544, 'search_area_normd': np.float64(0.4094415923951918), 'completion_probability': 0.9998811735362466, 'reward_value': np.float64(0.26684768506766626)}, 'target_23': {'priority': 0.5153936931431213, 'r_LB_H_normd': array([-0.19228512,  0.36139417,  0.02692013]), 'target_angle_normd': np.float64(0.7595594818791253), 'target_angle_rate_normd': np.float64(0.043111542797273125), 'opportunity_open_normd': 1.0224450779544376, 'opportunity_close_normd': 1.4751689677846593, 'search_area_normd': np.float64(0.05897202051920154), 'completion_probability': 1.0, 'reward_value': np.float64(0.03039380744750321)}, 'target_24': {'priority': 0.9986310400923137, 'r_LB_H_normd': array([-0.20771336,  0.39164658,  0.08040122]), 'target_angle_normd': np.float64(0.8318748260016608), 'target_angle_rate_normd': np.float64(0.04007999429198626), 'opportunity_open_normd': 1.264691244263805, 'opportunity_close_normd': 1.4776166006473397, 'search_area_normd': np.float64(0.02649133767008183), 'completion_probability': 1.0, 'reward_value': np.float64(0.026455072090910508)}, 'target_25': {'priority': 0.4300280555930357, 'r_LB_H_normd': array([-0.22572952,  0.43701521, -0.03964356]), 'target_angle_normd': np.float64(0.6673390093030923), 'target_angle_rate_normd': np.float64(0.03655916254036476), 'opportunity_open_normd': 1.4290543837982037, 'opportunity_close_normd': 1.6054178739854785, 'search_area_normd': np.float64(0.8816851233407857), 'completion_probability': 0.4097010364942584, 'reward_value': np.float64(0.37914933923554395)}, 'target_26': {'priority': 0.975275806701713, 'r_LB_H_normd': array([-0.21667988,  0.41803398,  0.03815669]), 'target_angle_normd': np.float64(0.7696746660447653), 'target_angle_rate_normd': np.float64(0.036842700946282766), 'opportunity_open_normd': 1.2368887876979306, 'opportunity_close_normd': 1.6791810671742333, 'search_area_normd': np.float64(0.30069795312897707), 'completion_probability': 0.9999999994517701, 'reward_value': np.float64(0.293263438811417)}, 'target_27': {'priority': 0.42787877873635205, 'r_LB_H_normd': array([-0.21686823,  0.41947759,  0.0242645 ]), 'target_angle_normd': np.float64(0.7509749462852585), 'target_angle_rate_normd': np.float64(0.036740724862312654), 'opportunity_open_normd': 1.2328711719457215, 'opportunity_close_normd': 1.6883484708154057, 'search_area_normd': np.float64(0.15923232127240183), 'completion_probability': 1.0, 'reward_value': np.float64(0.06813213116138976)}, 'target_28': {'priority': 0.887364000181752, 'r_LB_H_normd': array([-0.22488963,  0.43688733,  0.01316222]), 'target_angle_normd': np.float64(0.7354630355597529), 'target_angle_rate_normd': np.float64(0.035355291754643886), 'opportunity_open_normd': 1.2978683845866201, 'opportunity_close_normd': 1.7490408457425466, 'search_area_normd': np.float64(0.1993247446227911), 'completion_probability': 1.0, 'reward_value': np.float64(0.17687360272368607)}, 'target_29': {'priority': 0.7724058204626488, 'r_LB_H_normd': array([-0.23292562,  0.45048789,  0.04995311]), 'target_angle_normd': np.float64(0.7807197125611256), 'target_angle_rate_normd': np.float64(0.03421116467347472), 'opportunity_open_normd': 1.372249650199565, 'opportunity_close_normd': 1.7914512992334497, 'search_area_normd': np.float64(0.030165243281192432), 'completion_probability': 1.0, 'reward_value': np.float64(0.023299809486064846)}, 'target_30': {'priority': 0.5718685532886608, 'r_LB_H_normd': array([-0.28672144,  0.54531078, -0.03289818]), 'target_angle_normd': np.float64(0.6841857588216017), 'target_angle_rate_normd': np.float64(0.029512715848961323), 'opportunity_open_normd': 1.8378409298380125, 'opportunity_close_normd': 2.039035741458926, 'search_area_normd': np.float64(0.17585273110104194), 'completion_probability': 0.9999314259236561, 'reward_value': np.float64(0.10056464692661274)}, 'target_31': {'priority': 0.07841079909978321, 'r_LB_H_normd': array([-0.28068789,  0.53629174,  0.02633705]), 'target_angle_normd': np.float64(0.7457609076708701), 'target_angle_rate_normd': np.float64(0.029213330034149384), 'opportunity_open_normd': 1.6814643943687038, 'opportunity_close_normd': 2.1368810732720886, 'search_area_normd': np.float64(0.20581854171150613), 'completion_probability': 1.0, 'reward_value': np.float64(0.01613839632515126)}}

Then, run the simulation until timeout.

[10]:
while True:
    action_step = np.random.randint(0, 32)  # Random action

    observation, reward, terminated, truncated, info = env.step(action_step)

    if terminated or truncated:
        print("Episode complete.")
        break
2026-11-09 20:10:19,094 gym                            INFO       <0.00> === STARTING STEP ===
2026-11-09 20:10:19,094 sats.satellite.EO              INFO       <0.00> EO: target index 18 tasked
2026-11-09 20:10:19,094 sats.satellite.EO              INFO       <0.00> EO: Target(tgt-2153) tasked for imaging, image_time: 1.9, duration: 2.8
2026-11-09 20:10:19,095 sats.satellite.EO              INFO       <0.00> EO: Target(tgt-2153) window enabled: 355.0 to 403.1
2026-11-09 20:10:19,095 sats.satellite.EO              INFO       <0.00> EO: setting timed terminal event at 403.1
2026-11-09 20:10:19,149 sats.satellite.EO              INFO       <358.50> EO: imaged Target(tgt-2153)
2026-11-09 20:10:19,150 data.base                      INFO       <358.50> Total reward: {'EO': np.float64(0.01778255805966138)}
2026-11-09 20:10:19,150 comm.communication             INFO       <358.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,150 sats.satellite.EO              INFO       <358.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,170 gym                            INFO       <358.50> Step reward: 0.01778255805966138
2026-11-09 20:10:19,190 gym                            INFO       <358.50> === STARTING STEP ===
2026-11-09 20:10:19,191 sats.satellite.EO              INFO       <358.50> EO: target index 4 tasked
2026-11-09 20:10:19,191 sats.satellite.EO              INFO       <358.50> EO: Target(tgt-3200) tasked for imaging, image_time: 20.1, duration: 50.5
2026-11-09 20:10:19,192 sats.satellite.EO              INFO       <358.50> EO: Target(tgt-3200) window enabled: 267.5 to 404.0
2026-11-09 20:10:19,192 sats.satellite.EO              INFO       <358.50> EO: setting timed terminal event at 404.0
2026-11-09 20:10:19,200 sats.satellite.EO              INFO       <404.50> EO: timed termination at 404.0 for Target(tgt-3200) window
2026-11-09 20:10:19,201 data.base                      INFO       <404.50> Total reward: {}
2026-11-09 20:10:19,201 comm.communication             INFO       <404.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,202 sats.satellite.EO              INFO       <404.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,226 gym                            INFO       <404.50> Step reward: 0.0
2026-11-09 20:10:19,245 gym                            INFO       <404.50> === STARTING STEP ===
2026-11-09 20:10:19,246 sats.satellite.EO              INFO       <404.50> EO: target index 31 tasked
2026-11-09 20:10:19,246 sats.satellite.EO              INFO       <404.50> EO: Target(tgt-3394) tasked for imaging, image_time: 3.4, duration: 11.5
2026-11-09 20:10:19,247 sats.satellite.EO              INFO       <404.50> EO: Target(tgt-3394) window enabled: 934.7 to 1032.2
2026-11-09 20:10:19,247 sats.satellite.EO              INFO       <404.50> EO: setting timed terminal event at 1032.2
2026-11-09 20:10:19,334 sats.satellite.EO              INFO       <939.50> EO: imaged Target(tgt-3394)
2026-11-09 20:10:19,334 data.base                      INFO       <939.50> Total reward: {'EO': np.float64(0.05737898552644931)}
2026-11-09 20:10:19,335 comm.communication             INFO       <939.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,335 sats.satellite.EO              INFO       <939.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,355 gym                            INFO       <939.50> Step reward: 0.05737898552644931
2026-11-09 20:10:19,374 gym                            INFO       <939.50> === STARTING STEP ===
2026-11-09 20:10:19,375 sats.satellite.EO              INFO       <939.50> EO: target index 28 tasked
2026-11-09 20:10:19,375 sats.satellite.EO              INFO       <939.50> EO: Target(tgt-114) tasked for imaging, image_time: 6.1, duration: 15.3
2026-11-09 20:10:19,376 sats.satellite.EO              INFO       <939.50> EO: Target(tgt-114) window enabled: 1587.5 to 1672.5
2026-11-09 20:10:19,376 sats.satellite.EO              INFO       <939.50> EO: setting timed terminal event at 1672.5
2026-11-09 20:10:19,483 sats.satellite.EO              INFO       <1595.00> EO: imaged Target(tgt-114)
2026-11-09 20:10:19,484 data.base                      INFO       <1595.00> Total reward: {'EO': np.float64(0.020028599319681307)}
2026-11-09 20:10:19,484 comm.communication             INFO       <1595.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,484 sats.satellite.EO              INFO       <1595.00> EO: Satellite EO requires retasking
2026-11-09 20:10:19,505 gym                            INFO       <1595.00> Step reward: 0.020028599319681307
2026-11-09 20:10:19,524 gym                            INFO       <1595.00> === STARTING STEP ===
2026-11-09 20:10:19,525 sats.satellite.EO              INFO       <1595.00> EO: target index 7 tasked
2026-11-09 20:10:19,525 sats.satellite.EO              INFO       <1595.00> EO: Target(tgt-3686) tasked for imaging, image_time: 4.1, duration: 113.8
2026-11-09 20:10:19,526 sats.satellite.EO              INFO       <1595.00> EO: Target(tgt-3686) window enabled: 1955.7 to 1976.9
2026-11-09 20:10:19,526 sats.satellite.EO              INFO       <1595.00> EO: setting timed terminal event at 1976.9
2026-11-09 20:10:19,580 sats.satellite.EO              INFO       <1961.50> EO: imaged Target(tgt-3686)
2026-11-09 20:10:19,581 data.base                      INFO       <1961.50> Total reward: {'EO': np.float64(0.423862862662096)}
2026-11-09 20:10:19,582 comm.communication             INFO       <1961.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,582 sats.satellite.EO              INFO       <1961.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,601 gym                            INFO       <1961.50> Step reward: 0.423862862662096
2026-11-09 20:10:19,621 gym                            INFO       <1961.50> === STARTING STEP ===
2026-11-09 20:10:19,621 sats.satellite.EO              INFO       <1961.50> EO: target index 28 tasked
2026-11-09 20:10:19,622 sats.satellite.EO              INFO       <1961.50> EO: Target(tgt-1947) tasked for imaging, image_time: 34.2, duration: 36.5
2026-11-09 20:10:19,622 sats.satellite.EO              INFO       <1961.50> EO: Target(tgt-1947) window enabled: 2380.1 to 2512.2
2026-11-09 20:10:19,623 sats.satellite.EO              INFO       <1961.50> EO: setting timed terminal event at 2512.2
2026-11-09 20:10:19,691 sats.satellite.EO              INFO       <2416.00> EO: imaged Target(tgt-1947)
2026-11-09 20:10:19,692 data.base                      INFO       <2416.00> Total reward: {'EO': np.float64(0.08010351431725703)}
2026-11-09 20:10:19,692 comm.communication             INFO       <2416.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,693 sats.satellite.EO              INFO       <2416.00> EO: Satellite EO requires retasking
2026-11-09 20:10:19,711 gym                            INFO       <2416.00> Step reward: 0.08010351431725703
2026-11-09 20:10:19,731 gym                            INFO       <2416.00> === STARTING STEP ===
2026-11-09 20:10:19,731 sats.satellite.EO              INFO       <2416.00> EO: target index 23 tasked
2026-11-09 20:10:19,732 sats.satellite.EO              INFO       <2416.00> EO: Target(tgt-189) tasked for imaging, image_time: 94.2, duration: 185.2
2026-11-09 20:10:19,732 sats.satellite.EO              INFO       <2416.00> EO: Target(tgt-189) window enabled: 2885.9 to 3019.2
2026-11-09 20:10:19,733 sats.satellite.EO              INFO       <2416.00> EO: setting timed terminal event at 3019.2
2026-11-09 20:10:19,827 sats.satellite.EO              INFO       <2981.50> EO: imaged Target(tgt-189)
2026-11-09 20:10:19,828 data.base                      INFO       <2981.50> Total reward: {'EO': 0.6309592003395305}
2026-11-09 20:10:19,828 comm.communication             INFO       <2981.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,829 sats.satellite.EO              INFO       <2981.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,847 gym                            INFO       <2981.50> Step reward: 0.6309592003395305
2026-11-09 20:10:19,867 gym                            INFO       <2981.50> === STARTING STEP ===
2026-11-09 20:10:19,867 sats.satellite.EO              INFO       <2981.50> EO: target index 24 tasked
2026-11-09 20:10:19,868 sats.satellite.EO              INFO       <2981.50> EO: Target(tgt-1960) tasked for imaging, image_time: 58.6, duration: 112.2
2026-11-09 20:10:19,868 sats.satellite.EO              INFO       <2981.50> EO: Target(tgt-1960) window enabled: 3460.2 to 3577.9
2026-11-09 20:10:19,868 sats.satellite.EO              INFO       <2981.50> EO: setting timed terminal event at 3577.9
2026-11-09 20:10:19,947 sats.satellite.EO              INFO       <3520.50> EO: imaged Target(tgt-1960)
2026-11-09 20:10:19,948 data.base                      INFO       <3520.50> Total reward: {'EO': np.float64(0.6109519356188728)}
2026-11-09 20:10:19,948 comm.communication             INFO       <3520.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:19,949 sats.satellite.EO              INFO       <3520.50> EO: Satellite EO requires retasking
2026-11-09 20:10:19,968 gym                            INFO       <3520.50> Step reward: 0.6109519356188728
2026-11-09 20:10:19,987 gym                            INFO       <3520.50> === STARTING STEP ===
2026-11-09 20:10:19,988 sats.satellite.EO              INFO       <3520.50> EO: target index 27 tasked
2026-11-09 20:10:19,988 sats.satellite.EO              INFO       <3520.50> EO: Target(tgt-1407) tasked for imaging, image_time: 146.1, duration: 248.0
2026-11-09 20:10:19,988 sats.satellite.EO              INFO       <3520.50> EO: Target(tgt-1407) window enabled: 3890.4 to 4005.4
2026-11-09 20:10:19,989 sats.satellite.EO              INFO       <3520.50> EO: setting timed terminal event at 4005.4
2026-11-09 20:10:20,061 sats.satellite.EO              INFO       <4005.50> EO: timed termination at 4005.4 for Target(tgt-1407) window
2026-11-09 20:10:20,062 data.base                      INFO       <4005.50> Total reward: {}
2026-11-09 20:10:20,063 comm.communication             INFO       <4005.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,063 sats.satellite.EO              INFO       <4005.50> EO: Satellite EO requires retasking
2026-11-09 20:10:20,082 gym                            INFO       <4005.50> Step reward: 0.0
2026-11-09 20:10:20,101 gym                            INFO       <4005.50> === STARTING STEP ===
2026-11-09 20:10:20,102 sats.satellite.EO              INFO       <4005.50> EO: target index 26 tasked
2026-11-09 20:10:20,102 sats.satellite.EO              INFO       <4005.50> EO: Target(tgt-1758) tasked for imaging, image_time: 104.5, duration: 245.7
2026-11-09 20:10:20,103 sats.satellite.EO              INFO       <4005.50> EO: Target(tgt-1758) window enabled: 4686.1 to 4793.6
2026-11-09 20:10:20,103 sats.satellite.EO              INFO       <4005.50> EO: setting timed terminal event at 4793.6
2026-11-09 20:10:20,218 sats.satellite.EO              INFO       <4792.00> EO: imaged Target(tgt-1758)
2026-11-09 20:10:20,218 data.base                      INFO       <4792.00> Total reward: {'EO': 0.9305881393615434}
2026-11-09 20:10:20,219 comm.communication             INFO       <4792.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,219 sats.satellite.EO              INFO       <4792.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,238 gym                            INFO       <4792.00> Step reward: 0.9305881393615434
2026-11-09 20:10:20,258 gym                            INFO       <4792.00> === STARTING STEP ===
2026-11-09 20:10:20,259 sats.satellite.EO              INFO       <4792.00> EO: target index 20 tasked
2026-11-09 20:10:20,259 sats.satellite.EO              INFO       <4792.00> EO: Target(tgt-1127) tasked for imaging, image_time: 43.0, duration: 79.6
2026-11-09 20:10:20,260 sats.satellite.EO              INFO       <4792.00> EO: Target(tgt-1127) window enabled: 5207.0 to 5316.6
2026-11-09 20:10:20,260 sats.satellite.EO              INFO       <4792.00> EO: setting timed terminal event at 5316.6
2026-11-09 20:10:20,327 sats.satellite.EO              INFO       <5251.00> EO: imaged Target(tgt-1127)
2026-11-09 20:10:20,328 data.base                      INFO       <5251.00> Total reward: {'EO': np.float64(0.33600749751096437)}
2026-11-09 20:10:20,328 comm.communication             INFO       <5251.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,328 sats.satellite.EO              INFO       <5251.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,347 gym                            INFO       <5251.00> Step reward: 0.33600749751096437
2026-11-09 20:10:20,366 gym                            INFO       <5251.00> === STARTING STEP ===
2026-11-09 20:10:20,367 sats.satellite.EO              INFO       <5251.00> EO: target index 16 tasked
2026-11-09 20:10:20,367 sats.satellite.EO              INFO       <5251.00> EO: Target(tgt-2853) tasked for imaging, image_time: 75.9, duration: 142.1
2026-11-09 20:10:20,367 sats.satellite.EO              INFO       <5251.00> EO: Target(tgt-2853) window enabled: 5640.7 to 5759.6
2026-11-09 20:10:20,368 sats.satellite.EO              INFO       <5251.00> EO: setting timed terminal event at 5759.6
2026-11-09 20:10:20,444 sats.satellite.EO              INFO       <5718.00> EO: imaged Target(tgt-2853)
2026-11-09 20:10:20,444 data.base                      INFO       <5718.00> Total reward: {'EO': np.float64(0.20767038860307005)}
2026-11-09 20:10:20,445 comm.communication             INFO       <5718.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,445 sats.satellite.EO              INFO       <5718.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,464 gym                            INFO       <5718.00> Step reward: 0.20767038860307005
2026-11-09 20:10:20,483 gym                            INFO       <5718.00> === STARTING STEP ===
2026-11-09 20:10:20,484 sats.satellite.EO              INFO       <5718.00> EO: target index 24 tasked
2026-11-09 20:10:20,484 sats.satellite.EO              INFO       <5718.00> EO: Target(tgt-3703) tasked for imaging, image_time: 0.1, duration: 123.3
2026-11-09 20:10:20,485 sats.satellite.EO              INFO       <5718.00> EO: Target(tgt-3703) window enabled: 6184.1 to 6264.8
2026-11-09 20:10:20,485 sats.satellite.EO              INFO       <5718.00> EO: setting timed terminal event at 6264.8
2026-11-09 20:10:20,556 sats.satellite.EO              INFO       <6186.00> EO: imaged Target(tgt-3703)
2026-11-09 20:10:20,557 data.base                      INFO       <6186.00> Total reward: {'EO': np.float64(0.02154604344621261)}
2026-11-09 20:10:20,558 comm.communication             INFO       <6186.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,558 sats.satellite.EO              INFO       <6186.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,577 gym                            INFO       <6186.00> Step reward: 0.02154604344621261
2026-11-09 20:10:20,596 gym                            INFO       <6186.00> === STARTING STEP ===
2026-11-09 20:10:20,597 sats.satellite.EO              INFO       <6186.00> EO: target index 13 tasked
2026-11-09 20:10:20,597 sats.satellite.EO              INFO       <6186.00> EO: Target(tgt-974) tasked for imaging, image_time: 51.7, duration: 154.0
2026-11-09 20:10:20,598 sats.satellite.EO              INFO       <6186.00> EO: Target(tgt-974) window enabled: 6381.7 to 6449.1
2026-11-09 20:10:20,598 sats.satellite.EO              INFO       <6186.00> EO: setting timed terminal event at 6449.1
2026-11-09 20:10:20,642 sats.satellite.EO              INFO       <6435.00> EO: imaged Target(tgt-974)
2026-11-09 20:10:20,642 data.base                      INFO       <6435.00> Total reward: {'EO': 0.9798927970615768}
2026-11-09 20:10:20,643 comm.communication             INFO       <6435.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,643 sats.satellite.EO              INFO       <6435.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,662 gym                            INFO       <6435.00> Step reward: 0.9798927970615768
2026-11-09 20:10:20,681 gym                            INFO       <6435.00> === STARTING STEP ===
2026-11-09 20:10:20,682 sats.satellite.EO              INFO       <6435.00> EO: target index 9 tasked
2026-11-09 20:10:20,682 sats.satellite.EO              INFO       <6435.00> EO: Target(tgt-1864) tasked for imaging, image_time: 145.9, duration: 198.2
2026-11-09 20:10:20,683 sats.satellite.EO              INFO       <6435.00> EO: Target(tgt-1864) window enabled: 6393.1 to 6520.3
2026-11-09 20:10:20,683 sats.satellite.EO              INFO       <6435.00> EO: setting timed terminal event at 6520.3
2026-11-09 20:10:20,699 sats.satellite.EO              INFO       <6520.50> EO: timed termination at 6520.3 for Target(tgt-1864) window
2026-11-09 20:10:20,700 data.base                      INFO       <6520.50> Total reward: {}
2026-11-09 20:10:20,700 comm.communication             INFO       <6520.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,700 sats.satellite.EO              INFO       <6520.50> EO: Satellite EO requires retasking
2026-11-09 20:10:20,719 gym                            INFO       <6520.50> Step reward: 0.0
2026-11-09 20:10:20,739 gym                            INFO       <6520.50> === STARTING STEP ===
2026-11-09 20:10:20,740 sats.satellite.EO              INFO       <6520.50> EO: target index 13 tasked
2026-11-09 20:10:20,740 sats.satellite.EO              INFO       <6520.50> EO: Target(tgt-2730) tasked for imaging, image_time: 65.5, duration: 364.5
2026-11-09 20:10:20,741 sats.satellite.EO              INFO       <6520.50> EO: Target(tgt-2730) window enabled: 6735.6 to 6860.1
2026-11-09 20:10:20,741 sats.satellite.EO              INFO       <6520.50> EO: setting timed terminal event at 6860.1
2026-11-09 20:10:20,783 sats.satellite.EO              INFO       <6803.00> EO: imaged Target(tgt-2730)
2026-11-09 20:10:20,784 data.base                      INFO       <6803.00> Total reward: {'EO': 0.9920399375376314}
2026-11-09 20:10:20,784 comm.communication             INFO       <6803.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,785 sats.satellite.EO              INFO       <6803.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,804 gym                            INFO       <6803.00> Step reward: 0.9920399375376314
2026-11-09 20:10:20,824 gym                            INFO       <6803.00> === STARTING STEP ===
2026-11-09 20:10:20,824 sats.satellite.EO              INFO       <6803.00> EO: target index 28 tasked
2026-11-09 20:10:20,824 sats.satellite.EO              INFO       <6803.00> EO: Target(tgt-1463) tasked for imaging, image_time: 55.7, duration: 154.7
2026-11-09 20:10:20,825 sats.satellite.EO              INFO       <6803.00> EO: Target(tgt-1463) window enabled: 7407.5 to 7516.2
2026-11-09 20:10:20,825 sats.satellite.EO              INFO       <6803.00> EO: setting timed terminal event at 7516.2
2026-11-09 20:10:20,922 sats.satellite.EO              INFO       <7465.00> EO: imaged Target(tgt-1463)
2026-11-09 20:10:20,923 data.base                      INFO       <7465.00> Total reward: {'EO': 0.49199780239350377}
2026-11-09 20:10:20,923 comm.communication             INFO       <7465.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:20,923 sats.satellite.EO              INFO       <7465.00> EO: Satellite EO requires retasking
2026-11-09 20:10:20,942 gym                            INFO       <7465.00> Step reward: 0.49199780239350377
2026-11-09 20:10:20,961 gym                            INFO       <7465.00> === STARTING STEP ===
2026-11-09 20:10:20,962 sats.satellite.EO              INFO       <7465.00> EO: target index 14 tasked
2026-11-09 20:10:20,962 sats.satellite.EO              INFO       <7465.00> EO: Target(tgt-3552) tasked for imaging, image_time: 113.1, duration: 136.4
2026-11-09 20:10:20,962 sats.satellite.EO              INFO       <7465.00> EO: Target(tgt-3552) window enabled: 7673.7 to 7809.1
2026-11-09 20:10:20,963 sats.satellite.EO              INFO       <7465.00> EO: setting timed terminal event at 7809.1
2026-11-09 20:10:21,010 sats.satellite.EO              INFO       <7788.50> EO: imaged Target(tgt-3552)
2026-11-09 20:10:21,011 data.base                      INFO       <7788.50> Total reward: {'EO': 0.7337722662558089}
2026-11-09 20:10:21,012 comm.communication             INFO       <7788.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,012 sats.satellite.EO              INFO       <7788.50> EO: Satellite EO requires retasking
2026-11-09 20:10:21,031 gym                            INFO       <7788.50> Step reward: 0.7337722662558089
2026-11-09 20:10:21,050 gym                            INFO       <7788.50> === STARTING STEP ===
2026-11-09 20:10:21,051 sats.satellite.EO              INFO       <7788.50> EO: target index 29 tasked
2026-11-09 20:10:21,051 sats.satellite.EO              INFO       <7788.50> EO: Target(tgt-1308) tasked for imaging, image_time: 107.9, duration: 293.4
2026-11-09 20:10:21,052 sats.satellite.EO              INFO       <7788.50> EO: Target(tgt-1308) window enabled: 8516.3 to 8633.4
2026-11-09 20:10:21,052 sats.satellite.EO              INFO       <7788.50> EO: setting timed terminal event at 8633.4
2026-11-09 20:10:21,184 sats.satellite.EO              INFO       <8625.50> EO: imaged Target(tgt-1308)
2026-11-09 20:10:21,185 data.base                      INFO       <8625.50> Total reward: {'EO': 0.6435484366693806}
2026-11-09 20:10:21,185 comm.communication             INFO       <8625.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,186 sats.satellite.EO              INFO       <8625.50> EO: Satellite EO requires retasking
2026-11-09 20:10:21,205 gym                            INFO       <8625.50> Step reward: 0.6435484366693806
2026-11-09 20:10:21,224 gym                            INFO       <8625.50> === STARTING STEP ===
2026-11-09 20:10:21,224 sats.satellite.EO              INFO       <8625.50> EO: target index 7 tasked
2026-11-09 20:10:21,225 sats.satellite.EO              INFO       <8625.50> EO: Target(tgt-2421) tasked for imaging, image_time: 84.4, duration: 135.0
2026-11-09 20:10:21,225 sats.satellite.EO              INFO       <8625.50> EO: Target(tgt-2421) window enabled: 8724.1 to 8812.4
2026-11-09 20:10:21,226 sats.satellite.EO              INFO       <8625.50> EO: setting timed terminal event at 8812.4
2026-11-09 20:10:21,254 sats.satellite.EO              INFO       <8810.00> EO: imaged Target(tgt-2421)
2026-11-09 20:10:21,255 data.base                      INFO       <8810.00> Total reward: {'EO': np.float64(0.49547057571877806)}
2026-11-09 20:10:21,255 comm.communication             INFO       <8810.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,255 sats.satellite.EO              INFO       <8810.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,274 gym                            INFO       <8810.00> Step reward: 0.49547057571877806
2026-11-09 20:10:21,294 gym                            INFO       <8810.00> === STARTING STEP ===
2026-11-09 20:10:21,294 sats.satellite.EO              INFO       <8810.00> EO: target index 11 tasked
2026-11-09 20:10:21,295 sats.satellite.EO              INFO       <8810.00> EO: Target(tgt-2336) tasked for imaging, image_time: 16.7, duration: 73.6
2026-11-09 20:10:21,295 sats.satellite.EO              INFO       <8810.00> EO: Target(tgt-2336) window enabled: 9125.7 to 9233.8
2026-11-09 20:10:21,295 sats.satellite.EO              INFO       <8810.00> EO: setting timed terminal event at 9233.8
2026-11-09 20:10:21,349 sats.satellite.EO              INFO       <9144.00> EO: imaged Target(tgt-2336)
2026-11-09 20:10:21,349 data.base                      INFO       <9144.00> Total reward: {'EO': np.float64(0.21346336857877682)}
2026-11-09 20:10:21,350 comm.communication             INFO       <9144.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,350 sats.satellite.EO              INFO       <9144.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,369 gym                            INFO       <9144.00> Step reward: 0.21346336857877682
2026-11-09 20:10:21,390 gym                            INFO       <9144.00> === STARTING STEP ===
2026-11-09 20:10:21,390 sats.satellite.EO              INFO       <9144.00> EO: target index 22 tasked
2026-11-09 20:10:21,390 sats.satellite.EO              INFO       <9144.00> EO: Target(tgt-1332) tasked for imaging, image_time: 281.9, duration: 330.6
2026-11-09 20:10:21,391 sats.satellite.EO              INFO       <9144.00> EO: Target(tgt-1332) window enabled: 9677.6 to 9733.7
2026-11-09 20:10:21,391 sats.satellite.EO              INFO       <9144.00> EO: setting timed terminal event at 9733.7
2026-11-09 20:10:21,483 sats.satellite.EO              INFO       <9734.00> EO: timed termination at 9733.7 for Target(tgt-1332) window
2026-11-09 20:10:21,484 data.base                      INFO       <9734.00> Total reward: {}
2026-11-09 20:10:21,484 comm.communication             INFO       <9734.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,485 sats.satellite.EO              INFO       <9734.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,503 gym                            INFO       <9734.00> Step reward: 0.0
2026-11-09 20:10:21,523 gym                            INFO       <9734.00> === STARTING STEP ===
2026-11-09 20:10:21,523 sats.satellite.EO              INFO       <9734.00> EO: target index 5 tasked
2026-11-09 20:10:21,524 sats.satellite.EO              INFO       <9734.00> EO: Target(tgt-1554) tasked for imaging, image_time: 86.7, duration: 296.2
2026-11-09 20:10:21,524 sats.satellite.EO              INFO       <9734.00> EO: Target(tgt-1554) window enabled: 9797.7 to 9932.5
2026-11-09 20:10:21,524 sats.satellite.EO              INFO       <9734.00> EO: setting timed terminal event at 9932.5
2026-11-09 20:10:21,549 sats.satellite.EO              INFO       <9886.00> EO: imaged Target(tgt-1554)
2026-11-09 20:10:21,549 data.base                      INFO       <9886.00> Total reward: {'EO': 0.48218095859430343}
2026-11-09 20:10:21,551 comm.communication             INFO       <9886.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,551 sats.satellite.EO              INFO       <9886.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,570 gym                            INFO       <9886.00> Step reward: 0.48218095859430343
2026-11-09 20:10:21,590 gym                            INFO       <9886.00> === STARTING STEP ===
2026-11-09 20:10:21,590 sats.satellite.EO              INFO       <9886.00> EO: target index 2 tasked
2026-11-09 20:10:21,591 sats.satellite.EO              INFO       <9886.00> EO: Target(tgt-1231) tasked for imaging, image_time: 63.6, duration: 141.6
2026-11-09 20:10:21,591 sats.satellite.EO              INFO       <9886.00> EO: Target(tgt-1231) window enabled: 9835.3 to 9964.7
2026-11-09 20:10:21,591 sats.satellite.EO              INFO       <9886.00> EO: setting timed terminal event at 9964.7
2026-11-09 20:10:21,607 sats.satellite.EO              INFO       <9965.00> EO: timed termination at 9964.7 for Target(tgt-1231) window
2026-11-09 20:10:21,608 data.base                      INFO       <9965.00> Total reward: {}
2026-11-09 20:10:21,608 comm.communication             INFO       <9965.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,608 sats.satellite.EO              INFO       <9965.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,628 gym                            INFO       <9965.00> Step reward: 0.0
2026-11-09 20:10:21,648 gym                            INFO       <9965.00> === STARTING STEP ===
2026-11-09 20:10:21,649 sats.satellite.EO              INFO       <9965.00> EO: target index 10 tasked
2026-11-09 20:10:21,649 sats.satellite.EO              INFO       <9965.00> EO: Target(tgt-536) tasked for imaging, image_time: 25.7, duration: 179.8
2026-11-09 20:10:21,649 sats.satellite.EO              INFO       <9965.00> EO: Target(tgt-536) window enabled: 10197.9 to 10288.6
2026-11-09 20:10:21,650 sats.satellite.EO              INFO       <9965.00> EO: setting timed terminal event at 10288.6
2026-11-09 20:10:21,690 sats.satellite.EO              INFO       <10225.00> EO: imaged Target(tgt-536)
2026-11-09 20:10:21,691 data.base                      INFO       <10225.00> Total reward: {'EO': 0.08595222757741783}
2026-11-09 20:10:21,691 comm.communication             INFO       <10225.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,691 sats.satellite.EO              INFO       <10225.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,710 gym                            INFO       <10225.00> Step reward: 0.08595222757741783
2026-11-09 20:10:21,730 gym                            INFO       <10225.00> === STARTING STEP ===
2026-11-09 20:10:21,730 sats.satellite.EO              INFO       <10225.00> EO: target index 15 tasked
2026-11-09 20:10:21,731 sats.satellite.EO              INFO       <10225.00> EO: Target(tgt-511) tasked for imaging, image_time: 97.0, duration: 383.3
2026-11-09 20:10:21,731 sats.satellite.EO              INFO       <10225.00> EO: Target(tgt-511) window enabled: 10565.3 to 10697.6
2026-11-09 20:10:21,732 sats.satellite.EO              INFO       <10225.00> EO: setting timed terminal event at 10697.6
2026-11-09 20:10:21,800 sats.satellite.EO              INFO       <10664.00> EO: imaged Target(tgt-511)
2026-11-09 20:10:21,801 data.base                      INFO       <10664.00> Total reward: {'EO': 0.3641702986535258}
2026-11-09 20:10:21,801 comm.communication             INFO       <10664.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,802 sats.satellite.EO              INFO       <10664.00> EO: Satellite EO requires retasking
2026-11-09 20:10:21,821 gym                            INFO       <10664.00> Step reward: 0.3641702986535258
2026-11-09 20:10:21,840 gym                            INFO       <10664.00> === STARTING STEP ===
2026-11-09 20:10:21,841 sats.satellite.EO              INFO       <10664.00> EO: target index 15 tasked
2026-11-09 20:10:21,841 sats.satellite.EO              INFO       <10664.00> EO: Target(tgt-1328) tasked for imaging, image_time: 106.5, duration: 171.6
2026-11-09 20:10:21,842 sats.satellite.EO              INFO       <10664.00> EO: Target(tgt-1328) window enabled: 11018.7 to 11142.5
2026-11-09 20:10:21,842 sats.satellite.EO              INFO       <10664.00> EO: setting timed terminal event at 11142.5
2026-11-09 20:10:21,909 sats.satellite.EO              INFO       <11126.50> EO: imaged Target(tgt-1328)
2026-11-09 20:10:21,910 data.base                      INFO       <11126.50> Total reward: {'EO': 0.13296890172545006}
2026-11-09 20:10:21,911 comm.communication             INFO       <11126.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:21,911 sats.satellite.EO              INFO       <11126.50> EO: Satellite EO requires retasking
2026-11-09 20:10:21,930 gym                            INFO       <11126.50> Step reward: 0.13296890172545006
2026-11-09 20:10:21,949 gym                            INFO       <11126.50> === STARTING STEP ===
2026-11-09 20:10:21,949 sats.satellite.EO              INFO       <11126.50> EO: target index 29 tasked
2026-11-09 20:10:21,950 sats.satellite.EO              INFO       <11126.50> EO: Target(tgt-2423) tasked for imaging, image_time: 398.5, duration: 595.9
2026-11-09 20:10:21,950 sats.satellite.EO              INFO       <11126.50> EO: Target(tgt-2423) window enabled: 11845.1 to 11966.4
2026-11-09 20:10:21,951 sats.satellite.EO              INFO       <11126.50> EO: setting timed terminal event at 11966.4
2026-11-09 20:10:22,082 sats.satellite.EO              INFO       <11966.50> EO: timed termination at 11966.4 for Target(tgt-2423) window
2026-11-09 20:10:22,083 data.base                      INFO       <11966.50> Total reward: {}
2026-11-09 20:10:22,083 comm.communication             INFO       <11966.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,084 sats.satellite.EO              INFO       <11966.50> EO: Satellite EO requires retasking
2026-11-09 20:10:22,102 gym                            INFO       <11966.50> Step reward: 0.0
2026-11-09 20:10:22,121 gym                            INFO       <11966.50> === STARTING STEP ===
2026-11-09 20:10:22,122 sats.satellite.EO              INFO       <11966.50> EO: target index 10 tasked
2026-11-09 20:10:22,122 sats.satellite.EO              INFO       <11966.50> EO: Target(tgt-2644) tasked for imaging, image_time: 461.5, duration: 672.6
2026-11-09 20:10:22,123 sats.satellite.EO              INFO       <11966.50> EO: Target(tgt-2644) window enabled: 12055.0 to 12189.6
2026-11-09 20:10:22,123 sats.satellite.EO              INFO       <11966.50> EO: setting timed terminal event at 12189.6
2026-11-09 20:10:22,157 sats.satellite.EO              INFO       <12190.00> EO: timed termination at 12189.6 for Target(tgt-2644) window
2026-11-09 20:10:22,157 data.base                      INFO       <12190.00> Total reward: {}
2026-11-09 20:10:22,158 comm.communication             INFO       <12190.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,158 sats.satellite.EO              INFO       <12190.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,177 gym                            INFO       <12190.00> Step reward: 0.0
2026-11-09 20:10:22,196 gym                            INFO       <12190.00> === STARTING STEP ===
2026-11-09 20:10:22,197 sats.satellite.EO              INFO       <12190.00> EO: target index 18 tasked
2026-11-09 20:10:22,197 sats.satellite.EO              INFO       <12190.00> EO: Target(tgt-3537) tasked for imaging, image_time: 254.1, duration: 311.8
2026-11-09 20:10:22,198 sats.satellite.EO              INFO       <12190.00> EO: Target(tgt-3537) window enabled: 12262.8 to 12390.7
2026-11-09 20:10:22,198 sats.satellite.EO              INFO       <12190.00> EO: setting timed terminal event at 12390.7
2026-11-09 20:10:22,233 sats.satellite.EO              INFO       <12391.00> EO: timed termination at 12390.7 for Target(tgt-3537) window
2026-11-09 20:10:22,234 data.base                      INFO       <12391.00> Total reward: {}
2026-11-09 20:10:22,234 comm.communication             INFO       <12391.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,235 sats.satellite.EO              INFO       <12391.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,253 gym                            INFO       <12391.00> Step reward: 0.0
2026-11-09 20:10:22,273 gym                            INFO       <12391.00> === STARTING STEP ===
2026-11-09 20:10:22,273 sats.satellite.EO              INFO       <12391.00> EO: target index 23 tasked
2026-11-09 20:10:22,274 sats.satellite.EO              INFO       <12391.00> EO: Target(tgt-1447) tasked for imaging, image_time: 263.7, duration: 328.3
2026-11-09 20:10:22,274 sats.satellite.EO              INFO       <12391.00> EO: Target(tgt-1447) window enabled: 13206.1 to 13329.8
2026-11-09 20:10:22,275 sats.satellite.EO              INFO       <12391.00> EO: setting timed terminal event at 13329.8
2026-11-09 20:10:22,423 sats.satellite.EO              INFO       <13330.00> EO: timed termination at 13329.8 for Target(tgt-1447) window
2026-11-09 20:10:22,424 data.base                      INFO       <13330.00> Total reward: {}
2026-11-09 20:10:22,424 comm.communication             INFO       <13330.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,424 sats.satellite.EO              INFO       <13330.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,443 gym                            INFO       <13330.00> Step reward: 0.0
2026-11-09 20:10:22,461 gym                            INFO       <13330.00> === STARTING STEP ===
2026-11-09 20:10:22,462 sats.satellite.EO              INFO       <13330.00> EO: target index 3 tasked
2026-11-09 20:10:22,462 sats.satellite.EO              INFO       <13330.00> EO: Target(tgt-3541) tasked for imaging, image_time: 145.9, duration: 388.4
2026-11-09 20:10:22,463 sats.satellite.EO              INFO       <13330.00> EO: Target(tgt-3541) window enabled: 13269.5 to 13395.9
2026-11-09 20:10:22,463 sats.satellite.EO              INFO       <13330.00> EO: setting timed terminal event at 13395.9
2026-11-09 20:10:22,473 sats.satellite.EO              INFO       <13396.00> EO: timed termination at 13395.9 for Target(tgt-3541) window
2026-11-09 20:10:22,474 data.base                      INFO       <13396.00> Total reward: {}
2026-11-09 20:10:22,474 comm.communication             INFO       <13396.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,475 sats.satellite.EO              INFO       <13396.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,492 gym                            INFO       <13396.00> Step reward: 0.0
2026-11-09 20:10:22,511 gym                            INFO       <13396.00> === STARTING STEP ===
2026-11-09 20:10:22,512 sats.satellite.EO              INFO       <13396.00> EO: target index 27 tasked
2026-11-09 20:10:22,512 sats.satellite.EO              INFO       <13396.00> EO: Target(tgt-2316) tasked for imaging, image_time: 48.7, duration: 419.4
2026-11-09 20:10:22,513 sats.satellite.EO              INFO       <13396.00> EO: Target(tgt-2316) window enabled: 13806.4 to 13941.8
2026-11-09 20:10:22,513 sats.satellite.EO              INFO       <13396.00> EO: setting timed terminal event at 13941.8
2026-11-09 20:10:22,590 sats.satellite.EO              INFO       <13856.50> EO: imaged Target(tgt-2316)
2026-11-09 20:10:22,590 data.base                      INFO       <13856.50> Total reward: {'EO': 0.30167954458577917}
2026-11-09 20:10:22,591 comm.communication             INFO       <13856.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,591 sats.satellite.EO              INFO       <13856.50> EO: Satellite EO requires retasking
2026-11-09 20:10:22,610 gym                            INFO       <13856.50> Step reward: 0.30167954458577917
2026-11-09 20:10:22,628 gym                            INFO       <13856.50> === STARTING STEP ===
2026-11-09 20:10:22,629 sats.satellite.EO              INFO       <13856.50> EO: target index 13 tasked
2026-11-09 20:10:22,629 sats.satellite.EO              INFO       <13856.50> EO: Target(tgt-2625) tasked for imaging, image_time: 339.9, duration: 379.9
2026-11-09 20:10:22,630 sats.satellite.EO              INFO       <13856.50> EO: Target(tgt-2625) window enabled: 14126.2 to 14205.0
2026-11-09 20:10:22,630 sats.satellite.EO              INFO       <13856.50> EO: setting timed terminal event at 14205.0
2026-11-09 20:10:22,683 sats.satellite.EO              INFO       <14205.00> EO: timed termination at 14205.0 for Target(tgt-2625) window
2026-11-09 20:10:22,684 data.base                      INFO       <14205.00> Total reward: {}
2026-11-09 20:10:22,685 comm.communication             INFO       <14205.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,685 sats.satellite.EO              INFO       <14205.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,704 gym                            INFO       <14205.00> Step reward: 0.0
2026-11-09 20:10:22,722 gym                            INFO       <14205.00> === STARTING STEP ===
2026-11-09 20:10:22,723 sats.satellite.EO              INFO       <14205.00> EO: target index 2 tasked
2026-11-09 20:10:22,723 sats.satellite.EO              INFO       <14205.00> EO: Target(tgt-2638) tasked for imaging, image_time: 171.1, duration: 227.4
2026-11-09 20:10:22,724 sats.satellite.EO              INFO       <14205.00> EO: Target(tgt-2638) window enabled: 14183.7 to 14257.8
2026-11-09 20:10:22,724 sats.satellite.EO              INFO       <14205.00> EO: setting timed terminal event at 14257.8
2026-11-09 20:10:22,733 sats.satellite.EO              INFO       <14258.00> EO: timed termination at 14257.8 for Target(tgt-2638) window
2026-11-09 20:10:22,733 data.base                      INFO       <14258.00> Total reward: {}
2026-11-09 20:10:22,733 comm.communication             INFO       <14258.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,734 sats.satellite.EO              INFO       <14258.00> EO: Satellite EO requires retasking
2026-11-09 20:10:22,751 gym                            INFO       <14258.00> Step reward: 0.0
2026-11-09 20:10:22,770 gym                            INFO       <14258.00> === STARTING STEP ===
2026-11-09 20:10:22,771 sats.satellite.EO              INFO       <14258.00> EO: target index 11 tasked
2026-11-09 20:10:22,771 sats.satellite.EO              INFO       <14258.00> EO: Target(tgt-2015) tasked for imaging, image_time: 347.8, duration: 530.3
2026-11-09 20:10:22,771 sats.satellite.EO              INFO       <14258.00> EO: Target(tgt-2015) window enabled: 14300.4 to 14435.2
2026-11-09 20:10:22,772 sats.satellite.EO              INFO       <14258.00> EO: setting timed terminal event at 14435.2
2026-11-09 20:10:22,798 sats.satellite.EO              INFO       <14435.50> EO: timed termination at 14435.2 for Target(tgt-2015) window
2026-11-09 20:10:22,799 data.base                      INFO       <14435.50> Total reward: {}
2026-11-09 20:10:22,800 comm.communication             INFO       <14435.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,800 sats.satellite.EO              INFO       <14435.50> EO: Satellite EO requires retasking
2026-11-09 20:10:22,818 gym                            INFO       <14435.50> Step reward: 0.0
2026-11-09 20:10:22,837 gym                            INFO       <14435.50> === STARTING STEP ===
2026-11-09 20:10:22,838 sats.satellite.EO              INFO       <14435.50> EO: target index 28 tasked
2026-11-09 20:10:22,838 sats.satellite.EO              INFO       <14435.50> EO: Target(tgt-1751) tasked for imaging, image_time: 139.5, duration: 195.2
2026-11-09 20:10:22,839 sats.satellite.EO              INFO       <14435.50> EO: Target(tgt-1751) window enabled: 14901.9 to 15028.4
2026-11-09 20:10:22,839 sats.satellite.EO              INFO       <14435.50> EO: setting timed terminal event at 15028.4
2026-11-09 20:10:22,938 sats.satellite.EO              INFO       <15028.50> EO: timed termination at 15028.4 for Target(tgt-1751) window
2026-11-09 20:10:22,939 data.base                      INFO       <15028.50> Total reward: {}
2026-11-09 20:10:22,939 comm.communication             INFO       <15028.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:22,940 sats.satellite.EO              INFO       <15028.50> EO: Satellite EO requires retasking
2026-11-09 20:10:22,941 sats.satellite.EO              INFO       <15028.50> EO: Finding opportunity windows from 18600.00 to 19200.00 seconds
2026-11-09 20:10:23,022 gym                            INFO       <15028.50> Step reward: 0.0
2026-11-09 20:10:23,041 gym                            INFO       <15028.50> === STARTING STEP ===
2026-11-09 20:10:23,041 sats.satellite.EO              INFO       <15028.50> EO: target index 10 tasked
2026-11-09 20:10:23,042 sats.satellite.EO              INFO       <15028.50> EO: Target(tgt-3092) tasked for imaging, image_time: 0.0, duration: 771.1
2026-11-09 20:10:23,042 sats.satellite.EO              INFO       <15028.50> EO: Target(tgt-3092) window enabled: 15124.3 to 15215.9
2026-11-09 20:10:23,042 sats.satellite.EO              INFO       <15028.50> EO: setting timed terminal event at 15215.9
2026-11-09 20:10:23,060 sats.satellite.EO              INFO       <15125.50> EO: imaged Target(tgt-3092)
2026-11-09 20:10:23,061 data.base                      INFO       <15125.50> Total reward: {'EO': 0.5789818568445113}
2026-11-09 20:10:23,061 comm.communication             INFO       <15125.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,061 sats.satellite.EO              INFO       <15125.50> EO: Satellite EO requires retasking
2026-11-09 20:10:23,083 gym                            INFO       <15125.50> Step reward: 0.5789818568445113
2026-11-09 20:10:23,105 gym                            INFO       <15125.50> === STARTING STEP ===
2026-11-09 20:10:23,106 sats.satellite.EO              INFO       <15125.50> EO: target index 26 tasked
2026-11-09 20:10:23,106 sats.satellite.EO              INFO       <15125.50> EO: Target(tgt-1704) tasked for imaging, image_time: 666.0, duration: 1076.7
2026-11-09 20:10:23,107 sats.satellite.EO              INFO       <15125.50> EO: Target(tgt-1704) window enabled: 15530.3 to 15660.9
2026-11-09 20:10:23,107 sats.satellite.EO              INFO       <15125.50> EO: setting timed terminal event at 15660.9
2026-11-09 20:10:23,184 sats.satellite.EO              INFO       <15661.00> EO: timed termination at 15660.9 for Target(tgt-1704) window
2026-11-09 20:10:23,185 data.base                      INFO       <15661.00> Total reward: {}
2026-11-09 20:10:23,186 comm.communication             INFO       <15661.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,186 sats.satellite.EO              INFO       <15661.00> EO: Satellite EO requires retasking
2026-11-09 20:10:23,187 sats.satellite.EO              INFO       <15661.00> EO: Finding opportunity windows from 19200.00 to 19800.00 seconds
2026-11-09 20:10:23,264 gym                            INFO       <15661.00> Step reward: 0.0
2026-11-09 20:10:23,283 gym                            INFO       <15661.00> === STARTING STEP ===
2026-11-09 20:10:23,284 sats.satellite.EO              INFO       <15661.00> EO: target index 15 tasked
2026-11-09 20:10:23,284 sats.satellite.EO              INFO       <15661.00> EO: Target(tgt-107) tasked for imaging, image_time: 119.5, duration: 331.4
2026-11-09 20:10:23,285 sats.satellite.EO              INFO       <15661.00> EO: Target(tgt-107) window enabled: 15891.1 to 16021.9
2026-11-09 20:10:23,285 sats.satellite.EO              INFO       <15661.00> EO: setting timed terminal event at 16021.9
2026-11-09 20:10:23,345 sats.satellite.EO              INFO       <16012.50> EO: imaged Target(tgt-107)
2026-11-09 20:10:23,346 data.base                      INFO       <16012.50> Total reward: {'EO': 0.13766274094560316}
2026-11-09 20:10:23,346 comm.communication             INFO       <16012.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,346 sats.satellite.EO              INFO       <16012.50> EO: Satellite EO requires retasking
2026-11-09 20:10:23,365 gym                            INFO       <16012.50> Step reward: 0.13766274094560316
2026-11-09 20:10:23,384 gym                            INFO       <16012.50> === STARTING STEP ===
2026-11-09 20:10:23,384 sats.satellite.EO              INFO       <16012.50> EO: target index 17 tasked
2026-11-09 20:10:23,384 sats.satellite.EO              INFO       <16012.50> EO: Target(tgt-1083) tasked for imaging, image_time: 351.9, duration: 658.5
2026-11-09 20:10:23,385 sats.satellite.EO              INFO       <16012.50> EO: Target(tgt-1083) window enabled: 16525.9 to 16661.7
2026-11-09 20:10:23,385 sats.satellite.EO              INFO       <16012.50> EO: setting timed terminal event at 16661.7
2026-11-09 20:10:23,479 sats.satellite.EO              INFO       <16662.00> EO: timed termination at 16661.7 for Target(tgt-1083) window
2026-11-09 20:10:23,480 data.base                      INFO       <16662.00> Total reward: {}
2026-11-09 20:10:23,480 comm.communication             INFO       <16662.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,481 sats.satellite.EO              INFO       <16662.00> EO: Satellite EO requires retasking
2026-11-09 20:10:23,482 sats.satellite.EO              INFO       <16662.00> EO: Finding opportunity windows from 19800.00 to 21000.00 seconds
2026-11-09 20:10:23,604 gym                            INFO       <16662.00> Step reward: 0.0
2026-11-09 20:10:23,623 gym                            INFO       <16662.00> === STARTING STEP ===
2026-11-09 20:10:23,624 sats.satellite.EO              INFO       <16662.00> EO: target index 14 tasked
2026-11-09 20:10:23,624 sats.satellite.EO              INFO       <16662.00> EO: Target(tgt-1913) tasked for imaging, image_time: 206.6, duration: 429.4
2026-11-09 20:10:23,625 sats.satellite.EO              INFO       <16662.00> EO: Target(tgt-1913) window enabled: 16973.4 to 17064.3
2026-11-09 20:10:23,625 sats.satellite.EO              INFO       <16662.00> EO: setting timed terminal event at 17064.3
2026-11-09 20:10:23,685 sats.satellite.EO              INFO       <17064.50> EO: timed termination at 17064.3 for Target(tgt-1913) window
2026-11-09 20:10:23,685 data.base                      INFO       <17064.50> Total reward: {}
2026-11-09 20:10:23,686 comm.communication             INFO       <17064.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,686 sats.satellite.EO              INFO       <17064.50> EO: Satellite EO requires retasking
2026-11-09 20:10:23,704 gym                            INFO       <17064.50> Step reward: 0.0
2026-11-09 20:10:23,723 gym                            INFO       <17064.50> === STARTING STEP ===
2026-11-09 20:10:23,724 sats.satellite.EO              INFO       <17064.50> EO: target index 11 tasked
2026-11-09 20:10:23,724 sats.satellite.EO              INFO       <17064.50> EO: Target(tgt-203) tasked for imaging, image_time: 549.7, duration: 1033.8
2026-11-09 20:10:23,725 sats.satellite.EO              INFO       <17064.50> EO: Target(tgt-203) window enabled: 17202.5 to 17314.5
2026-11-09 20:10:23,725 sats.satellite.EO              INFO       <17064.50> EO: setting timed terminal event at 17314.5
2026-11-09 20:10:23,763 sats.satellite.EO              INFO       <17315.00> EO: timed termination at 17314.5 for Target(tgt-203) window
2026-11-09 20:10:23,764 data.base                      INFO       <17315.00> Total reward: {}
2026-11-09 20:10:23,765 comm.communication             INFO       <17315.00> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,765 sats.satellite.EO              INFO       <17315.00> EO: Satellite EO requires retasking
2026-11-09 20:10:23,766 sats.satellite.EO              INFO       <17315.00> EO: Finding opportunity windows from 21000.00 to 21600.00 seconds
2026-11-09 20:10:23,847 gym                            INFO       <17315.00> Step reward: 0.0
2026-11-09 20:10:23,866 gym                            INFO       <17315.00> === STARTING STEP ===
2026-11-09 20:10:23,867 sats.satellite.EO              INFO       <17315.00> EO: target index 31 tasked
2026-11-09 20:10:23,867 sats.satellite.EO              INFO       <17315.00> EO: Target(tgt-3232) tasked for imaging, image_time: 79.6, duration: 153.4
2026-11-09 20:10:23,867 sats.satellite.EO              INFO       <17315.00> EO: Target(tgt-3232) window enabled: 17995.3 to 18074.3
2026-11-09 20:10:23,868 sats.satellite.EO              INFO       <17315.00> EO: setting timed terminal event at 18074.3
2026-11-09 20:10:23,982 sats.satellite.EO              INFO       <18074.50> EO: timed termination at 18074.3 for Target(tgt-3232) window
2026-11-09 20:10:23,983 data.base                      INFO       <18074.50> Total reward: {}
2026-11-09 20:10:23,984 comm.communication             INFO       <18074.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:23,984 sats.satellite.EO              INFO       <18074.50> EO: Satellite EO requires retasking
2026-11-09 20:10:23,985 sats.satellite.EO              INFO       <18074.50> EO: Finding opportunity windows from 21600.00 to 22200.00 seconds
2026-11-09 20:10:24,067 gym                            INFO       <18074.50> Step reward: 0.0
2026-11-09 20:10:24,090 gym                            INFO       <18074.50> === STARTING STEP ===
2026-11-09 20:10:24,091 sats.satellite.EO              INFO       <18074.50> EO: target index 22 tasked
2026-11-09 20:10:24,091 sats.satellite.EO              INFO       <18074.50> EO: Target(tgt-3646) tasked for imaging, image_time: 98.4, duration: 199.1
2026-11-09 20:10:24,091 sats.satellite.EO              INFO       <18074.50> EO: Target(tgt-3646) window enabled: 18480.5 to 18613.9
2026-11-09 20:10:24,092 sats.satellite.EO              INFO       <18074.50> EO: setting timed terminal event at 18613.9
2026-11-09 20:10:24,109 data.base                      INFO       <18157.50> Total reward: {}
2026-11-09 20:10:24,110 comm.communication             INFO       <18157.50> Optimizing data communication between all pairs of satellites
2026-11-09 20:10:24,132 gym                            INFO       <18157.50> Step reward: 0.0
2026-11-09 20:10:24,132 gym                            INFO       <18157.50> Episode terminated: False
2026-11-09 20:10:24,133 gym                            INFO       <18157.50> Episode truncated: True
Episode complete.

After running the simulation, we can check the total reward, the number of unique targets that were imaged at least once, and the number of duplicated (re-imaged) targets collected by the rewarder.

[11]:
print("Total reward:", env.rewarder.cum_reward)
print(
    "Number of unique imaged targets:",
    len(set(env.rewarder.data.imaged)),
)
print(
    "Number of duplicated targets:",
    env.rewarder.data.duplicates,
)
Total reward: {'EO': np.float64(9.970661437907387)}
Number of unique imaged targets: 25
Number of duplicated targets: 0

Check Training with RLlib PPO for an example on how to train the agent in this environment.