def compute_solutions(body, isp_list, twr_list): m_prop_list = [] for i in range(np.size(isp_list)): sc = Spacecraft(isp_list[i], twr_list[i], g=body.g) m_prop_i = solve_nlp(body, sc) m_prop_list.append(m_prop_i) return np.asarray(m_prop_list)
heo_period = 6.5655 * 86400 # target HEO period [s] # spacecraft isp = 400. # specific impulse [s] log_scale = False # twr_list in logarithmic scale or not twr_list = np.arange( 1.0, 0.09, -0.1) # range of thrust/weight ratios in absolute/logarithmic scale [-] # maximum thrust/weight ratio in absolute value [-] if log_scale: twr0 = np.exp(twr_list[0]) else: twr0 = twr_list[0] sc = Spacecraft(isp, twr0, g=moon.g) # Spacecraft object # NLP method = 'gauss-lobatto' segments = 200 order = 3 solver = 'IPOPT' snopt_opts = { 'Major feasibility tolerance': 1e-12, 'Major optimality tolerance': 1e-12, 'Minor feasibility tolerance': 1e-12 } # additional settings run_driver = True # solve the NLP exp_sim = True # perform explicit simulation
self.p[phase_name + '.t_duration'] = tof self.p.run_model() # run the model to compute the time grid # states and controls nodes indices sn = phase.options['transcription'].grid_data.subset_node_indices['state_input'] cn = phase.options['transcription'].grid_data.subset_node_indices['control_input'] state_nodes = np.reshape(sn, (len(sn), 1)) control_nodes = np.reshape(cn, (len(cn), 1)) # time vectors on all, states and controls nodes t_all = self.p[phase_name + '.time'] t_all = np.reshape(t_all, (len(t_all), 1)) t_control = np.take(t_all, control_nodes) t_state = np.take(t_all, state_nodes) return state_nodes, control_nodes, t_state, t_control, t_all if __name__ == '__main__': from latom.utils.primary import Moon from latom.utils.spacecraft import Spacecraft moon = Moon() nlp = NLP(moon, Spacecraft(450., 2.1, g=moon.g), 'gauss-lobatto', 100, 3, 'IPOPT') print(nlp)
self.pow1.mf, sc.T_max, sc.Isp, t0=(self.pow1.tf + self.ht.tof), theta0=(self.pow1.thetaf + np.pi)) self.pow2.compute_final_time_states() self.tf = self.pow2.tf if __name__ == '__main__': from latom.utils.primary import Moon from latom.utils.spacecraft import Spacecraft from copy import deepcopy moon = Moon() sat = Spacecraft(450., 2.1, g=moon.g) nb = 50 ff = False dg = TwoDimDescGuess(moon.GM, moon.R, 100e3, sat) dg2 = deepcopy(dg) tvec = np.reshape(np.linspace(0.0, dg.pow2.tf, nb), (nb, 1)) tvec2 = np.sort(np.vstack((tvec, tvec[1:-1])), axis=0) dg.compute_trajectory(fix_final=ff, t_eval=tvec) dg2.compute_trajectory(fix_final=ff, t_eval=tvec2)
moon = Moon() # central attracting body alt = 100e3 # initial orbit altitude [m] alt_p = 15e3 # periselene altitude [m] alt_switch = 4e3 # switch altitude [m] theta = np.pi # guessed spawn angle [rad] tof = (1000, 100) # guessed time of flight [s] t_bounds = (0., 2.) # time of flight bounds [-] # condition to trigger the final vertical descent, 'alt' for fixed altitude equal to 'alt_switch' or 'time' for # fixed time-to-go equal to the second component of 'tof' fix = 'alt' # spacecraft isp = 310. # specific impulse [s] twr = 0.9 # initial thrust/weight ratio [-] sc = Spacecraft(isp, twr, g=moon.g) # NLP method = 'gauss-lobatto' segments = (100, 20) order = 3 solver = 'IPOPT' # additional settings check_partials = False # check partial derivatives run_driver = True # solve the NLP exp_sim = True # perform explicit simulation rec = False # record the solution if rec: # files IDs in the current working directory where the solutions are serialized if 'rec' is set to 'True' rec_file = 'example.sql' # implicit NLP solution
def sampling(self, body, twr_lim, isp_lim, alt, t_bounds, method, nb_seg, order, solver, nb_samp, snopt_opts=None, u_bound=None, rec_file=None, **kwargs): """Compute a new set of training data starting from a given sampling grid. Parameters ---------- body : Primary Central attracting body twr_lim : iterable Thrust/weight ratio lower and upper limits [-] isp_lim : iterable Specific impulse lower and upper limits [s] alt : float Orbit altitude [m] t_bounds : iterable Time of flight lower and upper bounds expressed as fraction of `tof` method : str Transcription method used to discretize the continuous time trajectory into a finite set of nodes, allowed ``gauss-lobatto``, ``radau-ps`` and ``runge-kutta`` nb_seg : int or iterable Number of segments in which each phase is discretized order : int or iterable Transcription order within each phase, must be odd solver : str NLP solver, must be supported by OpenMDAO nb_samp : iterable Number of samples along the `twr` and `Isp` axes snopt_opts : dict or None, optional SNOPT optional settings expressed as key-value pairs. Default is None u_bound : str, optional Specify the bounds on the radial velocity along the transfer as ``lower``, ``upper`` or ``None``. Default is ``None`` rec_file : str, optional Name of the file in `latom.data.metamodels` where the meta model will be stored. Default is ``None`` Other Parameters ---------------- rp : float HEO periapsis radius [m] t : float HEO period [s] log_scale : bool ``True`` if `twr` values are given in logarithmic scale as `log(twr)` """ self.compute_grid(twr_lim, isp_lim, nb_samp) twr_flip = np.flip(self.twr) for j in range(nb_samp[1]): # loop over specific impulses print( f"\nMajor Iteration {j}\nSpecific impulse: {self.Isp[j]:.6f} s\n" ) if kwargs['log_scale']: sc = Spacecraft(self.Isp[j], np.exp(twr_flip[0]), g=body.g) else: sc = Spacecraft(self.Isp[j], twr_flip[0], g=body.g) tr = TwoDimLLO2ApoContinuationAnalyzer( body, sc, alt, kwargs['rp'], kwargs['t'], t_bounds, twr_flip, method, nb_seg, order, solver, snopt_opts=snopt_opts, log_scale=kwargs['log_scale']) tr.run_continuation() self.m_prop[:, j] = np.flip(tr.m_prop_list) self.energy[:, j] = np.flip(tr.energy_list) self.setup() if rec_file is not None: self.save(rec_file)
def sampling(self, body, isp_lim, twr_lim, alt, alt_p, alt_switch, theta, tof, t_bounds, method, nb_seg, order, solver, nb_samp, samp_method='lhs', criterion='m', snopt_opts=None): """Compute a new set of training data starting from a given sampling grid. Parameters ---------- body : Primary Central attracting body isp_lim : iterable Specific impulse lower and upper limits [s] twr_lim : iterable Thrust/weight ratio lower and upper limits [-] alt : float Orbit altitude [m] alt_p : float Periapsis altitude where the final powered descent is initiated [m] alt_switch : float Altitude at which the final vertical descent is triggered [m] theta : float Guessed spawn angle [rad] tof : iterable Guessed time of flight for the two phases [s] t_bounds : iterable Time of flight lower and upper bounds expressed as fraction of `tof` method : str Transcription method used to discretize the continuous time trajectory into a finite set of nodes, allowed ``gauss-lobatto``, ``radau-ps`` and ``runge-kutta`` nb_seg : int or iterable Number of segments in which each phase is discretized order : int or iterable Transcription order within each phase, must be odd solver : str NLP solver, must be supported by OpenMDAO nb_samp : iterable Total number of sampling points samp_method : str, optional Sampling scheme, ``lhs`` for Latin Hypercube Sampling or ``full`` for Full-Factorial Sampling. Default is ``lhs`` criterion : str, optional Criterion used to construct the LHS design among ``center``, ``maximin``, ``centermaximin``, ``correlation``, ``c``, ``m``, ``cm``, ``corr``, ``ese``. ``c``, ``m``, ``cm`` and ``corr`` are abbreviations of ``center``, ``maximin``, ``centermaximin`` and ``correlation``, ``respectively``. Default is ``m`` snopt_opts : dict or None, optional SNOPT optional settings expressed as key-value pairs. Default is None """ self.compute_grid(isp_lim, twr_lim, nb_samp, samp_method=samp_method, criterion=criterion) ht = HohmannTransfer(body.GM, TwoDimOrb(body.GM, a=(body.R + alt), e=0.0), TwoDimOrb(body.GM, a=(body.R + alt_p), e=0.0)) for i in range(nb_samp): sc = Spacecraft(self.x_samp[i, 0], self.x_samp[i, 1], g=body.g) deorbit_burn = ImpulsiveBurn(sc, ht.dva) nlp = TwoDimDescTwoPhasesNLP(body, deorbit_burn.sc, alt, alt_switch, ht.transfer.vp, theta, (0.0, np.pi), tof, t_bounds, method, nb_seg, order, solver, ('free', 'vertical'), snopt_opts=snopt_opts) self.m_prop[i, 0], self.failures[i, 0] = self.solve(nlp, i)
def sampling(self, body, isp_lim, twr_lim, alt, alt_safe, slope, t_bounds, method, nb_seg, order, solver, nb_samp, samp_method='lhs', criterion='m', snopt_opts=None, u_bound='upper'): """Compute a new set of training data starting from a given sampling grid. Parameters ---------- body : Primary Central attracting body isp_lim : iterable Specific impulse lower and upper limits [s] twr_lim : iterable Thrust/weight ratio lower and upper limits [-] alt : float Orbit altitude [m] alt_safe : float Asymptotic minimum safe altitude [m] slope : float Minimum safe altitude slope close to the launch site [-] t_bounds : iterable Time of flight lower and upper bounds expressed as fraction of `tof` method : str Transcription method used to discretize the continuous time trajectory into a finite set of nodes, allowed ``gauss-lobatto``, ``radau-ps`` and ``runge-kutta`` nb_seg : int or iterable Number of segments in which each phase is discretized order : int or iterable Transcription order within each phase, must be odd solver : str NLP solver, must be supported by OpenMDAO nb_samp : iterable Total number of sampling points samp_method : str, optional Sampling scheme, ``lhs`` for Latin Hypercube Sampling or ``full`` for Full-Factorial Sampling. Default is ``lhs`` criterion : str, optional Criterion used to construct the LHS design among ``center``, ``maximin``, ``centermaximin``, ``correlation``, ``c``, ``m``, ``cm``, ``corr``, ``ese``. ``c``, ``m``, ``cm`` and ``corr`` are abbreviations of ``center``, ``maximin``, ``centermaximin`` and ``correlation``, ``respectively``. Default is ``m`` snopt_opts : dict or None, optional SNOPT optional settings expressed as key-value pairs. Default is None u_bound : str, optional Specify the bounds on the radial velocity along the transfer as ``lower``, ``upper`` or ``None``. Default is ``upper`` """ self.compute_grid(isp_lim, twr_lim, nb_samp, samp_method=samp_method, criterion=criterion) for i in range(nb_samp): sc = Spacecraft(self.x_samp[i, 0], self.x_samp[i, 1], g=body.g) nlp = TwoDimDescVLandNLP(body, sc, alt, alt_safe, slope, (0.0, 3 / 2 * np.pi), t_bounds, method, nb_seg, order, solver, 'powered', snopt_opts=snopt_opts, u_bound=u_bound) self.m_prop[i, 0], self.failures[i, 0] = self.solve(nlp, i)
def sampling(self, body, twr_lim, isp_lim, alt, t_bounds, method, nb_seg, order, solver, nb_samp, snopt_opts=None, u_bound=None, rec_file=None, **kwargs): """Compute a new set of training data starting from a given sampling grid. Parameters ---------- body : Primary Central attracting body twr_lim : iterable Thrust/weight ratio lower and upper limits [-] isp_lim : iterable Specific impulse lower and upper limits [s] alt : float Orbit altitude [m] t_bounds : iterable Time of flight lower and upper bounds expressed as fraction of `tof` method : str Transcription method used to discretize the continuous time trajectory into a finite set of nodes, allowed ``gauss-lobatto``, ``radau-ps`` and ``runge-kutta`` nb_seg : int or iterable Number of segments in which each phase is discretized order : int or iterable Transcription order within each phase, must be odd solver : str NLP solver, must be supported by OpenMDAO nb_samp : iterable Number of samples along the `twr` and `Isp` axes snopt_opts : dict or None, optional SNOPT optional settings expressed as key-value pairs. Default is None u_bound : str, optional Specify the bounds on the radial velocity along the transfer as ``lower``, ``upper`` or ``None``. Default is ``None`` rec_file : str, optional Name of the file in `latom.data.metamodels` where the meta model will be stored. Default is ``None`` """ self.compute_grid(twr_lim, isp_lim, nb_samp) count = 1 for i in range(nb_samp[0]): # loop over thrust/weight ratios for j in range(nb_samp[1]): # loop over specific impulses print(f"\nMajor Iteration {j}" f"\nSpecific impulse: {self.Isp[j]:.6f} s" f"\nThrust/weight ratio: {self.twr[i]:.6f}\n") sc = Spacecraft(self.Isp[j], self.twr[i], g=body.g) try: m, f = self.solve(body, sc, alt, t_bounds, method, nb_seg, order, solver, snopt_opts=snopt_opts, u_bound=u_bound, **kwargs) except ValueError: m = None f = 1. self.m_prop[i, j] = m self.failures[i, j] = f count += 1 self.setup() if rec_file is not None: self.save(rec_file)