Skip to content

Commit 3fdd838

Browse files
committed
Improve tutorial-mpc: add explanatory text and reorganize code into collapsible notes
1 parent 7d40d14 commit 3fdd838

2 files changed

Lines changed: 105 additions & 36 deletions

File tree

docs/src/tutorial-mam.md

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
# Minimal Action Method using Optimal Control
22

3-
```@meta
4-
Draft = false
5-
```
6-
73
The Minimal Action Method (MAM) is a numerical technique for finding the most probable transition pathway between stable states in stochastic dynamical systems. It achieves this by minimizing an action functional that represents the path's deviation from the deterministic dynamics, effectively identifying the path of least resistance through the system's landscape.
84

95
This tutorial demonstrates how to implement MAM as an optimal control problem, using the classical Maier-Stein model as a benchmark example.
@@ -145,7 +141,7 @@ function continuation_mam(Ts; init_guess=init)
145141
iterations_list = Int[]
146142
current_sol = init_guess
147143
148-
opts = (display=false, grid_size=1000, tol=1e-8, print_level=0)
144+
opts = (display=false, grid_size=1000, tol=1e-8)
149145
for T in Ts
150146
current_sol = solve(ocp(T); init=current_sol, opts...)
151147
push!(objectives, objective(current_sol))

docs/src/tutorial-mpc.md

Lines changed: 104 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
# Navigation problem, MPC approach
22

3-
We consider a ship in a constant current $w=(w_x,w_y)$, where $\|w\|<1$.
4-
The [heading angle](https://en.wikipedia.org/wiki/Heading) is controlled, leading to the following differential equations:
3+
```@meta
4+
Draft = false
5+
```
6+
7+
We consider a ship in a constant current $w=(w_x,w_y)$, where $\|w\|<1$. The [heading angle](https://en.wikipedia.org/wiki/Heading) is controlled, leading to the following differential equations:
58

69
```math
710
\begin{array}{rcl}
@@ -11,7 +14,17 @@ The [heading angle](https://en.wikipedia.org/wiki/Heading) is controlled, leadin
1114
\end{array}
1215
```
1316

14-
The angular velocity is limited and normalized: $\|u(t)\| \leq 1$. There are boundary conditions at the initial time $t=0$ and at the final time $t=t_f$, on the position $(x,y)$ and on the angle $\theta$. The objective is to minimize the final time. This topic stems from a collaboration between the University Côte d'Azur and the French company [CGG](https://www.cgg.com), which is interested in optimal maneuvers of very large ships for marine exploration.
17+
The state variables represent:
18+
19+
- $(x, y)$: the ship's position in the plane
20+
- $\theta$: the heading angle (direction of the ship's velocity relative to the x-axis)
21+
- $u$: the angular velocity (rate of change of the heading angle)
22+
23+
The angular velocity is limited and normalized: $\|u(t)\| \leq 1$. There are boundary conditions at the initial time $t=0$ and at the final time $t=t_f$, on the position $(x,y)$ and on the angle $\theta$. The objective is to minimize the final time.
24+
25+
The condition $\|w\|<1$ ensures that the ship can always make progress against the current, since the ship's own velocity has unit magnitude.
26+
27+
This topic stems from a collaboration between the University Côte d'Azur and the French company [CGG](https://www.cgg.com), which is interested in optimal maneuvers of very large ships for marine exploration.
1528

1629
```@raw html
1730
<img
@@ -23,7 +36,7 @@ The angular velocity is limited and normalized: $\|u(t)\| \leq 1$. There are bou
2336
>
2437
```
2538

26-
## Data
39+
## Data
2740

2841
```@example main-mpc
2942
using LinearAlgebra
@@ -42,6 +55,9 @@ xf = 4.
4255
yf = 7.
4356
θf = -π/2
4457
58+
# Current model: combines a constant base current with a position-dependent perturbation.
59+
# The parameter ε controls the magnitude of the spatial variation, while the base
60+
# current w = [0.6, 0.4] represents the mean flow direction.
4561
function current(x, y) # current as a function of position
4662
ε = 1e-1
4763
w = [ 0.6, 0.4 ]
@@ -52,8 +68,15 @@ function current(x, y) # current as a function of position
5268
end
5369
return w
5470
end
71+
```
5572

56-
#
73+
!!! note "Plotting utility functions"
74+
75+
```@raw html
76+
<details><summary>Click to unfold the plotting functions.</summary>
77+
```
78+
79+
```@example main-mpc
5780
function plot_state!(plt, x, y, θ; color=1)
5881
plot!(plt, [x], [y], marker=:circle, legend=false, color=color, markerstrokecolor=color, markersize=5, z_order=:front)
5982
quiver!(plt, [x], [y], quiver=([cos(θ)], [sin(θ)]), color=color, linewidth=2, z_order=:front)
@@ -70,26 +93,6 @@ function plot_current!(plt; current=current, N=10, scaling=1)
7093
return plt
7194
end
7295

73-
# Display the boundary conditions and the current in the augmented phase plane
74-
plt = plot(
75-
xlims=(-2, 6),
76-
ylims=(-1, 8),
77-
size=(600, 600),
78-
aspect_ratio=1,
79-
xlabel="x",
80-
ylabel="y",
81-
title="Boundary Conditions",
82-
leftmargin=5mm,
83-
bottommargin=5mm,
84-
)
85-
86-
plot_state!(plt, x0, y0, θ0; color=2)
87-
plot_state!(plt, xf, yf, θf; color=2)
88-
annotate!([(x0, y0, ("q₀", 12, :top)), (xf, yf, ("qf", 12, :bottom))])
89-
plot_current!(plt)
90-
```
91-
92-
```@example main-mpc
9396
function plot_trajectory!(plt, t, x, y, θ; N=5) # N: number of points where we will display θ
9497

9598
# trajectory
@@ -126,13 +129,37 @@ function plot_trajectory!(plt, t, x, y, θ; N=5) # N: number of points where we
126129

127130
end
128131
nothing # hide
132+
```
133+
134+
```@raw html
135+
</details>
136+
```
137+
138+
```@example main-mpc
139+
# Display the boundary conditions and the current in the augmented phase plane
140+
plt = plot(
141+
xlims=(-2, 6),
142+
ylims=(-1, 8),
143+
size=(600, 600),
144+
aspect_ratio=1,
145+
xlabel="x",
146+
ylabel="y",
147+
title="Boundary Conditions",
148+
leftmargin=5mm,
149+
bottommargin=5mm,
150+
)
151+
152+
plot_state!(plt, x0, y0, θ0; color=2)
153+
plot_state!(plt, xf, yf, θf; color=2)
154+
annotate!([(x0, y0, ("q₀", 12, :top)), (xf, yf, ("qf", 12, :bottom))])
155+
plot_current!(plt)
129156
```
130157

131158
## OptimalControl solver
132159

133160
```@example main-mpc
134161
function solve(t0, x0, y0, θ0, xf, yf, θf, w;
135-
grid_size=300, tol=1e-8, max_iter=500, print_level=4, display=true, disc_method=:euler)
162+
grid_size=300, tol=1e-8, max_iter=500, print_level=4, display=true, scheme=:euler)
136163
137164
# Definition of the problem
138165
ocp = @def begin
@@ -159,9 +186,11 @@ function solve(t0, x0, y0, θ0, xf, yf, θf, w;
159186
160187
# Initialization
161188
tf_init = 1.5*norm([xf, yf]-[x0, y0])
162-
x_init(t) = [ x0, y0, θ0 ] * (tf_init-t)/(tf_init-t0) + [xf, yf, θf] * (t-t0)/(tf_init-t0)
163-
u_init = (θf - θ0) / (tf_init-t0)
164-
init = (state=x_init, control=u_init, variable=tf_init)
189+
init = @init ocp begin
190+
tf := tf_init
191+
q(t) := [ x0, y0, θ0 ] * (tf_init-t)/(tf_init-t0) + [xf, yf, θf] * (t-t0)/(tf_init-t0)
192+
u(t) := (θf - θ0) / (tf_init-t0)
193+
end
165194
166195
# Resolution
167196
sol = OptimalControl.solve(ocp;
@@ -171,7 +200,7 @@ function solve(t0, x0, y0, θ0, xf, yf, θf, w;
171200
max_iter=max_iter,
172201
print_level=print_level,
173202
display=display,
174-
disc_method=disc_method,
203+
scheme=scheme,
175204
)
176205
177206
# Retrieval of useful data
@@ -191,7 +220,7 @@ nothing # hide
191220

192221
## First resolution
193222

194-
We consider a constant current and we solve a first time the problem.
223+
We consider a constant current, and we solve a first time the problem. The current is evaluated at the initial position and assumed to remain constant throughout the trajectory.
195224

196225
```@example main-mpc
197226
# Resolution
@@ -202,6 +231,12 @@ println("Constraints violation: ", cons)
202231
println("tf: ", tf)
203232
```
204233

234+
The solution provides:
235+
236+
- The optimal final time `tf`: the minimum time needed to reach the target
237+
- The optimal state trajectory $(x(t), y(t), \theta(t))$
238+
- The optimal control $u(t)$: the angular velocity profile
239+
205240
```@example main-mpc
206241
# Displaying the trajectory
207242
plt_q = plot(xlims=(-2, 6), ylims=(-1, 8), aspect_ratio=1, xlabel="x", ylabel="y")
@@ -223,10 +258,18 @@ plot(plt_q, plt_u;
223258
)
224259
```
225260

261+
The trajectory shows the ship's path when assuming the current is constant and equal to its value at the initial position.
262+
226263
## Simulation of the Real System
227264

228265
In the previous simulation, we assumed that the current is constant. However, from a practical standpoint, the current depends on the position $(x, y)$. Given a current model, provided by the function `current`, we can simulate the actual trajectory of the ship, as long as we have the initial condition and the control over time.
229266

267+
!!! note "Realistic trajectory simulation function"
268+
269+
```@raw html
270+
<details><summary>Click to unfold the simulation code.</summary>
271+
```
272+
230273
```@example main-mpc
231274
function realistic_trajectory(tf, t0, x0, y0, θ0, u, current; abstol=1e-12, reltol=1e-12, saveat=[])
232275
@@ -254,6 +297,10 @@ end
254297
nothing # hide
255298
```
256299

300+
```@raw html
301+
</details>
302+
```
303+
257304
```@example main-mpc
258305
# Realistic trajectory
259306
t, x, y, θ = realistic_trajectory(tf, t0, x0, y0, θ0, u, current)
@@ -279,10 +326,27 @@ plot(plt_q, plt_u;
279326
)
280327
```
281328

329+
Note that the final position (shown in red) differs from the target position (shown in orange). This discrepancy occurs because the control was computed assuming a constant current, but the actual current varies with position. The ship drifts due to the unmodeled spatial variation of the current.
330+
282331
## MPC Approach
283332

284333
In practice, we do not have the actual current data for the entire trajectory in advance, which is why we will regularly recalculate the optimal control. The idea is to update the optimal control at regular time intervals, taking into account the current at the position where the ship is located. We are therefore led to solve a number of problems with constant current, with this being updated regularly. This is an introduction to the so-called Model Predictive Control (MPC) methods.
285334

335+
The MPC algorithm works as follows:
336+
337+
1. At each iteration, measure the current at the ship's current position
338+
2. Solve an optimal control problem assuming this current is constant over the entire remaining trajectory
339+
3. Apply the optimal control for a fixed time step `Δt`
340+
4. Simulate the ship's motion using the actual position-dependent current
341+
5. Update the ship's position and repeat until reaching the target
342+
343+
The parameters are:
344+
345+
- `Nmax`: maximum number of MPC iterations (safety limit)
346+
- `ε`: convergence tolerance - the algorithm stops when within this distance of the target
347+
- `Δt`: prediction horizon - how long to apply each computed control before re-planning
348+
- `P`: number of discretization points for the optimal control solver
349+
286350
```@example main-mpc
287351
function MPC(t0, x0, y0, θ0, xf, yf, θf, current)
288352
@@ -356,6 +420,15 @@ nothing # hide
356420

357421
## Display
358422

423+
The final plot shows:
424+
425+
- The complete MPC trajectory (blue) composed of segments from each iteration
426+
- Starting points of each segment (orange) where re-planning occurs
427+
- The final position reached (red) - note that it is much closer to the target than in the constant-current simulation
428+
- The control profile (right) showing the piecewise re-planning strategy
429+
430+
The MPC approach successfully compensates for the spatial variation of the current by continuously updating the control based on local current measurements.
431+
359432
```@example main-mpc
360433
# Trajectory
361434
plt_q = plot(xlims=(-2, 6), ylims=(-1, 8), aspect_ratio=1, xlabel="x", ylabel="y")

0 commit comments

Comments
 (0)