|
| 1 | +# Breaking Changes: v1.x → v2.0 |
| 2 | + |
| 3 | +This document describes the breaking changes when migrating from **OptimalControl.jl v1.1.6** (last stable release) to **v2.0.0**. |
| 4 | + |
| 5 | +## Overview |
| 6 | + |
| 7 | +Version 2.0.0 represents a major architectural redesign of OptimalControl.jl, introducing: |
| 8 | + |
| 9 | +- **Complete solve architecture redesign** with descriptive and explicit modes |
| 10 | +- **GPU/CPU parameter system** for heterogeneous computing |
| 11 | +- **Advanced option routing** with introspection and disambiguation tools |
| 12 | +- **New solver integrations** (Uno, MadNCL) |
| 13 | +- **Control-free problems** support |
| 14 | +- **Modernized reexport system** using `@reexport import` |
| 15 | + |
| 16 | +## Removed Functions |
| 17 | + |
| 18 | +The following functions from v1.1.6 have been removed and replaced: |
| 19 | + |
| 20 | +### CTDirect Functions |
| 21 | + |
| 22 | +| v1.1.6 Function | v2.0.0 Replacement | Notes | |
| 23 | +| ---------------------- | ------------------ | ------------------------------------------------------ | |
| 24 | +| `direct_transcription` | `discretize` | New function from CTDirect.jl | |
| 25 | +| `set_initial_guess` | `@init` macro | Use the `@init` macro for initial guess construction | |
| 26 | +| `build_OCP_solution` | `ocp_solution` | New function from CTSolvers.jl | |
| 27 | + |
| 28 | +**Migration example:** |
| 29 | + |
| 30 | +```julia |
| 31 | +# v1.1.6 |
| 32 | +docp = direct_transcription(ocp, grid_size=100) |
| 33 | +set_initial_guess(docp, x_init, u_init) |
| 34 | +sol = build_OCP_solution(docp, nlp_sol) |
| 35 | + |
| 36 | +# v2.0.0 |
| 37 | +docp = discretize(ocp, Collocation(); grid_size=100) |
| 38 | +init = @init ocp begin |
| 39 | + x = x_init |
| 40 | + u = u_init |
| 41 | +end |
| 42 | +sol = ocp_solution(docp, nlp_sol) |
| 43 | +``` |
| 44 | + |
| 45 | +## Changed Exports |
| 46 | + |
| 47 | +### CTBase Exceptions |
| 48 | + |
| 49 | +**Removed exports:** |
| 50 | + |
| 51 | +- `IncorrectMethod` |
| 52 | +- `IncorrectOutput` |
| 53 | +- `UnauthorizedCall` |
| 54 | + |
| 55 | +**Added exports:** |
| 56 | + |
| 57 | +- `PreconditionError` |
| 58 | + |
| 59 | +These exceptions are still available via `CTBase.IncorrectMethod`, etc., but are no longer re-exported by OptimalControl.jl. |
| 60 | + |
| 61 | +### CTFlows Types |
| 62 | + |
| 63 | +The following types are **no longer exported** (but still available via qualified access): |
| 64 | + |
| 65 | +- `VectorField` → use `OptimalControl.VectorField` or `CTFlows.VectorField` |
| 66 | +- `Hamiltonian` → use `OptimalControl.Hamiltonian` or `CTFlows.Hamiltonian` |
| 67 | +- `HamiltonianLift` → use `OptimalControl.HamiltonianLift` or `CTFlows.HamiltonianLift` |
| 68 | +- `HamiltonianVectorField` → use `OptimalControl.HamiltonianVectorField` or `CTFlows.HamiltonianVectorField` |
| 69 | + |
| 70 | +**Migration example:** |
| 71 | + |
| 72 | +```julia |
| 73 | +# v1.1.6 |
| 74 | +X = VectorField(f) |
| 75 | + |
| 76 | +# v2.0.0 |
| 77 | +X = OptimalControl.VectorField(f) |
| 78 | +# or |
| 79 | +using CTFlows: VectorField |
| 80 | +X = VectorField(f) |
| 81 | +``` |
| 82 | + |
| 83 | +## New Solve Architecture |
| 84 | + |
| 85 | +The `solve` function has been completely redesigned with two modes: |
| 86 | + |
| 87 | +### Descriptive Mode (Symbolic) |
| 88 | + |
| 89 | +```julia |
| 90 | +# Specify strategies using symbols |
| 91 | +sol = solve(ocp, :collocation, :adnlp, :ipopt, :cpu) |
| 92 | + |
| 93 | +# Partial specification (auto-completed) |
| 94 | +sol = solve(ocp, :ipopt) # Uses first matching method |
| 95 | +sol = solve(ocp, :gpu) # Uses first GPU method |
| 96 | +``` |
| 97 | + |
| 98 | +### Explicit Mode (Typed Components) |
| 99 | + |
| 100 | +```julia |
| 101 | +# Specify strategies using typed components |
| 102 | +sol = solve(ocp; |
| 103 | + discretizer=Collocation(), |
| 104 | + modeler=ADNLP(), |
| 105 | + solver=Ipopt() |
| 106 | +) |
| 107 | +``` |
| 108 | + |
| 109 | +### Methods System |
| 110 | + |
| 111 | +The `methods()` function now returns **4-tuples** instead of 3-tuples: |
| 112 | + |
| 113 | +```julia |
| 114 | +# v1.1.6 |
| 115 | +methods() # Returns (discretizer, modeler, solver) |
| 116 | + |
| 117 | +# v2.0.0 |
| 118 | +methods() # Returns (discretizer, modeler, solver, parameter) |
| 119 | +# Example: (:collocation, :adnlp, :ipopt, :cpu) |
| 120 | +``` |
| 121 | + |
| 122 | +The 4th element is the **parameter** (`:cpu` or `:gpu`) for execution backend. |
| 123 | + |
| 124 | +## Option Routing System |
| 125 | + |
| 126 | +v2.0.0 introduces automatic option routing with new introspection tools: |
| 127 | + |
| 128 | +### New Functions |
| 129 | + |
| 130 | +- `describe(strategy)` — Display available options for a strategy |
| 131 | +- `route_to(strategy=value)` — Disambiguate shared options |
| 132 | +- `bypass(option=value)` — Pass undeclared options to strategies |
| 133 | + |
| 134 | +**Example:** |
| 135 | + |
| 136 | +```julia |
| 137 | +# Inspect available options |
| 138 | +describe(:ipopt) |
| 139 | +describe(:collocation) |
| 140 | + |
| 141 | +# Disambiguate shared options |
| 142 | +sol = solve(ocp, :ipopt; |
| 143 | + max_iter=100, # Shared option (auto-routed) |
| 144 | + route_to(solver=:print_level=>0) # Explicitly route to solver |
| 145 | +) |
| 146 | + |
| 147 | +# Pass undeclared options |
| 148 | +sol = solve(ocp, :ipopt; |
| 149 | + bypass(solver=:custom_option=>42) |
| 150 | +) |
| 151 | +``` |
| 152 | + |
| 153 | +## Initial Guess with @init Macro |
| 154 | + |
| 155 | +v2.0.0 introduces the `@init` macro for constructing initial guesses: |
| 156 | + |
| 157 | +```julia |
| 158 | +# v2.0.0 |
| 159 | +init = @init ocp begin |
| 160 | + u = 0.5 |
| 161 | + x = [1.0, 2.0] |
| 162 | +end |
| 163 | + |
| 164 | +sol = solve(ocp; initial_guess=init) |
| 165 | +# or using alias |
| 166 | +sol = solve(ocp; init=init) |
| 167 | +``` |
| 168 | + |
| 169 | +The old functional approach is no longer supported. |
| 170 | + |
| 171 | +## New Features (Non-Breaking) |
| 172 | + |
| 173 | +These features are new in v2.0.0 but don't break existing code: |
| 174 | + |
| 175 | +### Control-Free Problems |
| 176 | + |
| 177 | +Support for optimal control problems without control variables: |
| 178 | + |
| 179 | +```julia |
| 180 | +ocp = @def begin |
| 181 | + tf ∈ R, variable |
| 182 | + t ∈ [0, tf], time |
| 183 | + x ∈ R², state |
| 184 | + ẋ(t) == f(x(t)) # No control |
| 185 | + ∫(L(x(t))) → min |
| 186 | +end |
| 187 | +``` |
| 188 | + |
| 189 | +### New Solvers |
| 190 | + |
| 191 | +- **Uno**: CPU-only nonlinear optimization solver |
| 192 | +- **MadNCL**: GPU-capable solver |
| 193 | + |
| 194 | +Total of 5 solvers: Ipopt, MadNLP, Uno, MadNCL, Knitro |
| 195 | + |
| 196 | +### Additional Discretization Schemes |
| 197 | + |
| 198 | +**Basic schemes:** |
| 199 | + |
| 200 | +- `:trapeze` — Trapezoidal rule |
| 201 | +- `:midpoint` — Midpoint rule |
| 202 | +- `:euler` / `:euler_explicit` / `:euler_forward` — Explicit Euler |
| 203 | +- `:euler_implicit` / `:euler_backward` — Implicit Euler |
| 204 | + |
| 205 | +**ADNLP-only schemes:** |
| 206 | + |
| 207 | +- `:gauss_legendre_2` — 2-point Gauss-Legendre collocation |
| 208 | +- `:gauss_legendre_3` — 3-point Gauss-Legendre collocation |
| 209 | + |
| 210 | +### GPU Support |
| 211 | + |
| 212 | +Explicit GPU/CPU selection via parameter: |
| 213 | + |
| 214 | +```julia |
| 215 | +# CPU execution (default) |
| 216 | +sol = solve(ocp, :collocation, :adnlp, :ipopt, :cpu) |
| 217 | + |
| 218 | +# GPU execution (requires ExaModels + MadNLP/MadNCL) |
| 219 | +using CUDA, MadNLPGPU |
| 220 | +sol = solve(ocp, :collocation, :exa, :madnlp, :gpu) |
| 221 | +``` |
| 222 | + |
| 223 | +## Dependency Updates |
| 224 | + |
| 225 | +v2.0.0 requires updated versions of CTX packages: |
| 226 | + |
| 227 | +| Package | v1.1.6 | v2.0.0 | |
| 228 | +| --------- | --------- | ------ | |
| 229 | +| CTBase | 0.16-0.17 | 0.18 | |
| 230 | +| CTModels | 0.6 | 0.9 | |
| 231 | +| CTDirect | 0.x | 1.0 | |
| 232 | +| CTSolvers | N/A | 0.4 | |
| 233 | +| CTParser | 0.7-0.8 | 0.8 | |
| 234 | + |
| 235 | +**New dependency:** CTSolvers.jl (handles NLP modeling and solving) |
| 236 | + |
| 237 | +## Summary |
| 238 | + |
| 239 | +The main breaking changes are: |
| 240 | + |
| 241 | +1. **Removed functions**: `direct_transcription`, `set_initial_guess`, `build_OCP_solution` |
| 242 | +2. **Changed exports**: Some CTBase exceptions and CTFlows types no longer exported |
| 243 | +3. **New solve architecture**: Descriptive/explicit modes with 4-tuple methods |
| 244 | +4. **Initial guess**: Use `@init` macro instead of functional approach |
| 245 | + |
| 246 | +For detailed usage examples, see the [documentation](https://control-toolbox.org/OptimalControl.jl/stable/). |
0 commit comments