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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
*.jld2
*.json
!.zenodo.json
!.markdownlint.json

# System-specific files and directories generated by the BinaryProvider and BinDeps packages
# They contain absolute paths specific to the host computer, and so should not be committed
Expand Down
4 changes: 4 additions & 0 deletions .markdownlint.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"MD046": false,
"MD013": false
}
3 changes: 1 addition & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -129,8 +129,6 @@ Draft = false
=#
makedocs(;
draft=false,
#draft=true,
#warnonly=[:cross_references, :autodocs_block],
sitename="OptimalControl.jl",
format=Documenter.HTML(;
repolink="https://" * repo_url,
Expand All @@ -141,6 +139,7 @@ makedocs(;
assets=[
asset("https://control-toolbox.org/assets/css/documentation.css"),
asset("https://control-toolbox.org/assets/js/documentation.js"),
"assets/custom.css",
],
),
pages=[
Expand Down
2 changes: 1 addition & 1 deletion docs/src/assets/Manifest.toml
Original file line number Diff line number Diff line change
Expand Up @@ -1677,7 +1677,7 @@ version = "0.5.6+0"
deps = ["ADNLPModels", "CTBase", "CTDirect", "CTFlows", "CTModels", "CTParser", "CommonSolve", "DocStringExtensions", "ExaModels"]
path = "/Users/ocots/Research/logiciels/dev/control-toolbox/OptimalControl"
uuid = "5f98b655-cc9a-415a-b60e-744165666948"
version = "1.1.2"
version = "1.1.3"

[[deps.Opus_jll]]
deps = ["Artifacts", "JLLWrappers", "Libdl"]
Expand Down
36 changes: 36 additions & 0 deletions docs/src/assets/custom.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* Responsive layout for two-column content */
.responsive-columns-left-priority {
display: flex;
gap: 1rem;
align-items: flex-start;
margin-bottom: 1em;
}

.responsive-columns-left-priority > div {
flex: 1;
min-width: 0;
transition: opacity 0.5s ease-in-out, flex 0.5s ease-in-out, max-width 0.5s ease-in-out, max-height 0.5s ease-in-out;
}

.responsive-columns-left-priority > div:last-child {
opacity: 1;
max-width: 100%;
max-height: none;
}

/* Media query for screens smaller than 700px */
@media (max-width: 700px) {
.responsive-columns-left-priority > div:last-child {
opacity: 0;
max-width: 0;
max-height: 0;
flex: 0 0 0;
overflow: hidden;
margin: 0;
padding: 0;
}

.responsive-columns-left-priority > div:first-child {
flex: 1 1 100%;
}
}
51 changes: 38 additions & 13 deletions docs/src/example-double-integrator-energy.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,18 +13,15 @@ We assume that the mass is constant and equal to one, and that there is no frict
\dot x_1(t) = x_2(t), \quad \dot x_2(t) = u(t),\quad u(t) \in \R,
```

which is simply the [double integrator](https://en.wikipedia.org/w/index.php?title=Double_integrator&oldid=1071399674) system.
Let us consider a transfer starting at time $t_0 = 0$ and ending at time $t_f = 1$, for which we want to minimise the transfer energy
which is simply the [double integrator](https://en.wikipedia.org/w/index.php?title=Double_integrator&oldid=1071399674) system. Let us consider a transfer starting at time $t_0 = 0$ and ending at time $t_f = 1$, for which we want to minimise the transfer energy

```math
\frac{1}{2}\int_{0}^{1} u^2(t) \, \mathrm{d}t
```

starting from $x(0) = (-1, 0)$ and aiming to reach the target $x(1) = (0, 0)$.

First, we need to import the [OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) package to define the
optimal control problem, [NLPModelsIpopt.jl](https://jso.dev/NLPModelsIpopt.jl) to solve it,
and [Plots.jl](https://docs.juliaplots.org) to visualise the solution.
First, we need to import the [OptimalControl.jl](https://control-toolbox.org/OptimalControl.jl) package to define the optimal control problem, [NLPModelsIpopt.jl](https://jso.dev/NLPModelsIpopt.jl) to solve it, and [Plots.jl](https://docs.juliaplots.org) to visualise the solution.

```@example main
using OptimalControl
Expand All @@ -36,6 +33,11 @@ using Plots

Let us define the problem with the [`@def`](@ref) macro:

```@raw html
<div class="responsive-columns-left-priority">
<div>
```

```@example main
t0 = 0
tf = 1
Expand All @@ -47,12 +49,35 @@ ocp = @def begin
u ∈ R, control
x(t0) == x0
x(tf) == xf
(t) == [x₂(t), u(t)]
(t) == [x₂(t), u(t)]
0.5∫( u(t)^2 ) → min
end
nothing # hide
```

```@raw html
</div>
<div>
```

### Mathematical formulation

```math
\begin{aligned}
& \text{Minimise} && \frac{1}{2}\int_0^1 u^2(t) \,\mathrm{d}t \\
& \text{subject to} \\
& && \dot{x}_1(t) = x_2(t), \\[0.5em]
& && \dot{x}_2(t) = u(t), \\[1.0em]
& && x(0) = (-1,0), \\[0.5em]
& && x(1) = (0,0).
\end{aligned}
```

```@raw html
</div>
</div>
```

!!! note "Nota bene"

For a comprehensive introduction to the syntax used above to define the optimal control problem, see [this abstract syntax tutorial](@ref manual-abstract-syntax). In particular, non-Unicode alternatives are available for derivatives, integrals, *etc.*
Expand Down Expand Up @@ -142,12 +167,12 @@ plot(sol)

## State constraint

### Direct method
### Direct method: constrained case

We add the path constraint

```math
x_2(t) \le 1.2.
x_2(t) \le 1.2.
```

Let us model, solve and plot the optimal control problem with this constraint.
Expand Down Expand Up @@ -175,7 +200,7 @@ sol = solve(ocp)
plt = plot(sol; label="Direct", size=(800, 600))
```

### Indirect method
### Indirect method: constrained case

The pseudo-Hamiltonian is (considering the normal case):

Expand All @@ -186,13 +211,13 @@ H(x, p, u, \mu) = p_1 x_2 + p_2 u - \frac{u^2}{2} + \mu\, c(x),
with $c(x) = x_2 - a$. Along a boundary arc we have $c(x(t)) = 0$. Differentiating, we obtain:

```math
\frac{\mathrm{d}}{\mathrm{d}t}c(x(t)) = \dot{x}_2(t) = u(t) = 0.
\frac{\mathrm{d}}{\mathrm{d}t}c(x(t)) = \dot{x}_2(t) = u(t) = 0.
```

The zero control is maximising; hence, $p_2(t) = 0$ along the boundary arc.
The zero control is maximising; hence, $p_2(t) = 0$ along the boundary arc.

```math
\dot{p}_2(t) = -p_1(t) - \mu(t) \quad \Rightarrow \mu(t) = -p_1(t).
\dot{p}_2(t) = -p_1(t) - \mu(t) \quad \Rightarrow \mu(t) = -p_1(t).
```

Since the adjoint vector is continuous at the entry time $t_1$ and the exit time $t_2$, we have four unknowns: the initial costate $p_0 \in \mathbb{R}^2$ and the times $t_1$ and $t_2$. We need four equations: the target condition provides two, reaching the constraint at time $t_1$ gives $c(x(t_1)) = 0$, and finally $p_2(t_1) = 0$.
Expand Down Expand Up @@ -253,4 +278,4 @@ flow_sol = φ((t0, tf), x0, p0; saveat=range(t0, tf, 100))

# plot the solution on the previous plot
plot!(plt, flow_sol; label="Indirect", color=2, linestyle=:dash)
```
```
54 changes: 54 additions & 0 deletions docs/src/example-double-integrator-time.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,60 @@ using Plots

Let us define the problem:

```@raw html
<div class="responsive-columns-left-priority">
<div>
```

```@example main
ocp = @def begin

tf ∈ R, variable
t ∈ [0, tf], time
x = (q, v) ∈ R², state
u ∈ R, control

-1 ≤ u(t) ≤ 1

q(0) == -1
v(0) == 0
q(tf) == 0
v(tf) == 0

ẋ(t) == [v(t), u(t)]

tf → min

end
nothing # hide
```

```@raw html
</div>
<div>
```

### Mathematical formulation

```math
\begin{aligned}
& \text{Minimise} && t_f \\[0.5em]
& \text{subject to} \\[0.5em]
& && \dot q(t) = v(t), \\
& && \dot v(t) = u(t), \\[0.5em]
& && -1 \le u(t) \le 1, \\[0.5em]
& && q(0) = -1, \\[0.5em]
& && v(0) = 0, \\[0.5em]
& && q(t_f) = 0, \\[0.5em]
& && v(t_f) = 0.
\end{aligned}
```

```@raw html
</div>
</div>
```

```@example main
ocp = @def begin

Expand Down
Loading