Ejemplo n.º 1
0
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)
Ejemplo n.º 2
0
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
Ejemplo n.º 3
0
        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)
Ejemplo n.º 4
0
                                   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)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
    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)
Ejemplo n.º 7
0
    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)
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)