Source code for latom.analyzer.analyzer_2d

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

"""

import numpy as np

from latom.analyzer.analyzer import Analyzer
from latom.nlp.nlp_2d import TwoDimAscConstNLP, TwoDimAscVarNLP, TwoDimAscVToffNLP, TwoDimDescConstNLP, \
    TwoDimDescTwoPhasesNLP, TwoDimDescVarNLP, TwoDimDescVLandNLP
from latom.plots.solutions import TwoDimSolPlot, TwoDimDescTwoPhasesSolPlot
from latom.utils.const import states_2d
from latom.guess.guess_2d import HohmannTransfer
from latom.utils.spacecraft import ImpulsiveBurn
from latom.utils.keplerian_orbit import TwoDimOrb


[docs]class TwoDimAnalyzer(Analyzer): """TwoDimAnalyzer class defines the methods to analyze the results of a two dimensional simulation. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [-] or [m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling """ def __init__(self, body, sc): """Initializes the `TwoDimAnalyzer` class variables. """ Analyzer.__init__(self, body, sc) # reference values: # radius: equatorial radius of the central attracting body (Moon) # velocity: velocity on a circular orbit at zero altitude # thrust magnitude: initial spacecraft weight on the Moon surface self.states_scalers = np.array([self.body.R, 1.0, self.body.vc, self.body.vc, 1.0]) self.controls_scalers = np.array([self.body.g * self.sc.m0, 1.0])
[docs] def get_time_series_phase(self, p, phase_name, scaled=False): """Access the time series of one of the problem phases. Parameters ---------- p : Problem Instance of `Problem` class phase_name : str Name defined for the problem phase scaled : bool, optional If ``True`` scales the simulation results. Default is ``False`` Returns ------- tof : float Time of flight resulting from the optimized simulation phase [-] or [s] t : ndarray Time of flight time series for the optimized simulation phase [-] or [s] states : ndarray States time series for the optimized simulation phase controls : ndarray Controls time series for the optimized simulation phase """ tof = float(p.get_val(phase_name + '.t_duration')) # non dimensional time of flight [-] t = p.get_val(phase_name + '.timeseries.time') # non dimensional time [-] states = np.empty((np.size(t), 0)) for k in states_2d: s = p.get_val(phase_name + '.timeseries.states:' + k) # non dimensional states [-] states = np.append(states, s, axis=1) alpha = p.get_val(phase_name + '.timeseries.controls:alpha') # thrust direction [rad] try: thrust = p.get_val(phase_name + '.timeseries.controls:thrust') # non dimensional thrust [-] except KeyError: thrust = p.get_val(phase_name + '.design_parameters:thrust') thrust = thrust * np.ones((len(alpha), 1)) # non dimensional thrust [-] controls = np.hstack((thrust, alpha)) if not scaled: tof = tof * self.body.tc # dimensional time of flight [s] t = t * self.body.tc # dimensional time [s] states = states * self.states_scalers # dimensional states [m, rad, m/s, m/s, kg] controls = controls * self.controls_scalers # dimensional controls [N, rad] return tof, t, states, controls
[docs] def get_discretization_phase(self, p, phase_name, scaled=False): """Access the time of flight, the states on the states discretization nodes and the controls on the control discretization nodes for a given `Problem` and `Phase`. Parameters ---------- p : Problem Instance of `Problem` class phase_name : str Name defined for the problem phase scaled : bool, optional If ``True`` scales the simulation results. Default is ``False`` Returns ------- tof : float Time of flight resulting from the optimized simulation phase [-] or [s] states : ndarray States values on the state discretization nodes for the optimized simulation phase controls : ndarray Controls values on the controls discretization nodes for the optimized simulation phase """ tof = float(p.get_val(phase_name + '.t_duration')) # non dimensional time of flight [-] # non dimensional states [-] states = p.get_val(phase_name + '.states:' + states_2d[0]) for k in states_2d[1:]: s = p.get_val(phase_name + '.states:' + k) states = np.append(states, s, axis=1) alpha = p.get_val(phase_name + '.controls:alpha') # thrust direction [rad] try: thrust = p.get_val(phase_name + '.controls:thrust') # non dimensional thrust [-] except KeyError: thrust = p.get_val(phase_name + '.design_parameters:thrust') thrust = thrust * np.ones((len(alpha), 1)) # non dimensional thrust [-] controls = np.hstack((thrust, alpha)) if not scaled: tof = tof * self.body.tc # dimensional time of flight [s] states = states * self.states_scalers # dimensional states [m, rad, m/s, m/s, kg] controls = controls * self.controls_scalers # dimensional controls [N, rad] return tof, states, controls
def __str__(self): """Prints info on the TwoDimAnalyzer. Returns ------- s : str Info lines """ lines = [self.sc.__str__(), self.nlp.__str__()] if self.err is not None: try: lines_err = ['\n{:^50s}'.format('Error:'), '\n{:<25s}{:>20.12f}{:>5s}'.format('Radius:', self.err[0] / 1e3, 'km'), '{:<25s}{:>20.12f}{:>5s}'.format('Angle:', self.err[1] * np.pi / 180, 'deg'), '{:<25s}{:>20.12f}{:>5s}'.format('Radial velocity:', self.err[2] / 1e3, 'km/s'), '{:<25s}{:>20.12f}{:>5s}'.format('Tangential velocity:', self.err[3] / 1e3, 'km/s'), '{:<25s}{:>20.12f}{:>5s}'.format('Mass:', self.err[4], 'kg')] except TypeError: lines_err = ['\n{:^50s}'.format('Error:'), '\n{:<25s}{:>50s}{:>5s}'.format('Radius:', str(self.err[:, 0] / 1e3), 'km'), '{:<25s}{:>50s}{:>5s}'.format('Angle:', str(self.err[:, 1] * np.pi / 180), 'deg'), '{:<25s}{:>50s}{:>5s}'.format('Radial velocity:', str(self.err[:, 2] / 1e3), 'km/s'), '{:<25s}{:>50s}{:>5s}'.format('Tangential velocity:', str(self.err[:, 3] / 1e3), 'km/s'), '{:<25s}{:>50s}{:>5s}'.format('Mass:', str(self.err[:, 4]), 'kg')] lines.extend(lines_err) s = '\n'.join(lines) return s
[docs]class TwoDimSinglePhaseAnalyzer(TwoDimAnalyzer): """TwoDimSinglePhaseAnalyzer class defines the methods to analyze the results of a two dimensional single phase simulation. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __init__(self, body, sc, alt): """Initializes the `TwoDimSinglePhaseAnalyzer` class attributes. """ TwoDimAnalyzer.__init__(self, body, sc) self.alt = alt self.phase_name = 'powered'
[docs] def get_time_series(self, p, scaled=False): """Access the time series of one of the problem phases. Parameters ---------- p : Problem Instance of `Problem` class scaled : bool Scales the simulation results Returns ------- tof : float Time of flight resulting from the optimized simulation phase [s] t : ndarray Time of flight time series for the optimized simulation phase [s] states : ndarray States time series for the optimized simulation phase controls : ndarray Controls time series for the optimized simulation phase """ tof, t, states, controls = self.get_time_series_phase(p, self.nlp.phase_name, scaled=scaled) return tof, t, states, controls
def __str__(self): """Prints infos on the `TwoDimSinglePhaseAnalyser`. Returns ------- s : str Info on the `TwoDimSinglePhaseAnalyser` """ lines = ['{:<25s}{:>20.6f}{:>5s}'.format('Propellant fraction:', (1 - self.states[-1, -1] / self.sc.m0), ''), '{:<25s}{:>20.6f}{:>5s}'.format('Time of flight:', self.tof, 's'), TwoDimAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs]class TwoDimAscAnalyzer(TwoDimSinglePhaseAnalyzer): """TwoDimAscAnalyzer class defines the methods to analyze the results of a two dimensional ascent simulation from the Moon surface to a given Low Lunar Orbit. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __str__(self): """Prints info on the `TwoDimAscAnalyzer`. Returns ------- s : str Info on `TwoDimAscAnalyzer` """ lines = ['\n{:^50s}'.format('2D Ascent Trajectory:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Final orbit altitude:', self.alt / 1e3, 'km'), TwoDimSinglePhaseAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs]class TwoDimAscConstAnalyzer(TwoDimAscAnalyzer): """TwoDimAscConstAnalyzer class defines the methods to analyze the results of a two dimensional ascent simulation from the Moon surface to a given Low Lunar Orbit performed at constant thrust. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] theta : float Value for the guessed angle spawn during the trajectory [rad] tof : float Value for the guessed trajectory time of flight [s] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``lower`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __init__(self, body, sc, alt, theta, tof, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='lower'): """Initializes the `TwoDimAscConstAnalyzer` class variables. """ TwoDimAscAnalyzer.__init__(self, body, sc, alt) self.nlp = TwoDimAscConstNLP(body, sc, alt, theta, (-np.pi / 2, np.pi / 2), tof, t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound)
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, threshold=None) sol_plot.plot()
[docs]class TwoDimAscVarAnalyzer(TwoDimAscAnalyzer): """TwoDimAscVarAnalyzer class defines the methods to analyze the results of a two dimensional ascent simulation from the Moon surface to a given Low Lunar Orbit performed at variable thrust. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] theta : float Value for the guessed angle spawn during the trajectory [rad] tof : float Value for the guessed trajectory time of flight [s] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``lower`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __init__(self, body, sc, alt, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='lower'): """Initializes the `TwoDimAscVarAnalyzer` class variables. """ TwoDimAscAnalyzer.__init__(self, body, sc, alt) self.nlp = TwoDimAscVarNLP(body, sc, alt, (-np.pi / 2, np.pi / 2), t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound)
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp) sol_plot.plot()
[docs]class TwoDimAscVToffAnalyzer(TwoDimAscVarAnalyzer): """TwoDimAscVToffAnalyzer class defines the methods to analyze the results of a two dimensional ascent simulation from the Moon surface to a given Low Lunar Orbit performed at variable thrust with vertical take-off. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] alt_safe : float Value of the minimun safe altitude to avoid geographical constraints [m] slope : float Value of the slope of the constraint on minimum safe altitude [-] theta : float Value for the guessed angle spawn during the trajectory [rad] tof : float Value for the guessed trajectory time of flight [-] t_bounds : float Value for the time of flight bounds [s] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``lower`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase alt_safe : float Value of the minimum safe altitude to avoid geographical constraints [m] slope : float Value of the slope of the constraint on minimum safe altitude [-] r_safe : float Value of the minimum orbit radius to be compliant with the constraints [m] """ def __init__(self, body, sc, alt, alt_safe, slope, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='lower'): """Initializes the `TwoDimAscVarAnalyzer` class variables. """ TwoDimAscAnalyzer.__init__(self, body, sc, alt) self.nlp = TwoDimAscVToffNLP(body, sc, alt, alt_safe, slope, (-np.pi / 2, np.pi / 2), t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound) self.alt_safe = alt_safe self.slope = slope self.r_safe = None
[docs] def get_solutions(self, explicit=True, scaled=False): """Access the simulation solution. Parameters ---------- explicit : bool Computes also the explicit simulation. Default is ``True`` scaled : bool Scales the simulation results. Default is ``False`` """ TwoDimAnalyzer.get_solutions(self, explicit=explicit, scaled=scaled) self.r_safe = self.nlp.p.get_val(self.nlp.phase_name + '.timeseries.r_safe') if not scaled: self.r_safe = self.r_safe * self.body.R
def __str__(self): """Prints info on the `TwoDimAscVToffAnalyzer`. Returns ------- s : str Info on `TwoDimAscVToffAnalyzer` """ lines = ['\n{:^50s}'.format('2D Ascent Trajectory with Safe Altitude:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Final orbit altitude:', self.alt / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Safe altitude:', self.alt_safe / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Slope:', self.slope, ''), TwoDimSinglePhaseAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, r_safe=self.r_safe) sol_plot.plot()
[docs]class TwoDimDescAnalyzer(TwoDimSinglePhaseAnalyzer): """TwoDimDescAnalyzer class defines the methods to analyze the results of a two dimensional descent simulation from a given Low Lunar Orbit to the Moon surface. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers = ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __str__(self): """Prints info on the `TwoDimDescAnalyzer`. Returns ------- s : str Info on `TwoDimDescAnalyzer` """ lines = ['\n{:^50s}'.format('2D Descent Trajectory:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Initial orbit altitude:', self.alt / 1e3, 'km'), TwoDimSinglePhaseAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs]class TwoDimDescConstAnalyzer(TwoDimDescAnalyzer): """TwoDimDescConstAnalyzer class defines the methods to analyze the results of a two dimensional descent simulation from a given Low Lunar Orbit to the Moon surface performed at constant thrust. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] alt_p : float Value of the orbit periselene altitude [m] theta : float Value for the guessed angle spawn during the trajectory [rad] tof : float Value for the guessed trajectory time of flight [s] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``upper`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase alt_p : float Value of the final orbit altitude [m] """ def __init__(self, body, sc, alt, alt_p, theta, tof, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='upper'): """Initializes the `TwoDimDescConstAnalyzer` class variables. """ TwoDimDescAnalyzer.__init__(self, body, sc, alt) self.alt_p = alt_p dep = TwoDimOrb(body.GM, a=(body.R + alt), e=0.0) arr = TwoDimOrb(body.GM, a=(body.R + alt_p), e=0.0) self.ht = HohmannTransfer(body.GM, dep, arr) self.deorbit_burn = ImpulsiveBurn(sc, self.ht.dva) self.nlp = TwoDimDescConstNLP(body, self.deorbit_burn.sc, alt_p, self.ht.transfer.vp, theta, (0.0, 1.5 * np.pi), tof, t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound) def __str__(self): """Prints info on the `TwoDimDescConstAnalyzer`. Returns ------- s : str Info on `TwoDimDescConstAnalyzer` """ lines = ['\n{:^50s}'.format('2D Descent Trajectory at constant thrust:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Parking orbit altitude:', self.alt / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Periapsis altitude:', self.alt_p / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Deorbit burn fraction:', self.deorbit_burn.dm / self.sc.m0, ''), TwoDimSinglePhaseAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, threshold=None, kind='descent') sol_plot.plot()
[docs]class TwoDimDescVarAnalyzer(TwoDimDescAnalyzer): """TwoDimDescVarAnalyzer class defines the methods to analyze the results of a two dimensional descent simulation from a given Low Lunar Orbit to the Moon surface performed at variable thrust. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``upper`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase """ def __init__(self, body, sc, alt, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='upper'): """Initializes the `TwoDimDescVarAnalyzer` class variables. """ TwoDimDescAnalyzer.__init__(self, body, sc, alt) self.nlp = TwoDimDescVarNLP(body, sc, alt, (0.0, 1.5 * np.pi), t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound)
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, kind='descent') sol_plot.plot()
[docs]class TwoDimDescVLandAnalyzer(TwoDimDescVarAnalyzer): """TwoDimDescVarAnalyzer class defines the methods to analyze the results of a two dimensional descent simulation from a given Low Lunar Orbit to the Moon surface performed at variable thrust with vertical landing. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] alt_safe : float Value of the minimum safe altitude to avoid geographical constraints [m] slope : float Value of the slope of the constraint on minimum safe altitude [-] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` u_bound : str Sets the bound of the radial velocity. Can be ``lower``, ``upper`` or ``None``. Default is ``upper`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] phase_name : str Name assigned to the problem phase alt_safe : float Value of the minimum safe altitude to avoid geographical constraints [m] slope : float Value of the slope of the constraint on minimum safe altitude [-] r_safe : float Value of the minimum orbit radius to be compliant with the constraints [m] """ def __init__(self, body, sc, alt, alt_safe, slope, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, u_bound='upper'): """Initializes the `TwoDimDescVLandAnalyzer` class variables. """ TwoDimDescAnalyzer.__init__(self, body, sc, alt) self.nlp = TwoDimDescVLandNLP(body, sc, alt, alt_safe, slope, (0.0, 1.5 * np.pi), t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, u_bound=u_bound, fix_final=True) self.alt_safe = alt_safe self.slope = slope self.r_safe = None
[docs] def get_time_series(self, p, scaled=False): """Access the time series of the simulation. Parameters ---------- p : Problem Instance of `Problem` class scaled : bool Scales the simulation results Returns ------- tof : float Time of flight resulting from the optimized simulation [s] t : ndarray Time of flight time series for the optimized simulation [s] states : ndarray States time series for the optimized simulation controls : ndarray Controls time series for the optimized simulation """ tof, t, states, controls = TwoDimDescVarAnalyzer.get_time_series(self, p, scaled=scaled) states[:, 1] = states[:, 1] - states[0, 1] return tof, t, states, controls
[docs] def get_solutions(self, explicit=True, scaled=False): """Access the simulation solution. Parameters ---------- explicit : bool Computes also the explicit simulation. Default is ``True`` scaled : bool Scales the simulation results. Default is ``False`` """ TwoDimAnalyzer.get_solutions(self, explicit=explicit, scaled=scaled) self.r_safe = self.nlp.p.get_val(self.nlp.phase_name + '.timeseries.r_safe') if not scaled: self.r_safe = self.r_safe * self.body.R
def __str__(self): """Prints info on the `TwoDimDescVLandAnalyzer`. Returns ------- s : str Info on `TwoDimAscVToffAnalyzer` """ lines = ['\n{:^50s}'.format('2D Descent Trajectory with Safe Altitude:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Initial orbit altitude:', self.alt / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Safe altitude:', self.alt_safe / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Slope:', self.slope, ''), TwoDimSinglePhaseAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimSolPlot(self.rm_res, self.time, self.states, self.controls, self.time_exp, self.states_exp, r_safe=self.r_safe, kind='descent') sol_plot.plot()
[docs]class TwoDimDescTwoPhasesAnalyzer(TwoDimAnalyzer): """TwoDimDescTwoPhasesAnalyzer class defines the methods to analyze the results of a two dimensional descent simulation from a given Low Lunar Orbit to the Moon surface composed by two subsequent phases. Firstly, the spacecraft is injected in a ballistic arc (Hohmann transfer) to move from the initial Low Lunar Orbit to a lower altitude. Starting from the periselene of the Hohmann transfer, the spacecraft performs a powered descent at constant thrust and free attitude (first phase) until the final vertical descent (second phase) is triggered at a given altitude or time-to-go. Parameters ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics alt : float Value of the final orbit altitude [m] alt_switch : float Value of the minimum safe altitude to avoid geographical constraints [m] theta : float Value for the guessed angle spawn during the trajectory [rad] tof : float Value for the guessed trajectory time of flight [s] t_bounds : float Value for the time of flight bounds [-] method : str NLP transcription method nb_seg : int Number of segments for the transcription order : int Transcription order solver : str NLP solver snopt_opts : dict Sets some SNOPT's options. Default is ``None`` rec_file : str Directory path for the solution recording file. Default is ``None`` check_partials : bool Checking of partial derivatives. Default is ``False`` fix : str Chooses to switch from the optimized phase to the vertical one at a specific altitude or time. Can be ``alt`` or ``time``. Default is ``alt`` Attributes ---------- body : Primary Instance of `Primary` class describing the central attracting body sc : Spacecraft Instance of `Spacecraft` class describing the spacecraft characteristics phase_name : str Describes the phase name in case of multi-phase trajectories nlp : NLP Instance of `NLP` object describing the type of Non Linear Problem solver used tof : float Value of the time of flight resulting by the simulation [s] tof_exp : float Value of the time of flight of the explicit simulation [s] err : float Value of the error between the optimized simulation results and the explicit simulation results rm_res : float Value of the central body radius [- or m] states_scalers : ndarray Reference values of the states with which perform the scaling controls_scalers : ndarray Reference values of the controls with which perform the scaling alt : float Value of the final orbit altitude [m] alt_p: float Value of the minimum safe altitude to avoid geographical constraints [m] alt_switch : float Value of the minimum safe altitude to avoid geographical constraints [m] ht : `Guess_2d` Instance of `Guess_2d` class to define an Hohmann transfer trajectory deorbit_burn : `Guess_2d` Instance of `Guess_2d` class to define an an impulsive burn """ def __init__(self, body, sc, alt, alt_p, alt_switch, theta, tof, t_bounds, method, nb_seg, order, solver, snopt_opts=None, rec_file=None, check_partials=False, fix='alt'): """Initializes the `TwoDimDescTwoPhasesAnalyzer` class variables. """ TwoDimAnalyzer.__init__(self, body, sc) self.alt = alt self.alt_p = alt_p self.alt_switch = alt_switch self.phase_name = ('free', 'vertical') dep = TwoDimOrb(body.GM, a=(body.R + alt), e=0.0) arr = TwoDimOrb(body.GM, a=(body.R + alt_p), e=0.0) self.ht = HohmannTransfer(body.GM, dep, arr) self.deorbit_burn = ImpulsiveBurn(sc, self.ht.dva) self.nlp = TwoDimDescTwoPhasesNLP(body, self.deorbit_burn.sc, alt_p, alt_switch, self.ht.transfer.vp, theta, (0.0, np.pi), tof, t_bounds, method, nb_seg, order, solver, self.phase_name, snopt_opts=snopt_opts, rec_file=rec_file, check_partials=check_partials, fix=fix)
[docs] def get_time_series(self, p, scaled=False): """Access the time series of the simulation. Parameters ---------- p : Problem Instance of `Problem` class scaled : bool Scales the simulation results Returns ------- tof : float Time of flight resulting from the optimized simulation [s] t : ndarray Time of flight time series for the optimized simulation [s] states : ndarray States time series for the optimized simulation controls : ndarray Controls time series for the optimized simulation """ # attitude free tof_free = float(p.get_val(self.nlp.phase_name[0] + '.t_duration')) * self.body.tc t_free = p.get_val(self.nlp.phase_name[0] + '.timeseries.time') * self.body.tc states_free = np.empty((np.size(t_free), 0)) for k in states_2d: s = p.get_val(self.nlp.phase_name[0] + '.timeseries.states:' + k) states_free = np.append(states_free, s, axis=1) states_free = states_free * self.states_scalers alpha_free = p.get_val(self.nlp.phase_name[0] + '.timeseries.controls:alpha') controls_free = np.hstack((self.sc.T_max * np.ones((np.size(t_free), 1)), alpha_free)) # vertical tof_vertical = float(p.get_val(self.nlp.phase_name[1] + '.t_duration')) * self.body.tc t_vertical = p.get_val(self.nlp.phase_name[1] + '.timeseries.time') * self.body.tc r_vertical = p.get_val(self.nlp.phase_name[1] + '.timeseries.states:r') * self.body.R theta_vertical = states_free[-1, 1] * np.ones((np.size(t_vertical), 1)) u_vertical = p.get_val(self.nlp.phase_name[1] + '.timeseries.states:u') * self.body.vc m_vertical = p.get_val(self.nlp.phase_name[1] + '.timeseries.states:m') states_vertical = np.hstack((r_vertical, theta_vertical, u_vertical, np.zeros((np.size(t_vertical), 1)), m_vertical)) controls_vertical = np.hstack((self.sc.T_max * np.ones((np.size(t_vertical), 1)), np.pi / 2 * np.ones((np.size(t_vertical), 1)))) tof = [tof_free, tof_vertical] t = [t_free, t_vertical] states = [states_free, states_vertical] controls = [controls_free, controls_vertical] return tof, t, states, controls
def __str__(self): """Prints info on the `TwoDimDescTwoPhasesAnalyzer`. Returns ------- s : str Info on `TwoDimDescTwoPhasesAnalyzer` """ lines = ['\n{:^50s}'.format('2D Descent Trajectory with vertical touch-down:'), '\n{:<25s}{:>20.6f}{:>5s}'.format('Parking orbit altitude:', self.alt / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Periapsis altitude:', self.alt_p / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Switch altitude:', (self.states[0][-1, 0] - self.body.R) / 1e3, 'km'), '{:<25s}{:>20.6f}{:>5s}'.format('Deorbit burn fraction:', self.deorbit_burn.dm / self.sc.m0, ''), '{:<25s}{:>20.6f}{:>5s}'.format('Propellant fraction:', (1 - self.states[-1][-1, -1] / self.sc.m0), ''), '{:<25s}{:>20.6f}{:>5s}'.format('Time of flight:', sum(self.tof), 's'), '{:<25s}{:>20.6f}{:>5s}'.format('Switch time:', self.tof[0], 's'), TwoDimAnalyzer.__str__(self)] s = '\n'.join(lines) return s
[docs] def plot(self): """Plots the states and controls resulting from the simulation and the ones from the explicit computation in time. """ sol_plot = TwoDimDescTwoPhasesSolPlot(self.rm_res, self.time, self.states, self.controls, time_exp=self.time_exp, states_exp=self.states_exp) sol_plot.plot()