OptimalControl.jl

The OptimalControl.jl package is the root package of the control-toolbox ecosystem. The control-toolbox ecosystem gathers Julia packages for mathematical control and applications. It aims to provide tools to model and solve optimal control problems with ordinary differential equations by direct and indirect methods, both on CPU and GPU.

Installation

To install OptimalControl.jl, please open Julia's interactive session (known as REPL) and use the Julia package manager:

using Pkg
Pkg.add("OptimalControl")
Tip

If you are new to Julia, please follow this guidelines.

Basic usage

Let us model, solve and plot a simple optimal control problem.

using OptimalControl
using NLPModelsIpopt
using Plots

ocp = @def begin
    t ∈ [0, 1], time
    x ∈ R², state
    u ∈ R, control
    x(0) == [-1, 0]
    x(1) == [0, 0]
    ẋ(t) == [x₂(t), u(t)]
    ∫( 0.5u(t)^2 ) → min
end

sol = solve(ocp)
plot(sol)

Mathematical formulation

An optimal control problem (OCP) with fixed initial and final times can be described as minimising the cost functional (in Bolza form)

\[J(x, u) = g(x(t_0), x(t_f)) + \int_{t_0}^{t_f} f^{0}(t, x(t), u(t))\,\mathrm{d}t\]

where the state $x$ and the control $u$ are functions of time $t$, subject for $t \in [t_0, t_f]$ to the differential constraint

\[\dot{x}(t) = f(t, x(t), u(t))\]

and other constraints such as

\[\begin{array}{llcll} x_{\mathrm{lower}} & \le & x(t) & \le & x_{\mathrm{upper}}, \\ u_{\mathrm{lower}} & \le & u(t) & \le & u_{\mathrm{upper}}, \\ c_{\mathrm{lower}} & \le & c(t, x(t), u(t)) & \le & c_{\mathrm{upper}}, \\ b_{\mathrm{lower}} & \le & b(x(t_0), x(t_f)) & \le & b_{\mathrm{upper}}. \end{array}\]

If $g = 0$, the cost is said to be in Lagrange form; if $f^0 = 0$, it is in Mayer form.

Free times and extra variables

The initial time $t_0$ and the final time $t_f$ may also be free, that is part of the optimisation variables:

\[J(x, u, t_0, t_f) \to \min.\]

More generally, a vector $v \in \mathbb{R}^k$ of $k$ additional variables can be introduced (it may contain $t_0$, $t_f$, or any other free parameter). The cost, dynamics, and constraints then all depend on $v$:

\[J(x, u, v) = g(x(t_0), x(t_f), v) + \int_{t_0}^{t_f} f^{0}(t, x(t), u(t), v)\,\mathrm{d}t \to \min,\]

\[\dot{x}(t) = f(t, x(t), u(t), v),\]

with, in addition, box constraints on $v$:

\[v_{\mathrm{lower}} \le v \le v_{\mathrm{upper}}.\]

Citing us

If you use OptimalControl.jl in your work, please cite us:

Caillau, J.-B., Cots, O., Gergaud, J., Martinon, P., & Sed, S. OptimalControl.jl: a Julia package to model and solve optimal control problems with ODE's. doi.org/10.5281/zenodo.13336563

or in bibtex format:

@software{OptimalControl_jl,
author = {Caillau, Jean-Baptiste and Cots, Olivier and Gergaud, Joseph and Martinon, Pierre and Sed, Sophia},
doi = {10.5281/zenodo.13336563},
license = {["MIT"]},
title = {{OptimalControl.jl: a Julia package to model and solve optimal control problems with ODE's}},
url = {https://control-toolbox.org/OptimalControl.jl}
}

Contributing

If you think you found a bug or if you have a feature request / suggestion, feel free to open an issue. Before opening a pull request, please start an issue or a discussion on the topic.

Contributions are welcomed, check out how to contribute to a Github project. If it is your first contribution, you can also check this first contribution tutorial. You can find first good issues (if any 🙂) here. You may find other packages to contribute to at the control-toolbox organization.

If you want to ask a question, feel free to start a discussion here. This forum is for general discussion about this repository and the control-toolbox organization.

Note

If you want to add an application or a package to the control-toolbox ecosystem, please follow this set up tutorial.

Reproducibility

using Pkg
using InteractiveUtils
using Markdown

# Download links for the benchmark environment
function _downloads_toml(DIR)
    link_manifest = joinpath("assets", DIR, "Manifest.toml")
    link_project = joinpath("assets", DIR, "Project.toml")
    return Markdown.parse("""
    You can download the exact environment used to build this documentation:
    - 📦 [Project.toml]($link_project) - Package dependencies
    - 📋 [Manifest.toml]($link_manifest) - Complete dependency tree with versions
    """)
end
<< @setup-block not executed in draft mode >>
_downloads_toml(".") # hide
<< @example-block not executed in draft mode >>
ℹ️ Version info
versioninfo() # hide
<< @example-block not executed in draft mode >>
📦 Package status
Pkg.status() # hide
<< @example-block not executed in draft mode >>
📚 Complete manifest
Pkg.status(; mode = PKGMODE_MANIFEST) # hide
<< @example-block not executed in draft mode >>