Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP - add some boolean indicators for OCP #153

Merged
merged 12 commits into from
Jun 20, 2024
4 changes: 3 additions & 1 deletion src/CTBase.jl
Original file line number Diff line number Diff line change
Expand Up @@ -249,12 +249,14 @@ export __OCPModel # redirection to Model to avoid confusion with other Model fun
export variable!, time!, constraint!, dynamics!, objective!, state!, control!, remove_constraint!, constraint
export is_time_independent, is_time_dependent, is_min, is_max, is_variable_dependent, is_variable_independent
export nlp_constraints, constraints_labels
export has_free_final_time, has_free_initial_time, has_lagrange_cost, has_mayer_cost
export dim_boundary_conditions, dim_control_constraints, dim_state_constraints, dim_variable_constraints, dim_mixed_constraints, dim_path_constraints, dim_control_box, dim_state_box, dim_variable_box

# solution
export OptimalControlSolution

# initialization
export OCPInit
export OptimalControlInit

# utils
export ctgradient, ctjacobian, ctinterpolate, ctindices, ctupperscripts
Expand Down
32 changes: 19 additions & 13 deletions src/init.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,22 +5,22 @@ Initialization of the OCP solution that can be used when solving the discretized

# Constructors:

- `OCPInit()`: default initialization
- `OCPInit(x_init, u_init, v_init)`: constant vector and/or function handles
- `OCPInit(sol)`: from existing solution
- `OptimalControlInit()`: default initialization
- `OptimalControlInit(x_init, u_init, v_init)`: constant vector and/or function handles
- `OptimalControlInit(sol)`: from existing solution

# Examples

```julia-repl
julia> init = OCPInit()
julia> init = OCPInit(x_init=[0.1, 0.2], u_init=0.3)
julia> init = OCPInit(x_init=[0.1, 0.2], u_init=0.3, v_init=0.5)
julia> init = OCPInit(x_init=[0.1, 0.2], u_init=t->sin(t), v_init=0.5)
julia> init = OCPInit(sol)
julia> init = OptimalControlInit()
julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=0.3)
julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=0.3, v_init=0.5)
julia> init = OptimalControlInit(x_init=[0.1, 0.2], u_init=t->sin(t), v_init=0.5)
julia> init = OptimalControlInit(sol)
```

"""
mutable struct OCPInit
mutable struct OptimalControlInit

state_init::Function
control_init::Function
Expand All @@ -30,7 +30,7 @@ mutable struct OCPInit
info::Symbol

# warm start from solution
function OCPInit(sol::OptimalControlSolution)
function OptimalControlInit(sol::OptimalControlSolution)

init = new()
init.info = :from_solution
Expand All @@ -43,7 +43,7 @@ mutable struct OCPInit
end

# constant / functional init with explicit arguments
function OCPInit(; state::Union{Nothing, ctVector, Function}=nothing, control::Union{Nothing, ctVector, Function}=nothing, variable::Union{Nothing, ctVector}=nothing)
function OptimalControlInit(; state::Union{Nothing, ctVector, Function}=nothing, control::Union{Nothing, ctVector, Function}=nothing, variable::Union{Nothing, ctVector}=nothing)

init = new()
init.info = :constant_or_function
Expand All @@ -57,13 +57,19 @@ mutable struct OCPInit

# version with arguments as collection/iterable
# (may be fused with version above ?)
function OCPInit(init)
function OptimalControlInit(init)

x_init = :state ∈ keys(init) ? init[:state] : nothing
u_init = :control ∈ keys(init) ? init[:control] : nothing
v_init = :variable ∈ keys(init) ? init[:variable] : nothing
return OCPInit(state=x_init, control=u_init, variable=v_init)
return OptimalControlInit(state=x_init, control=u_init, variable=v_init)

end

# trivial version that just returns its argument
# used for unified syntax in caller functions
function OptimalControlInit(init::OptimalControlInit)
return init
end

end
63 changes: 62 additions & 1 deletion src/model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,36 @@ Return `true` if the model has been defined as variable independent.
"""
is_variable_independent(ocp::OptimalControlModel) = !is_variable_dependent(ocp)


"""
$(TYPEDSIGNATURES)

Return `true` if the model has been defined with free initial time.
"""
has_free_initial_time(ocp::OptimalControlModel) = (typeof(ocp.initial_time)==Index)

"""
$(TYPEDSIGNATURES)

Return `true` if the model has been defined with free final time.
"""
has_free_final_time(ocp::OptimalControlModel) = (typeof(ocp.final_time)==Index)

"""
$(TYPEDSIGNATURES)

Return `true` if the model has been defined with lagrange cost.
"""
has_lagrange_cost(ocp::OptimalControlModel) = !isnothing(ocp.lagrange)

"""
$(TYPEDSIGNATURES)

Return `true` if the model has been defined with mayer cost.
"""
has_mayer_cost(ocp::OptimalControlModel) = !isnothing(ocp.mayer)


"""
$(TYPEDSIGNATURES)

Expand Down Expand Up @@ -625,12 +655,14 @@ function constraint!(
". Please choose in [ :initial, :final, :control, :state, :variable ] or check the arguments of the constraint! method."))
end
ocp.constraints[label] = (type, fun_rg, lb, ub)
nothing # to force to return nothing

end #
_ => throw(IncorrectArgument("Provided arguments are inconsistent."))
end

# update constraints dimensions
__set_dim_constraints(ocp)

end

"""
Expand Down Expand Up @@ -775,6 +807,7 @@ function remove_constraint!(ocp::OptimalControlModel, label::Symbol)
". Please check the list of constraints: ocp.constraints."))
end
delete!(ocp.constraints, label)
__set_dim_constraints(ocp) # update constraints dimensions
nothing
end

Expand Down Expand Up @@ -961,6 +994,34 @@ function nlp_constraints(ocp::OptimalControlModel)
return val
end

# set specific constraints dimensions
ocp.dim_control_constraints = length(ξl)
ocp.dim_state_constraints = length(ηl)
ocp.dim_mixed_constraints = length(ψl)
ocp.dim_path_constraints = ocp.dim_control_constraints + ocp.dim_state_constraints + ocp.dim_mixed_constraints
ocp.dim_boundary_conditions = length(ϕl)
ocp.dim_variable_constraints = length(θl)
ocp.dim_control_box = length(ul)
ocp.dim_state_box = length(xl)
ocp.dim_variable_box = length(vl)

return (ξl, ξ, ξu), (ηl, η, ηu), (ψl, ψ, ψu), (ϕl, ϕ, ϕu), (θl, θ, θu), (ul, uind, uu), (xl, xind, xu), (vl, vind, vu)

end

#
function __set_dim_constraints(ocp::OptimalControlModel)
nlp_constraints(ocp)
nothing
end

# getters for constraints dimensions
dim_control_constraints(ocp::OptimalControlModel) = ocp.dim_control_constraints
dim_state_constraints(ocp::OptimalControlModel) = ocp.dim_state_constraints
dim_mixed_constraints(ocp::OptimalControlModel) = ocp.dim_mixed_constraints
dim_path_constraints(ocp::OptimalControlModel) = ocp.dim_path_constraints
dim_boundary_conditions(ocp::OptimalControlModel) = ocp.dim_boundary_conditions
dim_variable_constraints(ocp::OptimalControlModel) = ocp.dim_variable_constraints
dim_control_box(ocp::OptimalControlModel) = ocp.dim_control_box
dim_state_box(ocp::OptimalControlModel) = ocp.dim_state_box
dim_variable_box(ocp::OptimalControlModel) = ocp.dim_variable_box
2 changes: 1 addition & 1 deletion src/print.jl
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function Base.show(io::IO, ::MIME"text/plain", ocp::OptimalControlModel{<: TimeD
#
println(io)
printstyled(io, "Declarations ", bold=true)
printstyled(io, "(* for required):\n", bold=false)
printstyled(io, "(* required):\n", bold=false)
#println(io)

# print table of settings
Expand Down
11 changes: 11 additions & 0 deletions src/types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1174,6 +1174,17 @@ $(TYPEDFIELDS)
criterion::Union{Symbol,Nothing}=nothing
dynamics::Union{Dynamics,Nothing}=nothing
constraints::Dict{Symbol, Tuple{Vararg{Any}}}=Dict{Symbol, Tuple{Vararg{Any}}}()

# internal dimensions for constraints
dim_control_constraints::Union{Dimension, Nothing}=nothing
dim_state_constraints::Union{Dimension, Nothing}=nothing
dim_mixed_constraints::Union{Dimension, Nothing}=nothing
dim_path_constraints::Union{Dimension, Nothing}=nothing
dim_boundary_conditions::Union{Dimension, Nothing}=nothing
dim_variable_constraints::Union{Dimension, Nothing}=nothing
dim_control_box::Union{Dimension, Nothing}=nothing
dim_state_box::Union{Dimension, Nothing}=nothing
dim_variable_box::Union{Dimension, Nothing}=nothing
end

# used for checkings
Expand Down
Loading