Source code for latom.reader.reader_heo_2d

"""
@authors: Alberto FOSSA' Giuliana Elena MICELI

"""

import numpy as np

from latom.reader.reader import Reader
from latom.plots.solutions import TwoDimMultiPhaseSolPlot
from latom.utils.keplerian_orbit import TwoDimOrb
from latom.utils.const import states_2d


[docs]class TwoDim3PhasesLLO2HEOReader(Reader): """`TwoDim3PhasesLLO2HEOReader` class loads and displays a stored simulation corresponding to a three-phases transfer trajectory from LLO to HEO using an OpenMDAO `CaseReader` class instance. Parameters ---------- body : Primary Central attracting body db : str Full path of the database where the solution is stored case_id : str, optional Case identifier, ``initial`` to load the first iteration, ``final`` to load the final solution. Default is ``final`` db_exp : str or ``None``, optional Full path of the database where the explicit simulation is stored or ``None``. Default is ``None`` scaled : bool, optional ``False`` to retrieve the solution in dimensional units, ``True`` otherwise. Default is ``False`` Attributes ---------- body : Primary Central attracting body gm_res : float Central attracting body standard gravitational parameter [m^3/s^2] or [-] rm_res : float Central attracting body equatorial radius [m] or [-] states_scalers : ndarray Scaling parameters for distances, angles, velocities and mass phase_name : list List of phases names within the OpenMDAO `Problem` object tof : float Time of flight for the implicit solution [s] time : list Time vector for the implicit solution [s] states : list States time series for the implicit solution as `[r, theta, u, v, m]` controls : list Controls variables time series for the implicit solution as `[thrust, alpha]` tof_exp : float or ``None`` Time of flight for the explicit simulation [s] or ``None`` time_exp : list or ``None`` Time vector for the explicit simulation [s] or ``None`` states_exp : list or ``None`` States time series for the explicit simulation as `[r, theta, u, v, m]` or ``None`` controls_exp : list or ``None`` Controls variables time series for the explicit simulation as `[thrust, alpha]` or ``None`` coe_inj : iterable Classical orbital elements at injection as `(a, e, h, ta)` with `a` semi-major axis, `e` eccentricity, `h` specific angular momentum vector and `ta` true anomaly """ def __init__(self, body, db, case_id='final', db_exp=None, scaled=False): Reader.__init__(self, db, case_id=case_id, db_exp=db_exp) self.body = body if scaled: self.gm_res = 1.0 self.rm_res = 1.0 self.states_scalers = None else: self.gm_res = body.GM self.rm_res = body.R self.states_scalers = np.array([body.R, 1.0, body.vc, body.vc, 1.0]) self.phase_name = [] for s in ['dep', 'coast', 'arr']: ph_name = '.'.join(['traj', s, 'timeseries']) self.phase_name.append(ph_name) self.tof, self.time, self.states, self.controls = self.get_time_series(self.case) if db_exp is not None: self.tof_exp, self.time_exp, self.states_exp, self.controls_exp = self.get_time_series(self.case_exp) else: self.tof_exp = self.time_exp = self.states_exp = self.controls_exp = None self.coe_inj = TwoDimOrb.polar2coe(self.gm_res, self.states[-1][-1, 0], self.states[-1][-1, 2], self.states[-1][-1, 3])
[docs] def get_time_series(self, case): """Retrieve the time of flight, time vector and states, controls and minimum safe altitude time series for the specified `case` and `kind` of transfer. Parameters ---------- case : Case OpenMDAO `Case` object Returns ------- tof : float Time of flight for the given `Case` [s] time : list Time vector for the given `Case` [s] states : list States time series for the given `Case` as `[r, theta, u, v, m]` controls : list Controls variables time series for the given `Case` as `[thrust, alpha]` """ # initialization time = [] tof = [] states = [] controls = [] # loop over three phases for i in range(3): # non-dimensional time vector t = case.outputs.get(self.phase_name[i] + '.time') # non-dimensional states s = np.empty((np.size(t), 0)) for k in states_2d: sk = case.outputs.get(self.phase_name[i] + '.states:' + k) s = np.append(s, sk, axis=1) # non-dimensional controls alpha = case.outputs.get(self.phase_name[i] + '.controls:alpha') thrust = case.outputs.get(self.phase_name[i] + '.design_parameters:thrust') # dimensional states and controls if self.states_scalers is not None: t = t*self.body.tc s = s*self.states_scalers thrust = thrust*self.body.g*s[0, -1] c = np.hstack((thrust, alpha)) time.append(t) tof.append(t[-1] - t[0]) states.append(s) controls.append(c) return tof, time, states, controls
[docs] def plot(self): """Plot the optimal transfer trajectory corresponding to the loaded `Case`. """ dtheta = self.coe_inj[-1] - self.states[-1][-1, 1] sol_plot = TwoDimMultiPhaseSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, a=self.coe_inj[0], e=self.coe_inj[1], dtheta=dtheta) sol_plot.plot()