Broadcast Communication
By default, communication occurs between all satellites that are specified by the communication method. This tutorial shows how to use two classes to configure a broadcast action that must be taken for communication to occur:
Broadcast, which gives satellites an action that enables communication from them at the end of the current step.
BroadcastCommunication, which can be combined with another communication method to limit communication from broadcasters to those satellites satisfying the requirements of the other communication method.
Configuring the Environment
For this example, a multisatellite target imaging environment will be used. The goal is to maximize the value of unique images taken. This configuration is similar to the Multi-Agent Environments example.
[1]:
from bsk_rl import sats, act, obs, scene, data, comm
from bsk_rl.sim import dyn, fsw
class ImagingSatellite(sats.ImagingSatellite):
observation_spec = [
obs.OpportunityProperties(
dict(prop="priority"),
dict(prop="opportunity_open", norm=5700.0),
n_ahead_observe=4,
)
]
action_spec = [act.Broadcast(duration=15.0), act.Image(n_ahead_image=4)]
dyn_type = dyn.FullFeaturedDynModel
fsw_type = fsw.SteeringImagerFSWModel
ACTION_BROADCAST = 0
ACTION_IMAGE_0 = 1
ACTION_IMAGE_1 = 2
ACTION_IMAGE_2 = 3
ACTION_IMAGE_3 = 4
Satellite properties are set to give the satellite near-unlimited power and storage resources. To randomize some parameters in a correlated manner across satellites, a sat_arg_randomizer
is set and passed to the environment. In this case, the satellites are distributed in a trivial single-plane Walker-delta constellation.
[2]:
from bsk_rl.utils.orbital import walker_delta_args
N_AGENTS = 2
sat_args = dict(
imageAttErrorRequirement=0.01,
imageRateErrorRequirement=0.01,
batteryStorageCapacity=1e9,
storedCharge_Init=1e9,
dataStorageCapacity=1e12,
u_max=0.4,
K1=0.25,
K3=3.0,
omega_max=0.087,
servo_Ki=5.0,
servo_P=150 / 5,
)
sat_arg_randomizer = walker_delta_args(
altitude=800.0, inc=60.0, n_planes=1, clustersize=N_AGENTS, clusterspacing=5.0
)
A communication type is defined that uses multidegree line-of-sight communication with broadcasting.
[3]:
class BroadcastLOS(comm.BroadcastCommunication, comm.LOSMultiCommunication):
pass
Finally, the environment can be instantiated.
[4]:
from bsk_rl import ConstellationTasking
env = ConstellationTasking(
satellites=[ImagingSatellite(f"EO-{i + 1}", sat_args) for i in range(N_AGENTS)],
scenario=scene.UniformTargets(1000),
rewarder=data.UniqueImageReward(),
communicator=BroadcastLOS(),
sat_arg_randomizer=sat_arg_randomizer,
log_level="INFO",
)
_ = env.reset()
2025-08-25 18:15:04,052 gym INFO Resetting environment with seed=2682356272
2025-08-25 18:15:04,054 scene.targets INFO Generating 1000 targets
2025-08-25 18:15:04,196 sats.satellite.EO-1 INFO <0.00> EO-1: Finding opportunity windows from 0.00 to 600.00 seconds
2025-08-25 18:15:04,238 sats.satellite.EO-2 INFO <0.00> EO-2: Finding opportunity windows from 0.00 to 600.00 seconds
2025-08-25 18:15:04,283 gym INFO <0.00> Environment reset
In the first step, both agents are tasked with an imaging action, and one successfully images a target.
[5]:
_ = env.step({"EO-1": ACTION_IMAGE_3, "EO-2": ACTION_IMAGE_2})
2025-08-25 18:15:04,288 gym INFO <0.00> === STARTING STEP ===
2025-08-25 18:15:04,289 sats.satellite.EO-1 INFO <0.00> EO-1: target index 3 tasked
2025-08-25 18:15:04,289 sats.satellite.EO-1 INFO <0.00> EO-1: Target(tgt-105) tasked for imaging
2025-08-25 18:15:04,291 sats.satellite.EO-1 INFO <0.00> EO-1: Target(tgt-105) window enabled: 0.0 to 149.7
2025-08-25 18:15:04,292 sats.satellite.EO-1 INFO <0.00> EO-1: setting timed terminal event at 149.7
2025-08-25 18:15:04,292 sats.satellite.EO-2 INFO <0.00> EO-2: target index 2 tasked
2025-08-25 18:15:04,293 sats.satellite.EO-2 INFO <0.00> EO-2: Target(tgt-158) tasked for imaging
2025-08-25 18:15:04,294 sats.satellite.EO-2 INFO <0.00> EO-2: Target(tgt-158) window enabled: 0.0 to 77.3
2025-08-25 18:15:04,295 sats.satellite.EO-2 INFO <0.00> EO-2: setting timed terminal event at 77.3
2025-08-25 18:15:04,326 sats.satellite.EO-2 INFO <67.00> EO-2: imaged Target(tgt-158)
2025-08-25 18:15:04,328 data.base INFO <67.00> Total reward: {'EO-2': 0.1178050919860516}
2025-08-25 18:15:04,330 sats.satellite.EO-2 INFO <67.00> EO-2: Satellite EO-2 requires retasking
2025-08-25 18:15:04,332 gym INFO <67.00> Step reward: {'EO-2': 0.1178050919860516}
When both select the broadcast action, data is shared in both directions. This is subject to line-of-sight availability as well as selecting the correct action.
[6]:
_ = env.step({"EO-1": ACTION_BROADCAST, "EO-2": ACTION_BROADCAST})
2025-08-25 18:15:04,337 gym INFO <67.00> === STARTING STEP ===
2025-08-25 18:15:04,338 sats.satellite.EO-1 INFO <67.00> EO-1: setting timed terminal event at 82.0
2025-08-25 18:15:04,339 sats.satellite.EO-2 INFO <67.00> EO-2: setting timed terminal event at 82.0
2025-08-25 18:15:04,348 sats.satellite.EO-1 INFO <82.00> EO-1: timed termination at 82.0 for broadcast
2025-08-25 18:15:04,348 sats.satellite.EO-2 INFO <82.00> EO-2: timed termination at 82.0 for broadcast
2025-08-25 18:15:04,351 data.base INFO <82.00> Total reward: {}
2025-08-25 18:15:04,352 comm.communication INFO <82.00> Communicating data in 2 directions.
2025-08-25 18:15:04,352 comm.communication INFO <82.00> Optimizing data communication between all pairs of satellites
2025-08-25 18:15:04,354 sats.satellite.EO-1 INFO <82.00> EO-1: Satellite EO-1 requires retasking
2025-08-25 18:15:04,355 sats.satellite.EO-2 INFO <82.00> EO-2: Satellite EO-2 requires retasking
2025-08-25 18:15:04,357 gym INFO <82.00> Step reward: {}
One agent can broadcast while the others are completing a different task.
[7]:
_ = env.step({"EO-1": ACTION_IMAGE_2, "EO-2": ACTION_BROADCAST}) # Agent 1 broadcasts
2025-08-25 18:15:04,362 gym INFO <82.00> === STARTING STEP ===
2025-08-25 18:15:04,363 sats.satellite.EO-1 INFO <82.00> EO-1: target index 2 tasked
2025-08-25 18:15:04,363 sats.satellite.EO-1 INFO <82.00> EO-1: Target(tgt-480) tasked for imaging
2025-08-25 18:15:04,365 sats.satellite.EO-1 INFO <82.00> EO-1: Target(tgt-480) window enabled: 160.7 to 172.1
2025-08-25 18:15:04,366 sats.satellite.EO-1 INFO <82.00> EO-1: setting timed terminal event at 172.1
2025-08-25 18:15:04,366 sats.satellite.EO-2 INFO <82.00> EO-2: setting timed terminal event at 97.0
2025-08-25 18:15:04,374 sats.satellite.EO-2 INFO <97.00> EO-2: timed termination at 97.0 for broadcast
2025-08-25 18:15:04,376 data.base INFO <97.00> Total reward: {}
2025-08-25 18:15:04,378 comm.communication INFO <97.00> Communicating data in 1 direction.
2025-08-25 18:15:04,379 sats.satellite.EO-2 INFO <97.00> EO-2: Satellite EO-2 requires retasking
2025-08-25 18:15:04,381 gym INFO <97.00> Step reward: {}