示例#1
0
    def test_ex_double_integrator_deprecated_time_options(
            self, transcription='radau-ps'):
        """
        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())

        phase = Phase(transcription,
                      ode_class=DoubleIntegratorODE,
                      num_segments=20,
                      transcription_order=3,
                      compressed=True)

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

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            phase.set_time_options(opt_initial=False,
                                   initial_bounds=(-5, 5),
                                   initial_ref0=1,
                                   initial_ref=10,
                                   initial_adder=0,
                                   initial_scaler=1,
                                   opt_duration=False,
                                   duration_bounds=(-5, 5),
                                   duration_ref0=1,
                                   duration_ref=10,
                                   duration_adder=0,
                                   duration_scaler=1)

        self.assertTrue(len(ctx) == 4,
                        msg='Expected 4 warnings, got {0}'.format(len(ctx)))

        self.assertEqual(
            str(ctx[0].message), 'opt_initial has been deprecated in favor of '
            'fix_initial, which has the opposite meaning. '
            'If the user desires to input the initial '
            'phase time from an exterior source, set '
            'input_initial=True.')

        self.assertEqual(
            str(ctx[1].message), 'opt_duration has been deprecated in favor '
            'of fix_duration, which has the opposite '
            'meaning. If the user desires to input the '
            'phase duration from an exterior source, '
            'set input_duration=True.')

        self.assertEqual(
            str(ctx[2].message),
            'Phase time options have no effect because fix_initial=True for phase '
            '"phase0": initial_bounds, initial_scaler, initial_adder, initial_ref, '
            'initial_ref0')

        self.assertEqual(
            str(ctx[3].message),
            'Phase time options have no effect because fix_duration=True for phase '
            '"phase0": duration_bounds, duration_scaler, duration_adder, duration_ref,'
            ' duration_ref0')
示例#2
0
    def test_ex_double_integrator_input_times_warns(self,
                                                    transcription='radau-ps'):
        """
        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())

        times_ivc = p.model.add_subsystem('times_ivc',
                                          IndepVarComp(),
                                          promotes_outputs=['t0', 'tp'])
        times_ivc.add_output(name='t0', val=0.0, units='s')
        times_ivc.add_output(name='tp', val=1.0, units='s')

        phase = Phase(transcription,
                      ode_class=DoubleIntegratorODE,
                      num_segments=20,
                      transcription_order=3,
                      compressed=True)

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

        p.model.connect('t0', 'phase0.t_initial')
        p.model.connect('tp', 'phase0.t_duration')

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            phase.set_time_options(input_initial=True,
                                   initial_bounds=(-5, 5),
                                   initial_ref0=1,
                                   initial_ref=10,
                                   initial_adder=0,
                                   initial_scaler=1,
                                   input_duration=True,
                                   duration_bounds=(-5, 5),
                                   duration_ref0=1,
                                   duration_ref=10,
                                   duration_adder=0,
                                   duration_scaler=1)

        self.assertTrue(len(ctx) == 2,
                        msg='Expected 2 warnings, got {0}'.format(len(ctx)))

        self.assertEqual(
            str(ctx[0].message),
            'Phase time options have no effect because input_initial=True for phase '
            '"phase0": initial_bounds, initial_scaler, initial_adder, initial_ref, '
            'initial_ref0')

        self.assertEqual(
            str(ctx[1].message),
            'Phase time options have no effect because input_duration=True for phase '
            '"phase0": duration_bounds, duration_scaler, duration_adder, duration_ref,'
            ' duration_ref0')
示例#3
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)
示例#4
0
    def test_invalid_design_parameter_name(self):

        p = Phase('gauss-lobatto',
                  ode_class=BrachistochroneODE,
                  num_segments=8,
                  transcription_order=3)

        with self.assertRaises(ValueError) as e:

            p.add_design_parameter('foo')

        expected = 'foo is not a controllable parameter in the ODE system.'
        self.assertEqual(str(e.exception), expected)
    def test_solver_defects_reverse_propagation(self):
        prob = Problem()

        num_seg = 5
        seg_ends, _ = lgl(num_seg + 1)

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

        # First phase: normal operation.
        transcription = Radau(num_segments=5,
                              order=5,
                              segment_ends=seg_ends,
                              compressed=True)
        phase0 = Phase(ode_class=BatteryODE, transcription=transcription)
        traj_p0 = traj.add_phase('phase0', phase0)

        traj_p0.set_time_options(fix_initial=True, fix_duration=True)
        traj_p0.set_state_options('state_of_charge',
                                  fix_initial=True,
                                  fix_final=False,
                                  solve_segments=True)

        # Second phase: normal operation.
        phase1 = Phase(ode_class=BatteryODE, transcription=transcription)
        traj_p1 = traj.add_phase('phase1', phase1)

        traj_p1.set_time_options(fix_initial=False, fix_duration=True)
        traj_p1.set_state_options('state_of_charge',
                                  fix_initial=False,
                                  fix_final=False,
                                  solve_segments=True)
        traj_p1.add_objective('time', loc='final')

        traj.link_phases(phases=['phase0', 'phase1'],
                         vars=['state_of_charge', 'time'],
                         connected=True)

        prob.setup()

        prob['traj.phase0.t_initial'] = 0
        prob['traj.phase0.t_duration'] = -1.0 * 3600
        prob['traj.phase0.states:state_of_charge'][:] = 0.23794217

        prob['traj.phase1.t_initial'] = 0
        prob['traj.phase1.t_duration'] = -1.0 * 3600

        prob.set_solver_print(level=0)
        prob.run_model()

        soc1 = prob['traj.phase1.states:state_of_charge']
        assert_rel_error(self, soc1[-1], 1.0, 1e-6)
示例#6
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
    def test_single_phase_reverse_propagation_rk(self):
        prob = Problem()

        num_seg = 10
        seg_ends, _ = lgl(num_seg + 1)

        # First phase: normal operation.
        transcription = RungeKutta(num_segments=num_seg)
        phase0 = Phase(ode_class=BatteryODE, transcription=transcription)
        traj_p0 = prob.model.add_subsystem('phase0', phase0)

        traj_p0.set_time_options(fix_initial=True, fix_duration=True)
        traj_p0.set_state_options('state_of_charge',
                                  fix_initial=True,
                                  fix_final=False)

        prob.setup()

        prob['phase0.t_initial'] = 0
        prob['phase0.t_duration'] = -1.0 * 3600
        prob['phase0.states:state_of_charge'][:] = 0.63464982

        prob.set_solver_print(level=0)
        prob.run_model()

        soc0 = prob['phase0.states:state_of_charge']
        assert_rel_error(self, soc0[-1], 1.0, 1e-6)
示例#8
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]]))
示例#9
0
    def make_problem(self,
                     transcription=GaussLobatto,
                     optimizer='SLSQP',
                     numseg=30):
        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.declare_coloring()
        p.driver.options['optimizer'] = optimizer

        if optimizer == 'SNOPT':
            p.driver.declare_coloring()
            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
        elif optimizer == 'IPOPT':
            p.driver.opt_settings['hessian_approximation'] = 'limited-memory'
            # p.driver.opt_settings['nlp_scaling_method'] = 'user-scaling'
            p.driver.opt_settings['print_level'] = 5
            p.driver.opt_settings['linear_solver'] = 'mumps'
            p.driver.declare_coloring()
        else:
            p.driver.declare_coloring()

        traj = p.model.add_subsystem('traj', Trajectory())
        phase0 = traj.add_phase(
            'phase0',
            Phase(ode_class=HyperSensitiveODE,
                  transcription=transcription(num_segments=numseg, order=3)))
        phase0.set_time_options(fix_initial=True, fix_duration=True)
        phase0.add_state('x',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='x_dot',
                         targets=['x'])
        phase0.add_state('xL',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='L',
                         targets=['xL'])
        phase0.add_control('u', opt=True, targets=['u'])

        phase0.add_boundary_constraint('x', loc='final', equals=1)

        phase0.add_objective('xL', loc='final')

        phase0.set_refine_options(refine=True, tol=1e-6, max_order=14)

        p.setup(check=True)

        p.set_val('traj.phase0.states:x',
                  phase0.interpolate(ys=[1.5, 1], nodes='state_input'))
        p.set_val('traj.phase0.states:xL',
                  phase0.interpolate(ys=[0, 1], nodes='state_input'))
        p.set_val('traj.phase0.t_initial', 0)
        p.set_val('traj.phase0.t_duration', tf)
        p.set_val('traj.phase0.controls:u',
                  phase0.interpolate(ys=[-0.6, 2.4], nodes='control_input'))

        return p
示例#10
0
    def test_invalid_options_nonoptimal_control(self):

        p = Phase('gauss-lobatto',
                  ode_class=BrachistochroneODE,
                  num_segments=8,
                  transcription_order=3)

        with warnings.catch_warnings(record=True) as w:
            warnings.simplefilter('always')
            p.add_control('theta', opt=False, lower=5, upper=10, ref0=5, ref=10,
                          scaler=1, adder=0)

        expected = 'Invalid options for non-optimal control "theta":' \
                   'lower, upper, scaler, adder, ref, ref0'

        self.assertEqual(len(w), 1)
        self.assertEqual(str(w[0].message), expected)
示例#11
0
    def test_invalid_ode_class_wrong_class(self):

        with self.assertRaises(ValueError) as e:
            phase = Phase('gauss-lobatto',
                          ode_class=_A,
                          num_segments=8,
                          transcription_order=3)
        self.assertEqual(str(e.exception), 'ode_class must be derived from openmdao.core.System.')
示例#12
0
    def test_invalid_ode_class_instance(self):

        with self.assertRaises(ValueError) as e:
            Phase('gauss-lobatto',
                  ode_class=BrachistochroneODE(),
                  num_segments=8,
                  transcription_order=3)
        self.assertEqual(str(e.exception), 'ode_class must be a class, not an instance.')
    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))
示例#14
0
    def test_invalid_ode_class_invalid_metadata(self):

        with self.assertRaises(ValueError) as e:
            Phase('gauss-lobatto',
                  ode_class=_D,
                  num_segments=8,
                  transcription_order=3)
        self.assertEqual(str(e.exception), 'ode_class has no ODE metadata.  '
                                           'Use @declare_time, @declare_stateand @declare_control '
                                           'to assign ODE metadata.')
示例#15
0
    def test_ex_double_integrator_input_and_fixed_times_warns(
            self, transcription='radau-ps'):
        """
        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())

        times_ivc = p.model.add_subsystem('times_ivc',
                                          IndepVarComp(),
                                          promotes_outputs=['t0', 'tp'])
        times_ivc.add_output(name='t0', val=0.0, units='s')
        times_ivc.add_output(name='tp', val=1.0, units='s')

        phase = Phase(transcription,
                      ode_class=DoubleIntegratorODE,
                      num_segments=20,
                      transcription_order=3,
                      compressed=True)

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

        p.model.connect('t0', 'phase0.t_initial')
        p.model.connect('tp', 'phase0.t_duration')

        with warnings.catch_warnings(record=True) as ctx:
            warnings.simplefilter('always')
            phase.set_time_options(input_initial=True,
                                   fix_initial=True,
                                   input_duration=True,
                                   fix_duration=True)

        self.assertTrue(
            len(ctx) == 2, 'Expected 2 warnings, got {0}'.format(len(ctx)))

        expected = 'Phase "phase0" initial time is an externally-connected input, therefore ' \
                   'fix_initial has no effect.'
        self.assertEqual(str(ctx[0].message), expected)
        expected = 'Phase "phase0" time duration is an externally-connected input, ' \
                   'therefore fix_duration has no effect.'
        self.assertEqual(str(ctx[1].message), expected)
示例#16
0
    def make_problem(self, transcription=Radau, optimizer='SLSQP', numseg=30):
        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.declare_coloring(tol=1.0E-12)
        OPT, OPTIMIZER = set_pyoptsparse_opt(optimizer, fallback=False)
        p.driver.options['optimizer'] = OPTIMIZER
        if OPTIMIZER == 'SNOPT':
            p.driver.opt_settings['iSumm'] = 6
            p.driver.opt_settings['Verify level'] = 3
        elif OPTIMIZER == 'IPOPT':
            p.driver.opt_settings['max_iter'] = 500
            p.driver.opt_settings['print_level'] = 4
            p.driver.opt_settings['tol'] = 1.0E-6
            p.driver.opt_settings['acceptable_tol'] = 1.0E-5
        traj = p.model.add_subsystem('traj', Trajectory())

        phase = traj.add_phase('phase', Phase(ode_class=RobotArmODE,
                                              transcription=transcription(num_segments=numseg, order=3)))
        phase.set_time_options(fix_initial=True, fix_duration=False)

        phase.add_state('x0', fix_initial=True, fix_final=True, rate_source='x0_dot', units='m')
        phase.add_state('x1', fix_initial=True, fix_final=True, rate_source='x1_dot', units='rad')
        phase.add_state('x2', fix_initial=True, fix_final=True, rate_source='x2_dot', units='rad')
        phase.add_state('x3', fix_initial=True, fix_final=True, rate_source='x3_dot', units='m/s')
        phase.add_state('x4', fix_initial=True, fix_final=True, rate_source='x4_dot', units='rad/s')
        phase.add_state('x5', fix_initial=True, fix_final=True, rate_source='x5_dot', units='rad/s')

        phase.add_control('u0', opt=True, lower=-1, upper=1, scaler=0.1, units='m**2/s**2',
                          continuity=False, rate_continuity=False)
        phase.add_control('u1', opt=True, lower=-1, upper=1, scaler=0.1, units='m**3*rad/s**2',
                          continuity=False, rate_continuity=False)
        phase.add_control('u2', opt=True, lower=-1, upper=1, scaler=0.1, units='m**3*rad/s**2',
                          continuity=False, rate_continuity=False)

        phase.add_path_constraint('u0', lower=-1, upper=1, scaler=0.1)
        phase.add_path_constraint('u1', lower=-1, upper=1, scaler=0.1)
        phase.add_path_constraint('u2', lower=-1, upper=1, scaler=0.1)

        phase.add_objective('time', ref=0.1)

        phase.set_refine_options(refine=True, tol=1e-5, smoothness_factor=1.2)

        p.setup(check=True, force_alloc_complex=False, mode='auto')

        p.set_val('traj.phase.t_initial', 0)
        p.set_val('traj.phase.t_duration', 10)
        p.set_val('traj.phase.states:x0', phase.interpolate(ys=[4.5, 4.5], nodes='state_input'))
        p.set_val('traj.phase.states:x1', phase.interpolate(ys=[0.0, 2 * np.pi / 3], nodes='state_input'))
        p.set_val('traj.phase.states:x2', phase.interpolate(ys=[np.pi / 4, np.pi / 4], nodes='state_input'))
        p.set_val('traj.phase.states:x3', phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))
        p.set_val('traj.phase.states:x4', phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))
        p.set_val('traj.phase.states:x5', phase.interpolate(ys=[0.0, 0.0], nodes='state_input'))

        return p
示例#17
0
    def test_invalid_options(self, transcription='gauss-lobatto'):
        p = Problem(model=Group())

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

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

        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')
            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)
        self.assertEqual(len(ctx),
                         2,
                         msg='set_time_options failed to raise two warnings')
        self.assertEqual(str(ctx[0].message), expected_msg0)
        self.assertEqual(str(ctx[1].message), expected_msg1)
示例#18
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)
示例#19
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)
示例#20
0
    def make_problem(self,
                     transcription=GaussLobatto,
                     optimizer='SLSQP',
                     numseg=30):
        p = Problem(model=Group())
        p.driver = pyOptSparseDriver()
        p.driver.declare_coloring()
        OPT, OPTIMIZER = set_pyoptsparse_opt(optimizer, fallback=False)
        p.driver.options['optimizer'] = OPTIMIZER

        traj = p.model.add_subsystem('traj', Trajectory())
        phase0 = traj.add_phase(
            'phase0',
            Phase(ode_class=HyperSensitiveODE,
                  transcription=transcription(num_segments=numseg, order=3)))
        phase0.set_time_options(fix_initial=True, fix_duration=True)
        phase0.add_state('x',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='x_dot',
                         targets=['x'])
        phase0.add_state('xL',
                         fix_initial=True,
                         fix_final=False,
                         rate_source='L',
                         targets=['xL'])
        phase0.add_control('u', opt=True, targets=['u'])

        phase0.add_boundary_constraint('x', loc='final', equals=1)

        phase0.add_objective('xL', loc='final')

        p.setup(check=True)

        p.set_val('traj.phase0.states:x',
                  phase0.interpolate(ys=[1.5, 1], nodes='state_input'))
        p.set_val('traj.phase0.states:xL',
                  phase0.interpolate(ys=[0, 1], nodes='state_input'))
        p.set_val('traj.phase0.t_initial', 0)
        p.set_val('traj.phase0.t_duration', tf)
        p.set_val('traj.phase0.controls:u',
                  phase0.interpolate(ys=[-0.6, 2.4], nodes='control_input'))

        return p
示例#21
0
    def test_add_existing_input_parameter_as_input_parameter(self):

        p = Phase('gauss-lobatto',
                  ode_class=BrachistochroneODE,
                  num_segments=8,
                  transcription_order=3)

        p.add_input_parameter('theta')

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

        expected = 'theta has already been added as an input parameter.'
        self.assertEqual(str(e.exception), expected)
示例#22
0
    def setup(self, problem, ndv, nstate, nproc, flag):

        simul_derivs = flag
        num_segments = nstate
        transcription = 'radau-ps'
        top_level_jacobian = 'csc'
        transcription_order = 3
        force_alloc_complex = False

        p = problem

        self.phase = phase = Phase(transcription,
                                   ode_class=BrachistochroneODE,
                                   num_segments=num_segments,
                                   transcription_order=transcription_order,
                                   compressed=False)

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

        p.model.options['assembled_jac_type'] = top_level_jacobian.lower()
        p.model.linear_solver = DirectSolver(assemble_jac=True)

        p.driver = ColoringOnly()
        p.driver.options['dynamic_simul_derivs'] = simul_derivs
示例#23
0
def make_problem(transcription=GaussLobatto, num_segments=10, order=3, compressed=True):
    p = om.Problem(model=om.Group())
    p.driver = om.pyOptSparseDriver()
    p.driver.declare_coloring()

    traj = p.model.add_subsystem('traj', Trajectory())
    phase = traj.add_phase('phase', Phase(ode_class=crtbp_ode, transcription=transcription(num_segments=num_segments,
                                                                                           order=order,
                                                                                           compressed=compressed)))

    phase.set_time_options(fix_initial=True, fix_duration=True)
    phase.add_state('x', rate_source='vx', )
    phase.add_state('y', rate_source='vz', fix_initial=True)
    phase.add_state('z', rate_source='vz')
    phase.add_state('x_dot', rate_source='vx_dot', fix_initial=True, units=None)
    phase.add_state('y_dot', rate_source='vy_dot', units=None)
    phase.add_state('z_dot', rate_source='vz_dot', fix_initial=True, units=None)

    p.model.add_subsystem('x_periodic_bc', om.ExecComp('bc_defect=final-initial'))
    p.model.connect('traj.phase.timeseries.states:x', 'x_periodic_bc.initial', src_indices=0)
    p.model.connect('traj.phase.timeseries.states:x', 'x_periodic_bc.final', src_indices=-1)

    p.model.add_constraint('x_periodic_bc.bc_defect', equals=0)

    p.model.add_subsystem('z_periodic_bc', om.ExecComp('bc_defect=final-initial'))
    p.model.connect('traj.phase.timeseries.states:z', 'z_periodic_bc.initial', src_indices=0)
    p.model.connect('traj.phase.timeseries.states:z', 'z_periodic_bc.final', src_indices=-1)

    p.model.add_constraint('z_periodic_bc.bc_defect', equals=0)

    p.model.add_subsystem('vy_periodic_bc', om.ExecComp('bc_defect=final-initial'))
    p.model.connect('traj.phase.timeseries.states:y_dot', 'vy_periodic_bc.initial', src_indices=0)
    p.model.connect('traj.phase.timeseries.states:y_dot', 'vy_periodic_bc.final', src_indices=-1)

    p.model.add_constraint('vy_periodic_bc.bc_defect', equals=0)

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

    p.setup(check=True)
    return p
示例#24
0
from __future__ import print_function, division, absolute_import

import numpy as np

import matplotlib.pyplot as plt

from openmdao.api import Problem, Group
from dymos import Phase
from dymos.examples.brachistochrone.brachistochrone_ode import BrachistochroneODE

p = Problem(model=Group())
phase = Phase('radau-ps', ode_class=BrachistochroneODE, num_segments=4,
              transcription_order=[3, 5, 3, 5])
p.model.add_subsystem('phase0', phase)

p.setup()
p['phase0.t_initial'] = 1.0
p['phase0.t_duration'] = 9.0
p.run_model()

t_disc = phase.get_values('time', nodes='state_disc')
t_col = phase.get_values('time', nodes='col')
t_all = phase.get_values('time', nodes='all')


def f(x):
    return np.sin(x) / x + 1


def fu(x):
    return (np.cos(x) * x - np.sin(x))/x**2
示例#25
0
    def make_problem(self,
                     constrained=True,
                     transcription=GaussLobatto,
                     optimizer='SLSQP',
                     numseg=30):
        p = om.Problem(model=om.Group())
        p.driver = om.pyOptSparseDriver()
        p.driver.declare_coloring()
        OPT, OPTIMIZER = set_pyoptsparse_opt(optimizer, fallback=False)
        p.driver.options['optimizer'] = OPTIMIZER

        traj = p.model.add_subsystem('traj', Trajectory())
        phase0 = traj.add_phase(
            'phase0',
            Phase(ode_class=ShuttleODE,
                  transcription=transcription(num_segments=numseg, 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,
                           targets=['alpha'])
        phase0.add_control('beta',
                           units='rad',
                           opt=True,
                           lower=-89 * np.pi / 180,
                           upper=1 * np.pi / 180,
                           targets=['beta'])

        if constrained:
            phase0.add_path_constraint('q', lower=0, upper=70, ref=70)

        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.controls:beta',
                  phase0.interpolate(ys=[-75 * np.pi / 180, 0 * np.pi / 180],
                                     nodes='control_input'),
                  units='rad')

        return p
示例#26
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)
示例#27
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
示例#28
0
def double_integrator_direct_collocation(transcription='gauss-lobatto',
                                         top_level_jacobian='csc',
                                         compressed=True):
    p = Problem(model=Group())
    p.driver = ScipyOptimizeDriver()
    p.driver.options['dynamic_simul_derivs'] = True

    phase = Phase(transcription,
                  ode_class=DoubleIntegratorODE,
                  num_segments=20,
                  transcription_order=3,
                  compressed=compressed)

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

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

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

    phase.add_control('u',
                      units='m/s**2',
                      scaler=0.01,
                      continuity=False,
                      rate_continuity=False,
                      rate2_continuity=False,
                      lower=-1.0,
                      upper=1.0)

    # Maximize distance travelled in one second.
    phase.add_objective('x', loc='final', scaler=-1)

    p.model.linear_solver = DirectSolver(assemble_jac=True)
    p.model.options['assembled_jac_type'] = top_level_jacobian.lower()

    p.setup(check=True)

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

    p['phase0.states:x'] = phase.interpolate(ys=[0, 0.25], nodes='state_input')
    p['phase0.states:v'] = phase.interpolate(ys=[0, 0], nodes='state_input')
    p['phase0.controls:u'] = phase.interpolate(ys=[1, -1],
                                               nodes='control_input')

    p.run_driver()

    return p
示例#29
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()
示例#30
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