예제 #1
0
    def setUp(self):
        self.p = Problem(model=Group())

        self.p.driver = pyOptSparseDriver()
        self.p.driver.options['optimizer'] = OPTIMIZER
        if OPTIMIZER == 'SNOPT':
            self.p.driver.opt_settings['Major iterations limit'] = 50
            self.p.driver.opt_settings['iSumm'] = 6
            self.p.driver.opt_settings['Verify level'] = 3

        phase = Phase(ode_class=_CannonballODE,
                      transcription=GaussLobatto(num_segments=15, order=3, compressed=False))

        self.p.model.add_subsystem('phase0', phase)

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(10, 20))

        phase.set_state_options('r', fix_initial=True, fix_final=False,
                                scaler=0.001, defect_scaler=0.001)

        phase.set_state_options('h', fix_initial=True, fix_final=True,  # Require final altitude
                                scaler=0.001, defect_scaler=0.001)

        phase.set_state_options('v', fix_initial=True, fix_final=False,
                                scaler=0.01, defect_scaler=0.01)

        phase.set_state_options('gam', fix_final=False,
                                scaler=1.0, defect_scaler=1.0)

        # Maximize final range by varying initial flight path angle
        phase.add_objective('r', loc='final', scaler=-0.01)
예제 #2
0
    def test_initial_val_and_final_val_stick(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8, order=3))

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

        phase.set_time_options(fix_initial=False, fix_duration=False,
                               initial_val=0.01, duration_val=1.9)

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        phase.add_boundary_constraint('time', loc='initial', equals=0)

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

        assert_rel_error(self, p['phase0.t_initial'], 0.01)
        assert_rel_error(self, p['phase0.t_duration'], 1.9)
예제 #3
0
    def __init__(self, body, sc, method, nb_seg, order, solver, ode_class, ode_kwargs, ph_name, snopt_opts=None,
                 rec_file=None):

        NLP.__init__(self, body, sc, method, nb_seg, order, solver, snopt_opts=snopt_opts, rec_file=rec_file)

        # Transcription object
        if self.method == 'gauss-lobatto':
            self.transcription = GaussLobatto(num_segments=self.nb_seg, order=self.order, compressed=True)
        elif self.method == 'radau-ps':
            self.transcription = Radau(num_segments=self.nb_seg, order=self.order, compressed=True)
        elif self.method == 'runge-kutta':
            self.transcription = RungeKutta(num_segments=self.nb_seg, order=self.order, compressed=True)
        else:
            raise ValueError('method must be either gauss-lobatto or radau-ps')

        # Phase object
        self.phase = self.trajectory.add_phase(ph_name, Phase(ode_class=ode_class, ode_init_kwargs=ode_kwargs,
                                                              transcription=self.transcription))
        self.phase_name = ''.join(['traj.', ph_name])

        # discretization nodes
        self.state_nodes = None
        self.control_nodes = None
        self.t_all = None
        self.t_state = None
        self.t_control = None
        self.idx_state_control = None

        # time of flight
        self.tof = None
예제 #4
0
    def __init__(self, body, sc, method, nb_seg, order, solver, ode_class, ode_kwargs, ph_name, snopt_opts=None,
                 rec_file=None):

        if isinstance(order, int):
            order = tuple(order for _ in range(len(nb_seg)))

        if isinstance(method, str):
            method = tuple(method for _ in range(len(nb_seg)))

        NLP.__init__(self, body, sc, method, nb_seg, order, solver, snopt_opts=snopt_opts, rec_file=rec_file)

        # Transcription objects list
        self.transcription = []

        for i in range(len(self.nb_seg)):
            if self.method[i] == 'gauss-lobatto':
                t = GaussLobatto(num_segments=self.nb_seg[i], order=self.order[i], compressed=True)
            elif self.method[i] == 'radau-ps':
                t = Radau(num_segments=self.nb_seg[i], order=self.order[i], compressed=True)
            elif self.method[i] == 'runge-kutta':
                t = RungeKutta(num_segments=self.nb_seg[i], order=self.order[i], compressed=True)
            else:
                raise ValueError('method must be either gauss-lobatto, radau-ps or runge-kutta')
            self.transcription.append(t)

        # Phase objects list
        self.phase = []
        self.phase_name = []

        for i in range(len(self.nb_seg)):
            ph = self.trajectory.add_phase(ph_name[i], Phase(ode_class=ode_class[i], ode_init_kwargs=ode_kwargs[i],
                                                             transcription=self.transcription[i]))
            self.phase.append(ph)
            self.phase_name.append(''.join(['traj.', ph_name[i]]))
예제 #5
0
    def test_control_rate_path_constraint_gl(self):
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10))

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

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        phase.add_path_constraint('theta_rate',
                                  lower=0,
                                  upper=100,
                                  units='deg/s')

        p.model.linear_solver = DirectSolver()

        p.setup()

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

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

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)
예제 #6
0
    def test_invalid_boundary_loc(self):

        p = Phase(ode_class=BrachistochroneODE,
                  transcription=GaussLobatto(num_segments=8,
                                             order=3,
                                             compressed=True))

        with self.assertRaises(ValueError) as e:
            p.add_boundary_constraint('x', loc='foo')

        expected = 'Invalid boundary constraint location "foo". Must be "initial" or "final".'
        self.assertEqual(str(e.exception), expected)
예제 #7
0
    def test_add_existing_control_as_design_parameter(self):

        p = Phase(ode_class=BrachistochroneODE,
                  transcription=GaussLobatto(num_segments=8, order=3))

        p.add_control('theta')

        with self.assertRaises(ValueError) as e:
            p.add_design_parameter('theta')

        expected = 'theta has already been added as a control.'
        self.assertEqual(str(e.exception), expected)
예제 #8
0
    def test_add_existing_design_parameter_as_input_parameter(self):
        p = Phase(ode_class=_A,
                  transcription=GaussLobatto(num_segments=14,
                                             order=3,
                                             compressed=True))

        p.add_design_parameter('theta')

        with self.assertRaises(ValueError) as e:
            p.add_input_parameter('theta')

        expected = 'theta has already been added as a design parameter.'
        self.assertEqual(str(e.exception), expected)
예제 #9
0
    def test_objective_design_parameter_gl(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=True, val=9.80665)

        # Minimize time at the end of the phase
        phase.add_objective('g')

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

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

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

        p.run_driver()

        assert_rel_error(self, p['phase0.t_duration'], 10, tolerance=1.0E-3)
예제 #10
0
    def test_invalid_options_nonoptimal_design_param(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True
        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=16,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          opt=False)

        phase.add_design_parameter('g',
                                   units='m/s**2',
                                   opt=False,
                                   lower=5,
                                   upper=10,
                                   ref0=5,
                                   ref=10,
                                   scaler=1,
                                   adder=0)

        # Minimize time at the end of the phase
        phase.add_objective('g')

        p.model.linear_solver = DirectSolver()

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter('always')
            p.setup(check=False)

        print('\n'.join([str(ww.message) for ww in w]))

        expected = 'Invalid options for non-optimal design_parameter \'g\' in phase \'phase0\': ' \
                   'lower, upper, scaler, adder, ref, ref0'

        self.assertIn(expected, [str(ww.message) for ww in w])
예제 #11
0
    def test_fixed_time_invalid_options(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8, order=3))

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

        phase.set_time_options(fix_initial=True, fix_duration=True,
                               initial_bounds=(1.0, 5.0), initial_adder=0.0,
                               initial_scaler=1.0, initial_ref0=0.0,
                               initial_ref=1.0, duration_bounds=(1.0, 5.0),
                               duration_adder=0.0, duration_scaler=1.0,
                               duration_ref0=0.0, duration_ref=1.0)

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        phase.add_boundary_constraint('time', loc='initial', equals=0)

        p.model.linear_solver = DirectSolver()

        expected_msg0 = 'Phase time options have no effect because fix_initial=True for ' \
                        'phase \'phase0\': initial_bounds, initial_scaler, initial_adder, ' \
                        'initial_ref, initial_ref0'

        expected_msg1 = 'Phase time options have no effect because fix_duration=True for' \
                        ' phase \'phase0\': duration_bounds, duration_scaler, ' \
                        'duration_adder, duration_ref, duration_ref0'

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            p.setup(check=True)

        self.assertIn(expected_msg0, [str(w.message) for w in ctx])
        self.assertIn(expected_msg1, [str(w.message) for w in ctx])
예제 #12
0
    def test_ex_double_integrator_input_and_fixed_times_warns(self):
        """
        Tests that time optimization options cause a ValueError to be raised when t_initial and
        t_duration are connected to external sources.
        """
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8, order=3))

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

        phase.set_time_options(input_initial=True, fix_initial=True,
                               input_duration=True, fix_duration=True)

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        phase.add_boundary_constraint('time', loc='initial', equals=0)

        p.model.linear_solver = DirectSolver()

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            p.setup(check=True)

        expected_msg0 = 'Phase \'phase0\' initial time is an externally-connected input, therefore ' \
                        'fix_initial has no effect.'

        expected_msg1 = 'Phase \'phase0\' time duration is an externally-connected input, ' \
                        'therefore fix_duration has no effect.'

        self.assertIn(expected_msg0, [str(w.message) for w in ctx])
        self.assertIn(expected_msg1, [str(w.message) for w in ctx])
예제 #13
0
    def _make_problem(self, transcription, num_seg, transcription_order=3):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        # Compute sparsity/coloring when run_driver is called
        p.driver.options['dynamic_simul_derivs'] = True

        t = {'gauss-lobatto': GaussLobatto(num_segments=num_seg, order=transcription_order),
             'radau-ps': Radau(num_segments=num_seg, order=transcription_order),
             'runge-kutta': RungeKutta(num_segments=num_seg)}

        phase = Phase(ode_class=_BrachistochroneTestODE, transcription=t[transcription])

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

        phase.set_time_options(initial_bounds=(1, 1), duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True)
        phase.set_state_options('y', fix_initial=True)
        phase.set_state_options('v', fix_initial=True)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        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', loc='final', scaler=10)

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 1.0
        p['phase0.t_duration'] = 3.0

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

        return p
    def test_gauss_lobatto(self):

        p = Problem(model=Group())

        phase = Phase(ode_class=MyODE,
                      ode_init_kwargs={'n_traj': n_traj},
                      transcription=GaussLobatto(num_segments=25,
                                                 order=3,
                                                 compressed=True))

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

        phase.add_input_parameter('alpha', val=np.ones((n_traj, 2)), units='m')

        try:
            p.setup()
        except Exception as e:
            self.fail('Exception encountered in setup:\n' + str(e))
예제 #15
0
    def test_unbounded_time(self):
            p = Problem(model=Group())

            p.driver = ScipyOptimizeDriver()
            p.driver.options['dynamic_simul_derivs'] = True

            phase = Phase(ode_class=BrachistochroneODE,
                          transcription=GaussLobatto(num_segments=8, order=3))

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

            phase.set_time_options(fix_initial=False, fix_duration=False)

            phase.set_state_options('x', fix_initial=True, fix_final=True)
            phase.set_state_options('y', fix_initial=True, fix_final=True)
            phase.set_state_options('v', fix_initial=True, fix_final=False)

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

            phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

            phase.add_boundary_constraint('time', loc='initial', equals=0)

            p.model.linear_solver = DirectSolver()
            p.setup(check=True)

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

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

            p.run_driver()

            self.assertTrue(p.driver.result.success,
                            msg='Brachistochrone with outbounded times has failed')
예제 #16
0
    def test_invalid_ode_wrong_class(self):

        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=_A,
                      transcription=GaussLobatto(num_segments=20,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

        phase.add_control('theta',
                          continuity=True,
                          rate_continuity=True,
                          opt=False)

        phase.add_design_parameter('g', units='m/s**2', opt=True, val=9.80665)

        # Minimize time at the end of the phase
        phase.add_objective('g')

        p.model.linear_solver = DirectSolver()

        with self.assertRaises(ValueError) as e:
            p.setup(check=True)

        self.assertEqual(
            str(e.exception),
            'ode_class must be derived from openmdao.core.System.')
예제 #17
0
    def test_timeseries_gl(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=8,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

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

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

        p.run_driver()

        gd = phase.options['transcription'].grid_data
        state_input_idxs = gd.subset_node_indices['state_input']
        control_input_idxs = gd.subset_node_indices['control_input']
        col_idxs = gd.subset_node_indices['col']

        assert_rel_error(self, p.get_val('phase0.time'),
                         p.get_val('phase0.timeseries.time')[:, 0])

        assert_rel_error(self, p.get_val('phase0.time_phase'),
                         p.get_val('phase0.timeseries.time_phase')[:, 0])

        for state in ('x', 'y', 'v'):
            assert_rel_error(
                self, p.get_val('phase0.states:{0}'.format(state)),
                p.get_val('phase0.timeseries.states:'
                          '{0}'.format(state))[state_input_idxs])

            assert_rel_error(
                self,
                p.get_val('phase0.state_interp.state_col:{0}'.format(state)),
                p.get_val('phase0.timeseries.states:'
                          '{0}'.format(state))[col_idxs])

        for control in ('theta', ):
            assert_rel_error(
                self, p.get_val('phase0.controls:{0}'.format(control)),
                p.get_val('phase0.timeseries.controls:'
                          '{0}'.format(control))[control_input_idxs])

        for dp in ('g', ):
            for i in range(gd.subset_num_nodes['all']):
                assert_rel_error(
                    self,
                    p.get_val('phase0.design_parameters:{0}'.format(dp))[0, :],
                    p.get_val('phase0.timeseries.design_parameters:{0}'.format(
                        dp))[i])
예제 #18
0
    def test_reentry_gauss_lobatto_dymos(self):

        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.declare_coloring()

        traj = p.model.add_subsystem("traj", Trajectory())
        phase0 = traj.add_phase(
            "phase0",
            Phase(ode_class=ShuttleODE,
                  transcription=GaussLobatto(num_segments=50, order=3)))

        phase0.set_time_options(fix_initial=True, units="s", duration_ref=200)
        phase0.set_state_options("h",
                                 fix_initial=True,
                                 fix_final=True,
                                 units="ft",
                                 rate_source="hdot",
                                 targets=["h"],
                                 lower=0,
                                 ref0=75000,
                                 ref=300000,
                                 defect_ref=1000)
        phase0.set_state_options("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.set_state_options("phi",
                                 fix_initial=True,
                                 fix_final=False,
                                 units="rad",
                                 rate_source="phidot",
                                 lower=0,
                                 upper=89. * np.pi / 180)
        phase0.set_state_options("psi",
                                 fix_initial=True,
                                 fix_final=False,
                                 units="rad",
                                 rate_source="psidot",
                                 targets=["psi"],
                                 lower=0,
                                 upper=90. * np.pi / 180)
        phase0.set_state_options("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.set_state_options("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"])
        phase0.add_path_constraint("q",
                                   lower=0,
                                   upper=70,
                                   units="Btu/ft**2/s",
                                   ref=70)
        phase0.add_objective("theta", loc="final", ref=-0.01)

        p.driver.options["optimizer"] = 'SNOPT'
        p.driver.opt_settings["iSumm"] = 6

        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 * np.pi / 180, -5 * np.pi / 180],
                                     nodes="state_input"),
                  units="rad")
        p.set_val("traj.phase0.states:phi",
                  phase0.interpolate(ys=[0, 75 * np.pi / 180],
                                     nodes="state_input"),
                  units="rad")
        p.set_val("traj.phase0.states:psi",
                  phase0.interpolate(ys=[90 * np.pi / 180, 10 * np.pi / 180],
                                     nodes="state_input"),
                  units="rad")
        p.set_val("traj.phase0.states:theta",
                  phase0.interpolate(ys=[0, 25 * np.pi / 180],
                                     nodes="state_input"),
                  units="rad")
        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 * np.pi / 180, 17.4 * np.pi / 180],
                      nodes="control_input"),
                  units="rad")
        p.set_val("traj.phase0.controls:beta",
                  phase0.interpolate(ys=[-75 * np.pi / 180, 0 * np.pi / 180],
                                     nodes="control_input"),
                  units="rad")

        p.run_driver()

        print(p.get_val("traj.phase0.timeseries.time")[-1])
        print(p.get_val("traj.phase0.timeseries.states:theta")[-1])
        assert_rel_error(self,
                         p.get_val("traj.phase0.timeseries.time")[-1],
                         2181.88191719,
                         tolerance=1e-3)
        assert_rel_error(self,
                         p.get_val("traj.phase0.timeseries.states:theta")[-1],
                         .53440955,
                         tolerance=1e-3)
    def test_brachistochrone_recording(self):
        import matplotlib
        matplotlib.use('Agg')
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver, \
            SqliteRecorder, CaseReader
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto
        from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10))

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

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        p.model.linear_solver = DirectSolver()

        # Recording
        rec = SqliteRecorder('brachistochrone_solution.db')

        p.driver.recording_options['record_desvars'] = True
        p.driver.recording_options['record_responses'] = True
        p.driver.recording_options['record_objectives'] = True
        p.driver.recording_options['record_constraints'] = True

        p.model.recording_options['record_metadata'] = True

        p.driver.add_recorder(rec)
        p.model.add_recorder(rec)
        phase.add_recorder(rec)

        p.setup()

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

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

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        cr = CaseReader('brachistochrone_solution.db')
        system_cases = cr.list_cases('root')
        case = cr.get_case(system_cases[-1])

        outputs = dict([
            (o[0], o[1])
            for o in case.list_outputs(units=True, shape=True, out_stream=None)
        ])

        assert_rel_error(
            self, p['phase0.controls:theta'],
            outputs['phase0.control_group.indep_controls.controls:theta']
            ['value'])
예제 #20
0
ignored_pairs = []
for i, j in combinations(range(n_traj), 2):
    theta, heading, start_x, start_y, end_x, end_y = locs[i]
    line1 = [start_x, start_y, end_x, end_y]

    theta, heading, start_x, start_y, end_x, end_y = locs[j]
    line2 = [start_x, start_y, end_x, end_y]

    crosses, pt = intersect(line1, line2, r_space)
    if not crosses:
        ignored_pairs.append((i, j))
        print("ignoring pair:", (i, j))

if not coloring:
    ignored_pairs = []
phase = Phase(transcription=GaussLobatto(num_segments=20, order=3),
              ode_class=PlaneODE2D,
              ode_init_kwargs={'ignored_pairs': ignored_pairs})

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

max_time = 500.0
start_mass = 25.0

phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(10, max_time))

for i in range(n_traj):

    theta, heading, start_x, start_y, end_x, end_y = locs[i]

    phase.set_state_options('p%dx' % i,
예제 #21
0
    def test_brachistochrone_integrated_control_gauss_lobatto(self):
        import numpy as np
        from openmdao.api import Problem, Group, ScipyOptimizeDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from dymos import Phase, GaussLobatto

        p = Problem(model=Group())
        p.driver = ScipyOptimizeDriver()

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=10))

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

        phase.set_time_options(initial_bounds=(0, 0), duration_bounds=(.5, 10))

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True)
        phase.set_state_options('theta', targets='theta', fix_initial=False)

        phase.add_control('theta_dot',
                          units='deg/s',
                          rate_continuity=True,
                          lower=0,
                          upper=60)

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

        p.model.linear_solver = DirectSolver()

        p.setup()

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

        p['phase0.states:x'] = phase.interpolate(ys=[0, 10],
                                                 nodes='state_input')
        p['phase0.states:y'] = phase.interpolate(ys=[10, 5],
                                                 nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.states:theta'] = np.radians(
            phase.interpolate(ys=[0.05, 100.0], nodes='state_input'))
        p['phase0.controls:theta_dot'] = phase.interpolate(
            ys=[50, 50], nodes='control_input')

        # Solve for the optimal trajectory
        p.run_driver()

        # Test the results
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-3)

        sim_out = phase.simulate(times_per_seg=20)

        x_sol = p.get_val('phase0.timeseries.states:x')
        y_sol = p.get_val('phase0.timeseries.states:y')
        v_sol = p.get_val('phase0.timeseries.states:v')
        theta_sol = p.get_val('phase0.timeseries.states:theta')
        theta_dot_sol = p.get_val('phase0.timeseries.controls:theta_dot')
        time_sol = p.get_val('phase0.timeseries.time')

        x_sim = sim_out.get_val('phase0.timeseries.states:x')
        y_sim = sim_out.get_val('phase0.timeseries.states:y')
        v_sim = sim_out.get_val('phase0.timeseries.states:v')
        theta_sim = sim_out.get_val('phase0.timeseries.states:theta')
        theta_dot_sim = sim_out.get_val('phase0.timeseries.controls:theta_dot')
        time_sim = sim_out.get_val('phase0.timeseries.time')

        x_interp = interp1d(time_sim[:, 0], x_sim[:, 0])
        y_interp = interp1d(time_sim[:, 0], y_sim[:, 0])
        v_interp = interp1d(time_sim[:, 0], v_sim[:, 0])
        theta_interp = interp1d(time_sim[:, 0], theta_sim[:, 0])
        theta_dot_interp = interp1d(time_sim[:, 0], theta_dot_sim[:, 0])

        assert_rel_error(self, x_interp(time_sol), x_sol, tolerance=1.0E-5)
        assert_rel_error(self, y_interp(time_sol), y_sol, tolerance=1.0E-5)
        assert_rel_error(self, v_interp(time_sol), v_sol, tolerance=1.0E-5)
        assert_rel_error(self,
                         theta_interp(time_sol),
                         theta_sol,
                         tolerance=1.0E-5)
        assert_rel_error(self,
                         theta_dot_interp(time_sol),
                         theta_dot_sol,
                         tolerance=1.0E-5)
    def test_two_phase_cannonball_for_docs(self):
        from openmdao.api import Problem, Group, IndepVarComp, DirectSolver, SqliteRecorder, \
            pyOptSparseDriver
        from openmdao.utils.assert_utils import assert_rel_error

        from dymos import Phase, Trajectory, Radau, GaussLobatto
        from dymos.examples.cannonball.cannonball_ode import CannonballODE

        from dymos.examples.cannonball.size_comp import CannonballSizeComp

        p = Problem(model=Group())

        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = 'SLSQP'
        p.driver.options['dynamic_simul_derivs'] = True

        external_params = p.model.add_subsystem('external_params', IndepVarComp())

        external_params.add_output('radius', val=0.10, units='m')
        external_params.add_output('dens', val=7.87, units='g/cm**3')

        external_params.add_design_var('radius', lower=0.01, upper=0.10, ref0=0.01, ref=0.10)

        p.model.add_subsystem('size_comp', CannonballSizeComp())

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

        transcription = Radau(num_segments=5, order=3, compressed=True)
        ascent = Phase(ode_class=CannonballODE, transcription=transcription)

        ascent = traj.add_phase('ascent', ascent)

        # All initial states except flight path angle are fixed
        # Final flight path angle is fixed (we will set it to zero so that the phase ends at apogee)
        ascent.set_time_options(fix_initial=True, duration_bounds=(1, 100),
                                duration_ref=100, units='s')
        ascent.set_state_options('r', fix_initial=True, fix_final=False)
        ascent.set_state_options('h', fix_initial=True, fix_final=False)
        ascent.set_state_options('gam', fix_initial=False, fix_final=True)
        ascent.set_state_options('v', fix_initial=False, fix_final=False)

        # Limit the muzzle energy
        ascent.add_boundary_constraint('kinetic_energy.ke', loc='initial', units='J',
                                       upper=400000, lower=0, ref=100000, shape=(1,))

        # Second Phase (descent)
        transcription = GaussLobatto(num_segments=5, order=3, compressed=True)
        descent = Phase(ode_class=CannonballODE, transcription=transcription)

        traj.add_phase('descent', descent)

        # All initial states and time are free (they will be linked to the final states of ascent.
        # Final altitude is fixed (we will set it to zero so that the phase ends at ground impact)
        descent.set_time_options(initial_bounds=(.5, 100), duration_bounds=(.5, 100),
                                 duration_ref=100)
        descent.set_state_options('r', fix_initial=False, fix_final=False)
        descent.set_state_options('h', fix_initial=False, fix_final=True)
        descent.set_state_options('gam', fix_initial=False, fix_final=False)
        descent.set_state_options('v', fix_initial=False, fix_final=False)

        descent.add_objective('r', loc='final', scaler=-1.0)

        # Add internally-managed design parameters to the trajectory.
        traj.add_design_parameter('CD', val=0.5, units=None, opt=False)
        traj.add_design_parameter('CL', val=0.0, units=None, opt=False)
        traj.add_design_parameter('T', val=0.0, units='N', opt=False)
        traj.add_design_parameter('alpha', val=0.0, units='deg', opt=False)

        # Add externally-provided design parameters to the trajectory.
        traj.add_input_parameter('mass',
                                 target_params={'ascent': 'm', 'descent': 'm'},
                                 val=1.0)

        traj.add_input_parameter('S', val=0.005)

        # Link Phases (link time and all state variables)
        traj.link_phases(phases=['ascent', 'descent'], vars=['*'])

        # Issue Connections
        p.model.connect('external_params.radius', 'size_comp.radius')
        p.model.connect('external_params.dens', 'size_comp.dens')

        p.model.connect('size_comp.mass', 'traj.input_parameters:mass')
        p.model.connect('size_comp.S', 'traj.input_parameters:S')

        # Finish Problem Setup
        p.model.linear_solver = DirectSolver()

        p.driver.add_recorder(SqliteRecorder('ex_two_phase_cannonball.db'))

        p.setup(check=True)

        # Set Initial Guesses
        p.set_val('external_params.radius', 0.05, units='m')
        p.set_val('external_params.dens', 7.87, units='g/cm**3')

        p.set_val('traj.design_parameters:CD', 0.5)
        p.set_val('traj.design_parameters:CL', 0.0)
        p.set_val('traj.design_parameters:T', 0.0)

        p.set_val('traj.ascent.t_initial', 0.0)
        p.set_val('traj.ascent.t_duration', 10.0)

        p.set_val('traj.ascent.states:r', ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:h', ascent.interpolate(ys=[0, 100], nodes='state_input'))
        p.set_val('traj.ascent.states:v', ascent.interpolate(ys=[200, 150], nodes='state_input'))
        p.set_val('traj.ascent.states:gam', ascent.interpolate(ys=[25, 0], nodes='state_input'),
                  units='deg')

        p.set_val('traj.descent.t_initial', 10.0)
        p.set_val('traj.descent.t_duration', 10.0)

        p.set_val('traj.descent.states:r', descent.interpolate(ys=[100, 200], nodes='state_input'))
        p.set_val('traj.descent.states:h', descent.interpolate(ys=[100, 0], nodes='state_input'))
        p.set_val('traj.descent.states:v', descent.interpolate(ys=[150, 200], nodes='state_input'))
        p.set_val('traj.descent.states:gam', descent.interpolate(ys=[0, -45], nodes='state_input'),
                  units='deg')

        p.run_driver()

        assert_rel_error(self, p.get_val('traj.descent.states:r')[-1],
                         3183.25, tolerance=1.0E-2)

        exp_out = traj.simulate()

        print('optimal radius: {0:6.4f} m '.format(p.get_val('external_params.radius',
                                                             units='m')[0]))
        print('cannonball mass: {0:6.4f} kg '.format(p.get_val('size_comp.mass',
                                                               units='kg')[0]))
        print('launch angle: {0:6.4f} '
              'deg '.format(p.get_val('traj.ascent.timeseries.states:gam',  units='deg')[0, 0]))
        print('maximum range: {0:6.4f} '
              'm '.format(p.get_val('traj.descent.timeseries.states:r')[-1, 0]))

        fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(10, 6))

        time_imp = {'ascent': p.get_val('traj.ascent.timeseries.time'),
                    'descent': p.get_val('traj.descent.timeseries.time')}

        time_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.time'),
                    'descent': exp_out.get_val('traj.descent.timeseries.time')}

        r_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:r'),
                 'descent': p.get_val('traj.descent.timeseries.states:r')}

        r_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:r'),
                 'descent': exp_out.get_val('traj.descent.timeseries.states:r')}

        h_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:h'),
                 'descent': p.get_val('traj.descent.timeseries.states:h')}

        h_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:h'),
                 'descent': exp_out.get_val('traj.descent.timeseries.states:h')}

        axes.plot(r_imp['ascent'], h_imp['ascent'], 'bo')

        axes.plot(r_imp['descent'], h_imp['descent'], 'ro')

        axes.plot(r_exp['ascent'], h_exp['ascent'], 'b--')

        axes.plot(r_exp['descent'], h_exp['descent'], 'r--')

        axes.set_xlabel('range (m)')
        axes.set_ylabel('altitude (m)')

        fig, axes = plt.subplots(nrows=4, ncols=1, figsize=(10, 6))
        states = ['r', 'h', 'v', 'gam']
        for i, state in enumerate(states):
            x_imp = {'ascent': p.get_val('traj.ascent.timeseries.states:{0}'.format(state)),
                     'descent': p.get_val('traj.descent.timeseries.states:{0}'.format(state))}

            x_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.states:{0}'.format(state)),
                     'descent': exp_out.get_val('traj.descent.timeseries.states:{0}'.format(state))}

            axes[i].set_ylabel(state)

            axes[i].plot(time_imp['ascent'], x_imp['ascent'], 'bo')
            axes[i].plot(time_imp['descent'], x_imp['descent'], 'ro')
            axes[i].plot(time_exp['ascent'], x_exp['ascent'], 'b--')
            axes[i].plot(time_exp['descent'], x_exp['descent'], 'r--')

        params = ['CL', 'CD', 'T', 'alpha', 'm', 'S']
        fig, axes = plt.subplots(nrows=6, ncols=1, figsize=(12, 6))
        for i, param in enumerate(params):
            p_imp = {
                'ascent': p.get_val('traj.ascent.timeseries.traj_parameters:{0}'.format(param)),
                'descent': p.get_val('traj.descent.timeseries.traj_parameters:{0}'.format(param))}

            p_exp = {'ascent': exp_out.get_val('traj.ascent.timeseries.'
                                               'traj_parameters:{0}'.format(param)),
                     'descent': exp_out.get_val('traj.descent.timeseries.'
                                                'traj_parameters:{0}'.format(param))}

            axes[i].set_ylabel(param)

            axes[i].plot(time_imp['ascent'], p_imp['ascent'], 'bo')
            axes[i].plot(time_imp['descent'], p_imp['descent'], 'ro')
            axes[i].plot(time_exp['ascent'], p_exp['ascent'], 'b--')
            axes[i].plot(time_exp['descent'], p_exp['descent'], 'r--')

        plt.show()
예제 #23
0
    def test_cruise_results_gl(self):
        p = Problem(model=Group())
        if optimizer == 'SNOPT':
            p.driver = pyOptSparseDriver()
            p.driver.options['optimizer'] = optimizer
            p.driver.options['dynamic_simul_derivs'] = True
            p.driver.opt_settings['Major iterations limit'] = 100
            p.driver.opt_settings['Major step limit'] = 0.05
            p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
            p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
            p.driver.opt_settings["Linesearch tolerance"] = 0.10
            p.driver.opt_settings['iSumm'] = 6
            p.driver.opt_settings['Verify level'] = 3
        else:
            p.driver = ScipyOptimizeDriver()
            p.driver.options['dynamic_simul_derivs'] = True

        transcription = GaussLobatto(num_segments=1,
                                     order=13,
                                     compressed=False)
        phase = Phase(ode_class=AircraftODE, transcription=transcription)
        p.model.add_subsystem('phase0', phase)

        # Pass Reference Area from an external source
        assumptions = p.model.add_subsystem('assumptions', IndepVarComp())
        assumptions.add_output('S', val=427.8, units='m**2')
        assumptions.add_output('mass_empty', val=1.0, units='kg')
        assumptions.add_output('mass_payload', val=1.0, units='kg')

        phase.set_time_options(initial_bounds=(0, 0),
                               duration_bounds=(3600, 3600),
                               duration_ref=3600)

        phase.set_state_options('range',
                                units='km',
                                fix_initial=True,
                                fix_final=False,
                                scaler=0.01,
                                defect_scaler=0.01)
        phase.set_state_options('mass_fuel',
                                fix_final=True,
                                upper=20000.0,
                                lower=0.0,
                                scaler=1.0E-4,
                                defect_scaler=1.0E-2)
        phase.set_state_options('alt', units='km', fix_initial=True)

        phase.add_control('mach', units=None, opt=False)
        phase.add_control('climb_rate', units='m/s', opt=False)

        phase.add_input_parameter('S', units='m**2')
        phase.add_input_parameter('mass_empty', units='kg')
        phase.add_input_parameter('mass_payload', units='kg')

        phase.add_path_constraint('propulsion.tau',
                                  lower=0.01,
                                  upper=1.0,
                                  shape=(1, ))

        phase.add_timeseries_output('tas_comp.TAS', units='m/s')

        p.model.connect('assumptions.S', 'phase0.input_parameters:S')
        p.model.connect('assumptions.mass_empty',
                        'phase0.input_parameters:mass_empty')
        p.model.connect('assumptions.mass_payload',
                        'phase0.input_parameters:mass_payload')

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

        p.model.linear_solver = DirectSolver()

        p.setup()

        p['phase0.t_initial'] = 0.0
        p['phase0.t_duration'] = 1.515132 * 3600.0
        p['phase0.states:range'] = phase.interpolate(ys=(0, 1296.4),
                                                     nodes='state_input')
        p['phase0.states:mass_fuel'] = phase.interpolate(ys=(12236.594555, 0),
                                                         nodes='state_input')
        p['phase0.states:alt'] = 5.0
        p['phase0.controls:mach'] = 0.8
        p['phase0.controls:climb_rate'] = 0.0

        p['assumptions.S'] = 427.8
        p['assumptions.mass_empty'] = 0.15E6
        p['assumptions.mass_payload'] = 84.02869 * 400

        p.run_driver()

        time = p.get_val('phase0.timeseries.time')
        tas = p.get_val('phase0.timeseries.TAS', units='km/s')
        range = p.get_val('phase0.timeseries.states:range')

        assert_rel_error(self, range, tas * time, tolerance=1.0E-4)
예제 #24
0
    def test_control_rate2_boundary_constraint_gl(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()

        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=20,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        phase.add_boundary_constraint('theta_rate2',
                                      loc='final',
                                      equals=0.0,
                                      units='deg/s**2')

        # Minimize time at the end of the phase
        phase.add_objective('time')

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

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

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

        p.run_driver()

        plt.plot(p.get_val('phase0.timeseries.states:x'),
                 p.get_val('phase0.timeseries.states:y'), 'ko')

        plt.figure()

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.controls:theta'), 'ro')

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.control_rates:theta_rate'), 'bo')

        plt.plot(p.get_val('phase0.timeseries.time'),
                 p.get_val('phase0.timeseries.control_rates:theta_rate2'),
                 'go')
        plt.show()

        assert_rel_error(
            self,
            p.get_val('phase0.timeseries.control_rates:theta_rate2')[-1],
            0,
            tolerance=1.0E-6)
예제 #25
0
    def test_design_parameter_boundary_constraint(self):
        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneODE,
                      transcription=GaussLobatto(num_segments=20,
                                                 order=3,
                                                 compressed=True))

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

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

        phase.set_state_options('x', fix_initial=True, fix_final=True)
        phase.set_state_options('y', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=True, val=9.80665)

        # We'll let g vary, but make sure it hits the desired value.
        # It's a static design parameter, so it shouldn't matter whether we enforce it
        # at the start or the end of the phase, so here we'll do both.
        # Note if we make these equality constraints, some optimizers (SLSQP) will
        # see the problem as infeasible.
        phase.add_boundary_constraint('g',
                                      loc='initial',
                                      units='m/s**2',
                                      upper=9.80665)
        phase.add_boundary_constraint('g',
                                      loc='final',
                                      units='m/s**2',
                                      upper=9.80665)

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

        p.model.linear_solver = DirectSolver()
        p.setup(check=True)

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

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

        p.run_driver()

        assert_rel_error(self,
                         p.get_val('phase0.timeseries.time')[-1],
                         1.8016,
                         tolerance=1.0E-4)
        assert_rel_error(self,
                         p.get_val('phase0.timeseries.design_parameters:g')[0],
                         9.80665,
                         tolerance=1.0E-6)
        assert_rel_error(
            self,
            p.get_val('phase0.timeseries.design_parameters:g')[-1],
            9.80665,
            tolerance=1.0E-6)
예제 #26
0
def brachistochrone_min_time(transcription='gauss-lobatto',
                             num_segments=8,
                             transcription_order=3,
                             run_driver=True,
                             compressed=True,
                             optimizer='SLSQP'):
    p = Problem(model=Group())

    # if optimizer == 'SNOPT':
    p.driver = pyOptSparseDriver()
    p.driver.options['optimizer'] = optimizer
    p.driver.options['dynamic_simul_derivs'] = True

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

    phase = Phase(ode_class=BrachistochroneODE, transcription=t)

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

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

    phase.set_state_options('x',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)
    phase.set_state_options('y',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)
    phase.set_state_options('v',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=False)

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

    phase.add_input_parameter('g', units='m/s**2', val=9.80665)

    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.model.linear_solver = DirectSolver()
    p.setup(check=True)

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

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

    p.run_model()

    if run_driver:
        p.run_driver()

    # Plot results
    if SHOW_PLOTS:
        exp_out = phase.simulate()

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.states:x')
        y_imp = p.get_val('phase0.timeseries.states:y')

        x_exp = exp_out.get_val('phase0.timeseries.states:x')
        y_exp = exp_out.get_val('phase0.timeseries.states:y')

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('x (m)')
        ax.set_ylabel('y (m)')
        ax.grid(True)
        ax.legend(loc='upper right')

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.time_phase')
        y_imp = p.get_val('phase0.timeseries.controls:theta')

        x_exp = exp_out.get_val('phase0.timeseries.time_phase')
        y_exp = exp_out.get_val('phase0.timeseries.controls:theta')

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('time (s)')
        ax.set_ylabel('theta (rad)')
        ax.grid(True)
        ax.legend(loc='lower right')

        plt.show()

    return p
예제 #27
0
    def test_two_burn_orbit_raise_gl_rk_gl_constrained(self):
        import numpy as np

        import matplotlib.pyplot as plt

        from openmdao.api import Problem, Group, pyOptSparseDriver, DirectSolver
        from openmdao.utils.assert_utils import assert_rel_error
        from openmdao.utils.general_utils import set_pyoptsparse_opt

        from dymos import Phase, GaussLobatto, RungeKutta, Trajectory
        from dymos.examples.finite_burn_orbit_raise.finite_burn_eom import FiniteBurnODE

        traj = Trajectory()
        p = Problem(model=Group())
        p.model.add_subsystem('traj', traj)

        p.driver = pyOptSparseDriver()
        _, optimizer = set_pyoptsparse_opt('SNOPT', fallback=True)
        p.driver.options['optimizer'] = optimizer

        p.driver.options['dynamic_simul_derivs'] = True

        traj.add_design_parameter('c', opt=False, val=1.5, units='DU/TU')

        # First Phase (burn)

        burn1 = Phase(ode_class=FiniteBurnODE,
                      transcription=GaussLobatto(num_segments=10, order=3, compressed=True))

        burn1 = traj.add_phase('burn1', burn1)

        burn1.set_time_options(fix_initial=True, duration_bounds=(.5, 10))
        burn1.set_state_options('r', fix_initial=True, fix_final=False)
        burn1.set_state_options('theta', fix_initial=True, fix_final=False)
        burn1.set_state_options('vr', fix_initial=True, fix_final=False)
        burn1.set_state_options('vt', fix_initial=True, fix_final=False)
        burn1.set_state_options('accel', fix_initial=True, fix_final=False)
        burn1.set_state_options('deltav', fix_initial=True, fix_final=False)
        burn1.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg',
                          scaler=0.01, lower=-30, upper=30)

        # Second Phase (Coast)
        coast = Phase(ode_class=FiniteBurnODE,
                      transcription=RungeKutta(num_segments=20, compressed=True))

        traj.add_phase('coast', coast)

        coast.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), duration_ref=10)
        coast.set_state_options('r', fix_initial=False, fix_final=False)
        coast.set_state_options('theta', fix_initial=False, fix_final=False)
        coast.set_state_options('vr', fix_initial=False, fix_final=False)
        coast.set_state_options('vt', fix_initial=False, fix_final=False)
        coast.set_state_options('accel', fix_initial=True, fix_final=False)
        coast.set_state_options('deltav', fix_initial=False, fix_final=False)
        coast.add_design_parameter('u1', opt=False, val=0.0)

        # Third Phase (burn)

        burn2 = Phase(ode_class=FiniteBurnODE,
                      transcription=GaussLobatto(num_segments=10, order=3, compressed=True))

        traj.add_phase('burn2', burn2)

        burn2.set_time_options(initial_bounds=(0.5, 20), duration_bounds=(.5, 10), initial_ref=10)
        burn2.set_state_options('r', fix_initial=False, fix_final=True)
        burn2.set_state_options('theta', fix_initial=False, fix_final=False)
        burn2.set_state_options('vr', fix_initial=False, fix_final=True)
        burn2.set_state_options('vt', fix_initial=False, fix_final=True)
        burn2.set_state_options('accel', fix_initial=False, fix_final=False, defect_scaler=1.0)
        burn2.set_state_options('deltav', fix_initial=False, fix_final=False, defect_scaler=1.0)
        burn2.add_control('u1', rate_continuity=True, rate2_continuity=True, units='deg',
                          scaler=0.01, lower=-30, upper=30)

        burn2.add_objective('deltav', loc='final', scaler=1.0)

        burn1.add_timeseries_output('pos_x', units='DU')
        coast.add_timeseries_output('pos_x', units='DU')
        burn2.add_timeseries_output('pos_x', units='DU')

        burn1.add_timeseries_output('pos_y', units='DU')
        coast.add_timeseries_output('pos_y', units='DU')
        burn2.add_timeseries_output('pos_y', units='DU')

        # Link Phases
        traj.link_phases(phases=['burn1', 'coast', 'burn2'],
                         vars=['time', 'r', 'theta', 'vr', 'vt', 'deltav'])
        traj.link_phases(phases=['burn1', 'burn2'], vars=['accel'])

        # Finish Problem Setup
        p.model.linear_solver = DirectSolver()

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

        # Set Initial Guesses
        p.set_val('traj.design_parameters:c', value=1.5)

        p.set_val('traj.burn1.t_initial', value=0.0)
        p.set_val('traj.burn1.t_duration', value=2.25)

        p.set_val('traj.burn1.states:r',
                  value=burn1.interpolate(ys=[1, 1.5], nodes='state_input'))
        p.set_val('traj.burn1.states:theta',
                  value=burn1.interpolate(ys=[0, 1.7], nodes='state_input'))
        p.set_val('traj.burn1.states:vr',
                  value=burn1.interpolate(ys=[0, 0], nodes='state_input'))
        p.set_val('traj.burn1.states:vt',
                  value=burn1.interpolate(ys=[1, 1], nodes='state_input'))
        p.set_val('traj.burn1.states:accel',
                  value=burn1.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('traj.burn1.states:deltav',
                  value=burn1.interpolate(ys=[0, 0.1], nodes='state_input'), )
        p.set_val('traj.burn1.controls:u1',
                  value=burn1.interpolate(ys=[-3.5, 13.0], nodes='control_input'))

        p.set_val('traj.coast.t_initial', value=2.25)
        p.set_val('traj.coast.t_duration', value=3.0)

        p.set_val('traj.coast.states:r',
                  value=coast.interpolate(ys=[1.3, 1.5], nodes='state_input'))
        p.set_val('traj.coast.states:theta',
                  value=coast.interpolate(ys=[2.1767, 1.7], nodes='state_input'))
        p.set_val('traj.coast.states:vr',
                  value=coast.interpolate(ys=[0.3285, 0], nodes='state_input'))
        p.set_val('traj.coast.states:vt',
                  value=coast.interpolate(ys=[0.97, 1], nodes='state_input'))
        p.set_val('traj.coast.states:accel',
                  value=coast.interpolate(ys=[0, 0], nodes='state_input'))
        # p.set_val('traj.coast.controls:u1',
        #           value=coast.interpolate(ys=[0, 0], nodes='control_input'))

        p.set_val('traj.burn2.t_initial', value=5.25)
        p.set_val('traj.burn2.t_duration', value=1.75)

        p.set_val('traj.burn2.states:r',
                  value=burn2.interpolate(ys=[1.8, 3], nodes='state_input'))
        p.set_val('traj.burn2.states:theta',
                  value=burn2.interpolate(ys=[3.2, 4.0], nodes='state_input'))
        p.set_val('traj.burn2.states:vr',
                  value=burn2.interpolate(ys=[.5, 0], nodes='state_input'))
        p.set_val('traj.burn2.states:vt',
                  value=burn2.interpolate(ys=[1, np.sqrt(1 / 3)], nodes='state_input'))
        p.set_val('traj.burn2.states:accel',
                  value=burn2.interpolate(ys=[0.1, 0], nodes='state_input'))
        p.set_val('traj.burn2.states:deltav',
                  value=burn2.interpolate(ys=[0.1, 0.2], nodes='state_input'))
        p.set_val('traj.burn2.controls:u1',
                  value=burn2.interpolate(ys=[1, 1], nodes='control_input'))

        p.run_driver()

        assert_rel_error(self,
                         p.get_val('traj.burn2.timeseries.states:deltav')[-1],
                         0.3995,
                         tolerance=2.0E-3)

        # Plot results
        exp_out = traj.simulate()

        fig = plt.figure(figsize=(8, 4))
        fig.suptitle('Two Burn Orbit Raise Solution')
        ax_u1 = plt.subplot2grid((2, 2), (0, 0))
        ax_deltav = plt.subplot2grid((2, 2), (1, 0))
        ax_xy = plt.subplot2grid((2, 2), (0, 1), rowspan=2)

        span = np.linspace(0, 2 * np.pi, 100)
        ax_xy.plot(np.cos(span), np.sin(span), 'k--', lw=1)
        ax_xy.plot(3 * np.cos(span), 3 * np.sin(span), 'k--', lw=1)
        ax_xy.set_xlim(-4.5, 4.5)
        ax_xy.set_ylim(-4.5, 4.5)

        ax_xy.set_xlabel('x ($R_e$)')
        ax_xy.set_ylabel('y ($R_e$)')

        ax_u1.set_xlabel('time ($TU$)')
        ax_u1.set_ylabel('$u_1$ ($deg$)')
        ax_u1.grid(True)

        ax_deltav.set_xlabel('time ($TU$)')
        ax_deltav.set_ylabel('${\Delta}v$ ($DU/TU$)')
        ax_deltav.grid(True)

        t_sol = dict((phs, p.get_val('traj.{0}.timeseries.time'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        x_sol = dict((phs, p.get_val('traj.{0}.timeseries.pos_x'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        y_sol = dict((phs, p.get_val('traj.{0}.timeseries.pos_y'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        dv_sol = dict((phs, p.get_val('traj.{0}.timeseries.states:deltav'.format(phs)))
                      for phs in ['burn1', 'coast', 'burn2'])
        u1_sol = dict((phs, p.get_val('traj.{0}.timeseries.controls:u1'.format(phs), units='deg'))
                      for phs in ['burn1', 'burn2'])

        t_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.time'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        x_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.pos_x'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        y_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.pos_y'.format(phs)))
                     for phs in ['burn1', 'coast', 'burn2'])
        dv_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.states:deltav'.format(phs)))
                      for phs in ['burn1', 'coast', 'burn2'])
        u1_exp = dict((phs, exp_out.get_val('traj.{0}.timeseries.controls:u1'.format(phs),
                                            units='deg'))
                      for phs in ['burn1', 'burn2'])

        for phs in ['burn1', 'coast', 'burn2']:
            try:
                ax_u1.plot(t_sol[phs], u1_sol[phs], 'ro', ms=3)
                ax_u1.plot(t_exp[phs], u1_exp[phs], 'b-')
            except KeyError:
                pass

            ax_deltav.plot(t_sol[phs], dv_sol[phs], 'ro', ms=3)
            ax_deltav.plot(t_exp[phs], dv_exp[phs], 'b-')

            ax_xy.plot(x_sol[phs], y_sol[phs], 'ro', ms=3, label='implicit')
            ax_xy.plot(x_exp[phs], y_exp[phs], 'b-', label='explicit')

        plt.show()
예제 #28
0
def brachistochrone_min_time(transcription='gauss-lobatto',
                             num_segments=8,
                             transcription_order=3,
                             compressed=True,
                             sim_record='brach_min_time_sim.db',
                             optimizer='SLSQP',
                             dynamic_simul_derivs=True,
                             force_alloc_complex=False,
                             solve_segments=False,
                             run_driver=True):
    p = Problem(model=Group())

    if optimizer == 'SNOPT':
        p.driver = pyOptSparseDriver()
        p.driver.options['optimizer'] = optimizer
        p.driver.opt_settings['Major iterations limit'] = 100
        p.driver.opt_settings['Major feasibility tolerance'] = 1.0E-6
        p.driver.opt_settings['Major optimality tolerance'] = 1.0E-6
        p.driver.opt_settings['iSumm'] = 6
    else:
        p.driver = ScipyOptimizeDriver()

    p.driver.options['dynamic_simul_derivs'] = dynamic_simul_derivs

    if transcription == 'runge-kutta':
        transcription = RungeKutta(num_segments=num_segments,
                                   compressed=compressed)
    elif transcription == 'gauss-lobatto':
        transcription = GaussLobatto(num_segments=num_segments,
                                     order=transcription_order,
                                     compressed=compressed)
    elif transcription == 'radau-ps':
        transcription = Radau(num_segments=num_segments,
                              order=transcription_order,
                              compressed=compressed)

    phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                  transcription=transcription)

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

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

    fix_final = not solve_segments  # can't fix final position if you're solving the segments
    phase.set_state_options('pos',
                            fix_initial=True,
                            fix_final=fix_final,
                            solve_segments=solve_segments)
    phase.set_state_options('v',
                            fix_initial=True,
                            fix_final=False,
                            solve_segments=solve_segments)

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

    phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

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

    p.model.linear_solver = DirectSolver()
    p.setup(check=True, force_alloc_complex=force_alloc_complex)

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

    pos0 = [0, 10]
    posf = [10, 5]

    p['phase0.states:pos'] = phase.interpolate(ys=[pos0, posf],
                                               nodes='state_input')
    p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9], nodes='state_input')
    p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                   nodes='control_input')
    p['phase0.design_parameters:g'] = 9.80665

    p.run_model()
    if run_driver:
        p.run_driver()

    # Plot results
    if SHOW_PLOTS:
        p.run_driver()
        exp_out = phase.simulate(record_file=sim_record)

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0]
        y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1]

        x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0]
        y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1]

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('x (m)')
        ax.set_ylabel('y (m)')
        ax.grid(True)
        ax.legend(loc='upper right')

        fig, ax = plt.subplots()
        fig.suptitle('Brachistochrone Solution')

        x_imp = p.get_val('phase0.timeseries.time')
        y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2')

        x_exp = exp_out.get_val('phase0.timeseries.time')
        y_exp = exp_out.get_val('phase0.timeseries.control_rates:theta_rate2')

        ax.plot(x_imp, y_imp, 'ro', label='implicit')
        ax.plot(x_exp, y_exp, 'b-', label='explicit')

        ax.set_xlabel('time (s)')
        ax.set_ylabel('theta rate2 (rad/s**2)')
        ax.grid(True)
        ax.legend(loc='lower right')

        plt.show()

    return p
예제 #29
0
    def test_reentry_mixed_controls(self):

        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()
        OPT, OPTIMIZER = set_pyoptsparse_opt('IPOPT', fallback=False)
        p.driver.options['optimizer'] = OPTIMIZER

        traj = p.model.add_subsystem('traj', Trajectory())
        phase0 = traj.add_phase(
            'phase0',
            Phase(ode_class=ShuttleODE,
                  transcription=GaussLobatto(num_segments=20, 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=500,
                         ref0=2500,
                         ref=25000)
        phase0.add_control('alpha',
                           units='rad',
                           opt=True,
                           lower=-np.pi / 2,
                           upper=np.pi / 2)
        phase0.add_polynomial_control('beta',
                                      order=5,
                                      units='rad',
                                      opt=True,
                                      lower=-89 * np.pi / 180,
                                      upper=1 * np.pi / 180)

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

        p.setup(check=True, force_alloc_complex=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 * np.pi / 180, -5 * np.pi / 180],
                                     nodes='state_input'),
                  units='rad')
        p.set_val('traj.phase0.states:phi',
                  phase0.interpolate(ys=[0, 75 * np.pi / 180],
                                     nodes='state_input'),
                  units='rad')
        p.set_val('traj.phase0.states:psi',
                  phase0.interpolate(ys=[90 * np.pi / 180, 10 * np.pi / 180],
                                     nodes='state_input'),
                  units='rad')
        p.set_val('traj.phase0.states:theta',
                  phase0.interpolate(ys=[0, 25 * np.pi / 180],
                                     nodes='state_input'),
                  units='rad')
        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 * np.pi / 180, 17.4 * np.pi / 180],
                      nodes='control_input'),
                  units='rad')
        p.set_val('traj.phase0.polynomial_controls:beta', np.radians(-75))

        p.run_driver()

        exp_out = traj.simulate()

        from scipy.interpolate import interp1d

        t_sol = p.get_val('traj.phase0.timeseries.time')
        beta_sol = p.get_val('traj.phase0.timeseries.polynomial_controls:beta')

        t_sim = exp_out.get_val('traj.phase0.timeseries.time')
        beta_sim = exp_out.get_val(
            'traj.phase0.timeseries.polynomial_controls:beta')

        sol_interp = interp1d(t_sol.ravel(), beta_sol.ravel())
        sim_interp = interp1d(t_sim.ravel(), beta_sim.ravel())

        t = np.linspace(0, t_sol.ravel()[-1], 100)

        assert_near_equal(sim_interp(t), sol_interp(t), tolerance=1.0E-3)
    def test_brachistochrone_vector_ode_path_constraints_gl_no_indices(self):

        p = Problem(model=Group())

        p.driver = ScipyOptimizeDriver()
        p.driver.options['dynamic_simul_derivs'] = True

        phase = Phase(ode_class=BrachistochroneVectorStatesODE,
                      transcription=GaussLobatto(num_segments=20, order=3))

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

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

        phase.set_state_options('pos', fix_initial=True, fix_final=True)
        phase.set_state_options('v', fix_initial=True, fix_final=False)

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

        phase.add_design_parameter('g', units='m/s**2', opt=False, val=9.80665)

        phase.add_path_constraint('pos_dot',
                                  shape=(2, ),
                                  units='m/s',
                                  lower=-4,
                                  upper=12)

        phase.add_timeseries_output('pos_dot', shape=(2, ), units='m/s')

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

        p.model.linear_solver = DirectSolver()
        p.setup(check=True, force_alloc_complex=True)

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

        pos0 = [0, 10]
        posf = [10, 5]

        p['phase0.states:pos'] = phase.interpolate(ys=[pos0, posf],
                                                   nodes='state_input')
        p['phase0.states:v'] = phase.interpolate(ys=[0, 9.9],
                                                 nodes='state_input')
        p['phase0.controls:theta'] = phase.interpolate(ys=[5, 100],
                                                       nodes='control_input')
        p['phase0.design_parameters:g'] = 9.80665

        p.run_driver()

        assert_rel_error(self,
                         np.min(p.get_val('phase0.timeseries.pos_dot')[:, -1]),
                         -4,
                         tolerance=1.0E-2)

        # Plot results
        if SHOW_PLOTS:
            exp_out = phase.simulate(times_per_seg=20)

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution')

            x_imp = p.get_val('phase0.timeseries.states:pos')[:, 0]
            y_imp = p.get_val('phase0.timeseries.states:pos')[:, 1]

            x_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 0]
            y_exp = exp_out.get_val('phase0.timeseries.states:pos')[:, 1]

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('x (m)')
            ax.set_ylabel('y (m)')
            ax.grid(True)
            ax.legend(loc='upper right')

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution\nVelocity')

            t_imp = p.get_val('phase0.timeseries.time')
            t_exp = exp_out.get_val('phase0.timeseries.time')

            xdot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_imp = p.get_val('phase0.timeseries.pos_dot')[:, 1]

            xdot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 0]
            ydot_exp = exp_out.get_val('phase0.timeseries.pos_dot')[:, 1]

            ax.plot(t_imp, xdot_imp, 'bo', label='implicit')
            ax.plot(t_exp, xdot_exp, 'b-', label='explicit')

            ax.plot(t_imp, ydot_imp, 'ro', label='implicit')
            ax.plot(t_exp, ydot_exp, 'r-', label='explicit')

            ax.set_xlabel('t (s)')
            ax.set_ylabel('v (m/s)')
            ax.grid(True)
            ax.legend(loc='upper right')

            fig, ax = plt.subplots()
            fig.suptitle('Brachistochrone Solution')

            x_imp = p.get_val('phase0.timeseries.time')
            y_imp = p.get_val('phase0.timeseries.control_rates:theta_rate2')

            x_exp = exp_out.get_val('phase0.timeseries.time')
            y_exp = exp_out.get_val(
                'phase0.timeseries.control_rates:theta_rate2')

            ax.plot(x_imp, y_imp, 'ro', label='implicit')
            ax.plot(x_exp, y_exp, 'b-', label='explicit')

            ax.set_xlabel('time (s)')
            ax.set_ylabel('theta rate2 (rad/s**2)')
            ax.grid(True)
            ax.legend(loc='lower right')

            plt.show()

        return p