@@ -19,9 +19,9 @@ function Base.show(io::IO, sol::DynamicOptSolution)
19
19
end
20
20
21
21
"""
22
- JuMPDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps, guesses, kwargs...)
22
+ JuMPDynamicOptProblem(sys::System , u0, tspan, p; dt, steps, guesses, kwargs...)
23
23
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
25
25
for solving using optimization. Must provide either `dt`, the timestep between collocation
26
26
points (which, along with the timespan, determines the number of points), or directly
27
27
provide the number of points as `steps`.
@@ -30,9 +30,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
30
30
"""
31
31
function JuMPDynamicOptProblem end
32
32
"""
33
- InfiniteOptDynamicOptProblem(sys::ODESystem, u0map , tspan, pmap ; dt)
33
+ InfiniteOptDynamicOptProblem(sys::System, op , tspan; dt)
34
34
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
36
36
for solving using optimization. Must provide `dt` for determining the length
37
37
of the interpolation arrays.
38
38
@@ -43,9 +43,9 @@ To construct the problem, please load InfiniteOpt along with ModelingToolkit.
43
43
"""
44
44
function InfiniteOptDynamicOptProblem end
45
45
"""
46
- CasADiDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps, guesses, kwargs...)
46
+ CasADiDynamicOptProblem(sys::System , u0, tspan, p; dt, steps, guesses, kwargs...)
47
47
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
49
49
for solving using optimization. Must provide either `dt`, the timestep between collocation
50
50
points (which, along with the timespan, determines the number of points), or directly
51
51
provide the number of points as `steps`.
@@ -54,9 +54,9 @@ To construct the problem, please load CasADi along with ModelingToolkit.
54
54
"""
55
55
function CasADiDynamicOptProblem end
56
56
"""
57
- PyomoDynamicOptProblem(sys::ODESystem , u0, tspan, p; dt, steps)
57
+ PyomoDynamicOptProblem(sys::System , u0, tspan, p; dt, steps)
58
58
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
60
60
for solving using optimization. Must provide either `dt`, the timestep between collocation
61
61
points (which, along with the timespan, determines the number of points), or directly
62
62
provide the number of points as `steps`.
@@ -91,11 +91,12 @@ Pyomo Collocation solver.
91
91
"""
92
92
function PyomoCollocation end
93
93
94
- function warn_overdetermined (sys, u0map )
94
+ function warn_overdetermined (sys, op )
95
95
cstrs = constraints (sys)
96
+ init_conds = filter (x -> value (x) ∈ Set (unknowns (sys)), [k for (k,v) in op])
96
97
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."
99
100
end
100
101
end
101
102
@@ -226,24 +227,27 @@ end
226
227
# #########################
227
228
# ## MODEL CONSTRUCTION ###
228
229
# #########################
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;
230
231
dt = nothing ,
231
232
steps = nothing ,
232
233
guesses = Dict (), kwargs... )
233
- warn_overdetermined (sys, u0map)
234
+
235
+ warn_overdetermined (sys, op)
234
236
ctrls = unbound_inputs (sys)
235
237
states = unknowns (sys)
236
238
237
- _u0map = has_alg_eqs (sys) ? u0map : merge (Dict (u0map), Dict (guesses))
238
239
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 ])
240
241
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) ]
242
243
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;
244
246
t = tspan != = nothing ? tspan[1 ] : tspan, kwargs... )
245
247
model_tspan, steps, is_free_t = process_tspan (tspan, dt, steps)
248
+ warn_overdetermined (sys, op)
246
249
250
+ pmap = filter (p -> (first (p) ∉ Set (unknowns (sys))), op)
247
251
pmap = recursive_unwrap (AnyDict (pmap))
248
252
evaluate_varmap! (pmap, keys (pmap))
249
253
c0 = value .([pmap[c] for c in ctrls])
@@ -261,7 +265,7 @@ function process_DynamicOptProblem(prob_type::Type{<:AbstractDynamicOptProblem},
261
265
add_user_constraints! (fullmodel, sys, tspan, pmap)
262
266
add_initial_constraints! (fullmodel, u0, u0_idxs, model_tspan[1 ])
263
267
264
- prob_type (f, u0, tspan, p, fullmodel, kwargs... )
268
+ prob_type (f, u0, tspan, p, fullmodel, kwargs... ), pmap
265
269
end
266
270
267
271
function generate_time_variable! end
@@ -301,16 +305,16 @@ end
301
305
is_free_final (model) = model. is_free_final
302
306
303
307
function 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)
307
310
set_objective! (model, 0 )
308
311
return
309
312
end
310
- jcosts = substitute_model_vars (model, sys, jcosts, tspan)
313
+
314
+ jcosts = substitute_model_vars (model, sys, [jcosts], tspan)
311
315
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))
314
318
end
315
319
316
320
"""
@@ -319,16 +323,16 @@ Substitute integrals. For an integral from (ts, te):
319
323
- CasADi cannot handle partial timespans, even for non-free-final time problems.
320
324
time problems and unchanged otherwise.
321
325
"""
322
- function substitute_integral (model, exprs , tspan)
326
+ function substitute_integral (model, expr , tspan)
323
327
intmap = Dict ()
324
- for int in collect_applied_operators (exprs , Symbolics. Integral)
328
+ for int in collect_applied_operators (expr , Symbolics. Integral)
325
329
op = operation (int)
326
330
arg = only (arguments (value (int)))
327
331
lo, hi = value .((op. domain. domain. left, op. domain. domain. right))
328
332
lo, hi = process_integral_bounds (model, (lo, hi), tspan)
329
333
intmap[int] = lowered_integral (model, arg, lo, hi)
330
334
end
331
- exprs = map (c -> Symbolics. substitute (c , intmap), value .(exprs) )
335
+ Symbolics. substitute (expr , intmap)
332
336
end
333
337
334
338
function process_integral_bounds (model, integral_span, tspan)
@@ -386,13 +390,13 @@ function lowered_var end
386
390
function fixed_t_map end
387
391
388
392
function 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)
391
394
(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)
394
398
395
- jconstraints = substitute_toterm (consvars , jconstraints)
399
+ jconstraints = substitute_toterm (cons_dvs , jconstraints)
396
400
jconstraints = substitute_model_vars (model, sys, jconstraints, tspan)
397
401
jconstraints = substitute_params (pmap, jconstraints)
398
402
0 commit comments