OpenMDAO / dymos

Open Source Optimization of Dynamic Multidisciplinary Systems
Apache License 2.0
208 stars 66 forks source link

Initial States Doesn't Seem Supported for Explicit Shooting #904

Closed andrewellis55 closed 1 year ago

andrewellis55 commented 1 year ago

Description

The following code functions to set my initial states with Radau, but when I swap over to Explicit Shooting, I can no longer promote initial_states:x out of the phase. Looking at the n2, I don't immediately see an alternative

import openmdao.api as om
import dymos as dm
from dymos.examples.oscillator.oscillator_ode import OscillatorODE

# Instantiate an OpenMDAO Problem instance.
prob = om.Problem()

# Instantiate a Dymos Trajectory and add it to the Problem model.
traj = dm.Trajectory()
prob.model.add_subsystem('traj', traj)
phase = dm.Phase(
    ode_class=OscillatorODE,
    transcription=dm.Radau(num_segments=4))
traj.add_phase('phase0', phase, promotes_inputs=['initial_states:x'])

phase.add_timeseries_output('output1')

# Tell Dymos the states to be propagated using the given ODE.
phase.add_state('v', rate_source='v_dot', targets=['v'], units='m/s')
phase.add_state('x', input_initial=True, rate_source='v', targets=['x'], units='m')

idv: om.IndepVarComp = traj.add_subsystem('idv', om.IndepVarComp(), promotes=['*'])
idv.add_output('initial_states:x', val=2)

# Setup the OpenMDAO problem
prob.setup()
prob.run_model()

om.n2(prob)

Example

import openmdao.api as om
import dymos as dm
from dymos.examples.oscillator.oscillator_ode import OscillatorODE

# Instantiate an OpenMDAO Problem instance.
prob = om.Problem()

# Instantiate a Dymos Trajectory and add it to the Problem model.
traj = dm.Trajectory()
prob.model.add_subsystem('traj', traj)
phase = dm.Phase(
    ode_class=OscillatorODE,
    transcription=dm.ExplicitShooting(num_segments=4))
traj.add_phase('phase0', phase, promotes_inputs=['initial_states:x'])

phase.add_timeseries_output('output1')

# Tell Dymos the states to be propagated using the given ODE.
phase.add_state('v', rate_source='v_dot', targets=['v'], units='m/s')
phase.add_state('x', input_initial=True, rate_source='v', targets=['x'], units='m')

idv: om.IndepVarComp = traj.add_subsystem('idv', om.IndepVarComp(), promotes=['*'])
idv.add_output('initial_states:x', val=2)

# Setup the OpenMDAO problem
prob.setup()
prob.run_model()

om.n2(prob)

Dymos Version

1.7.0

Relevant environment information

No response

robfalck commented 1 year ago

This is a change in the shooting API that didn't get documented I believe. the states that may be design variables of any transcription should just be phasename.states:statename now. For explicit shooting, this should just be the state initial values for now. Once we implement multiple shooting, it will be the initial value of the states within each segment.

robfalck commented 1 year ago

@andrewellis55 can you verify that this is working for you with states:x instead of initial_states:x?

robfalck commented 1 year ago

Well at least a few other users have found this behavior confusing, so before ExplicitShooting becomes too commonplace we should address this by making the state input value initial_states:x as opposed to states:x.

This will require some documentation changes as well as some changes to how things work within simulate.