Model
Optimal control model type
CTBase.OptimalControlModel
— Typemutable struct OptimalControlModel{time_dependence<:TimeDependence, variable_dependence<:VariableDependence} <: CTBase.AbstractOptimalControlModel
Fields
model_expression::Union{Nothing, Expr}
: Default: nothinginitial_time::Union{Nothing, Index, Real}
: Default: nothinginitial_time_name::Union{Nothing, String}
: Default: nothingfinal_time::Union{Nothing, Index, Real}
: Default: nothingfinal_time_name::Union{Nothing, String}
: Default: nothingtime_name::Union{Nothing, String}
: Default: nothingcontrol_dimension::Union{Nothing, Integer}
: Default: nothingcontrol_components_names::Union{Nothing, Vector{String}}
: Default: nothingcontrol_name::Union{Nothing, String}
: Default: nothingstate_dimension::Union{Nothing, Integer}
: Default: nothingstate_components_names::Union{Nothing, Vector{String}}
: Default: nothingstate_name::Union{Nothing, String}
: Default: nothingvariable_dimension::Union{Nothing, Integer}
: Default: nothingvariable_components_names::Union{Nothing, Vector{String}}
: Default: nothingvariable_name::Union{Nothing, String}
: Default: nothinglagrange::Union{Nothing, Lagrange}
: Default: nothingmayer::Union{Nothing, Mayer}
: Default: nothingcriterion::Union{Nothing, Symbol}
: Default: nothingdynamics::Union{Nothing, Dynamics}
: Default: nothingconstraints::Dict{Symbol, Tuple}
: Default: Dict{Symbol, Tuple{Vararg{Any}}}()dim_control_constraints::Union{Nothing, Integer}
: Default: nothingdim_state_constraints::Union{Nothing, Integer}
: Default: nothingdim_mixed_constraints::Union{Nothing, Integer}
: Default: nothingdim_boundary_constraints::Union{Nothing, Integer}
: Default: nothingdim_variable_constraints::Union{Nothing, Integer}
: Default: nothingdim_control_range::Union{Nothing, Integer}
: Default: nothingdim_state_range::Union{Nothing, Integer}
: Default: nothingdim_variable_range::Union{Nothing, Integer}
: Default: nothing
Getters
CTBase.constraint
— Methodconstraint(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
label::Symbol
) -> Union{Nothing, VariableConstraint, BoundaryConstraint, ControlConstraint, MixedConstraint, StateConstraint}
Retrieve a labeled constraint. The result is a function associated with the constraint computation (not taking into account provided value / bounds).
Example
julia> constraint!(ocp, :initial, 0, :c0)
julia> c = constraint(ocp, :c0)
julia> c(1)
1
CTBase.constraints_labels
— Methodconstraints_labels(
ocp::OptimalControlModel
) -> Base.KeySet{Symbol, Dict{Symbol, Tuple}}
Return the labels of the constraints as a Base.keys
.
CTBase.control_components_names
— Methodcontrol_components_names(
ocp::OptimalControlModel
) -> Union{Nothing, Vector{String}}
Return the names of the components of the control of the optimal control problem or nothing
.
CTBase.control_dimension
— Methodcontrol_dimension(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimention of the control of the optimal control problem or nothing
.
CTBase.control_name
— Methodcontrol_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the control of the optimal control problem or nothing
.
CTBase.criterion
— Methodcriterion(
ocp::OptimalControlModel
) -> Union{Nothing, Symbol}
Return the criterion (:min
or :max
) of the optimal control problem or nothing
.
CTBase.dim_boundary_constraints
— Methoddim_boundary_constraints(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of the boundary constraints (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_control_constraints
— Methoddim_control_constraints(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of nonlinear control constraints (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_control_range
— Methoddim_control_range(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of range constraints on control (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_mixed_constraints
— Methoddim_mixed_constraints(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of nonlinear mixed constraints (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_path_constraints
— Methoddim_path_constraints(ocp::OptimalControlModel) -> Any
Return the dimension of nonlinear path (state + control + mixed) constraints (nothing
if one of them is not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_state_constraints
— Methoddim_state_constraints(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of nonlinear state constraints (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_state_range
— Methoddim_state_range(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of range constraints on state (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_variable_constraints
— Methoddim_variable_constraints(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of nonlinear variable constraints (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dim_variable_range
— Methoddim_variable_range(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of range constraints on variable (nothing
if not knonw). Information is updated after nlp_constraints!
is called.
CTBase.dynamics
— Methoddynamics(
ocp::OptimalControlModel
) -> Union{Nothing, Dynamics}
Return the dynamics of the optimal control problem or nothing
.
CTBase.final_time
— Methodfinal_time(
ocp::OptimalControlModel
) -> Union{Nothing, Index, Real}
Return the final time of the optimal control problem or nothing
.
CTBase.final_time_name
— Methodfinal_time_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the final time of the optimal control problem or nothing
.
CTBase.has_free_final_time
— Methodhas_free_final_time(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined with free final time.
CTBase.has_free_initial_time
— Methodhas_free_initial_time(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined with free initial time.
CTBase.has_lagrange_cost
— Methodhas_lagrange_cost(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined with lagrange cost.
CTBase.has_mayer_cost
— Methodhas_mayer_cost(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined with mayer cost.
CTBase.initial_time
— Methodinitial_time(
ocp::OptimalControlModel
) -> Union{Nothing, Index, Real}
Return the initial time of the optimal control problem or nothing
.
CTBase.initial_time_name
— Methodinitial_time_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the initial time of the optimal control problem or nothing
.
CTBase.is_autonomous
— Methodis_autonomous(ocp::OptimalControlModel{Autonomous}) -> Bool
Return true
if the model is autonomous.
CTBase.is_fixed
— Methodis_fixed(
ocp::OptimalControlModel{<:TimeDependence, Fixed}
) -> Bool
Return true
if the model is fixed (= has no variable).
CTBase.is_max
— Methodis_max(ocp::OptimalControlModel) -> Bool
Return true
if the criterion type of ocp
is :max
.
CTBase.is_min
— Methodis_min(ocp::OptimalControlModel) -> Bool
Return true
if the criterion type of ocp
is :min
.
CTBase.is_time_dependent
— Methodis_time_dependent(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined as time dependent.
CTBase.is_time_independent
— Methodis_time_independent(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined as time independent.
CTBase.is_variable_dependent
— Methodis_variable_dependent(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined as variable dependent.
CTBase.is_variable_independent
— Methodis_variable_independent(ocp::OptimalControlModel) -> Bool
Return true
if the model has been defined as variable independent.
CTBase.lagrange
— Methodlagrange(
ocp::OptimalControlModel
) -> Union{Nothing, Lagrange}
Return the Lagrange part of the cost of the optimal control problem or nothing
.
CTBase.mayer
— Methodmayer(ocp::OptimalControlModel) -> Union{Nothing, Mayer}
Return the Mayer part of the cost of the optimal control problem or nothing
.
CTBase.model_expression
— Methodmodel_expression(
ocp::OptimalControlModel
) -> Union{Nothing, Expr}
Return the model expression of the optimal control problem or nothing
.
CTBase.nlp_constraints!
— Methodnlp_constraints!(
ocp::OptimalControlModel
) -> Tuple{Tuple{Any, CTBase.var"#ξ#41", Vector{Real}}, Tuple{Any, CTBase.var"#η#42", Vector{Real}}, Tuple{Any, CTBase.var"#ψ#43", Vector{Real}}, Tuple{Any, CTBase.var"#ϕ#44", Vector{Real}}, Tuple{Any, CTBase.var"#θ#45", Vector{Real}}, Tuple{Vector{Real}, Vector{Int64}, Vector{Real}}, Tuple{Vector{Real}, Vector{Int64}, Vector{Real}}, Tuple{Vector{Real}, Vector{Int64}, Vector{Real}}}
Return a 6-tuple of tuples:
(ξl, ξ, ξu)
are control constraints(ηl, η, ηu)
are state constraints(ψl, ψ, ψu)
are mixed constraints(ϕl, ϕ, ϕu)
are boundary constraints(θl, θ, θu)
are variable constraints(ul, uind, uu)
are control linear constraints of a subset of indices(xl, xind, xu)
are state linear constraints of a subset of indices(vl, vind, vu)
are variable linear constraints of a subset of indices
and update information about constraints dimensions of ocp
.
- The dimensions of the state and control must be set before calling
nlp_constraints!
. - For a
Fixed
problem, dimensions associated with constraints on the variable are set to zero.
Example
julia> (ξl, ξ, ξu), (ηl, η, ηu), (ψl, ψ, ψu), (ϕl, ϕ, ϕu), (θl, θ, θu),
(ul, uind, uu), (xl, xind, xu), (vl, vind, vu) = nlp_constraints!(ocp)
CTBase.state_components_names
— Methodstate_components_names(
ocp::OptimalControlModel
) -> Union{Nothing, Vector{String}}
Return the names of the components of the state of the optimal control problem or nothing
.
CTBase.state_dimension
— Methodstate_dimension(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of the state of the optimal control problem or nothing
.
CTBase.state_name
— Methodstate_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the state of the optimal control problem or nothing
.
CTBase.time_name
— Methodtime_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the time component of the optimal control problem or nothing
.
CTBase.variable_components_names
— Methodvariable_components_names(
ocp::OptimalControlModel
) -> Union{Nothing, Vector{String}}
Return the names of the components of the variable of the optimal control problem or nothing
.
CTBase.variable_dimension
— Methodvariable_dimension(
ocp::OptimalControlModel
) -> Union{Nothing, Integer}
Return the dimension of the variable of the optimal control problem or nothing
.
CTBase.variable_name
— Methodvariable_name(
ocp::OptimalControlModel
) -> Union{Nothing, String}
Return the name of the variable of the optimal control problem or nothing
.
Constructors and setters
CTBase.Model
— MethodModel(
dependencies::DataType...
) -> OptimalControlModel{Autonomous, Fixed}
Return a new OptimalControlModel
instance, that is a model of an optimal control problem.
The model is defined by the following argument:
dependencies
: eitherAutonomous
orNonAutonomous
. Default isAutonomous
. And eitherNonFixed
orFixed
. Default isFixed
.
Examples
julia> ocp = Model()
julia> ocp = Model(NonAutonomous)
julia> ocp = Model(Autonomous, NonFixed)
- If the time dependence of the model is defined as nonautonomous, then, the dynamics function, the lagrange cost and the path constraints must be defined as functions of time and state, and possibly control. If the model is defined as autonomous, then, the dynamics function, the lagrange cost and the path constraints must be defined as functions of state, and possibly control.
CTBase.Model
— MethodModel(
;
autonomous,
variable
) -> OptimalControlModel{Autonomous, Fixed}
Return a new OptimalControlModel
instance, that is a model of an optimal control problem.
The model is defined by the following optional keyword argument:
autonomous
: eithertrue
orfalse
. Default istrue
.variable
: eithertrue
orfalse
. Default isfalse
.
Examples
julia> ocp = Model()
julia> ocp = Model(autonomous=false)
julia> ocp = Model(autonomous=false, variable=true)
- If the time dependence of the model is defined as nonautonomous, then, the dynamics function, the lagrange cost and the path constraints must be defined as functions of time and state, and possibly control. If the model is defined as autonomous, then, the dynamics function, the lagrange cost and the path constraints must be defined as functions of state, and possibly control.
CTBase.constraint!
— Methodconstraint!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
type::Symbol;
rg,
f,
lb,
ub,
val,
label
)
Add a constraint to an optimal control problem, denoted ocp
.
- The state, control and variable dimensions must be set before. Use state!, control! and variable!.
- The initial and final times must be set before. Use time!.
- When an element is of dimension 1, consider it as a scalar.
You can add an :initial
, :final
, :control
, :state
or :variable
box constraint (whole range).
Range constraint on the state, control or variable
You can add an :initial
, :final
, :control
, :state
or :variable
box constraint on a range of it, that is only on some components. If not range is specified, then the constraint is on the whole range. We denote by x
, u
and v
respectively the state, control and variable. We denote by n
, m
and q
respectively the dimension of the state, control and variable. The range of the constraint must be contained in 1:n if the constraint is on the state, or 1:m if the constraint is on the control, or 1:q if the constraint is on the variable.
Examples
julia> constraint!(ocp, :initial; rg=1:2:5, lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ])
julia> constraint!(ocp, :initial; rg=2:3, lb=[ 0, 0 ], ub=[ 1, 2 ])
julia> constraint!(ocp, :final; rg=1, lb=0, ub=2)
julia> constraint!(ocp, :control; rg=1, lb=0, ub=2)
julia> constraint!(ocp, :state; rg=2:3, lb=[ 0, 0 ], ub=[ 1, 2 ])
julia> constraint!(ocp, :variable; rg=1:2, lb=[ 0, 0 ], ub=[ 1, 2 ])
julia> constraint!(ocp, :initial; lb=[ 0, 0, 0 ]) # [ 0, 0, 0 ] ≤ x(t0), dim(x) = 3
julia> constraint!(ocp, :initial; lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ]) # [ 0, 0, 0 ] ≤ x(t0) ≤ [ 1, 2, 1 ], dim(x) = 3
julia> constraint!(ocp, :final; lb=-1, ub=1) # -1 ≤ x(tf) ≤ 1, dim(x) = 1
julia> constraint!(ocp, :control; lb=0, ub=2) # 0 ≤ u(t) ≤ 2, t ∈ [t0, tf], dim(u) = 1
julia> constraint!(ocp, :state; lb=[ 0, 0 ], ub=[ 1, 2 ]) # [ 0, 0 ] ≤ x(t) ≤ [ 1, 2 ], t ∈ [t0, tf], dim(x) = 2
julia> constraint!(ocp, :variable; lb=[ 0, 0 ], ub=[ 1, 2 ]) # [ 0, 0 ] ≤ v ≤ [ 1, 2 ], dim(v) = 2
Functional constraint
You can add a :boundary
, :control
, :state
, :mixed
or :variable
box functional constraint.
Examples
# variable independent ocp
julia> constraint!(ocp, :boundary; f = (x0, xf) -> x0[3]+xf[2], lb=0, ub=1)
# variable dependent ocp
julia> constraint!(ocp, :boundary; f = (x0, xf, v) -> x0[3]+xf[2]*v[1], lb=0, ub=1)
# time independent and variable independent ocp
julia> constraint!(ocp, :control; f = u -> 2u, lb=0, ub=1)
julia> constraint!(ocp, :state; f = x -> x-1, lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ])
julia> constraint!(ocp, :mixed; f = (x, u) -> x[1]-u, lb=0, ub=1)
# time dependent and variable independent ocp
julia> constraint!(ocp, :control; f = (t, u) -> 2u, lb=0, ub=1)
julia> constraint!(ocp, :state; f = (t, x) -> t * x, lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ])
julia> constraint!(ocp, :mixed; f = (t, x, u) -> x[1]-u, lb=0, ub=1)
# time independent and variable dependent ocp
julia> constraint!(ocp, :control; f = (u, v) -> 2u * v[1], lb=0, ub=1)
julia> constraint!(ocp, :state; f = (x, v) -> x * v[1], lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ])
julia> constraint!(ocp, :mixed; f = (x, u, v) -> x[1]-v[2]*u, lb=0, ub=1)
# time dependent and variable dependent ocp
julia> constraint!(ocp, :control; f = (t, u, v) -> 2u+v[2], lb=0, ub=1)
julia> constraint!(ocp, :state; f = (t, x, v) -> x-t*v[1], lb=[ 0, 0, 0 ], ub=[ 1, 2, 1 ])
julia> constraint!(ocp, :mixed; f = (t, x, u, v) -> x[1]*v[2]-u, lb=0, ub=1)
CTBase.control!
— Functioncontrol!(ocp::OptimalControlModel, m::Integer)
control!(ocp::OptimalControlModel, m::Integer, name::String)
control!(
ocp::OptimalControlModel,
m::Integer,
name::String,
components_names::Vector{String}
)
Define the control dimension and possibly the names of each coordinate.
You must use control! only once to set the control dimension.
Examples
julia> control!(ocp, 1)
julia> ocp.control_dimension
1
julia> ocp.control_components_names
["u"]
julia> control!(ocp, 1, "v")
julia> ocp.control_dimension
1
julia> ocp.control_components_names
["v"]
julia> control!(ocp, 2)
julia> ocp.control_dimension
2
julia> ocp.control_components_names
["u₁", "u₂"]
julia> control!(ocp, 2, :v)
julia> ocp.control_dimension
2
julia> ocp.control_components_names
["v₁", "v₂"]
julia> control!(ocp, 2, "v")
julia> ocp.control_dimension
2
julia> ocp.control_components_names
["v₁", "v₂"]
CTBase.dynamics!
— Methoddynamics!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
f::Function
)
Set the dynamics.
You can use dynamics! only once to define the dynamics.
- The state, control and variable dimensions must be set before. Use state!, control! and variable!.
- The times must be set before. Use time!.
- When an element is of dimension 1, consider it as a scalar.
Example
julia> dynamics!(ocp, f)
CTBase.objective!
— Methodobjective!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
type::Symbol,
g::Function,
f⁰::Function
)
objective!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
type::Symbol,
g::Function,
f⁰::Function,
criterion::Symbol
)
Set the criterion to the function g
and f⁰
. Type can be :bolza
. Criterion is :min
or :max
.
You can use objective! only once to define the objective.
- The state, control and variable dimensions must be set before. Use state!, control! and variable!.
- The times must be set before. Use time!.
- When an element is of dimension 1, consider it as a scalar.
Example
julia> objective!(ocp, :bolza, (x0, xf) -> x0[1] + xf[2], (x, u) -> x[1]^2 + u^2) # the control is of dimension 1
CTBase.objective!
— Methodobjective!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
type::Symbol,
f::Function
)
objective!(
ocp::OptimalControlModel{T<:TimeDependence, V<:VariableDependence},
type::Symbol,
f::Function,
criterion::Symbol
)
Set the criterion to the function f
. Type can be :mayer
or :lagrange
. Criterion is :min
or :max
.
You can use objective! only once to define the objective.
- The state, control and variable dimensions must be set before. Use state!, control! and variable!.
- The times must be set before. Use time!.
- When an element is of dimension 1, consider it as a scalar.
Examples
julia> objective!(ocp, :mayer, (x0, xf) -> x0[1] + xf[2])
julia> objective!(ocp, :lagrange, (x, u) -> x[1]^2 + u^2) # the control is of dimension 1
If you set twice the objective, only the last one will be taken into account.
CTBase.remove_constraint!
— Methodremove_constraint!(ocp::OptimalControlModel, label::Symbol)
Remove a labeled constraint.
Example
julia> remove_constraint!(ocp, :con)
CTBase.state!
— Functionstate!(ocp::OptimalControlModel, n::Integer)
state!(ocp::OptimalControlModel, n::Integer, name::String)
state!(
ocp::OptimalControlModel,
n::Integer,
name::String,
components_names::Vector{String}
)
Define the state dimension and possibly the names of each component.
You must use state! only once to set the state dimension.
Examples
julia> state!(ocp, 1)
julia> ocp.state_dimension
1
julia> ocp.state_components_names
["x"]
julia> state!(ocp, 1, "y")
julia> ocp.state_dimension
1
julia> ocp.state_components_names
["y"]
julia> state!(ocp, 2)
julia> ocp.state_dimension
2
julia> ocp.state_components_names
["x₁", "x₂"]
julia> state!(ocp, 2, :y)
julia> ocp.state_dimension
2
julia> ocp.state_components_names
["y₁", "y₂"]
julia> state!(ocp, 2, "y")
julia> ocp.state_dimension
2
julia> ocp.state_components_names
["y₁", "y₂"]
CTBase.time!
— Methodtime!(
ocp::OptimalControlModel{<:TimeDependence, VT};
t0,
tf,
ind0,
indf,
name
)
Set the initial and final times. We denote by t0 the initial time and tf the final time. The optimal control problem is denoted ocp. When a time is free, then one must provide the corresponding index of the ocp variable.
You must use time! only once to set either the initial or the final time, or both.
Examples
julia> time!(ocp, t0=0, tf=1 ) # Fixed t0 and fixed tf
julia> time!(ocp, t0=0, indf=2) # Fixed t0 and free tf
julia> time!(ocp, ind0=2, tf=1 ) # Free t0 and fixed tf
julia> time!(ocp, ind0=2, indf=3) # Free t0 and free tf
When you plot a solution of an optimal control problem, the name of the time variable appears. By default, the name is "t". Consider you want to set the name of the time variable to "s".
julia> time!(ocp, t0=0, tf=1, name="s") # name is a String
# or
julia> time!(ocp, t0=0, tf=1, name=:s ) # name is a Symbol
CTBase.variable!
— Functionvariable!(ocp::OptimalControlModel, q::Integer)
variable!(
ocp::OptimalControlModel,
q::Integer,
name::String
)
variable!(
ocp::OptimalControlModel,
q::Integer,
name::String,
components_names::Vector{String}
)
Define the variable dimension and possibly the names of each component.
You can use variable! once to set the variable dimension when the model is NonFixed
.
Examples
julia> variable!(ocp, 1, "v")
julia> variable!(ocp, 2, "v", [ "v₁", "v₂" ])