Agile Earth-Observing Satellite Environment
This example demonstrates the environment configuration for a power-free and power-constrained agile Earth-observing satellite. These environments reflect the configuration and values from an upcoming journal paper.
[1]:
import numpy as np
from Basilisk.architecture import bskLogging
from Basilisk.utilities import orbitalMotion
from bsk_rl import SatelliteTasking, act, data, obs, sats, scene
from bsk_rl.sim import fsw
from bsk_rl.utils.orbital import random_orbit, rv2HN
bskLogging.setDefaultLogLevel(bskLogging.BSK_WARNING)
Power-Free Environment
First, a function for generating satellite types is introduced. This function can generate one of three different observation types, and can choose to include the time through episode in the observation.
[2]:
def satellite_generator(observation, n_ahead=32, include_time=False):
"""_summary_
Args:
observation: Pick from "S1", "S2", "S3"
n_ahead: Number of requests to include in the observation and action spaces
include_time: Whether to include time through episode in the observation
"""
assert observation in ["S1", "S2", "S3"]
class CustomSatellite(sats.ImagingSatellite):
action_spec = [act.Image(n_ahead_image=n_ahead)]
if observation == "S1":
observation_spec = [
obs.SatProperties(
dict(prop="omega_BP_P", norm=0.03),
dict(prop="c_hat_P"),
dict(prop="r_BN_P", norm=orbitalMotion.REQ_EARTH * 1e3),
dict(prop="v_BN_P", norm=7616.5),
),
obs.OpportunityProperties(
dict(prop="priority"),
dict(prop="r_LP_P", norm=orbitalMotion.REQ_EARTH * 1e3),
type="target",
n_ahead_observe=n_ahead,
),
]
elif observation == "S2":
observation_spec = [
obs.SatProperties(
dict(prop="omega_BH_H", 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),
),
obs.OpportunityProperties(
dict(prop="priority"),
dict(prop="r_LB_H", norm=orbitalMotion.REQ_EARTH * 1e3),
type="target",
n_ahead_observe=n_ahead,
),
]
elif observation == "S3":
observation_spec = [
obs.SatProperties(
dict(prop="omega_BH_H", 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),
),
obs.OpportunityProperties(
dict(prop="priority"),
dict(prop="r_LB_H", norm=800 * 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),
type="target",
n_ahead_observe=n_ahead,
),
]
if include_time:
observation_spec.append(obs.Time())
fsw_type = fsw.SteeringImagerFSWModel
return CustomSatellite
Next, the parameters for the satellite are defined.
[3]:
SAT_ARGS = dict(
imageAttErrorRequirement=0.01,
imageRateErrorRequirement=0.01,
batteryStorageCapacity=80.0 * 3600 * 100,
storedCharge_Init=80.0 * 3600 * 100.0,
dataStorageCapacity=200 * 8e6 * 100,
u_max=0.4,
imageTargetMinimumElevation=np.arctan(800 / 500),
K1=0.25,
K3=3.0,
omega_max=np.radians(5),
servo_Ki=5.0,
servo_P=150 / 5,
oe=lambda: random_orbit(alt=800),
)
Finally, the environment can be initialized.
[4]:
duration = 5700.0 * 5 # 5 orbits
target_distribution = "uniform"
n_targets = 3000
n_ahead = 32
if target_distribution == "uniform":
targets = scene.UniformTargets(n_targets)
elif target_distribution == "cities":
targets = scene.CityTargets(n_targets)
env = SatelliteTasking(
satellite=satellite_generator(observation="S3", n_ahead=32, include_time=False)(
name="EO1",
sat_args=SAT_ARGS,
),
scenario=targets,
rewarder=data.UniqueImageReward(),
sim_rate=0.5,
max_step_duration=300.0,
time_limit=duration,
failure_penalty=0.0,
terminate_on_time_limit=True,
log_level="INFO",
)
_ = env.reset()
for i in range(5):
env.step(env.action_space.sample())
2025-02-13 15:16:51,667 gym INFO Resetting environment with seed=3834134456
2025-02-13 15:16:51,668 scene.targets INFO Generating 3000 targets
2025-02-13 15:16:51,799 sats.satellite.EO1 INFO <0.00> EO1: Finding opportunity windows from 0.00 to 28500.00 seconds
2025-02-13 15:16:52,307 gym INFO <0.00> Environment reset
2025-02-13 15:16:52,308 gym INFO <0.00> === STARTING STEP ===
2025-02-13 15:16:52,308 sats.satellite.EO1 INFO <0.00> EO1: target index 21 tasked
2025-02-13 15:16:52,309 sats.satellite.EO1 INFO <0.00> EO1: Target(tgt-2268) tasked for imaging
2025-02-13 15:16:52,311 sats.satellite.EO1 INFO <0.00> EO1: Target(tgt-2268) window enabled: 468.2 to 543.0
2025-02-13 15:16:52,311 sats.satellite.EO1 INFO <0.00> EO1: setting timed terminal event at 543.0
2025-02-13 15:16:52,380 sim.simulator INFO <300.00> Max step duration reached
2025-02-13 15:16:52,382 data.base INFO <300.00> Data reward: {}
2025-02-13 15:16:52,382 comm.communication INFO <300.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:52,394 gym INFO <300.00> Step reward: 0.0
2025-02-13 15:16:52,395 gym INFO <300.00> === STARTING STEP ===
2025-02-13 15:16:52,396 sats.satellite.EO1 INFO <300.00> EO1: target index 8 tasked
2025-02-13 15:16:52,396 sats.satellite.EO1 INFO <300.00> EO1: Target(tgt-697) tasked for imaging
2025-02-13 15:16:52,398 sats.satellite.EO1 INFO <300.00> EO1: Target(tgt-697) window enabled: 368.9 to 489.9
2025-02-13 15:16:52,398 sats.satellite.EO1 INFO <300.00> EO1: setting timed terminal event at 489.9
2025-02-13 15:16:52,415 sats.satellite.EO1 INFO <370.00> EO1: imaged Target(tgt-697)
2025-02-13 15:16:52,417 data.base INFO <370.00> Data reward: {'EO1': 0.4521306121638049}
2025-02-13 15:16:52,417 comm.communication INFO <370.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:52,419 sats.satellite.EO1 INFO <370.00> EO1: Satellite EO1 requires retasking
2025-02-13 15:16:52,429 gym INFO <370.00> Step reward: 0.4521306121638049
2025-02-13 15:16:52,430 gym INFO <370.00> === STARTING STEP ===
2025-02-13 15:16:52,431 sats.satellite.EO1 INFO <370.00> EO1: target index 0 tasked
2025-02-13 15:16:52,431 sats.satellite.EO1 INFO <370.00> EO1: Target(tgt-2678) tasked for imaging
2025-02-13 15:16:52,433 sats.satellite.EO1 INFO <370.00> EO1: Target(tgt-2678) window enabled: 320.3 to 408.2
2025-02-13 15:16:52,433 sats.satellite.EO1 INFO <370.00> EO1: setting timed terminal event at 408.2
2025-02-13 15:16:52,443 sats.satellite.EO1 INFO <408.50> EO1: timed termination at 408.2 for Target(tgt-2678) window
2025-02-13 15:16:52,445 data.base INFO <408.50> Data reward: {}
2025-02-13 15:16:52,446 comm.communication INFO <408.50> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:52,448 sats.satellite.EO1 INFO <408.50> EO1: Satellite EO1 requires retasking
2025-02-13 15:16:52,458 gym INFO <408.50> Step reward: 0.0
2025-02-13 15:16:52,459 gym INFO <408.50> === STARTING STEP ===
2025-02-13 15:16:52,459 sats.satellite.EO1 INFO <408.50> EO1: target index 11 tasked
2025-02-13 15:16:52,460 sats.satellite.EO1 INFO <408.50> EO1: Target(tgt-860) tasked for imaging
2025-02-13 15:16:52,462 sats.satellite.EO1 INFO <408.50> EO1: Target(tgt-860) window enabled: 520.0 to 652.4
2025-02-13 15:16:52,462 sats.satellite.EO1 INFO <408.50> EO1: setting timed terminal event at 652.4
2025-02-13 15:16:52,487 sats.satellite.EO1 INFO <521.00> EO1: imaged Target(tgt-860)
2025-02-13 15:16:52,490 data.base INFO <521.00> Data reward: {'EO1': 0.9127542586368591}
2025-02-13 15:16:52,490 comm.communication INFO <521.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:52,492 sats.satellite.EO1 INFO <521.00> EO1: Satellite EO1 requires retasking
2025-02-13 15:16:52,502 gym INFO <521.00> Step reward: 0.9127542586368591
2025-02-13 15:16:52,503 gym INFO <521.00> === STARTING STEP ===
2025-02-13 15:16:52,503 sats.satellite.EO1 INFO <521.00> EO1: target index 6 tasked
2025-02-13 15:16:52,503 sats.satellite.EO1 INFO <521.00> EO1: Target(tgt-1667) tasked for imaging
2025-02-13 15:16:52,505 sats.satellite.EO1 INFO <521.00> EO1: Target(tgt-1667) window enabled: 527.3 to 658.3
2025-02-13 15:16:52,506 sats.satellite.EO1 INFO <521.00> EO1: setting timed terminal event at 658.3
2025-02-13 15:16:52,513 sats.satellite.EO1 INFO <549.50> EO1: imaged Target(tgt-1667)
2025-02-13 15:16:52,515 data.base INFO <549.50> Data reward: {'EO1': 0.8568378292895359}
2025-02-13 15:16:52,516 comm.communication INFO <549.50> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:52,518 sats.satellite.EO1 INFO <549.50> EO1: Satellite EO1 requires retasking
2025-02-13 15:16:52,527 gym INFO <549.50> Step reward: 0.8568378292895359
Power-Constrained Environment
The power-constrained environment is like the power-free environment, but with an additional battery management requirement. The satellite has additional observation elements to be able to account for power.
First, the upcoming reward density observation is defined.
[5]:
class Density(obs.Observation):
def __init__(
self,
interval_duration=60 * 3,
intervals=10,
norm=3,
):
self.satellite: "sats.AccessSatellite"
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
The satellite generator function is then defined, along with some additional observations.
[6]:
def wheel_speed_3(sat):
return np.array(sat.dynamics.wheel_speeds[0:3]) / 630
def s_hat_H(sat):
r_SN_N = (
sat.simulator.world.gravFactory.spiceObject.planetStateOutMsgs[
sat.simulator.world.sun_index
]
.read()
.PositionVector
)
r_BN_N = sat.dynamics.r_BN_N
r_SB_N = np.array(r_SN_N) - np.array(r_BN_N)
r_SB_H = rv2HN(r_BN_N, sat.dynamics.v_BN_N) @ r_SB_N
return r_SB_H / np.linalg.norm(r_SB_H)
def power_sat_generator(n_ahead=32, include_time=False):
class PowerSat(sats.ImagingSatellite):
action_spec = [act.Image(n_ahead_image=n_ahead), act.Charge()]
observation_spec = [
obs.SatProperties(
dict(prop="omega_BH_H", 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),
dict(prop="battery_charge_fraction"),
dict(prop="wheel_speed_3", fn=wheel_speed_3),
dict(prop="s_hat_H", fn=s_hat_H),
),
obs.OpportunityProperties(
dict(prop="priority"),
dict(prop="r_LB_H", norm=800 * 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),
type="target",
n_ahead_observe=n_ahead,
),
obs.Eclipse(norm=5700),
Density(intervals=20, norm=5),
]
if include_time:
observation_spec.append(obs.Time())
fsw_type = fsw.SteeringImagerFSWModel
return PowerSat
Satellite parameters are also modified for the power-constrained environment.
[7]:
SAT_ARGS_POWER = {}
SAT_ARGS_POWER.update(SAT_ARGS)
SAT_ARGS_POWER.update(
dict(
batteryStorageCapacity=120.0 * 3600,
storedCharge_Init=lambda: 120.0 * 3600 * np.random.uniform(0.4, 1.0),
rwBasePower=20.4,
instrumentPowerDraw=-10,
thrusterPowerDraw=-30,
nHat_B=np.array([0, 0, -1]),
wheelSpeeds=lambda: np.random.uniform(-2000, 2000, 3),
desatAttitude="nadir",
)
)
Finally, the environment can be initialized.
[8]:
duration = 5700.0 * 5 # 5 orbits
target_distribution = "uniform"
n_targets = 3000
n_ahead = 32
if target_distribution == "uniform":
targets = scene.UniformTargets(n_targets)
elif target_distribution == "cities":
targets = scene.CityTargets(n_targets)
env = SatelliteTasking(
satellite=power_sat_generator(n_ahead=32, include_time=False)(
name="EO1-power",
sat_args=SAT_ARGS_POWER,
),
scenario=targets,
rewarder=data.UniqueImageReward(),
sim_rate=0.5,
max_step_duration=300.0,
time_limit=duration,
failure_penalty=0.0,
terminate_on_time_limit=True,
log_level="INFO",
)
_ = env.reset()
for i in range(5):
env.step(env.action_space.sample())
2025-02-13 15:16:52,550 WARNING Creating logger for new env on PID=96160. Old environments in process may now log times incorrectly.
2025-02-13 15:16:52,685 gym INFO Resetting environment with seed=557511160
2025-02-13 15:16:52,687 scene.targets INFO Generating 3000 targets
2025-02-13 15:16:52,784 sats.satellite.EO1-power INFO <0.00> EO1-power: Finding opportunity windows from 0.00 to 28500.00 seconds
2025-02-13 15:16:53,502 gym INFO <0.00> Environment reset
2025-02-13 15:16:53,502 gym INFO <0.00> === STARTING STEP ===
2025-02-13 15:16:53,503 sats.satellite.EO1-power INFO <0.00> EO1-power: target index 19 tasked
2025-02-13 15:16:53,503 sats.satellite.EO1-power INFO <0.00> EO1-power: Target(tgt-109) tasked for imaging
2025-02-13 15:16:53,505 sats.satellite.EO1-power INFO <0.00> EO1-power: Target(tgt-109) window enabled: 549.9 to 655.3
2025-02-13 15:16:53,505 sats.satellite.EO1-power INFO <0.00> EO1-power: setting timed terminal event at 655.3
2025-02-13 15:16:53,582 sim.simulator INFO <300.00> Max step duration reached
2025-02-13 15:16:53,584 data.base INFO <300.00> Data reward: {}
2025-02-13 15:16:53,584 comm.communication INFO <300.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:53,598 gym INFO <300.00> Step reward: 0.0
2025-02-13 15:16:53,599 gym INFO <300.00> === STARTING STEP ===
2025-02-13 15:16:53,600 sats.satellite.EO1-power INFO <300.00> EO1-power: target index 17 tasked
2025-02-13 15:16:53,600 sats.satellite.EO1-power INFO <300.00> EO1-power: Target(tgt-1237) tasked for imaging
2025-02-13 15:16:53,602 sats.satellite.EO1-power INFO <300.00> EO1-power: Target(tgt-1237) window enabled: 704.0 to 804.3
2025-02-13 15:16:53,602 sats.satellite.EO1-power INFO <300.00> EO1-power: setting timed terminal event at 804.3
2025-02-13 15:16:53,671 sim.simulator INFO <600.00> Max step duration reached
2025-02-13 15:16:53,674 data.base INFO <600.00> Data reward: {}
2025-02-13 15:16:53,674 comm.communication INFO <600.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:53,688 gym INFO <600.00> Step reward: 0.0
2025-02-13 15:16:53,689 gym INFO <600.00> === STARTING STEP ===
2025-02-13 15:16:53,690 sats.satellite.EO1-power INFO <600.00> EO1-power: action_charge tasked for 1000000000.0 seconds
2025-02-13 15:16:53,690 sats.satellite.EO1-power INFO <600.00> EO1-power: setting timed terminal event at 1000000600.0
2025-02-13 15:16:53,759 sim.simulator INFO <900.00> Max step duration reached
2025-02-13 15:16:53,761 data.base INFO <900.00> Data reward: {}
2025-02-13 15:16:53,762 comm.communication INFO <900.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:53,775 gym INFO <900.00> Step reward: 0.0
2025-02-13 15:16:53,776 gym INFO <900.00> === STARTING STEP ===
2025-02-13 15:16:53,776 sats.satellite.EO1-power INFO <900.00> EO1-power: target index 13 tasked
2025-02-13 15:16:53,777 sats.satellite.EO1-power INFO <900.00> EO1-power: Target(tgt-2932) tasked for imaging
2025-02-13 15:16:53,779 sats.satellite.EO1-power INFO <900.00> EO1-power: Target(tgt-2932) window enabled: 1125.7 to 1244.8
2025-02-13 15:16:53,779 sats.satellite.EO1-power INFO <900.00> EO1-power: setting timed terminal event at 1244.8
2025-02-13 15:16:53,831 sats.satellite.EO1-power INFO <1127.00> EO1-power: imaged Target(tgt-2932)
2025-02-13 15:16:53,834 data.base INFO <1127.00> Data reward: {'EO1-power': 0.26460427843956014}
2025-02-13 15:16:53,834 comm.communication INFO <1127.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:53,836 sats.satellite.EO1-power INFO <1127.00> EO1-power: Satellite EO1-power requires retasking
2025-02-13 15:16:53,848 gym INFO <1127.00> Step reward: 0.26460427843956014
2025-02-13 15:16:53,849 gym INFO <1127.00> === STARTING STEP ===
2025-02-13 15:16:53,850 sats.satellite.EO1-power INFO <1127.00> EO1-power: target index 0 tasked
2025-02-13 15:16:53,850 sats.satellite.EO1-power INFO <1127.00> EO1-power: Target(tgt-1163) tasked for imaging
2025-02-13 15:16:53,852 sats.satellite.EO1-power INFO <1127.00> EO1-power: Target(tgt-1163) window enabled: 1136.3 to 1159.6
2025-02-13 15:16:53,852 sats.satellite.EO1-power INFO <1127.00> EO1-power: setting timed terminal event at 1159.6
2025-02-13 15:16:53,861 sats.satellite.EO1-power INFO <1160.00> EO1-power: timed termination at 1159.6 for Target(tgt-1163) window
2025-02-13 15:16:53,863 data.base INFO <1160.00> Data reward: {}
2025-02-13 15:16:53,863 comm.communication INFO <1160.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:53,865 sats.satellite.EO1-power INFO <1160.00> EO1-power: Satellite EO1-power requires retasking
2025-02-13 15:16:53,877 gym INFO <1160.00> Step reward: 0.0
Enabling Vizard
Vizard visualization can be enabled by setting the vizard_dir
to save the Vizard binary to. Here, it is saved to /tmp/vizard
, but this can be modified. Scripting settings can also be passed to Vizard.
[9]:
env = SatelliteTasking(
satellite=satellite_generator(observation="S3", n_ahead=32, include_time=False)(
name="EO1",
sat_args=SAT_ARGS,
),
scenario=scene.CityTargets(100),
rewarder=data.UniqueImageReward(),
sim_rate=0.5,
max_step_duration=300.0,
time_limit=duration,
failure_penalty=0.0,
terminate_on_time_limit=True,
log_level="INFO",
vizard_dir="/tmp/vizard",
vizard_settings=dict(showLocationLabels=1),
)
_ = env.reset()
for i in range(5):
env.step(env.action_space.sample())
2025-02-13 15:16:53,883 WARNING Creating logger for new env on PID=96160. Old environments in process may now log times incorrectly.
2025-02-13 15:16:53,884 gym WARNING Vizard settings provided but Vizard is not enabled. Ignoring settings.
2025-02-13 15:16:53,970 gym INFO Resetting environment with seed=1842140160
2025-02-13 15:16:53,991 scene.targets INFO Generating 100 targets
2025-02-13 15:16:54,128 sats.satellite.EO1 INFO <0.00> EO1: Finding opportunity windows from 0.00 to 28500.00 seconds
2025-02-13 15:16:54,201 gym INFO <0.00> Environment reset
2025-02-13 15:16:54,201 gym INFO <0.00> === STARTING STEP ===
2025-02-13 15:16:54,201 sats.satellite.EO1 INFO <0.00> EO1: target index 16 tasked
2025-02-13 15:16:54,202 sats.satellite.EO1 INFO <0.00> EO1: Target(Gwoza, NG) tasked for imaging
2025-02-13 15:16:54,202 sats.satellite.EO1 INFO <0.00> EO1: Target(Gwoza, NG) window enabled: 15636.1 to 15690.5
2025-02-13 15:16:54,203 sats.satellite.EO1 INFO <0.00> EO1: setting timed terminal event at 15690.5
2025-02-13 15:16:54,299 sim.simulator INFO <300.00> Max step duration reached
2025-02-13 15:16:54,300 data.base INFO <300.00> Data reward: {}
2025-02-13 15:16:54,301 comm.communication INFO <300.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:54,311 gym INFO <300.00> Step reward: 0.0
2025-02-13 15:16:54,313 gym INFO <300.00> === STARTING STEP ===
2025-02-13 15:16:54,313 sats.satellite.EO1 INFO <300.00> EO1: target index 25 tasked
2025-02-13 15:16:54,314 sats.satellite.EO1 INFO <300.00> EO1: Target(Houzhuang, CN) tasked for imaging
2025-02-13 15:16:54,315 sats.satellite.EO1 INFO <300.00> EO1: Target(Houzhuang, CN) window enabled: 4433.5 to 4463.0
2025-02-13 15:16:54,315 sats.satellite.EO1 INFO <300.00> EO1: setting timed terminal event at 4463.0
Saving Viz file to /tmp/vizard/_VizFiles/viz_1739485014_UnityViz.bin
2025-02-13 15:16:54,421 sim.simulator INFO <600.00> Max step duration reached
2025-02-13 15:16:54,422 data.base INFO <600.00> Data reward: {}
2025-02-13 15:16:54,422 comm.communication INFO <600.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:54,432 gym INFO <600.00> Step reward: 0.0
2025-02-13 15:16:54,433 gym INFO <600.00> === STARTING STEP ===
2025-02-13 15:16:54,434 sats.satellite.EO1 INFO <600.00> EO1: target index 12 tasked
2025-02-13 15:16:54,434 sats.satellite.EO1 INFO <600.00> EO1: Target(Zhujiagua, CN) tasked for imaging
2025-02-13 15:16:54,435 sats.satellite.EO1 INFO <600.00> EO1: Target(Zhujiagua, CN) window enabled: 4391.7 to 4521.9
2025-02-13 15:16:54,435 sats.satellite.EO1 INFO <600.00> EO1: setting timed terminal event at 4521.9
2025-02-13 15:16:54,537 sim.simulator INFO <900.00> Max step duration reached
2025-02-13 15:16:54,538 data.base INFO <900.00> Data reward: {}
2025-02-13 15:16:54,539 comm.communication INFO <900.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:54,548 gym INFO <900.00> Step reward: 0.0
2025-02-13 15:16:54,549 gym INFO <900.00> === STARTING STEP ===
2025-02-13 15:16:54,550 sats.satellite.EO1 INFO <900.00> EO1: target index 4 tasked
2025-02-13 15:16:54,550 sats.satellite.EO1 INFO <900.00> EO1: Target(Dabhaura, IN) tasked for imaging
2025-02-13 15:16:54,551 sats.satellite.EO1 INFO <900.00> EO1: Target(Dabhaura, IN) window enabled: 3912.7 to 4026.0
2025-02-13 15:16:54,551 sats.satellite.EO1 INFO <900.00> EO1: setting timed terminal event at 4026.0
2025-02-13 15:16:54,660 sim.simulator INFO <1200.00> Max step duration reached
2025-02-13 15:16:54,661 data.base INFO <1200.00> Data reward: {}
2025-02-13 15:16:54,662 comm.communication INFO <1200.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:54,673 gym INFO <1200.00> Step reward: 0.0
2025-02-13 15:16:54,675 gym INFO <1200.00> === STARTING STEP ===
2025-02-13 15:16:54,675 sats.satellite.EO1 INFO <1200.00> EO1: target index 23 tasked
2025-02-13 15:16:54,676 sats.satellite.EO1 INFO <1200.00> EO1: Target(Chirchiq, UZ) tasked for imaging
2025-02-13 15:16:54,676 sats.satellite.EO1 INFO <1200.00> EO1: Target(Chirchiq, UZ) window enabled: 16604.1 to 16736.1
2025-02-13 15:16:54,677 sats.satellite.EO1 INFO <1200.00> EO1: setting timed terminal event at 16736.1
2025-02-13 15:16:54,794 sim.simulator INFO <1500.00> Max step duration reached
2025-02-13 15:16:54,795 data.base INFO <1500.00> Data reward: {}
2025-02-13 15:16:54,795 comm.communication INFO <1500.00> Optimizing data communication between all pairs of satellites
2025-02-13 15:16:54,806 gym INFO <1500.00> Step reward: 0.0