1- abstract type AbstractDynamicOptProblem{uType, tType, isinplace} < :
2- SciMLBase. AbstractODEProblem{uType, tType, isinplace} end
3-
41abstract type AbstractCollocation end
52
63struct DynamicOptSolution
2219 JuMPDynamicOptProblem(sys::System, op, tspan; dt, steps, guesses, kwargs...)
2320
2421Convert an System representing an optimal control system into a JuMP model
25- for solving using optimization. Must provide either `dt`, the timestep between collocation
26- points (which, along with the timespan, determines the number of points), or directly
22+ for solving using optimization. Must provide either `dt`, the timestep between collocation
23+ points (which, along with the timespan, determines the number of points), or directly
2724provide the number of points as `steps`.
2825
2926To construct the problem, please load InfiniteOpt along with ModelingToolkit.
@@ -33,7 +30,7 @@ function JuMPDynamicOptProblem end
3330 InfiniteOptDynamicOptProblem(sys::System, op, tspan; dt)
3431
3532Convert an System representing an optimal control system into a InfiniteOpt model
36- for solving using optimization. Must provide `dt` for determining the length
33+ for solving using optimization. Must provide `dt` for determining the length
3734of the interpolation arrays.
3835
3936Related to `JuMPDynamicOptProblem`, but directly adds the differential equations
@@ -46,8 +43,8 @@ function InfiniteOptDynamicOptProblem end
4643 CasADiDynamicOptProblem(sys::System, op, tspan; dt, steps, guesses, kwargs...)
4744
4845Convert an System representing an optimal control system into a CasADi model
49- for solving using optimization. Must provide either `dt`, the timestep between collocation
50- points (which, along with the timespan, determines the number of points), or directly
46+ for solving using optimization. Must provide either `dt`, the timestep between collocation
47+ points (which, along with the timespan, determines the number of points), or directly
5148provide the number of points as `steps`.
5249
5350To construct the problem, please load CasADi along with ModelingToolkit.
@@ -57,8 +54,8 @@ function CasADiDynamicOptProblem end
5754 PyomoDynamicOptProblem(sys::System, op, tspan; dt, steps)
5855
5956Convert an System representing an optimal control system into a Pyomo model
60- for solving using optimization. Must provide either `dt`, the timestep between collocation
61- points (which, along with the timespan, determines the number of points), or directly
57+ for solving using optimization. Must provide either `dt`, the timestep between collocation
58+ points (which, along with the timespan, determines the number of points), or directly
6259provide the number of points as `steps`.
6360
6461To construct the problem, please load Pyomo along with ModelingToolkit.
@@ -229,13 +226,15 @@ end
229226# ## MODEL CONSTRUCTION ###
230227# #########################
231228function process_DynamicOptProblem (
232- prob_type:: Type{<:AbstractDynamicOptProblem} , model_type, sys:: System , op, tspan;
229+ prob_type:: Type{<:SciMLBase. AbstractDynamicOptProblem} , model_type, sys:: System , op, tspan;
233230 dt = nothing ,
234231 steps = nothing ,
232+ tune_parameters = false ,
235233 guesses = Dict (), kwargs... )
236234 warn_overdetermined (sys, op)
237235 ctrls = unbound_inputs (sys)
238236 states = unknowns (sys)
237+ params = tune_parameters ? tunable_parameters (sys) : []
239238
240239 stidxmap = Dict ([v => i for (i, v) in enumerate (states)])
241240 op = Dict ([default_toterm (value (k)) => v for (k, v) in op])
@@ -253,14 +252,16 @@ function process_DynamicOptProblem(
253252 pmap = recursive_unwrap (AnyDict (pmap))
254253 evaluate_varmap! (pmap, keys (pmap))
255254 c0 = value .([pmap[c] for c in ctrls])
255+ p0, _ = SciMLStructures. canonicalize (SciMLStructures. Tunable (), p)
256256
257257 tsteps = LinRange (model_tspan[1 ], model_tspan[2 ], steps)
258258 model = generate_internal_model (model_type)
259259 generate_time_variable! (model, model_tspan, tsteps)
260260 U = generate_state_variable! (model, u0, length (states), tsteps)
261261 V = generate_input_variable! (model, c0, length (ctrls), tsteps)
262+ P = generate_tunable_params! (model, p0, length (params))
262263 tₛ = generate_timescale! (model, get (pmap, tspan[2 ], tspan[2 ]), is_free_t)
263- fullmodel = model_type (model, U, V, tₛ, is_free_t)
264+ fullmodel = model_type (model, U, V, P, tₛ, is_free_t)
264265
265266 set_variable_bounds! (fullmodel, sys, pmap, tspan[2 ])
266267 add_cost_function! (fullmodel, sys, tspan, pmap)
@@ -274,6 +275,7 @@ function generate_time_variable! end
274275function generate_internal_model end
275276function generate_state_variable! end
276277function generate_input_variable! end
278+ function generate_tunable_params! end
277279function generate_timescale! end
278280function add_initial_constraints! end
279281function add_constraint! end
@@ -467,24 +469,33 @@ function prepare_and_optimize! end
467469function get_t_values end
468470function get_U_values end
469471function get_V_values end
472+ function get_P_values end
470473function successful_solve end
471474
472475"""
473476 solve(prob::AbstractDynamicOptProblem, solver::AbstractCollocation; verbose = false, kwargs...)
474477
475478- kwargs are used for other options. For example, the `plugin_options` and `solver_options` will propagated to the Opti object in CasADi.
476479"""
477- function DiffEqBase. solve (prob:: AbstractDynamicOptProblem ,
480+ function DiffEqBase. solve (prob:: SciMLBase. AbstractDynamicOptProblem ,
478481 solver:: AbstractCollocation ; verbose = false , kwargs... )
479482 solved_model = prepare_and_optimize! (prob, solver; verbose, kwargs... )
480483
481484 ts = get_t_values (solved_model)
482485 Us = get_U_values (solved_model)
483486 Vs = get_V_values (solved_model)
487+ Ps = get_P_values (solved_model)
484488 is_free_final (prob. wrapped_model) && (ts .+ prob. tspan[1 ])
485489
486- ode_sol = DiffEqBase. build_solution (prob, solver, ts, Us)
487- input_sol = isnothing (Vs) ? nothing : DiffEqBase. build_solution (prob, solver, ts, Vs)
490+ # update the parameters with the ones in the solved_model
491+ if ! isempty (Ps)
492+ new_p = SciMLStructures. replace (SciMLStructures. Tunable (), prob. p, Ps)
493+ new_prob = remake (prob, p= new_p)
494+ else
495+ new_prob = prob
496+ end
497+ ode_sol = SciMLBase. build_solution (new_prob, solver, ts, Us)
498+ input_sol = isnothing (Vs) ? nothing : SciMLBase. build_solution (new_prob, solver, ts, Vs)
488499
489500 if ! successful_solve (solved_model)
490501 ode_sol = SciMLBase. solution_new_retcode (
0 commit comments