コード例 #1
0
def min_time_climb(num_seg=3,
                   transcription_order=3,
                   force_alloc_complex=False):

    p = om.Problem(model=om.Group())

    tx = dm.GaussLobatto(num_segments=num_seg, order=transcription_order)

    traj = dm.Trajectory()

    phase = dm.Phase(ode_class=MinTimeClimbODE, transcription=tx)
    traj.add_phase('phase0', phase)

    p.model.add_subsystem('traj', traj)

    phase.set_time_options(fix_initial=True,
                           duration_bounds=(50, 400),
                           duration_ref=100.0)

    phase.add_state('r',
                    fix_initial=True,
                    lower=0,
                    upper=1.0E6,
                    ref=1.0E3,
                    defect_ref=1.0E3,
                    units='m',
                    rate_source='flight_dynamics.r_dot')

    phase.add_state('h',
                    fix_initial=True,
                    lower=0,
                    upper=20000.0,
                    ref=1.0E2,
                    defect_ref=1.0E2,
                    units='m',
                    rate_source='flight_dynamics.h_dot',
                    targets=['h'])

    phase.add_state('v',
                    fix_initial=True,
                    lower=10.0,
                    ref=1.0E2,
                    defect_ref=1.0E2,
                    units='m/s',
                    rate_source='flight_dynamics.v_dot',
                    targets=['v'])

    phase.add_state('gam',
                    fix_initial=True,
                    lower=-1.5,
                    upper=1.5,
                    ref=1.0,
                    defect_ref=1.0,
                    units='rad',
                    rate_source='flight_dynamics.gam_dot',
                    targets=['gam'])

    phase.add_state('m',
                    fix_initial=True,
                    lower=10.0,
                    upper=1.0E5,
                    ref=1.0E3,
                    defect_ref=1.0E3,
                    units='kg',
                    rate_source='prop.m_dot',
                    targets=['m'])

    phase.add_control('alpha',
                      units='deg',
                      lower=-8.0,
                      upper=8.0,
                      scaler=1.0,
                      rate_continuity=True,
                      rate_continuity_scaler=100.0,
                      rate2_continuity=False,
                      targets=['alpha'])

    phase.add_parameter('S',
                        val=49.2386,
                        units='m**2',
                        opt=False,
                        targets=['S'])
    phase.add_parameter('Isp',
                        val=1600.0,
                        units='s',
                        opt=False,
                        targets=['Isp'])
    phase.add_parameter('throttle', val=1.0, opt=False, targets=['throttle'])

    phase.add_boundary_constraint('h',
                                  loc='final',
                                  equals=20000,
                                  scaler=1.0E-3)
    phase.add_boundary_constraint('aero.mach', loc='final', equals=1.0)
    phase.add_boundary_constraint('gam', loc='final', equals=0.0)

    phase.add_path_constraint(name='h', lower=100.0, upper=20000, ref=20000)
    phase.add_path_constraint(name='aero.mach', lower=0.1, upper=1.8)

    # Unnecessary but included to test capability
    phase.add_path_constraint(name='alpha', lower=-8, upper=8)
    phase.add_path_constraint(name='time', lower=0, upper=400)
    phase.add_path_constraint(name='time_phase', lower=0, upper=400)

    # Minimize time at the end of the phase
    phase.add_objective('time', loc='final', ref=1.0)

    p.model.linear_solver = om.DirectSolver()

    p.setup(check=True, force_alloc_complex=force_alloc_complex)

    p['traj.phase0.t_initial'] = 0.0
    p['traj.phase0.t_duration'] = 300.0

    p['traj.phase0.states:r'] = phase.interp('r', [0.0, 111319.54])
    p['traj.phase0.states:h'] = phase.interp('h', [100.0, 20000.0])
    p['traj.phase0.states:v'] = phase.interp('v', [135.964, 283.159])
    p['traj.phase0.states:gam'] = phase.interp('gam', [0.0, 0.0])
    p['traj.phase0.states:m'] = phase.interp('m', [19030.468, 16841.431])
    p['traj.phase0.controls:alpha'] = phase.interp('alpha', [0.0, 0.0])

    return p
コード例 #2
0
    def _make_problem(self,
                      transcription='gauss-lobatto',
                      num_segments=8,
                      transcription_order=3,
                      compressed=True,
                      optimizer='SLSQP',
                      run_driver=True,
                      force_alloc_complex=False,
                      solve_segments=False):

        p = om.Problem(model=om.Group())

        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = optimizer
        p.driver.declare_coloring(tol=1.0E-12)

        if transcription == 'gauss-lobatto':
            t = dm.GaussLobatto(num_segments=num_segments,
                                order=transcription_order,
                                compressed=compressed)
        elif transcription == 'radau-ps':
            t = dm.Radau(num_segments=num_segments,
                         order=transcription_order,
                         compressed=compressed)

        # upgrade_doc: begin exec_comp_ode
        ode = lambda num_nodes: om.ExecComp([
            'vdot = g * cos(theta)', 'xdot = v * sin(theta)',
            'ydot = -v * cos(theta)'
        ],
                                            g={
                                                'value': 9.80665,
                                                'units': 'm/s**2'
                                            },
                                            v={
                                                'shape': (num_nodes, ),
                                                'units': 'm/s'
                                            },
                                            theta={
                                                'shape': (num_nodes, ),
                                                'units': 'rad'
                                            },
                                            vdot={
                                                'shape': (num_nodes, ),
                                                'units': 'm/s**2'
                                            },
                                            xdot={
                                                'shape': (num_nodes, ),
                                                'units': 'm/s'
                                            },
                                            ydot={
                                                'shape': (num_nodes, ),
                                                'units': 'm/s'
                                            },
                                            has_diag_partials=True)

        phase = dm.Phase(ode_class=ode, transcription=t)
        # upgrade_doc: end declare_rate_source
        traj = dm.Trajectory()
        p.model.add_subsystem('traj0', traj)
        traj.add_phase('phase0', phase)

        phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

        phase.add_state('x',
                        fix_initial=True,
                        fix_final=False,
                        solve_segments=solve_segments,
                        rate_source='xdot')
        phase.add_state('y',
                        fix_initial=True,
                        fix_final=False,
                        solve_segments=solve_segments,
                        rate_source='ydot')

        # Note that by omitting the targets here Dymos will automatically attempt to connect
        # to a top-level input named 'v' in the ODE, and connect to nothing if it's not found.
        phase.add_state('v',
                        fix_initial=True,
                        fix_final=False,
                        solve_segments=solve_segments,
                        rate_source='vdot')

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          units='deg',
                          lower=0.01,
                          upper=179.9)

        phase.add_parameter('g', units='m/s**2', static_target=True)

        phase.add_boundary_constraint('x', loc='final', equals=10)
        phase.add_boundary_constraint('y', loc='final', equals=5)
        # Minimize time at the end of the phase
        phase.add_objective('time_phase', loc='final', scaler=10)

        p.setup(check=['unconnected_inputs'],
                force_alloc_complex=force_alloc_complex)

        p['traj0.phase0.t_initial'] = 0.0
        p['traj0.phase0.t_duration'] = 2.0

        p['traj0.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                       nodes='state_input')
        p['traj0.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                       nodes='state_input')
        p['traj0.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                       nodes='state_input')
        p['traj0.phase0.controls:theta'] = phase.interpolate(
            ys=[5, 100], nodes='control_input')
        p['traj0.phase0.parameters:g'] = 9.80665

        dm.run_problem(p, run_driver=run_driver, simulate=True)

        return p
コード例 #3
0
    def test_tags(self):
        """
        # upgrade_doc: begin tag_rate_source
        self.add_output('xdot', val=np.zeros(nn), desc='velocity component in x', units='m/s')
        self.add_output('ydot', val=np.zeros(nn), desc='velocity component in y', units='m/s')
        self.add_output('vdot', val=np.zeros(nn), desc='acceleration magnitude', units='m/s**2')
        # upgrade_doc: end tag_rate_source
        # upgrade_doc: begin declare_rate_source
        phase.add_state('x', rate_source='xdot', fix_initial=True, fix_final=True)
        phase.add_state('y', rate_source='ydot', fix_initial=True, fix_final=True)
        phase.add_state('v', rate_source='vdot', fix_initial=True, fix_final=False)
        # upgrade_doc: end declare_rate_source
        """
        import numpy as np
        import openmdao.api as om

        class BrachistochroneODE(om.ExplicitComponent):
            def initialize(self):
                self.options.declare('num_nodes', types=int)
                self.options.declare(
                    'static_gravity',
                    types=(bool, ),
                    default=False,
                    desc=
                    'If True, treat gravity as a static (scalar) input, rather than '
                    'having different values at each node.')

            def setup(self):
                nn = self.options['num_nodes']
                g_default_val = 9.80665 if self.options[
                    'static_gravity'] else 9.80665 * np.ones(nn)

                # Inputs
                self.add_input('v',
                               val=np.zeros(nn),
                               desc='velocity',
                               units='m/s')

                self.add_input('g',
                               val=g_default_val,
                               desc='grav. acceleration',
                               units='m/s/s')

                self.add_input('theta',
                               val=np.ones(nn),
                               desc='angle of wire',
                               units='rad')

                # upgrade_doc: begin tag_rate_source
                self.add_output(
                    'xdot',
                    val=np.zeros(nn),
                    desc='velocity component in x',
                    units='m/s',
                    tags=['dymos.state_rate_source:x', 'dymos.state_units:m'])

                self.add_output(
                    'ydot',
                    val=np.zeros(nn),
                    desc='velocity component in y',
                    units='m/s',
                    tags=['dymos.state_rate_source:y', 'dymos.state_units:m'])

                self.add_output('vdot',
                                val=np.zeros(nn),
                                desc='acceleration magnitude',
                                units='m/s**2',
                                tags=[
                                    'dymos.state_rate_source:v',
                                    'dymos.state_units:m/s'
                                ])
                # upgrade_doc: end tag_rate_source

                self.add_output('check',
                                val=np.zeros(nn),
                                desc='check solution: v/sin(theta) = constant',
                                units='m/s')

                # Setup partials
                arange = np.arange(self.options['num_nodes'])
                self.declare_partials(of='vdot',
                                      wrt='theta',
                                      rows=arange,
                                      cols=arange)

                self.declare_partials(of='xdot',
                                      wrt='v',
                                      rows=arange,
                                      cols=arange)
                self.declare_partials(of='xdot',
                                      wrt='theta',
                                      rows=arange,
                                      cols=arange)

                self.declare_partials(of='ydot',
                                      wrt='v',
                                      rows=arange,
                                      cols=arange)
                self.declare_partials(of='ydot',
                                      wrt='theta',
                                      rows=arange,
                                      cols=arange)

                self.declare_partials(of='check',
                                      wrt='v',
                                      rows=arange,
                                      cols=arange)
                self.declare_partials(of='check',
                                      wrt='theta',
                                      rows=arange,
                                      cols=arange)

                if self.options['static_gravity']:
                    c = np.zeros(self.options['num_nodes'])
                    self.declare_partials(of='vdot',
                                          wrt='g',
                                          rows=arange,
                                          cols=c)
                else:
                    self.declare_partials(of='vdot',
                                          wrt='g',
                                          rows=arange,
                                          cols=arange)

            def compute(self, inputs, outputs):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                g = inputs['g']
                v = inputs['v']

                outputs['vdot'] = g * cos_theta
                outputs['xdot'] = v * sin_theta
                outputs['ydot'] = -v * cos_theta
                outputs['check'] = v / sin_theta

            def compute_partials(self, inputs, partials):
                theta = inputs['theta']
                cos_theta = np.cos(theta)
                sin_theta = np.sin(theta)
                g = inputs['g']
                v = inputs['v']

                partials['vdot', 'g'] = cos_theta
                partials['vdot', 'theta'] = -g * sin_theta

                partials['xdot', 'v'] = sin_theta
                partials['xdot', 'theta'] = v * cos_theta

                partials['ydot', 'v'] = -cos_theta
                partials['ydot', 'theta'] = v * sin_theta

                partials['check', 'v'] = 1 / sin_theta
                partials['check', 'theta'] = -v * cos_theta / sin_theta**2

        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_near_equal
        import dymos as dm

        #
        # Initialize the Problem and the optimization driver
        #
        p = om.Problem(model=om.Group())
        p.driver = om.ScipyOptimizeDriver()
        p.driver.declare_coloring()

        #
        # Create a trajectory and add a phase to it
        #
        traj = p.model.add_subsystem('traj', dm.Trajectory())

        phase = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=BrachistochroneODE,
                     transcription=dm.GaussLobatto(num_segments=10)))

        #
        # Set the variables
        #
        phase.set_time_options(fix_initial=True, duration_bounds=(.5, 10))

        # upgrade_doc: begin declare_rate_source
        phase.add_state('x', fix_initial=True, fix_final=True)
        phase.add_state('y', fix_initial=True, fix_final=True)
        phase.add_state('v', fix_initial=True, fix_final=False)
        # upgrade_doc: end declare_rate_source

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          units='deg',
                          lower=0.01,
                          upper=179.9)

        phase.add_parameter('g', units='m/s**2', val=9.80665)
        #
        # Minimize time at the end of the phase
        #
        phase.add_objective('time', loc='final', scaler=10)

        p.model.linear_solver = om.DirectSolver()

        #
        # Setup the Problem
        #
        p.setup()

        #
        # Set the initial values
        #
        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 2.0

        p['traj.phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                      nodes='state_input')
        p['traj.phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                      nodes='state_input')
        p['traj.phase0.controls:theta'] = phase.interpolate(
            ys=[5, 100.5], nodes='control_input')

        #
        # Solve for the optimal trajectory
        #
        dm.run_problem(p)

        # Test the results
        assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1],
                          1.8016,
                          tolerance=1.0E-3)
コード例 #4
0
    def test_sequence_timeseries_outputs(self):
        """
        # upgrade_doc: begin sequence_timeseries_outputs
        phase.add_timeseries_output('aero.mach', shape=(1,), units=None)
        phase.add_timeseries_output('aero.CD0', shape=(1,), units=None)
        phase.add_timeseries_output('aero.kappa', shape=(1,), units=None)
        phase.add_timeseries_output('aero.CLa', shape=(1,), units=None)
        phase.add_timeseries_output('aero.CL', shape=(1,), units=None)
        phase.add_timeseries_output('aero.CD', shape=(1,), units=None)
        phase.add_timeseries_output('aero.q', shape=(1,), units='N/m**2')
        phase.add_timeseries_output('aero.f_lift', shape=(1,), units='lbf')
        phase.add_timeseries_output('aero.f_drag', shape=(1,), units='N')
        phase.add_timeseries_output('prop.thrust', shape=(1,), units='lbf')
        # upgrade_doc: end sequence_timeseries_outputs
        # upgrade_doc: begin state_endpoint_values
        final_range = p.get_val('traj.phase0.final_conditions.states:x0++')
        final_alpha = p.get_val('traj.phase0.final_conditions.controls:alpha++')
        # upgrade_doc: end state_endpoint_values
        """
        from dymos.examples.min_time_climb.min_time_climb_ode import MinTimeClimbODE

        p = om.Problem(model=om.Group())

        p.driver = om.pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.declare_coloring(tol=1.0E-12)

        traj = dm.Trajectory()

        phase = dm.Phase(ode_class=MinTimeClimbODE,
                         transcription=dm.GaussLobatto(num_segments=15,
                                                       compressed=True))

        traj.add_phase('phase0', phase)

        p.model.add_subsystem('traj', traj)

        phase.set_time_options(fix_initial=True,
                               duration_bounds=(50, 400),
                               duration_ref=100.0)

        phase.add_state('r',
                        fix_initial=True,
                        lower=0,
                        upper=1.0E6,
                        ref=1.0E3,
                        defect_ref=1.0E3,
                        units='m',
                        rate_source='flight_dynamics.r_dot')

        phase.add_state('h',
                        fix_initial=True,
                        lower=0,
                        upper=20000.0,
                        ref=1.0E2,
                        defect_ref=1.0E2,
                        units='m',
                        rate_source='flight_dynamics.h_dot')

        phase.add_state('v',
                        fix_initial=True,
                        lower=10.0,
                        ref=1.0E2,
                        defect_ref=1.0E2,
                        units='m/s',
                        rate_source='flight_dynamics.v_dot')

        phase.add_state('gam',
                        fix_initial=True,
                        lower=-1.5,
                        upper=1.5,
                        ref=1.0,
                        defect_ref=1.0,
                        units='rad',
                        rate_source='flight_dynamics.gam_dot')

        phase.add_state('m',
                        fix_initial=True,
                        lower=10.0,
                        upper=1.0E5,
                        ref=1.0E3,
                        defect_ref=1.0E3,
                        units='kg',
                        rate_source='prop.m_dot')

        phase.add_control('alpha',
                          units='deg',
                          lower=-8.0,
                          upper=8.0,
                          scaler=1.0,
                          rate_continuity=True,
                          rate_continuity_scaler=100.0,
                          rate2_continuity=False,
                          targets=['alpha'])

        phase.add_parameter('S',
                            val=49.2386,
                            units='m**2',
                            opt=False,
                            targets=['S'])
        phase.add_parameter('Isp',
                            val=1600.0,
                            units='s',
                            opt=False,
                            targets=['Isp'])
        phase.add_parameter('throttle',
                            val=1.0,
                            opt=False,
                            targets=['throttle'])

        phase.add_boundary_constraint('h',
                                      loc='final',
                                      equals=20000,
                                      scaler=1.0E-3,
                                      units='m')
        phase.add_boundary_constraint('aero.mach',
                                      loc='final',
                                      equals=1.0,
                                      shape=(1, ))
        phase.add_boundary_constraint('gam',
                                      loc='final',
                                      equals=0.0,
                                      units='rad')

        phase.add_path_constraint(name='h',
                                  lower=100.0,
                                  upper=20000,
                                  ref=20000)
        phase.add_path_constraint(name='aero.mach',
                                  lower=0.1,
                                  upper=1.8,
                                  shape=(1, ))

        phase.add_objective('time', loc='final', ref=1.0)

        p.model.linear_solver = om.DirectSolver()

        # upgrade_doc: begin sequence_timeseries_outputs
        phase.add_timeseries_output(['aero.*', 'prop.thrust'],
                                    units={
                                        'aero.f_lift': 'lbf',
                                        'prop.thrust': 'lbf'
                                    })
        # upgrade_doc: end sequence_timeseries_outputs

        p.setup(check=True)

        p['traj.phase0.t_initial'] = 0.0
        p['traj.phase0.t_duration'] = 500

        p['traj.phase0.states:r'] = phase.interpolate(ys=[0.0, 50000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:h'] = phase.interpolate(ys=[100.0, 20000.0],
                                                      nodes='state_input')
        p['traj.phase0.states:v'] = phase.interpolate(ys=[135.964, 283.159],
                                                      nodes='state_input')
        p['traj.phase0.states:gam'] = phase.interpolate(ys=[0.0, 0.0],
                                                        nodes='state_input')
        p['traj.phase0.states:m'] = phase.interpolate(ys=[19030.468, 10000.],
                                                      nodes='state_input')
        p['traj.phase0.controls:alpha'] = phase.interpolate(
            ys=[0.0, 0.0], nodes='control_input')

        p.run_model()

        # upgrade_doc: begin state_endpoint_values
        final_range = p.get_val('traj.phase0.timeseries.states:r')[-1, ...]
        final_alpha = p.get_val('traj.phase0.timeseries.controls:alpha')[-1,
                                                                         ...]
        # upgrade_doc: end state_endpoint_values
        self.assertEqual(final_range, 50000.0)
        self.assertEqual(final_alpha, 0.0)

        outputs = p.model.list_outputs(units=True,
                                       out_stream=None,
                                       prom_name=True)
        op_dict = {
            options['prom_name']: options['units']
            for abs_name, options in outputs
        }

        for name, units in [('mach', None), ('CD0', None), ('kappa', None),
                            ('CLa', None), ('CL', None), ('CD', None),
                            ('q', 'N/m**2'), ('f_lift', 'lbf'),
                            ('f_drag', 'N'), ('thrust', 'lbf')]:
            self.assertEqual(op_dict[f'traj.phase0.timeseries.{name}'], units)
コード例 #5
0
    def test_parameters(self):
        """
        # upgrade_doc: begin set_val
        p.set_val('traj.phase0.design_parameters:thrust', 2.1, units='MN')
        # upgrade_doc: end set_val
        # upgrade_doc: begin parameter_timeseries
        thrust = p.get_val('traj.phase0.timeseries.design_parameters:thrust')
        # upgrade_doc: end parameter_timeseries
        """
        import numpy as np
        import openmdao.api as om
        import dymos as dm

        #
        # Setup and solve the optimal control problem
        #
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring(tol=1.0E-12)

        from dymos.examples.ssto.launch_vehicle_ode import LaunchVehicleODE

        #
        # Initialize our Trajectory and Phase
        #
        traj = dm.Trajectory()

        phase = dm.Phase(ode_class=LaunchVehicleODE,
                         transcription=dm.GaussLobatto(num_segments=12,
                                                       order=3,
                                                       compressed=False))

        traj.add_phase('phase0', phase)
        p.model.add_subsystem('traj', traj)

        #
        # Set the options for the variables
        #
        phase.set_time_options(fix_initial=True, duration_bounds=(10, 500))

        phase.add_state('x',
                        fix_initial=True,
                        ref=1.0E5,
                        defect_ref=10000.0,
                        rate_source='xdot')
        phase.add_state('y',
                        fix_initial=True,
                        ref=1.0E5,
                        defect_ref=10000.0,
                        rate_source='ydot')
        phase.add_state('vx',
                        fix_initial=True,
                        ref=1.0E3,
                        defect_ref=1000.0,
                        rate_source='vxdot')
        phase.add_state('vy',
                        fix_initial=True,
                        ref=1.0E3,
                        defect_ref=1000.0,
                        rate_source='vydot')
        phase.add_state('m',
                        fix_initial=True,
                        ref=1.0E3,
                        defect_ref=100.0,
                        rate_source='mdot')

        phase.add_control('theta', units='rad', lower=-1.57, upper=1.57)
        phase.add_parameter('thrust', units='N', opt=False, val=2100000.0)

        #
        # Set the options for our constraints and objective
        #
        phase.add_boundary_constraint('y',
                                      loc='final',
                                      equals=1.85E5,
                                      linear=True)
        phase.add_boundary_constraint('vx', loc='final', equals=7796.6961)
        phase.add_boundary_constraint('vy', loc='final', equals=0)

        phase.add_objective('time', loc='final', scaler=0.01)

        p.model.linear_solver = om.DirectSolver()

        #
        # Setup and set initial values
        #
        p.setup(check=True)

        p.set_val('traj.phase0.t_initial', 0.0)
        p.set_val('traj.phase0.t_duration', 150.0)
        p.set_val('traj.phase0.states:x',
                  phase.interpolate(ys=[0, 1.15E5], nodes='state_input'))
        p.set_val('traj.phase0.states:y',
                  phase.interpolate(ys=[0, 1.85E5], nodes='state_input'))
        p.set_val('traj.phase0.states:vx',
                  phase.interpolate(ys=[0, 7796.6961], nodes='state_input'))
        p.set_val('traj.phase0.states:vy',
                  phase.interpolate(ys=[1.0E-6, 0], nodes='state_input'))
        p.set_val('traj.phase0.states:m',
                  phase.interpolate(ys=[117000, 1163], nodes='state_input'))
        p.set_val('traj.phase0.controls:theta',
                  phase.interpolate(ys=[1.5, -0.76], nodes='control_input'))

        # upgrade_doc: begin set_val
        p.set_val('traj.phase0.parameters:thrust', 2.1, units='MN')
        # upgrade_doc: end set_val

        #
        # Solve the Problem
        #
        dm.run_problem(p)

        #
        # Check the results.
        #
        assert_near_equal(p.get_val('traj.phase0.timeseries.time')[-1],
                          143,
                          tolerance=0.05)
        assert_near_equal(
            p.get_val('traj.phase0.timeseries.states:y')[-1], 1.85E5, 1e-4)
        assert_near_equal(
            p.get_val('traj.phase0.timeseries.states:vx')[-1], 7796.6961, 1e-4)
        assert_near_equal(
            p.get_val('traj.phase0.timeseries.states:vy')[-1], 0, 1e-4)

        # upgrade_doc: begin parameter_timeseries
        thrust = p.get_val('traj.phase0.timeseries.parameters:thrust')
        # upgrade_doc: end parameter_timeseries
        nn = phase.options['transcription'].grid_data.num_nodes
        assert_near_equal(thrust, 2.1E6 * np.ones([nn, 1]))
コード例 #6
0
    def test_reentry(self):
        import openmdao.api as om
        from openmdao.utils.assert_utils import assert_rel_error
        import dymos as dm
        from dymos.examples.shuttle_reentry.shuttle_ode import ShuttleODE
        from dymos.examples.plotting import plot_results

        # Instantiate the problem, add the driver, and allow it to use coloring
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()
        p.driver.options['optimizer'] = 'SLSQP'

        # Instantiate the trajectory and add a phase to it
        traj = p.model.add_subsystem('traj', dm.Trajectory())
        phase0 = traj.add_phase(
            'phase0',
            dm.Phase(ode_class=ShuttleODE,
                     transcription=dm.GaussLobatto(num_segments=30, order=3)))

        phase0.set_time_options(fix_initial=True, units='s', duration_ref=200)
        phase0.add_state('h',
                         fix_initial=True,
                         fix_final=True,
                         units='ft',
                         rate_source='hdot',
                         targets=['h'],
                         lower=0,
                         ref0=75000,
                         ref=300000,
                         defect_ref=1000)
        phase0.add_state('gamma',
                         fix_initial=True,
                         fix_final=True,
                         units='rad',
                         rate_source='gammadot',
                         targets=['gamma'],
                         lower=-89. * np.pi / 180,
                         upper=89. * np.pi / 180)
        phase0.add_state('phi',
                         fix_initial=True,
                         fix_final=False,
                         units='rad',
                         rate_source='phidot',
                         lower=0,
                         upper=89. * np.pi / 180)
        phase0.add_state('psi',
                         fix_initial=True,
                         fix_final=False,
                         units='rad',
                         rate_source='psidot',
                         targets=['psi'],
                         lower=0,
                         upper=90. * np.pi / 180)
        phase0.add_state('theta',
                         fix_initial=True,
                         fix_final=False,
                         units='rad',
                         rate_source='thetadot',
                         targets=['theta'],
                         lower=-89. * np.pi / 180,
                         upper=89. * np.pi / 180)
        phase0.add_state('v',
                         fix_initial=True,
                         fix_final=True,
                         units='ft/s',
                         rate_source='vdot',
                         targets=['v'],
                         lower=0,
                         ref0=2500,
                         ref=25000)
        phase0.add_control('alpha',
                           units='rad',
                           opt=True,
                           lower=-np.pi / 2,
                           upper=np.pi / 2,
                           targets=['alpha'])
        phase0.add_control('beta',
                           units='rad',
                           opt=True,
                           lower=-89 * np.pi / 180,
                           upper=1 * np.pi / 180,
                           targets=['beta'])

        # The original implementation by Betts includes a heating rate path constraint.
        # This will work with the SNOPT optimizer but SLSQP has difficulty converging the solution.
        # phase0.add_path_constraint('q', lower=0, upper=70, units='Btu/ft**2/s', ref=70)
        phase0.add_timeseries_output('q', shape=(1, ), units='Btu/ft**2/s')

        phase0.add_objective('theta', loc='final', ref=-0.01)

        p.setup(check=True)

        p.set_val('traj.phase0.states:h',
                  phase0.interpolate(ys=[260000, 80000], nodes='state_input'),
                  units='ft')
        p.set_val('traj.phase0.states:gamma',
                  phase0.interpolate(ys=[-1, -5], nodes='state_input'),
                  units='deg')
        p.set_val('traj.phase0.states:phi',
                  phase0.interpolate(ys=[0, 75], nodes='state_input'),
                  units='deg')
        p.set_val('traj.phase0.states:psi',
                  phase0.interpolate(ys=[90, 10], nodes='state_input'),
                  units='deg')
        p.set_val('traj.phase0.states:theta',
                  phase0.interpolate(ys=[0, 25], nodes='state_input'),
                  units='deg')
        p.set_val('traj.phase0.states:v',
                  phase0.interpolate(ys=[25600, 2500], nodes='state_input'),
                  units='ft/s')
        p.set_val('traj.phase0.t_initial', 0, units='s')
        p.set_val('traj.phase0.t_duration', 2000, units='s')
        p.set_val('traj.phase0.controls:alpha',
                  phase0.interpolate(ys=[17.4, 17.4], nodes='control_input'),
                  units='deg')
        p.set_val('traj.phase0.controls:beta',
                  phase0.interpolate(ys=[-75, 0], nodes='control_input'),
                  units='deg')

        # Run the driver
        p.run_driver()

        # Check the validity of the solution
        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.time')[-1],
                         2008.59,
                         tolerance=1e-3)
        assert_rel_error(self,
                         p.get_val('traj.phase0.timeseries.states:theta',
                                   units='deg')[-1],
                         34.1412,
                         tolerance=1e-3)
        # assert_rel_error(self, p.get_val('traj.phase0.timeseries.time')[-1], 2181.90371131, tolerance=1e-3)
        # assert_rel_error(self, p.get_val('traj.phase0.timeseries.states:theta')[-1], .53440626, tolerance=1e-3)

        # Run the simulation to check if the model is physically valid
        sim_out = traj.simulate()

        # Plot the results

        plot_results([
            ('traj.phase0.timeseries.time',
             'traj.phase0.timeseries.controls:alpha', 'time (s)',
             'alpha (rad)'),
            ('traj.phase0.timeseries.time',
             'traj.phase0.timeseries.controls:beta', 'time (s)', 'beta (rad)'),
            ('traj.phase0.timeseries.time',
             'traj.phase0.timeseries.states:theta', 'time (s)', 'theta (rad)'),
            ('traj.phase0.timeseries.time', 'traj.phase0.timeseries.q',
             'time (s)', 'q (btu/ft/ft/s')
        ],
                     title='Reentry Solution',
                     p_sol=p,
                     p_sim=sim_out)

        plt.show()