Short scenario & requirements
%matplotlib widget
import pickle
import numpy as np
from pacti.contracts import PolyhedralIoContract
from matplotlib.figure import Figure
from matplotlib.backends.backend_pdf import PdfPages
from typing import Tuple
from contract_utils import check_tuple, bounds, FailedMerges, Schedule
from plot_utils import plot_steps
This notebook demonstrates the visualization of a few schedulable combinations of the 5-step scenarios variants for the operational requirement variants.
f5 = open("results5.data", "rb")
results5 = pickle.load(f5)
f5.close()
print(f"Failure results: {len(results5[0])}")
print(f"Successful results: {len(results5[1])}")
---------------------------------------------------------------------------
FileNotFoundError Traceback (most recent call last)
c:\opt\local\github.pacti\cs-space-mission\space_mission\analysis_results1-5steps.ipynb Cell 3 line 1
----> <a href='vscode-notebook-cell:/c%3A/opt/local/github.pacti/cs-space-mission/space_mission/analysis_results1-5steps.ipynb#W2sZmlsZQ%3D%3D?line=0'>1</a> f5 = open("results5.data", "rb")
<a href='vscode-notebook-cell:/c%3A/opt/local/github.pacti/cs-space-mission/space_mission/analysis_results1-5steps.ipynb#W2sZmlsZQ%3D%3D?line=1'>2</a> results5 = pickle.load(f5)
<a href='vscode-notebook-cell:/c%3A/opt/local/github.pacti/cs-space-mission/space_mission/analysis_results1-5steps.ipynb#W2sZmlsZQ%3D%3D?line=2'>3</a> f5.close()
File c:\opt\local\github.pacti\cs-space-mission\.venv\Lib\site-packages\IPython\core\interactiveshell.py:286, in _modified_open(file, *args, **kwargs)
279 if file in {0, 1, 2}:
280 raise ValueError(
281 f"IPython won't let you open fd={file} by default "
282 "as it is likely to crash IPython. If you know what you are doing, "
283 "you can use builtins' open."
284 )
--> 286 return io_open(file, *args, **kwargs)
FileNotFoundError: [Errno 2] No such file or directory: 'results5.data'
We focus on showing the range of possible values for the battery state-of-charge at each step in the scenario. We also show the uncertainties associated with each step function across all 3 viewpoints: power, science and communication, and navigation. The operational requirements specify constraints on initial conditions and lower bounds at each step. Finally, we also compute the average batter state-of-charge as a figure of merit computed as a min/max optimization.
def showRange(name: str, range: Tuple[float, float]) -> str:
return f"{name}=[{range[0]:.3g},{range[1]:.3g}]\n"
def plot_results5(index: int, var: str) -> Figure:
schedule: Schedule = results5[1][index]
ranges = schedule.scenario
dsn_cons = ranges[0]
chrg_gen = ranges[1]
sbo_cons = ranges[2]
tcmh_cons = ranges[3]
tcmdv_cons = ranges[4]
dsn_speed = ranges[5]
sbo_gen = ranges[6]
dsn_noise = ranges[7]
chrg_noise = ranges[8]
sbo_imp = ranges[9]
tcm_dv_noise = ranges[10]
tcm_dv_progress = ranges[11]
op_reqs: np.ndarray = schedule.reqs
c: PolyhedralIoContract = schedule.contract
fsoc = " + ".join([f"0.05 output_soc{i}" for i in range(1, 6)])
max_soc = c.optimize(fsoc, maximize=True)
if max_soc is None:
max_soc = -1
min_soc = c.optimize(fsoc, maximize=False)
if min_soc is None:
min_soc = -1
u_bounds = check_tuple(c.get_variable_bounds("output_u5"))
r_bounds = check_tuple(c.get_variable_bounds("output_r5"))
c_bounds = check_tuple(c.get_variable_bounds("output_c5"))
text = \
"* Power uncertainties\n" + \
showRange(" chrg_gen", chrg_gen) + \
showRange(" dsn_cons", dsn_cons) + \
showRange(" sbo_cons", sbo_cons) + \
showRange(" tcmh_cons", tcmh_cons) + \
showRange(" tcmdv_cons", tcmdv_cons) + \
"* Science uncertainties\n" + \
showRange(" sbo_gen", sbo_gen) + \
showRange(" dsn_speed", dsn_speed) + \
"* Navigation uncertainties\n" + \
showRange(" sbo_imp", sbo_imp) + \
showRange(" dsn_noise", dsn_noise) + \
showRange(" chrg_noise", chrg_noise) + \
showRange(" tcm_dv_noise", tcm_dv_noise) + \
showRange(" tcm_dv_progress", tcm_dv_progress) + \
"* Initial conditions\n" + \
f" battery soc={op_reqs[0]:.3g}\n" + \
f" science data={op_reqs[3]:.3g}\n" + \
f" traj. est. u.={op_reqs[4]:.3g}\n" + \
"* Constraints @ each step\n" + \
f" min soc exit={op_reqs[1]:.3g}\n" + \
f" min time alloc={op_reqs[2]:.3g}\n" + \
"* Optimization bounds\n" + \
f" average soc=[{min_soc:.3g},{max_soc:.3g}]\n" + \
showRange(" traj. est. u.", u_bounds) + \
showRange(" rel. progress", r_bounds) + \
showRange(" total science", c_bounds)
bounds = [check_tuple(c.get_variable_bounds(f"{var}1_entry"))]
labels = ["initial"]
n = 5
for i in range(1, n):
bounds += [check_tuple(c.get_variable_bounds(f"output_{var}{i}"))]
labels += [f"{i}"]
bounds += [check_tuple(c.get_variable_bounds(f"output_{var}{n}"))]
labels += [f"final"]
return plot_steps(bounds, labels, ylabel=var, title=f"Possible values of {var} over the sequence", text=text)
Here, we focus on showing the first 15 schedulable combinations; information is also available about which operational requirement constraints resulted in a non-schedulable result.