Installation
Install
Open Julia's interactive session (REPL) and use the package manager:
using Pkg
Pkg.add("OptimalControl")Tip
If you are new to Julia, read New to Julia: how to use OptimalControl.
OptimalControl alone is enough to define a problem with @def and describe solve strategies. The features below are optional: each requires an additional package, which you only need to load when you use that feature.
You will also need a solver
solve requires an NLP solver backend to be loaded. NLPModelsIpopt is the default solver and is used throughout this documentation:
using NLPModelsIpoptOther solvers are available through their respective packages:
| Solver | Load |
|---|---|
:ipopt (default) | using NLPModelsIpopt |
:madnlp | using MadNLP (on GPU, see below) |
:uno | using UnoSolver |
:madncl | using MadNCL and using MadNLP (both) |
:knitro | using NLPModelsKnitro (commercial licence required) |
See Choosing a method to learn how these packages combine with a discretizer, a modeler, and a :cpu/:gpu parameter.
If you call solve before loading the appropriate package, it raises an ExtensionError that names the missing package and the using statement to add:
julia> solve(ocp)
ERROR: ExtensionError → _route_descriptive_options, descriptive_routing.jl:259
│
│ missing dependencies to access Ipopt{CPU} options metadata
│
│ Missing NLPModelsIpopt
│
│ Context Load NLPModelsIpopt extension first: using NLPModelsIpopt
│ Hint Run: using NLPModelsIpopt
└─The same mechanism covers every optional feature described on this page.
Optional: plotting
using PlotsLoading this package enables plot(sol). Without it, plot(sol) raises an ExtensionError that asks for using Plots. See Plot.
Makie is supported too. Load CairoMakie for static figures or GLMakie for an interactive window, then call Makie.plot(sol). See Plot with Makie.
Optional: flows
Creating a Flow—for indirect shooting, simulation, or inspecting a Hamiltonian vector field—requires an ODE integrator:
using OrdinaryDiffEqTsit5Loading this package enables the creation of a Flow. Without it, Flow raises an ExtensionError that asks for using OrdinaryDiffEqTsit5.
Other integrators
Tsit5 is the default integrator. To use another method from the SciML ODE solvers, load its package and pass the algorithm when you build the flow, for example Flow(ocp, law; alg=Vern9()) after using OrdinaryDiffEqVerner. OrdinaryDiffEqTsit5 is then not needed; without it, a flow built without alg raises an error that shows how to pass one. The umbrella packages OrdinaryDiffEq and DifferentialEquations include Tsit5 and work too.
Optional: saving solutions
using JLD2 # format=:JLD (default)
using JSON3 # format=:JSONLoading either of these packages enables export_ocp_solution and import_ocp_solution in the matching format. Without it, these functions raise an ExtensionError that names the package to load. See Save & load.
Optional: GPU
Only NVIDIA GPUs are supported. Load these three packages together:
using MadNLPGPU
using CUDA
using CUDSSCUDSS is the one people forget: using MadNLPGPU does not load it, and the GPU solvers do not work without it. If one of the three is missing, the ExtensionError names it. One exception: when MadNLPGPU is the missing one, the error first asks for MadNLP, and names MadNLPGPU only once MadNLP is loaded (CTSolvers#234).
ExaModels, the GPU-capable modeler, needs no using: it comes with OptimalControl, so :exa works out of the box.
Before relying on a :gpu solve, check that CUDA.functional() returns true. See GPU for the details and for a complete example.
See also
Your first problem — model, solve and plot one, end to end.
Choosing a method — the full discretizer/modeler/solver/parameter picture.