|
2 | 2 |
|
3 | 3 | The `CTParser.jl` package is part of the [control-toolbox ecosystem](https://github.com/control-toolbox). |
4 | 4 |
|
5 | | -The root package is [OptimalControl.jl](https://github.com/control-toolbox/OptimalControl.jl) which 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. |
| 5 | +!!! note |
| 6 | + |
| 7 | + The root package is [OptimalControl.jl](https://github.com/control-toolbox/OptimalControl.jl) which aims |
| 8 | + to provide tools to model and solve optimal control problems with ordinary differential equations |
| 9 | + by direct and indirect methods, both on CPU and GPU. |
| 10 | + |
| 11 | +!!! warning |
| 12 | + |
| 13 | + In some examples in the documentation, private methods are shown without the module prefix. |
| 14 | + This is done for the sake of clarity and readability. |
| 15 | + |
| 16 | + ```julia-repl |
| 17 | + julia> using CTParser |
| 18 | + julia> x = 1 |
| 19 | + julia> private_fun(x) # throws an error |
| 20 | + ``` |
| 21 | + |
| 22 | + This should instead be written as: |
| 23 | + |
| 24 | + ```julia-repl |
| 25 | + julia> using CTParser |
| 26 | + julia> x = 1 |
| 27 | + julia> CTParser.private_fun(x) |
| 28 | + ``` |
| 29 | + |
| 30 | + If the method is re-exported by another package, |
| 31 | + |
| 32 | + ```julia |
| 33 | + module OptimalControl |
| 34 | + import CTParser: private_fun |
| 35 | + export private_fun |
| 36 | + end |
| 37 | + ``` |
| 38 | + |
| 39 | + then there is no need to prefix it with the original module name: |
| 40 | + |
| 41 | + ```julia-repl |
| 42 | + julia> using OptimalControl |
| 43 | + julia> x = 1 |
| 44 | + julia> private_fun(x) |
| 45 | + ``` |
| 46 | + |
| 47 | +## What CTParser provides |
| 48 | + |
| 49 | +At a high level, `CTParser.jl` is responsible for turning a compact, |
| 50 | +mathematical DSL into executable Julia code for the rest of the |
| 51 | +ecosystem (in particular `CTModels.jl` and `ExaModels.jl`). It does not |
| 52 | +solve optimal control problems by itself; instead, it focuses on |
| 53 | +parsing and code generation. |
| 54 | + |
| 55 | +The two main entry points are: |
| 56 | + |
| 57 | +- **`@def` macro** – define an optimal control problem from a |
| 58 | + human-readable specification. |
| 59 | +- **`@init` macro** – define an initial guess for state, control and |
| 60 | + variables using a small initialisation DSL. |
| 61 | + |
| 62 | +### The `@def` macro and its backends |
| 63 | + |
| 64 | +The macro |
| 65 | + |
| 66 | +```julia |
| 67 | +ocp = @def begin |
| 68 | + # symbolic definition of an OCP |
| 69 | +end |
| 70 | +``` |
| 71 | + |
| 72 | +parses the block and builds an intermediate representation of the |
| 73 | +optimal control problem. Internally, `@def` can target different |
| 74 | +*backends*: |
| 75 | + |
| 76 | +- the **functional backend** `:fun` (default), where the OCP is |
| 77 | + represented by a `CTModels.Model` and evaluated through Julia |
| 78 | + functions; |
| 79 | +- the **ExaModels backend** `:exa`, where the same symbolic description |
| 80 | + is lowered to an `ExaModels.ExaModel` suitable for large-scale NLP |
| 81 | + solvers. |
| 82 | + |
| 83 | +The active backends and their prefixes are controlled by |
| 84 | +`prefix_fun()`, `prefix_exa()` and the corresponding setters. This |
| 85 | +allows other packages (such as `OptimalControl.jl`) to plug in custom |
| 86 | +model types while reusing the same parsing layer. |
| 87 | + |
| 88 | +### The `@init` macro for initial guesses |
| 89 | + |
| 90 | +The macro |
| 91 | + |
| 92 | +```julia |
| 93 | +ig = @init ocp begin |
| 94 | + # initialisation DSL |
| 95 | +end |
| 96 | +``` |
| 97 | + |
| 98 | +provides a compact way of building initial guesses for an OCP. The |
| 99 | +block can mix: |
| 100 | + |
| 101 | +- **time-dependent functions**, e.g. `u(t) := t` or `x(t) := [sin(t), 1]`; |
| 102 | +- **time grids**, e.g. `x(T) := X` where `T` is a vector of times and |
| 103 | + `X` samples along the trajectory; |
| 104 | +- **constants and aliases**, e.g. `a = 1.0; v(t) := a` or `tf := 1.0`. |
| 105 | + |
| 106 | +`@init` itself only rewrites this DSL into a `NamedTuple` of symbolic |
| 107 | +specifications. The actual construction and validation of a |
| 108 | +backend-specific initial guess object is delegated to the module |
| 109 | +selected by `init_prefix()` (by défaut `CTModels`), via |
| 110 | +`build_initial_guess` et `validate_initial_guess`. |
0 commit comments