Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion benchmarks/rso_inspection.py
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ def rewarder_config(
env_args = dict(
satellites=[
RSOSat("RSO", sat_args=rso_sat_args),
InspectorSat("Inspector-1", sat_args=inspector_sat_args),
InspectorSat("Inspector_1", sat_args=inspector_sat_args),
],
sat_arg_randomizer=sat_arg_randomizer,
scenario=scene.SphericalRSO(
Expand Down
24 changes: 24 additions & 0 deletions docs/source/release_notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,30 @@ Development - |version|
-----------------------
.. *Release Date: MMM. DD, YYYY*

* Add :doc:`the space-to-space imaging example <examples/space_to_space_rso_imaging>`
for independently orbiting spacecraft:
replayable RSO catalogs, explicitly named observers, moving-target access,
continuous and cumulative acquisition holds, optional ground-station downlink,
independently sized target observations and image actions, owned image ledgers, configurable
acquisition/delivery rewards, and replayable policy evaluation with plots.
Acquisition currently uses a temporary BSK-RL gate; adopting the proposed
Basilisk controller update is tracked in `#358
<https://github.com/AVSLab/bsk_rl/issues/358>`_.
Existing RSO surface-point inspection is unchanged.

* Validate satellite names at construction and renaming so simulator events use
those names directly. Names must be valid Python identifiers, for example
``EO_1`` rather than ``EO-1``. Target catalog IDs may still contain punctuation.
RSO image rewards default to full priority credit after complete downlink;
acquisition shaping is available through explicit reward callbacks.

* Fix incorrect eclipse-observation test assertions that assumed countdowns could
not increase across a long step. The tests now use the same simulation start
date, orbit, and random seed on every run, so the results are repeatable.
They check shadow entry and countdown rollover to later orbits.
Eclipse prediction is unchanged.
See `#359 <https://github.com/AVSLab/bsk_rl/issues/359>`_.

* Fix a bug where condensing ``NO_ACTION`` steps for sMDP discounting dropped the
final observation and ``d_ts``, and could give the last super-action an empty
reward. See issue #248.
Expand Down
7 changes: 4 additions & 3 deletions examples/_default.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ Earth Observation
cloud_environment_with_reimaging
aeos

RSO Inspection
~~~~~~~~~~~~~~
RSO Missions
~~~~~~~~~~~~
.. toctree::
:maxdepth: 1

rso_inspection
space_to_space_rso_imaging

Training
--------
Expand Down Expand Up @@ -66,4 +67,4 @@ training settings. The following environments are currently available:
* ``aeos:aeos_single``: A single-satellite agile Earth observation environment.
* ``aeos:aeos_constellation``: A multi-satellite agile Earth observation environment.
* ``rso_inspection:rso_inspection``: An RSO inspection environment with imaging constraints
and safety constraints.
and safety constraints.
2 changes: 1 addition & 1 deletion examples/aeos.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@
"\n",
"env = SatelliteTasking(\n",
" satellite=power_sat_generator(n_ahead=32, include_time=False)(\n",
" name=\"EO1-power\",\n",
" name=\"EO1_power\",\n",
" sat_args=SAT_ARGS_POWER,\n",
" ),\n",
" scenario=targets,\n",
Expand Down
2 changes: 1 addition & 1 deletion examples/async_multiagent_training.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
" fsw_type = fsw.ContinuousImagingFSWModel\n",
"\n",
"sats = [ScanningSatellite(\n",
" f\"Scanner-{i+1}\",\n",
" f\"Scanner_{i+1}\",\n",
" sat_args=dict(\n",
" # Data\n",
" dataStorageCapacity=5000 * 8e6, # bits\n",
Expand Down
2 changes: 1 addition & 1 deletion examples/cloud_environment_with_reimaging.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@
")\n",
"\n",
"satellites = [\n",
" C_F_Bayesian(f\"EO-{i}\", sat_args, belief_update_func=belief_update_func)\n",
" C_F_Bayesian(f\"EO_{i}\", sat_args, belief_update_func=belief_update_func)\n",
" for i in range(5)\n",
"]\n",
"\n",
Expand Down
13 changes: 8 additions & 5 deletions examples/communication_action.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,10 @@
" n_ahead_observe=4,\n",
" )\n",
" ]\n",
" action_spec: ClassVar[list[act.Action]] = [act.Broadcast(duration=15.0), act.Image(n_ahead_image=4)]\n",
" action_spec: ClassVar[list[act.Action]] = [\n",
" act.Broadcast(duration=15.0),\n",
" act.Image(n_ahead_image=4),\n",
" ]\n",
" dyn_type = dyn.FullFeaturedDynModel\n",
" fsw_type = fsw.SteeringImagerFSWModel\n",
"\n",
Expand Down Expand Up @@ -122,7 +125,7 @@
"from bsk_rl import ConstellationTasking\n",
"\n",
"env = ConstellationTasking(\n",
" satellites=[ImagingSatellite(f\"EO-{i + 1}\", sat_args) for i in range(N_AGENTS)],\n",
" satellites=[ImagingSatellite(f\"EO_{i + 1}\", sat_args) for i in range(N_AGENTS)],\n",
" scenario=scene.UniformTargets(1000),\n",
" rewarder=data.UniqueImageReward(),\n",
" communicator=BroadcastLOS(),\n",
Expand All @@ -145,7 +148,7 @@
"metadata": {},
"outputs": [],
"source": [
"_ = env.step({\"EO-1\": ACTION_IMAGE_3, \"EO-2\": ACTION_IMAGE_2})"
"_ = env.step({\"EO_1\": ACTION_IMAGE_3, \"EO_2\": ACTION_IMAGE_2})"
]
},
{
Expand All @@ -161,7 +164,7 @@
"metadata": {},
"outputs": [],
"source": [
"_ = env.step({\"EO-1\": ACTION_BROADCAST, \"EO-2\": ACTION_BROADCAST})"
"_ = env.step({\"EO_1\": ACTION_BROADCAST, \"EO_2\": ACTION_BROADCAST})"
]
},
{
Expand All @@ -177,7 +180,7 @@
"metadata": {},
"outputs": [],
"source": [
"_ = env.step({\"EO-1\": ACTION_IMAGE_2, \"EO-2\": ACTION_BROADCAST}) # Agent 1 broadcasts"
"_ = env.step({\"EO_1\": ACTION_IMAGE_2, \"EO_2\": ACTION_BROADCAST}) # Agent 1 broadcasts"
]
}
],
Expand Down
2 changes: 1 addition & 1 deletion examples/curriculum_learning.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -578,7 +578,7 @@
"environment_mode = \"standard_90\"\n",
"\n",
"sat = ScanningSatellite(\n",
" \"Scanner-1\",\n",
" \"Scanner_1\",\n",
" sat_args=dict(\n",
" **sat_config[\"sat_params\"],\n",
" batteryStorageCapacity=sat_config[environment_mode][\"batteryStorageCapacity\"],\n",
Expand Down
26 changes: 15 additions & 11 deletions examples/multiagent_envs.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"class ImagingSatellite(sats.ImagingSatellite):\n",
" observation_spec: ClassVar[list[obs.Observation]] = [\n",
" obs.OpportunityProperties(\n",
" dict(prop=\"priority\"), \n",
" dict(prop=\"priority\"),\n",
" dict(prop=\"opportunity_open\", norm=5700.0),\n",
" n_ahead_observe=10,\n",
" )\n",
Expand All @@ -62,7 +62,6 @@
"metadata": {},
"outputs": [],
"source": [
"\n",
"from bsk_rl.utils.orbital import walker_delta_args\n",
"\n",
"sat_args = dict(\n",
Expand Down Expand Up @@ -101,9 +100,9 @@
"\n",
"env = GeneralSatelliteTasking(\n",
" satellites=[\n",
" ImagingSatellite(\"EO-1\", sat_args),\n",
" ImagingSatellite(\"EO-2\", sat_args),\n",
" ImagingSatellite(\"EO-3\", sat_args),\n",
" ImagingSatellite(\"EO_1\", sat_args),\n",
" ImagingSatellite(\"EO_2\", sat_args),\n",
" ImagingSatellite(\"EO_3\", sat_args),\n",
" ],\n",
" scenario=scene.UniformTargets(1000),\n",
" rewarder=data.UniqueImageReward(),\n",
Expand Down Expand Up @@ -183,7 +182,10 @@
"metadata": {},
"outputs": [],
"source": [
"actions = [0 if info[sat.name][\"requires_retasking\"] else None for sat in env.unwrapped.satellites]\n",
"actions = [\n",
" 0 if info[sat.name][\"requires_retasking\"] else None\n",
" for sat in env.unwrapped.satellites\n",
"]\n",
"actions"
]
},
Expand Down Expand Up @@ -223,8 +225,9 @@
" log_failure=log_failure\n",
" )\n",
"\n",
"\n",
"env.unwrapped.satellites[0].is_alive = isnt_alive\n",
"observation, reward, terminated, truncated, info = env.step([6, 7, 9])\n"
"observation, reward, terminated, truncated, info = env.step([6, 7, 9])"
]
},
{
Expand All @@ -249,9 +252,9 @@
"\n",
"env = ConstellationTasking(\n",
" satellites=[\n",
" ImagingSatellite(\"EO-1\", sat_args),\n",
" ImagingSatellite(\"EO-2\", sat_args),\n",
" ImagingSatellite(\"EO-3\", sat_args),\n",
" ImagingSatellite(\"EO_1\", sat_args),\n",
" ImagingSatellite(\"EO_2\", sat_args),\n",
" ImagingSatellite(\"EO_3\", sat_args),\n",
" ],\n",
" scenario=scene.UniformTargets(1000),\n",
" rewarder=data.UniqueImageReward(),\n",
Expand Down Expand Up @@ -330,7 +333,8 @@
"metadata": {},
"outputs": [],
"source": [
"observation, reward, terminated, truncated, info = env.step({\n",
"observation, reward, terminated, truncated, info = env.step(\n",
" {\n",
" env.agents[0]: 7,\n",
" env.agents[1]: 9,\n",
" }\n",
Expand Down
31 changes: 18 additions & 13 deletions examples/rllib_training.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -58,33 +58,38 @@
"from bsk_rl.sim import dyn, fsw\n",
"\n",
"\n",
"class ScanningDownlinkDynModel(dyn.ContinuousImagingDynModel, dyn.GroundStationDynModel):\n",
"class ScanningDownlinkDynModel(\n",
" dyn.ContinuousImagingDynModel, dyn.GroundStationDynModel\n",
"):\n",
" # Define some custom properties to be accessed in the state\n",
" @property\n",
" def instrument_pointing_error(self) -> float:\n",
" r_BN_P_unit = self.r_BN_P/np.linalg.norm(self.r_BN_P) \n",
" r_BN_P_unit = self.r_BN_P / np.linalg.norm(self.r_BN_P)\n",
" c_hat_P = self.satellite.fsw.c_hat_P\n",
" return np.arccos(np.dot(-r_BN_P_unit, c_hat_P))\n",
" \n",
"\n",
" @property\n",
" def solar_pointing_error(self) -> float:\n",
" a = self.world.gravFactory.spiceObject.planetStateOutMsgs[\n",
" self.world.sun_index\n",
" ].read().PositionVector\n",
" a = (\n",
" self.world.gravFactory.spiceObject.planetStateOutMsgs[self.world.sun_index]\n",
" .read()\n",
" .PositionVector\n",
" )\n",
" a_hat_N = a / np.linalg.norm(a)\n",
" nHat_B = self.satellite.sat_args[\"nHat_B\"]\n",
" NB = np.transpose(self.BN)\n",
" nHat_N = NB @ nHat_B\n",
" return np.arccos(np.dot(nHat_N, a_hat_N))\n",
"\n",
"\n",
"class ScanningSatellite(sats.AccessSatellite):\n",
" observation_spec: ClassVar[list[obs.Observation]] = [\n",
" obs.SatProperties(\n",
" dict(prop=\"storage_level_fraction\"),\n",
" dict(prop=\"battery_charge_fraction\"),\n",
" dict(prop=\"wheel_speeds_fraction\"),\n",
" dict(prop=\"instrument_pointing_error\", norm=np.pi),\n",
" dict(prop=\"solar_pointing_error\", norm=np.pi)\n",
" dict(prop=\"solar_pointing_error\", norm=np.pi),\n",
" ),\n",
" obs.OpportunityProperties(\n",
" dict(prop=\"opportunity_open\", norm=5700),\n",
Expand Down Expand Up @@ -120,7 +125,7 @@
"outputs": [],
"source": [
"sat = ScanningSatellite(\n",
" \"Scanner-1\",\n",
" \"Scanner_1\",\n",
" sat_args=dict(\n",
" # Data\n",
" dataStorageCapacity=5000 * 8e6, # bits\n",
Expand All @@ -142,7 +147,7 @@
" maxWheelSpeed=6000.0, # RPM\n",
" wheelSpeeds=lambda: np.random.uniform(-3000, 3000, 3),\n",
" desatAttitude=\"nadir\",\n",
" )\n",
" ),\n",
")"
]
},
Expand All @@ -163,7 +168,7 @@
"duration = 5 * 5700.0 # About 5 orbits\n",
"env_args = dict(\n",
" satellite=sat,\n",
" scenario=scene.UniformNadirScanning(value_per_second=1/duration),\n",
" scenario=scene.UniformNadirScanning(value_per_second=1 / duration),\n",
" rewarder=data.ScanningTimeReward(),\n",
" time_limit=duration,\n",
" failure_penalty=-1.0,\n",
Expand Down Expand Up @@ -207,7 +212,7 @@
" data[\"reward_per_orbit\"] = reward / orbits\n",
" if not env.satellite.is_alive():\n",
" data[\"orbits_complete_partial_only\"] = orbits\n",
" \n",
"\n",
" return data"
]
},
Expand Down Expand Up @@ -251,7 +256,7 @@
"config = (\n",
" PPOConfig()\n",
" .training(**training_args)\n",
" .env_runners(num_env_runners=N_CPUS-1, sample_timeout_s=1000.0)\n",
" .env_runners(num_env_runners=N_CPUS - 1, sample_timeout_s=1000.0)\n",
" .environment(\n",
" env=\"SatelliteTasking-RLlib\",\n",
" env_config=dict(**env_args, episode_data_callback=episode_data_callback),\n",
Expand Down Expand Up @@ -304,7 +309,7 @@
" config=config.to_dict(),\n",
" stop={\"training_iteration\": 10}, # Adjust the number of iterations as needed\n",
" checkpoint_freq=10,\n",
" checkpoint_at_end=True\n",
" checkpoint_at_end=True,\n",
")\n",
"\n",
"# Shutdown Ray\n",
Expand Down
Loading
Loading