Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/workflows/CI.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,8 @@ on:
jobs:
call:
uses: control-toolbox/CTActions/.github/workflows/ci.yml@main
with:
runs_on: '["ubuntu-latest","macos-latest"]'
use_ct_registry: true
secrets:
SSH_KEY: ${{ secrets.SSH_KEY }}
20 changes: 3 additions & 17 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,34 +1,27 @@
name = "CTModels"
uuid = "34c4fa32-2049-4079-8329-de33c2a22e2d"
version = "0.7.1-beta"
version = "0.8.0-beta"
authors = ["Olivier Cots <olivier.cots@toulouse-inp.fr>"]

[deps]
ADNLPModels = "54578032-b7ea-4c30-94aa-7cbd1cce6c9a"
CTBase = "54762871-cc72-4466-b8e8-f6c8b58076cd"
DocStringExtensions = "ffbed154-4ef7-542d-bbb7-c09d3a79fcae"
ExaModels = "1037b233-b668-4ce9-9b63-f9f681f55dd2"
Interpolations = "a98d9a8b-a2ab-59e6-89dd-64a1c18fca59"
KernelAbstractions = "63c18a36-062a-441e-b654-da1e3ab1ce7c"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
MLStyle = "d8e11817-5142-5d16-987a-aa16d5891078"
MacroTools = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
NLPModels = "a4795742-8479-5a88-8948-cc11e1c8c1a6"
OrderedCollections = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
SolverCore = "ff4d7338-4cf1-434d-91df-b86cb86fb843"

[weakdeps]
JLD2 = "033835bb-8acc-5ee8-8aae-3f567f8a3819"
JSON3 = "0f8b85d8-7281-11e9-16c2-39a750bddbf1"
MadNLP = "2621e9c9-9eb4-46b1-8089-e8c72242dfb6"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[extensions]
CTModelsJLD = "JLD2"
CTModelsJSON = "JSON3"
CTModelsMadNLP = "MadNLP"
CTModelsPlots = "Plots"

[extras]
Expand All @@ -41,32 +34,25 @@ test = [
"Aqua",
"JLD2",
"JSON3",
"MadNLP",
"Plots",
"Random",
"Test"
]

[compat]
ADNLPModels = "0.8"
Aqua = "0.8"
CTBase = "0.16, 0.17"
CTBase = "0.18"
DocStringExtensions = "0.9"
ExaModels = "0.9"
Interpolations = "0.16"
JLD2 = "0.6"
JSON3 = "1"
KernelAbstractions = "0.9"
LinearAlgebra = "1"
MadNLP = "0.8"
MLStyle = "0.4"
MacroTools = "0.5"
NLPModels = "0.21"
OrderedCollections = "1"
Parameters = "0.12"
Plots = "1"
Random = "1"
RecipesBase = "1"
SolverCore = "0.3"
Test = "1"
julia = "1.10"
julia = "1.10"
2 changes: 1 addition & 1 deletion docs/Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ MarkdownAST = "d0879d2d-cac2-40c8-9cee-1863dc0c7391"
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"

[compat]
CTBase = "0.17"
CTBase = "0.18"
Documenter = "1"
JLD2 = "0.6"
JSON3 = "1"
Expand Down
540 changes: 195 additions & 345 deletions docs/api_reference.jl

Large diffs are not rendered by default.

51 changes: 4 additions & 47 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
using Documenter
using CTModels
using CTBase # For automatic_reference_documentation
using CTBase
using Plots
using JSON3
using JLD2
Expand All @@ -20,12 +20,10 @@ const CTModelsJSON = Base.get_extension(CTModels, :CTModelsJSON)
const CTModelsJLD = Base.get_extension(CTModels, :CTModelsJLD)
const DocumenterReference = Base.get_extension(CTBase, :DocumenterReference)

# Reset DocumenterReference configuration for proper local/remote link generation
if !isnothing(DocumenterReference)
DocumenterReference.reset_config!()
end

# to add docstrings from external packages
Modules = [Plots, CTModelsPlots, CTModelsJSON, CTModelsJLD]
for Module in Modules
isnothing(DocMeta.getdocmeta(Module, :DocTestSetup)) &&
Expand All @@ -48,61 +46,20 @@ include("api_reference.jl")
with_api_reference(src_dir, ext_dir) do api_pages
makedocs(;
draft=draft,
remotes=nothing, # Disable remote links. Needed for DocumenterReference
warnonly=true,
remotes=nothing,
warnonly=[:cross_references],
sitename="CTModels.jl",
format=Documenter.HTML(;
repolink="https://" * repo_url,
prettyurls=false,
#size_threshold_ignore=["api.md", "dev.md"],
#size_threshold=300_000, # 300 KiB threshold
assets=[
asset("https://control-toolbox.org/assets/css/documentation.css"),
asset("https://control-toolbox.org/assets/js/documentation.js"),
],
),
checkdocs=:none,
pages=[
"Introduction" => "index.md",
"User Guide" => [
"Defining Problems" => "interfaces/optimization_problems.md",
"Building Solutions" => "interfaces/ocp_solution_builders.md",
],
"Developer Guide" => [
"Tutorials" => [
"Creating a Strategy" => "tutorials/creating_a_strategy.md",
"Creating a Strategy Family" => "tutorials/creating_a_strategy_family.md",
],
"Interfaces" => [
"Strategies" => "interfaces/strategies.md",
"Strategy Families" => "interfaces/strategy_families.md",
"Orchestration & Routing" => "interfaces/orchestration.md",
"Optimization Modelers" => "interfaces/optimization_modelers.md",
],
"Examples" => [
"Simple Strategy" => "examples/simple_strategy.md",
"Strategy with Options" => "examples/strategy_with_options.md",
"Strategy Family" => "examples/strategy_family.md",
"Option Routing" => "examples/routing_example.md",
"Integration Example" => "examples/integration_example.md",
"Migration Example" => "examples/migration_example.md",
],
],
"API Reference" => [
"Public API" => [
"Options" => "options/options_public.md",
"Strategies (Contract)" => "strategies/strategies_contract_public.md",
"Strategies (API)" => "strategies/strategies_api_public.md",
"Orchestration" => "orchestration/orchestration_public.md",
],
"Internal API" => [
"Options (Internal)" => "options/options_internal.md",
"Strategies Contract (Internal)" => "strategies/strategies_contract_internal.md",
"Strategies API (Internal)" => "strategies/strategies_api_internal.md",
"Orchestration (Internal)" => "orchestration/orchestration_internal.md",
],
"Core & OCP" => api_pages,
],
"API Reference" => api_pages,
],
)
end
Expand Down
148 changes: 57 additions & 91 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,14 @@ It provides the **mathematical model layer** for optimal control problems:

- **types and building blocks** for states, controls, variables, time grids, and constraints;
- an `AbstractModel`/`Model` and `AbstractSolution`/`Solution` hierarchy for optimal control problems;
- tools to build **initial guesses**, connect to **NLP backends**, and interpret their solutions;
- optional extensions for **exporting solutions** (JSON/JLD) and **plotting**.
- tools to build **initial guesses** for optimization;
- optional extensions for **exporting/importing solutions** (JSON/JLD) and **plotting**.

!!! info "CTModels vs CTSolvers"

**CTModels** focuses on **defining** optimal control problems and representing their solutions.
For **solving** these problems (discretization, NLP backends, optimization strategies),
see [CTSolvers.jl](https://github.com/control-toolbox/CTSolvers.jl).

!!! note

Expand Down Expand Up @@ -64,25 +70,11 @@ At a high level, CTModels is responsible for:
`AbstractSolution` / `Solution` store state, control, dual variables, and solver information.
- **Managing time grids and dimensions** through convenient type aliases.
- **Structuring constraints** (path, boundary, box constraints on state, control, and variables).
- **Connecting to NLP backends** (ADNLPModels, ExaModels, etc.) via modelers and builders.
- **Strategy architecture** (NEW):
- **Options**: Generic option handling with aliases and validation
- **Strategies**: Configurable components (modelers, solvers, discretizers)
- **Providing utilities** for initial guesses, export/import, and plotting of solutions.

Most of the public API is organized in a way that closely mirrors the mathematical
objects you manipulate when formulating an optimal control problem.

## Strategy Architecture

CTModels provides a modern, type-stable architecture for configurable components:

- **Options Module**: Low-level option extraction, validation, and alias resolution.
- **Strategies Module**: Strategy contract, metadata, registry, and builders.

This architecture replaces the legacy `AbstractOCPTool` interface with a cleaner,
more maintainable design. See the **Developer Guide → Interfaces → Strategies** section for details.

## Time grids and basic aliases

CTModels defines a few central type aliases that appear throughout the API:
Expand Down Expand Up @@ -121,37 +113,30 @@ These objects are the main bridge between the mathematical problem and the NLP b
## Initial guesses

Good initial guesses are crucial for challenging optimal control problems.
CTModels provides a small layer to organize them:
CTModels provides a layer to organize them:

- `pre_initial_guess` builds an `OptimalControlPreInit` object from raw user data
(functions, vectors, or constants for state, control, and variables).
- `initial_guess` turns this into an `OptimalControlInitialGuess`, checking consistency
with the chosen `AbstractOptimalControlProblem`.

The corresponding API is implemented in `src/init/initial_guess.jl` and is documented
in the *Initial Guess* section of the API reference.

## NLP backends and modelers

CTModels does **not** solve the NLP itself. Instead, it connects to external NLP
backends via modelers and builders defined in `src/nlp/`:
with the chosen `AbstractModel`.
- `build_initial_guess` constructs initial guess objects from various input formats.
- `validate_initial_guess` ensures consistency with the problem dimensions.

- `ADNLPModeler` (based on `ADNLPModels.jl`),
- `ExaModeler` (based on `ExaModels.jl`),
- additional builder types and helper functions.
The corresponding API is documented in the *InitialGuess* section of the API reference.

These modelers:
## Solving optimal control problems

- expose options through the generic `AbstractOCPTool` interface from CTBase
(see the *Interfaces → OCP Tools* page),
- build backend-specific NLP models from an `AbstractOptimizationProblem`,
- optionally map NLP solutions back to `CTModels.Solution` objects.
CTModels defines the **problem structure** but does **not** solve it.
For solving optimal control problems, use [CTSolvers.jl](https://github.com/control-toolbox/CTSolvers.jl),
which provides:

The *Interfaces* section of the documentation contains detailed guides for:
- **Discretization strategies** (direct collocation, multiple shooting, etc.)
- **NLP backends** (ADNLPModels, ExaModels, etc.)
- **Optimization modelers** to connect problems to solvers
- **Strategy architecture** for configurable components

- implementing new **optimization problems**,
- implementing new **optimization modelers**, and
- implementing new **OCP solution builders**.
CTModels provides the `AbstractModel` type alias `AbstractOptimalControlProblem`
for compatibility with CTSolvers.

## Extensions: JSON, JLD, and plotting

Expand Down Expand Up @@ -183,56 +168,37 @@ throw a descriptive `CTBase.ExtensionError`.

## How this documentation is organized

The documentation is split into two main parts:

- **Interfaces**
- *OCP Tools*: how to implement new configurable tools (backends, discretizers, solvers).
- *Optimization Problems*: how to define `AbstractOptimizationProblem` types.
- *Optimization Modelers*: how to map optimization problems to specific NLP backends.
- *Solution Builders*: how to turn NLP execution statistics into `CTModels.Solution` objects.

- **API Reference**
- *Types*: core types for models, solutions, and internal structures.
- *Model / Times / Dynamics / Objective / Constraints*: detailed API for building OCP models.
- *Solution & Dual*: how solutions and dual variables are represented.
- *Initial Guess*: utilities to build and validate initial guesses.
- *NLP Backends*: ADNLPModels/ExaModels-based backends and related options.
- *Extensions*: Plot, JSON, and JLD extensions.

You can start by reading the **Interfaces** pages to understand the high-level
design, then use the **API Reference** to look up the details of particular
functions and types.

## I am X, I want to do Y → read…

### User Guide

- **I want to formulate a new optimal control / optimization problem**
Read **User Guide → Optimization Problems**, then **API Reference → Model / Times / Dynamics / Objective / Constraints**
for details about fields and conventions.
- **I want to build good initial guesses for my problems**
Read **User Guide → Solution Builders** for the overall philosophy, then **API Reference → Initial Guess**
for the `pre_initial_guess` and `initial_guess` functions.
- **I want to save / reload solutions (for example for numerical experiments)**
Read **API Reference → Extensions (JSON & JLD)** and the pages associated with the `CTModelsJSON` and `CTModelsJLD` modules.
- **I want to plot solution trajectories nicely**
Read **API Reference → Extensions (Plot Extension)**, and look at the examples using `Plots.plot(sol)` and `Plots.plot!(sol)`.
- **I use OptimalControl.jl and I just want to understand what CTModels does in the background**
Read this introduction page, then skim through the **User Guide** section to see how
problems, modelers, and builders fit together.

### Developer Guide

- **I want to create a new strategy (modeler, solver, discretizer)**
Read **Developer Guide → Tutorials → Creating a Strategy**, then **Developer Guide → Interfaces → Strategies**
for the complete contract specification.
- **I want to create a family of related strategies**
Read **Developer Guide → Tutorials → Creating a Strategy Family**, then **Developer Guide → Interfaces → Strategy Families**
for registry integration and best practices.
- **I want to migrate from AbstractOCPTool to AbstractStrategy**
Read **Developer Guide → Interfaces → Strategies → Migration Guide** for step-by-step instructions.
- **I want to connect a new NLP backend or tweak an existing backend**
Read **Developer Guide → Interfaces → Optimization Modelers** (updated) and the **API Reference → NLP Backends** section.
- **I want to contribute to the core of CTModels (types, constraints, dual variables, etc.)**
Start with **API Reference → Types**, then **Solution & Dual** and **Constraints** to understand the internal structures
before modifying or adding new fields.
The documentation consists of:

- **Introduction** (this page): Overview of CTModels and its role in the control-toolbox ecosystem.

- **API Reference**: Complete documentation of all modules and functions:
- *CTModels*: Main module and exports
- *Utils*: Utilities (interpolation, macros, matrix operations)
- *OCP*: Optimal Control Problem types, components, building, and validation
- *Display*: Text display and printing
- *Serialization*: Export/import functionality
- *InitialGuess*: Initial guess management
- *Extensions*: Plots, JSON, and JLD2 extensions

Use the **API Reference** to look up the details of particular functions and types.

## Quick start guide

- **I want to define an optimal control problem**
See **API Reference → OCP Components** for `state!`, `control!`, `dynamics!`, `objective!`, `constraint!`, etc.

- **I want to build initial guesses**
See **API Reference → InitialGuess** for `pre_initial_guess`, `initial_guess`, and `build_initial_guess`.

- **I want to save/load solutions**
See **API Reference → Serialization** and the JSON/JLD2 extension pages for `export_ocp_solution` and `import_ocp_solution`.

- **I want to plot solution trajectories**
See **API Reference → Plots Extension** for `plot(sol)` and `plot!(sol)` with `Plots.jl`.

- **I want to solve an optimal control problem**
Use [CTSolvers.jl](https://github.com/control-toolbox/CTSolvers.jl) which provides discretization, NLP backends, and optimization strategies.

- **I use OptimalControl.jl**
CTModels provides the underlying types and building blocks. OptimalControl.jl offers a higher-level interface.
3 changes: 3 additions & 0 deletions ext/CTModelsPlots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ using MLStyle: MLStyle

#
using CTBase
using CTBase: Exceptions
using CTModels
using LinearAlgebra
using Plots # redefine plot, plot!
Expand All @@ -16,4 +17,6 @@ include("plot_utils.jl")
include("plot_default.jl")
include("plot.jl")

export plot, plot!

end
Loading
Loading