Warm starting an Optimal Control Problem #338
Replies: 1 comment 6 replies
-
Good question. To warm start MPC problems, I typically reuse the previous solution. Since, InfiniteOpt models in continuous time, we have to map the discrete solution back to a continuous function. I use interpolation to accomplish this: using InfiniteOpt, Ipopt, Interpolations
# define the model
model = InfiniteModel(Ipopt.Optimizer)
@infinite_parameter(model, t in [0, 10], num_supports = 11)
@variable(model, y, Infinite(t), start = sin) # y(t) with some initial trajectory to get things going
# some model defined here....
# solve the first time
optimize!(model)
y_opt = value(y)
# now resolve as many times as we want
for i in 1:n
y_opt_interp = linear_interpolation(value(t), y_opt)
set_start_value_function(y, t -> y_opt_interp(t))
# update the model for as makes sense (i.e., update the initial condition and the setpoint trajectory)
optimize!(model)
y_opt = value(y)
end Currently, InfiniteOpt doesn't support specifying guesses for constraint primals/duals. This is on the todo list. However, you can always work directly with the underlying JuMP model once it is made (after using InfiniteOpt, Ipopt
# define the model
model = InfiniteModel(Ipopt.Optimizer)
@infinite_parameter(model, t in [0, 10], num_supports = 11)
@variable(model, y, Infinite(t), start = sin) # y(t) with some initial trajectory to get things going
# some model defined here....
@constraint(model, my_constr, y^2 <= 2)
# solve the first time (builds a JuMP model and solves it)
optimize!(model)
# get the solved JuMP model
discretized_model = optimizer_model(model)
discretized_y = transcription_variable(y)
discretized_my_constr = transcription_constraint(my_constr)
# update and resolve the JuMP model
for i in 1:n
# do some updates
# do the warmstart
for yt in discretized_y
set_start_value(yt, value(yt))
end
for ct in discretized_my_constr
set_start_value(ct, value(ct))
set_dual_start_value(ct, dual(ct))
end
end The API to work with the underlying JuMP model is described at https://infiniteopt.github.io/InfiniteOpt.jl/stable/guide/transcribe/. You can also use the For your using Interpolations, InfiniteOpt
function interpY(y::Vector{Float64}, timeArray::Vector{Float64})
return t -> linear_interpolation(timeArray, y)(t)
end
model = InfiniteModel(Ipopt.Optimizer)
@infinite_parameter(model, t in [0, 10], supports = my_ts)
@variable(model, y, Infinite(t), start = interpY(my_ys, my_ts)) As for handling times outside the array, this will vary on a case by case basis. Naturally, you might want to shift the previous solution forward in time which means adding on a new time point at the end. Choosing what value to use for this new time point will depend on the nature of the problem. |
Beta Was this translation helpful? Give feedback.
-
Inspired by some past discussions:
I started digging into the warm-starting solvers. I couldn't help to notice 2 things.
JuMP
you can use discrete arrays to load guess trajectories as:also using Primal and dual warm-starts
2. In InifiteOpt you use functions as in #335, which are then transcribed by the package. The issue is that the only valid arg is
t
But imagine you are solving consecutive problems in a rolling horizon fashion. How would I define a function with only one argument that does the following:
Should I implement a
@parameter_function
? How do I handle times outside of the original array? How's that going to be continuos?Beta Was this translation helpful? Give feedback.
All reactions