@@ -19,9 +19,9 @@ function Base.show(io::IO, sol::DynamicOptSolution)
1919end
2020
2121"""
22- JuMPDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps, guesses, kwargs...)
22+ JuMPDynamicOptProblem(sys::System , u0, tspan, p; dt, steps, guesses, kwargs...)
2323
24- Convert an ODESystem representing an optimal control system into a JuMP model
24+ Convert an System representing an optimal control system into a JuMP model
2525for solving using optimization. Must provide either `dt`, the timestep between collocation
2626points (which, along with the timespan, determines the number of points), or directly
2727provide the number of points as `steps`.
@@ -30,9 +30,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
3030"""
3131function JuMPDynamicOptProblem end
3232"""
33- InfiniteOptDynamicOptProblem(sys::ODESystem, u0map , tspan, pmap ; dt)
33+ InfiniteOptDynamicOptProblem(sys::System, op , tspan; dt)
3434
35- Convert an ODESystem representing an optimal control system into a InfiniteOpt model
35+ Convert an System representing an optimal control system into a InfiniteOpt model
3636for solving using optimization. Must provide `dt` for determining the length
3737of the interpolation arrays.
3838
@@ -43,9 +43,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
4343"""
4444function InfiniteOptDynamicOptProblem end
4545"""
46- CasADiDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps, guesses, kwargs...)
46+ CasADiDynamicOptProblem(sys::System , u0, tspan, p; dt, steps, guesses, kwargs...)
4747
48- Convert an ODESystem representing an optimal control system into a CasADi model
48+ Convert an System representing an optimal control system into a CasADi model
4949for solving using optimization. Must provide either `dt`, the timestep between collocation
5050points (which, along with the timespan, determines the number of points), or directly
5151provide the number of points as `steps`.
@@ -54,9 +54,9 @@ To construct the problem, please load CasADi along with ModelingToolkit.
5454"""
5555function CasADiDynamicOptProblem end
5656"""
57- PyomoDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps)
57+ PyomoDynamicOptProblem(sys::System , u0, tspan, p; dt, steps)
5858
59- Convert an ODESystem representing an optimal control system into a Pyomo model
59+ Convert an System representing an optimal control system into a Pyomo model
6060for solving using optimization. Must provide either `dt`, the timestep between collocation
6161points (which, along with the timespan, determines the number of points), or directly
6262provide the number of points as `steps`.
@@ -91,11 +91,12 @@ Pyomo Collocation solver.
9191"""
9292function PyomoCollocation end
9393
94- function warn_overdetermined (sys, u0map )
94+ function warn_overdetermined (sys, op )
9595 cstrs = constraints (sys)
96+ init_conds = filter (x -> value (x) ∈ Set (unknowns (sys)), [k for (k,v) in op])
9697 if ! isempty (cstrs)
97- (length (cstrs) + length (u0map ) > length (unknowns (sys))) &&
98- @warn " The control problem is overdetermined. The total number of conditions (# constraints + # fixed initial values given by u0map ) exceeds the total number of states. The solvers will default to doing a nonlinear least-squares optimization."
98+ (length (cstrs) + length (init_conds ) > length (unknowns (sys))) &&
99+ @warn " The control problem is overdetermined. The total number of conditions (# constraints + # fixed initial values given by op ) exceeds the total number of states. The solvers will default to doing a nonlinear least-squares optimization."
99100 end
100101end
101102
@@ -226,24 +227,27 @@ end
226227# #########################
227228# ## MODEL CONSTRUCTION ###
228229# #########################
229- function process_DynamicOptProblem (prob_type:: Type{<:AbstractDynamicOptProblem} , model_type, sys:: ODESystem , u0map , tspan, pmap ;
230+ function process_DynamicOptProblem (prob_type:: Type{<:AbstractDynamicOptProblem} , model_type, sys:: System , op , tspan;
230231 dt = nothing ,
231232 steps = nothing ,
232233 guesses = Dict (), kwargs... )
233- warn_overdetermined (sys, u0map)
234+
235+ warn_overdetermined (sys, op)
234236 ctrls = unbound_inputs (sys)
235237 states = unknowns (sys)
236238
237- _u0map = has_alg_eqs (sys) ? u0map : merge (Dict (u0map), Dict (guesses))
238239 stidxmap = Dict ([v => i for (i, v) in enumerate (states)])
239- u0map = Dict ([default_toterm (value (k)) => v for (k, v) in u0map ])
240+ op = Dict ([default_toterm (value (k)) => v for (k, v) in op ])
240241 u0_idxs = has_alg_eqs (sys) ? collect (1 : length (states)) :
241- [stidxmap[default_toterm (k)] for (k, v) in u0map ]
242+ [stidxmap[default_toterm (k)] for (k, v) in op if haskey (stidxmap, k) ]
242243
243- f, u0, p = process_SciMLProblem (ODEInputFunction, sys, _u0map, pmap;
244+ _op = has_alg_eqs (sys) ? op : merge (Dict (op), Dict (guesses))
245+ f, u0, p = process_SciMLProblem (ODEInputFunction, sys, _op;
244246 t = tspan != = nothing ? tspan[1 ] : tspan, kwargs... )
245247 model_tspan, steps, is_free_t = process_tspan (tspan, dt, steps)
248+ warn_overdetermined (sys, op)
246249
250+ pmap = filter (p -> (first (p) ∉ Set (unknowns (sys))), op)
247251 pmap = recursive_unwrap (AnyDict (pmap))
248252 evaluate_varmap! (pmap, keys (pmap))
249253 c0 = value .([pmap[c] for c in ctrls])
@@ -261,7 +265,7 @@ function process_DynamicOptProblem(prob_type::Type{<:AbstractDynamicOptProblem},
261265 add_user_constraints! (fullmodel, sys, tspan, pmap)
262266 add_initial_constraints! (fullmodel, u0, u0_idxs, model_tspan[1 ])
263267
264- prob_type (f, u0, tspan, p, fullmodel, kwargs... )
268+ prob_type (f, u0, tspan, p, fullmodel, kwargs... ), pmap
265269end
266270
267271function generate_time_variable! end
@@ -301,16 +305,16 @@ end
301305is_free_final (model) = model. is_free_final
302306
303307function add_cost_function! (model, sys, tspan, pmap)
304- jcosts = copy (get_costs (sys))
305- consolidate = get_consolidate (sys)
306- if isnothing (jcosts) || isempty (jcosts)
308+ jcosts = cost (sys)
309+ if Symbolics. _iszero (jcosts)
307310 set_objective! (model, 0 )
308311 return
309312 end
310- jcosts = substitute_model_vars (model, sys, jcosts, tspan)
313+
314+ jcosts = substitute_model_vars (model, sys, [jcosts], tspan)
311315 jcosts = substitute_params (pmap, jcosts)
312- jcosts = substitute_integral (model, jcosts, tspan)
313- set_objective! (model, consolidate (jcosts))
316+ jcosts = substitute_integral (model, only ( jcosts) , tspan)
317+ set_objective! (model, value (jcosts))
314318end
315319
316320"""
@@ -319,16 +323,16 @@ Substitute integrals. For an integral from (ts, te):
319323- CasADi cannot handle partial timespans, even for non-free-final time problems.
320324time problems and unchanged otherwise.
321325"""
322- function substitute_integral (model, exprs , tspan)
326+ function substitute_integral (model, expr , tspan)
323327 intmap = Dict ()
324- for int in collect_applied_operators (exprs , Symbolics. Integral)
328+ for int in collect_applied_operators (expr , Symbolics. Integral)
325329 op = operation (int)
326330 arg = only (arguments (value (int)))
327331 lo, hi = value .((op. domain. domain. left, op. domain. domain. right))
328332 lo, hi = process_integral_bounds (model, (lo, hi), tspan)
329333 intmap[int] = lowered_integral (model, arg, lo, hi)
330334 end
331- exprs = map (c -> Symbolics. substitute (c , intmap), value .(exprs) )
335+ Symbolics. substitute (expr , intmap)
332336end
333337
334338function process_integral_bounds (model, integral_span, tspan)
@@ -386,13 +390,13 @@ function lowered_var end
386390function fixed_t_map end
387391
388392function add_user_constraints! (model, sys, tspan, pmap)
389- conssys = get_constraintsystem (sys)
390- jconstraints = isnothing (conssys) ? nothing : get_constraints (conssys)
393+ jconstraints = get_constraints (sys)
391394 (isnothing (jconstraints) || isempty (jconstraints)) && return nothing
392- consvars = get_unknowns (conssys)
393- is_free_final (model) && check_constraint_vars (consvars)
395+ cons_dvs, cons_ps = process_constraint_system (jconstraints, Set (unknowns (sys)), parameters (sys), get_iv (sys); validate = false )
396+
397+ is_free_final (model) && check_constraint_vars (cons_dvs)
394398
395- jconstraints = substitute_toterm (consvars , jconstraints)
399+ jconstraints = substitute_toterm (cons_dvs , jconstraints)
396400 jconstraints = substitute_model_vars (model, sys, jconstraints, tspan)
397401 jconstraints = substitute_params (pmap, jconstraints)
398402
0 commit comments