Skip to content

Optimal control problems

CTModels defines and builds optimal control problems (OCPs) through four focused modules: CTModels.Components, CTModels.Models, CTModels.Building, and CTModels.Solutions. An OCP is assembled incrementally into a mutable PreModel, then frozen into an immutable Model by build.

CTModels builds a model through a three-stage pipeline:

text
PreModel  →  declare components  →  build  →  Model
(mutable)    state!/control!/...           (immutable)

The OCP layer is organised by responsibility across four modules:

ModuleDirectoryWhat it provides
CTModels.Componentssrc/Components/Component types (StateModel, TimeDependence, …) and their accessors
CTModels.Modelssrc/Models/Immutable Model type and all model accessor methods
CTModels.Buildingsrc/Building/PreModel, declaration verbs (state!, control!, …), name validation, build
CTModels.Solutionssrc/Solutions/build_solution, solution types, dual model, interpolation

Reading order

PageTopicKey symbols
Types and traitsThe noun/trait architectureTimeDependence, AbstractStateModel, Empty*
ComponentsDeclaring the spacesstate!, control!, variable!, time!
Dynamics and objectiveThe equations of motion and costdynamics!, objective!
ConstraintsPath, boundary and box constraintsconstraint!
Building a modelFreezing the PreModelbuild, Model
Displaying modelsBase.show and mathematical renderingModel, PreModel display

Qualified access

CTModels exports nothing at the package level: every public symbol is reached through a qualified path CTModels.symbol. Bring the package into scope and call its verbs qualified:

julia
using CTModels

Minimal end-to-end example

We build the beam problem: minimise   subject to  , fixed boundary conditions, and box constraints on and .

julia
# 1. A fresh, mutable pre-model
pre = CTModels.PreModel()

# 2. Declare the time interval, the spaces and (here) no optimisation variable
CTModels.variable!(pre, 0)
CTModels.time!(pre; t0=0.0, tf=1.0)
CTModels.state!(pre, 2)        # x ∈ ℝ²
CTModels.control!(pre, 1)      # u ∈ ℝ

# 3. Dynamics ẋ = (x₂, u), written in place
function beam_dynamics!(r, t, x, u, v)
    r[1] = x[2]
    r[2] = u[1]
    return nothing
end
CTModels.dynamics!(pre, beam_dynamics!)

# 4. Lagrange cost ∫ u² → min
beam_lagrange(t, x, u, v) = u[1]^2
CTModels.objective!(pre, :min; lagrange=beam_lagrange)

# 5. Boundary and box constraints
function beam_boundary!(r, x0, xf, v)
    r[1] = x0[1]      # x₁(0) = 0
    r[2] = x0[2] - 1  # x₂(0) = 1
    r[3] = xf[1]      # x₁(1) = 0
    r[4] = xf[2] + 1  # x₂(1) = -1
    return nothing
end
CTModels.constraint!(pre, :boundary; f=beam_boundary!, lb=zeros(4), ub=zeros(4), label=:bc)
CTModels.constraint!(pre, :state;   rg=1:1, lb=[0.0],   ub=[0.1],  label=:x1_box)
CTModels.constraint!(pre, :control; rg=1:1, lb=[-10.0], ub=[10.0], label=:u_box)

# 6. Mark the system autonomous and freeze it into an immutable Model
CTModels.time_dependence!(pre; autonomous=true)
ocp = CTModels.build(pre)
The (autonomous) optimal control problem is of the form:

    minimize  J(x, u) = ∫ f⁰(x(t), u(t)) dt, over [0.0, 1.0]

    subject to

        ẋ(t) = f(x(t), u(t)), t in [0.0, 1.0] a.e.,

        ϕ₋ ≤ ϕ(x(0.0), x(1.0)) ≤ ϕ₊, 
        x₋ ≤ x(t) ≤ x₊, 
        u₋ ≤ u(t) ≤ u₊, 

    where x(t) ∈ R² and u(t) ∈ R.

Once built, the Model answers queries through accessors:

julia
julia> CTModels.state_dimension(ocp)
2

julia> CTModels.control_dimension(ocp)
1

julia> CTModels.variable_dimension(ocp)
0

julia> CTModels.is_autonomous(ocp)
true

The shortcut CTModels.build_model(pre) is an alias for CTModels.build(pre); see Building a model for what build checks and guarantees.

Mathematical setting

CTModels represents a continuous-time OCP in Bolza form. With state   , control    and an optimisation variable   (free final time, design parameters, …):

Two orthogonal axes shape the representation:

  • Time dependence — whether , depend explicitly on (Autonomous vs NonAutonomous).

  • Time structure — whether / are fixed or free (FixedTimeModel vs FreeTimeModel).

How these axes become traits rather than separate types is the subject of Types and traits.