Skip to content

Commit

Permalink
Merge pull request #153 from control-toolbox/add_some_ocp_indicators
Browse files Browse the repository at this point in the history
WIP - add some boolean indicators for OCP
  • Loading branch information
ocots authored Jun 20, 2024
2 parents b214a72 + 5a74f24 commit 0e416f3
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 16 deletions.
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

0 comments on commit 0e416f3

Please sign in to comment.