Skip to content

Latest commit

 

History

History
119 lines (78 loc) · 19 KB

File metadata and controls

119 lines (78 loc) · 19 KB
title OptimalControl.jl: A Julia package for modeling and solving optimal control problems with ODEs
tags
Julia
optimal control
ordinary differential equations
direct methods
indirect methods
scientific computing
mathematical optimization
authors
name orcid affiliation
Jean-Baptiste Caillau
0000-0002-1719-2016
1
name orcid affiliation corresponding
Olivier Cots
0000-0002-4703-4369
2
true
name orcid affiliation
Joseph Gergaud
0009-0005-9825-8652
2
name orcid affiliation
Pierre Martinon
0000-0003-0571-2376
3
name affiliation
Sophia Sed
4
affiliations
name index
Université Côte d'Azur, CNRS, Inria, LJAD, France
1
name index
Université Toulouse, CNRS, ENSEEIHT-IRIT, France
2
name index
CAGE team, Inria Paris, France
3
name index
Inria Sophia Antipolis Méditerranée, France
4
date 12 April 2026
bibliography paper.bib
archive_doi 10.5281/zenodo.13336563

Summary

OptimalControl.jl [@OptimalControl_jl] is a Julia [@Bezanson2017] package for modeling and solving optimal control problems governed by ordinary differential equations (ODEs). As the core of the control-toolbox ecosystem, it provides a unified framework that supports both direct and indirect solution methods with applications spanning aerospace, medical imaging, epidemiology, and quantum control.

The package features an expressive domain-specific language (DSL) built around the @def macro, enabling users to define control problems using notation that closely resembles standard mathematical formulations. Problems are solved through direct transcription, converting the continuous problem into a nonlinear program (NLP) using discretization schemes including Euler, trapezoidal, midpoint, and high-order Gauss-Legendre collocation. Alternatively, indirect shooting methods based on Pontryagin's Maximum Principle can be employed. The architecture relies on a modeler-solver separation that provides a modular and extensible foundation, enabling GPU execution (currently limited to NVIDIA hardware) with minimal user intervention alongside standard CPU solvers.

The ecosystem includes extensive tutorial resources, a benchmark problem collection (OptimalControlProblems.jl [@OptimalControlProblems_jl] with formulations in OptimalControl DSL and JuMP [@Lubin2023]), and performance comparison tools (CTBenchmarks.jl). Integration with Julia's ecosystem enables access to state-of-the-art tools: NLP solvers IPOPT [@Wachter2006] and MadNLP.jl [@SHIN2024110651; @SHIN2021693], automatic differentiation and NLP modeling through JuliaSmoothOptimizers' ADNLPModels [@ADNLPModels_jl], GPU acceleration via ExaModels.jl [@shin2023accelerating], numerical integration from SciML's DifferentialEquations.jl [@rackauckas2017differentialequations], and visualization through Plots.jl [@PlotsJL].

Statement of Need

OptimalControl.jl is, to our knowledge, the only Julia package that unifies both direct and indirect methods for optimal control within a single, coherent framework.

This unified approach addresses a gap in the current optimal control software landscape. Existing tools are fragmented across programming languages and paradigms. Legacy packages such as HamPath [@caillau2012differential], NutoPy [@CAILLAU202213], and COTCOT [@bonnard2007second] implement sophisticated indirect methods but rely on Fortran implementations with MATLAB or Python interfaces, leading to complex and less extensible workflows. Proprietary solvers like GPOPS-II [@Patterson2014] limit transparency and reproducibility. Open-source tools such as BOCOP [@Bonnans2017], ACADO [@Houska2011], and acados [@Verschueren2021] provide valuable direct method implementations but are not natively integrated into a modern, high-level scientific computing ecosystem. Python-based tools such as Dymos [@Falck2021], Pyomo.DAE [@Nicholson2018], do-mpc [@Fiedler2023], and GEKKO [@Beal2018] offer complementary capabilities but are similarly limited to direct transcription approaches within the Python ecosystem.

Within Julia, most existing packages target specific domains: RobustAndOptimalControl.jl for linear systems, QuantumControl.jl and Piccolo.jl for quantum optimal control, DirectTrajectoryOptimization.jl for trajectory problems, LinearMPC.jl [@arnstrom2022daqp] and ModelPredictiveControl.jl [@Gagnon_ModelPredictiveControl_jl_advanced_process_2024] for model predictive control, and InfiniteOpt.jl [@pulsipher2022unifying] for infinite-dimensional optimization. In contrast with InfiniteOpt.jl that is designed as an extension of JuMP.jl, our package provides a modeler-agnostic approach, accepting general Julia code and leveraging various optimization solvers. Besides, contributing to general-purpose NLP modeling frameworks like JuMP or CasADi [@Andersson2019] would not address the specific needs of optimal control: these tools lack native support for shooting methods based on Pontryagin's Maximum Principle and that heavily rely on differential geometric primitives.

OptimalControl.jl fills this gap by providing a DSL that matches mathematical notation, multiple discretization schemes and shooting methods, with planned support for homotopy continuation methods. The modeler-solver separation enables complementary use with InfiniteOpt.jl (JuMP-based) through alternative NLP modeling backends (currently ADNLPModels, ExaModels) and solvers. GPU acceleration and an ecosystem with domain-specific applications, tutorials, and benchmarking tools complete the offering. Target users include researchers and engineers working in optimal control, control theorists developing new algorithms, and students learning optimal control through interactive tutorials.

State of the Field

OptimalControl.jl requires Julia version 1.10 or later and is registered in the Julia General registry, enabling straightforward installation via Pkg.add("OptimalControl"). We compare it below with existing software.

  • Legacy tools (COTCOT, HamPath, NutoPy): These Fortran packages excel at indirect methods and homotopy continuation but require multi-language setup (Fortran plus MATLAB / Python). OptimalControl.jl provides both direct and indirect methods in pure Julia with straightforward installation via package manager.

  • Direct method tools (BOCOP, ACADO, GPOPS-II, acados, nosnoc): Strong direct method implementations: GPOPS-II [@Patterson2014] delivers mature methods with MATLAB and C++ implementations but is proprietary; acados [@Verschueren2021] targets real-time MPC on embedded systems; nosnoc [@Nurkanovic2022] specializes in nonsmooth optimal control; CasADi [@Andersson2019], used as symbolic backend by several of these tools, is a general NLP modeler rather than an optimal control solver. OptimalControl.jl offers an open-source alternative with expressive DSL, native Julia ecosystem integration, GPU support, and unified direct and indirect approaches.

  • Julia packages: RobustAndOptimalControl.jl targets linear systems; QuantumControl.jl, Piccolo.jl and DirectTrajectoryOptimization.jl serve specific domains; LinearMPC.jl [@arnstrom2022daqp] and ModelPredictiveControl.jl [@Gagnon_ModelPredictiveControl_jl_advanced_process_2024] focus on model predictive control. InfiniteOpt.jl addresses a very rich range of problems, including optimization on PDE's or with chance constraints, focusing on direct transcription methods. OptimalControl.jl supports both CPU and GPU execution (currently NVIDIA-only, via ExaModels.jl + MadNLP.jl), and adds tools to do shooting in a unified framework plus systematic benchmarking through OptimalControlProblems.jl and CTBenchmarks.jl.

Illustrative Example

A self-contained illustrative example is provided as a companion repository [@joss_oc_example], archived on Zenodo. It combines direct and indirect solution approaches for a constrained energy minimization problem: a direct method on a coarse grid identifies the three-arc structure (unconstrained–constrained–unconstrained) and initializes a shooting method based on Pontryagin's Maximum Principle, which then converges to arbitrary precision.

Software Design

The package architecture balances expressiveness, performance, and extensibility through modular design. The core is organized across internal packages within the control-toolbox organization, each hosted as an independent Julia package and registered in the General registry: CTBase.jl defines the core types (optimal control models, solutions, initial guesses) and their accessors; CTParser.jl implements the @def DSL macro; CTDirect.jl handles direct transcription and NLP interfacing; and CTFlows.jl provides Hamiltonian flows and shooting for indirect methods. OptimalControl.jl re-exports these packages as a unified entry point. Contributors interested in a specific functionality can work directly on the relevant sub-package, each of which has its own documentation, tests, and continuous integration. The delegation of specific responsibilities is as follows:

  • DSL parsing: MLStyle.jl [@MLStyle_jl] enables pattern matching on abstract syntax trees generated from @def macro invocations. This design choice separates problem specification from solution methods, and allows a syntax as close as possible to the mathematical description of the problem.

  • Problem models and solutions: Structured types represent optimal control models, solutions, and initial guesses. Each type provides textual visualization, accessor methods for introspection, and visual plotting capabilities for solutions. Extensible abstractions enable addition of new problem classes without modifying core code.

  • Discretization: Direct transcription converts continuous problems into NLPs. Supporting multiple discretization schemes (Euler, midpoint, trapezoidal, Gauss-Legendre) required careful abstraction to share transcription logic while allowing scheme-specific implementations.

  • Modelers and solvers: We chose a clear modeler-solver separation: discretization produces ADNLPModels (able to deal with arbitrary user defined functions) or ExaModels [@shin2023accelerating] instances compatible with multiple NLP solvers (IPOPT via NLPModelsIpopt.jl [@Orban_NLPModelsIpopt_jl], Knitro [@Byrd2006], MadNLP, and Uno [@VanaretLeyffer2026]). These NLP solvers rely on linear solvers such as MUMPS.jl [@Montoison_MUMPS_jl; @MUMPS:1; @MUMPS:2] for CPU computations or CUDSS.jl [@CUDSS_nvidia] for GPU acceleration with MadNLP. Automatic differentiation via ForwardDiff.jl [@RevelsLubinPapamarkou2016] and DifferentiationInterface.jl [@dalle2026commoninterfaceautomaticdifferentiation] avoids manual derivative coding.

  • Indirect methods: Hamiltonian flows integrate with DifferentialEquations.jl to access adaptive stepping, event handling, and multiple ODE solvers without reimplementation. Shooting methods rely on NonlinearSolve.jl [@pal2024nonlinearsolve] or MINPACK.jl for root-finding. Future extensions will incorporate homotopy continuation methods leveraging bifurcation analysis tools like BifurcationKit.jl [@veltz:hal-02902346].

  • Testing and quality assurance: The multi-repository structure is matched by a layered testing strategy. Each sub-package is tested independently, combining unit tests, integration tests, and code-quality checks, while OptimalControl.jl adds strong end-to-end integration tests that solve complete optimal control problems by both direct and indirect methods. Continuous integration runs across Linux, macOS, and Windows, on both CPU and GPU (through a self-hosted CUDA runner), using reusable GitHub Actions workflows centralized in CTActions and shared across the ecosystem. Code coverage is tracked on Codecov, downstream packages and applications are guarded against regressions through dedicated breakage tests triggered on pull requests, and beta versions are distributed during development via a local registry, ct-registry. Non-regression on complex problems is increasingly driven by OptimalControlProblems.jl, used as a curated problem bank.

Key design trade-offs:

  1. DSL vs. programmatic API: We prioritized a mathematical DSL to reduce cognitive load for domain experts, accepting increased parsing complexity handled internally. Currently we do not address optimization of PDE or stochastic systems.

  2. GPU acceleration strategy: The modeler-solver separation enables a straightforward CPU-to-GPU transition. Users select the ExaModels modeler with MadNLP and the CUDSS linear solver for GPU execution, or simply append the :gpu token to the solve call. This modular approach minimizes maintenance burden while enabling GPU performance without reimplementing transcription logic. GPU support is currently limited to NVIDIA hardware and to the ExaModels + MadNLP modeler-solver combination.

  3. Method coverage: Supporting both direct and indirect approaches increases code complexity but serves distinct user needs: direct methods for constrained problems with many variables, indirect methods for theoretical analysis and smaller problems requiring high accuracy. Both approaches resort to iterative solvers and may converge or not, e.g. depending on the initial guess. In the case of optimization solvers, the full output status of the solver is returned allowing a posteriori analysis.

Research Impact Statement

OptimalControl.jl has been applied in published research across multiple domains. Independent external adoption demonstrates the package's broader impact: @ferede2025icra used it for drone racing trajectory optimization, @caio2025application for epidemiological models using indirect methods, @morsky2025vaccination for vaccination strategies under social norms, @opmeer2025optimal for optimal harvesting of age-structured populations, and @evangelakos2025fast for fast charging protocols for quantum batteries.

Research by close collaborators further demonstrates the package's versatility across aerospace (@herasimenka2026lowthrust), epidemiology (@bliman:hal-05194927), quantum control (@beschastnyi2025pulse), microbial growth control (@innerarityimizcoz:hal-05369609), and theoretical optimal control (@bouali:hal-04928858; @lutz:hal-05047678; @bayen2026minimum; @bonnard2026zermelo).

The control-toolbox organization hosts domain-specific application packages built on OptimalControl.jl: medical imaging optimization (MagneticResonanceImaging.jl), gene regulatory networks (PWLdynamics.jl), spacecraft orbital transfers (Kepler.jl), epidemiological modeling (SIRcontrol.jl), and variational calculus (CalculusOfVariations.jl).

The package serves educational purposes through Tutorials.jl covering topics from linear-quadratic regulators to Model Predictive Control. These resources are used in academic courses and workshops; the package was notably presented at JuliaCon 2023 [@caillau2023juliacon]. OptimalControlProblems.jl provides standardized test problems formulated in both OptimalControl DSL and JuMP, enabling systematic performance comparisons through CTBenchmarks.jl.

Development involves international collaborations with CNES (French space agency), Thales Alenia Space, Inria, and CNRS. The package development began in September 2022, with the first public release in February 2023. As of March 2026, OptimalControl.jl has published more than 40 releases with contributions from multiple developers across the control-toolbox ecosystem packages, demonstrating sustained community engagement.

AI Usage Disclosure

The core software implementation, algorithms, and architectural design of OptimalControl.jl were developed by the authors. Generative AI tools—specifically Claude Sonnet (version 4.6) and Claude Opus (version 4.8) by Anthropic—have been used to assist with code refactoring and generation of unit and integration tests, always under human review. This paper was drafted by the authors and subsequently revised with AI assistance for restructuring according to JOSS format requirements and language editing. All technical content, examples, and claims reflect the authors' work and judgment.

Acknowledgements

We thank the control-toolbox community and the broader Julia ecosystem for contributions that shaped the package design and educational resources. Development has been supported by partnerships with CNES, Thales Alenia Space, Inria, and CNRS. The software is distributed under the MIT license (see LICENSE). We welcome community contributions following the guidelines in CONTRIBUTING.md.

References