diff --git a/README.md b/README.md
index f3ff0290b6b494022760a01d76b02603b1ae69df..0822e09cb55cf1de2d3c0237a2393bb5f0b2e0a4 100644
--- a/README.md
+++ b/README.md
@@ -26,7 +26,7 @@ Calcul différentiel et équation différentielle ordinaire
 
 Projet
 
-* Sujet du projet : plus tard
+* [Projet : tp/transfert-orbital.ipynb](tp/transfert-orbital.ipynb) - Transfert orbital
 
 **Notes de cours supplémentaires - ressources**
 
diff --git a/tp/transfert-orbital.ipynb b/tp/transfert-orbital.ipynb
new file mode 100644
index 0000000000000000000000000000000000000000..8a157115732debdc5e044490964f131aee8eb1fb
--- /dev/null
+++ b/tp/transfert-orbital.ipynb
@@ -0,0 +1,690 @@
+{
+ "cells": [
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "[<img src=\"https://gitlab.irit.fr/toc/etu-n7/controle-optimal/-/raw/master/ressources/Logo-toulouse-inp-N7.png\" alt=\"N7\" height=\"100\"/>](https://gitlab.irit.fr/toc/etu-n7/controle-optimal)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:8px;\n",
+    "            background-color:#FAA299;\n",
+    "            border:2px solid #BF381B;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "* Nom :\n",
+    "* Prénom :\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "# Transfert orbital\n",
+    "\n",
+    "Ce sujet (ou TP-projet) est à rendre (voir la date sur moodle et les modalités du rendu) et sera évalué pour faire partie de la note finale de la matière Contrôle Optimal."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:8px;\n",
+    "            background-color:#afa;\n",
+    "            border:2px solid #bbffbb;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1.5em;\n",
+    "            text-align:center;\">\n",
+    "Transfert orbital à temps minimal\n",
+    "</div>\n",
+    "\n",
+    "\n",
+    "On considère le problème du transfert d'un satellite d'une orbite initiale à l'orbite géostationnaire à temps minimal. Ce problème s'écrit comme un problème de contrôle optimal sous la forme\n",
+    "\n",
+    "$$\n",
+    "\\left\\lbrace\n",
+    "\\begin{array}{l}\n",
+    "    \\min J(x, u, t_f) = t_f \\\\[1.0em]\n",
+    "    \\ \\ \\dot{x}_{1}(t) = ~ x_{3}(t)  \\\\[0.5em]\n",
+    "    \\ \\ \\dot{x}_{2}(t) = ~ x_{4}(t)  \\\\[0.5em]\n",
+    "    \\ \\ \\dot{x}_{3}(t) =  -\\dfrac{\\mu\\, x_{1}(t)}{r^{3}(x(t))} + u_{1}(t)  \\\\[1em]\n",
+    "    \\ \\ \\dot{x}_{4}(t) =  -\\dfrac{\\mu\\, x_{2}(t)}{r^{3}(x(t))} + u_{2}(t), ~~ ||u(t)|| \\leq \\gamma_\\mathrm{max}, ~~ t \\in [0,t_f] ~~ \\text{p.p.}, ~~ u(t) = (u_1(t),u_2(t)),  \\\\[1.5em]\n",
+    "    \\ \\ x_{1}(0)=x_{0,1}, ~~ x_{2}(0)=x_{0,2}, ~~ x_{3}(0)=x_{0,3}, ~~ x_{4}(0)=x_{0,4}, \\\\[1em]\n",
+    "    \\ \\ r(x(t_f)) = r_{f}, ~~ x_{3}(t_f)=-\\sqrt{\\dfrac{\\mu}{r_{f}^{3}}}x_{2}(t_f), ~~ x_{4}           (t_f)= \\sqrt{\\dfrac{\\mu}{r_{f}^{3}}}x_{1}(t_f), \\\\\n",
+    "\\end{array}\n",
+    "\\right.\n",
+    "$$\n",
+    "\n",
+    "avec $r(x)=\\sqrt{x_{1}^{2}+x_{2}^{2}}$.\n",
+    "Les unités choisies sont le kilomètre pour les distances et l'heure pour les  temps. On donne les paramètres suivants :\n",
+    " \n",
+    "$$\n",
+    "\\mu=5.1658620912 \\times 10^{12} \\ \\mathrm{km}^{3}.\\mathrm{h}^{-2}, \\quad r_{f} = 42165 \\ \\mathrm{km}.\n",
+    "$$\n",
+    "\n",
+    "Le paramètre $\\gamma_\\mathrm{max}$ dépend de la poussée maximale $F_\\mathrm{max}$ suivant la relation :\n",
+    "\n",
+    "$$\n",
+    "\\gamma_\\mathrm{max} = \\frac{F_\\mathrm{max}\\times 3600^2}{m} \n",
+    "$$\n",
+    "\n",
+    "où m est la masse du satellite qu'on fixe à $m=2000\\ \\mathrm{kg}$."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Résolution via du tir simple indirect"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "using DifferentialEquations, NLsolve, ForwardDiff, Plots, LinearAlgebra\n",
+    "include(\"utils.jl\"); # fonctions utilitaires"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Les constantes du pb\n",
+    "x0     = [-42272.67, 0, 0, -5796.72] # état initial\n",
+    "μ      = 5.1658620912*1e12\n",
+    "rf     = 42165\n",
+    "F_max  = 100\n",
+    "γ_max  = F_max*3600^2/(2000*10^3)\n",
+    "t0     = 0\n",
+    "rf3    = rf^3\n",
+    "α      = sqrt(μ/rf3);"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 1:_**\n",
+    "    \n",
+    "1. Donner le pseudo-hamiltonien associé au problème de contrôle optimal.\n",
+    "2. Donner le pseudo système hamiltonien\n",
+    "$$\n",
+    "    \\vec{H}(x, p, u) = \\left(\\frac{\\partial H}{\\partial p}(x, p, u), \n",
+    "    -\\frac{\\partial H}{\\partial x}(x, p, u) \\right).\n",
+    "$$\n",
+    "3. Calculer le contrôle maximisant. On supposera que $(p_3, p_4)\\neq (0,0)$."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Réponse** (double cliquer pour modifier le texte)\n",
+    "\n",
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:20px;\n",
+    "            background-color:#CFF3F7;\n",
+    "            border:2px solid #063970;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "Ecrire la réponse ici\n",
+    "</div>"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 2:_** Compléter le code suivant contenant le pseudo-hamiltonien, le pseudo système hamiltonien et le contrôle maximisant."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#####\n",
+    "##### A COMPLETER\n",
+    "\n",
+    "# pseudo-Hamiltonien\n",
+    "function H(x, p, u)\n",
+    "    h = 0\n",
+    "    return h\n",
+    "end\n",
+    "\n",
+    "# pseudo système hamiltonien\n",
+    "function Hv(x, p, u)\n",
+    "    n     = size(x, 1)\n",
+    "    dx    = zeros(eltype(x), n)\n",
+    "    dp    = zeros(eltype(x), n)\n",
+    "    return dx, dp\n",
+    "end\n",
+    "\n",
+    "# Contrôle maximisant\n",
+    "function control(p)\n",
+    "    u    = zeros(eltype(p),2)\n",
+    "    return u\n",
+    "end\n",
+    "\n",
+    "#####\n",
+    "##### FIN A COMPLETER\n",
+    "\n",
+    "# flot hamiltonien pour le calcul des extrémales\n",
+    "f = Flow((x, p) -> Hv(x, p, control(p)));"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On note \n",
+    "$\n",
+    "    \\alpha := \\sqrt{\\frac{\\mu}{r_f^3}}.\n",
+    "$\n",
+    "La condition terminale peut se mettre sous la forme $c(x(t_f)) = 0$, avec $c \\colon \\mathbb{R}^4 \\to \\mathbb{R}^3$.\n",
+    "\n",
+    "✏️ **_Question 3:_** Donner l'expression de $c(x)$."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Réponse** (double cliquer pour modifier le texte)\n",
+    "\n",
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:20px;\n",
+    "            background-color:#CFF3F7;\n",
+    "            border:2px solid #063970;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "Ecrire la réponse ici\n",
+    "</div>"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "Le temps final étant libre, on a la condition au temps final \n",
+    "\n",
+    "$$\n",
+    "    H(x(t_f), p(t_f), u(t_f)) = -p^0 = 1. \\quad \\text{(on se place dans le cas normal)}\n",
+    "$$\n",
+    "\n",
+    "De plus, la condition de transversalité \n",
+    "\n",
+    "$$\n",
+    "p(t_f) = c'(x(t_f))^T \\lambda, ~~ \\lambda \\in \\mathbb{R}^3,\n",
+    "$$\n",
+    "\n",
+    "conduit à la relation suivante (où $\\lambda$ n'apparaît plus)\n",
+    "\n",
+    "$$\n",
+    "\\Phi(x(t_f), p(t_f)) := x_2(t_f) \\Big( p_1(t_f) + \\alpha\\, p_4(t_f) \\Big) - x_1(t_f) \\Big( p_2(t_f) - \\alpha\\, p_3(t_f) \\Big) = 0.\n",
+    "$$\n",
+    "\n",
+    "En considérant la condition aux limites, la condition finale sur le pseudo-hamiltonien et la condition de transversalité, la fonction de tir simple est donnée par \n",
+    "\n",
+    "\\begin{equation*}\n",
+    "    \\begin{array}{rlll}\n",
+    "        S \\colon    & \\mathbb{R}^5          & \\longrightarrow   & \\mathbb{R}^5 \\\\\n",
+    "        & (p_0, t_f)      & \\longmapsto       &\n",
+    "        S(p_0, t_f) := \\begin{pmatrix}\n",
+    "            c(x(t_f, x_0, p_0)) \\\\[0.5em]\n",
+    "            \\Phi(z(t_f, x_0, p_0)) \\\\[0.5em]\n",
+    "            H(z(t_f, x_0, p_0), u(z(t_f, x_0, p_0))) - 1\n",
+    "        \\end{pmatrix}\n",
+    "    \\end{array}\n",
+    "\\end{equation*}\n",
+    "\n",
+    "où $z(t_f, x_0, p_0)$ est la solution au temps $t_f$ du pseudo système hamiltonien bouclé par\n",
+    "le contrôle maximisant, partant au temps $t_0=0$ du point $(x_0, p_0)$. On rappelle que l'on note\n",
+    "$z=(x, p)$."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 4:_** Compléter le code suivant de la fonction de tir."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "#####\n",
+    "##### A COMPLETER\n",
+    "\n",
+    "# Fonction de tir\n",
+    "function shoot(p0, tf)\n",
+    "    \n",
+    "    s = zeros(eltype(p0), 5)\n",
+    "\n",
+    "    ...\n",
+    "    \n",
+    "    return s\n",
+    "\n",
+    "end;"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 5:_** Expliquer simplement ce que fait le code suivant."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Réponse** (double cliquer pour modifier le texte)\n",
+    "\n",
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:20px;\n",
+    "            background-color:#CFF3F7;\n",
+    "            border:2px solid #063970;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "Ecrire la réponse ici\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Itéré initial\n",
+    "y_guess = [1.0323e-4, 4.915e-5, 3.568e-4, -1.554e-4, 13.4]   # pour F_max = 100N\n",
+    "\n",
+    "# Jacobienne de la fonction de tir\n",
+    "foo(y)  = shoot(y[1:4], y[5])\n",
+    "jfoo(y) = ForwardDiff.jacobian(foo, y)\n",
+    "\n",
+    "# Résolution de shoot(p0, tf) = 0\n",
+    "nl_sol = nlsolve(foo, jfoo, y_guess; xtol=1e-8, method=:trust_region, show_trace=true);\n",
+    "\n",
+    "# On récupère la solution si convergence\n",
+    "if converged(nl_sol)\n",
+    "    p0_sol_100 = nl_sol.zero[1:4]\n",
+    "    tf_sol_100 = nl_sol.zero[5]\n",
+    "    println(\"\\nFinal solution:\\n\", nl_sol.zero)\n",
+    "else\n",
+    "    error(\"Not converged\")\n",
+    "end"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Fonction d'affichage d'une solution\n",
+    "function plot_solution(p0, tf)\n",
+    "\n",
+    "    # On trace l'orbite de départ et d'arrivée\n",
+    "    gr(dpi=300, size=(500,400), thickness_scaling=1)\n",
+    "    r0        = norm(x0[1:2])\n",
+    "    v0        = norm(x0[3:4])\n",
+    "    a         = 1.0/(2.0/r0-v0*v0/μ)\n",
+    "    t1        = r0*v0*v0/μ - 1.0;\n",
+    "    t2        = (x0[1:2]'*x0[3:4])/sqrt(a*μ);\n",
+    "    e_ellipse = norm([t1 t2])\n",
+    "    p_orb     = a*(1-e_ellipse^2);\n",
+    "    n_theta   = 101\n",
+    "    Theta     = range(0, stop=2*pi, length=n_theta)\n",
+    "    X1_orb_init = zeros(n_theta)\n",
+    "    X2_orb_init = zeros(n_theta)\n",
+    "    X1_orb_arr  = zeros(n_theta)\n",
+    "    X2_orb_arr  = zeros(n_theta)\n",
+    "\n",
+    "    # Orbite initiale\n",
+    "    for  i in 1:n_theta\n",
+    "        theta = Theta[i]\n",
+    "        r_orb = p_orb/(1+e_ellipse*cos(theta));\n",
+    "        X1_orb_init[i] = r_orb*cos(theta);\n",
+    "        X2_orb_init[i] = r_orb*sin(theta);\n",
+    "    end\n",
+    "\n",
+    "    # Orbite d'arrivée\n",
+    "    for  i in 1:n_theta\n",
+    "        theta = Theta[i]\n",
+    "        X1_orb_arr[i] = rf*cos(theta) ;\n",
+    "        X2_orb_arr[i] = rf*sin(theta);\n",
+    "    end;\n",
+    "\n",
+    "    # Calcul de la trajectoire\n",
+    "    ode_sol  = f((t0, tf), x0, p0)\n",
+    "    t  = ode_sol.t\n",
+    "    x1 = [ode_sol[1, j] for j in 1:size(t, 1) ]\n",
+    "    x2 = [ode_sol[2, j] for j in 1:size(t, 1) ]\n",
+    "    u  = zeros(2, length(t))\n",
+    "\n",
+    "    for j in 1:size(t, 1)\n",
+    "        u[:,j] = control(ode_sol[5:8, j])\n",
+    "    end\n",
+    "\n",
+    "    px = plot(x1, x2, color=:red, legend=:best, label=\"Trajectoire\",\n",
+    "        border=:none, size = (800,400), aspect_ratio=:equal)\n",
+    "    plot!(px, X1_orb_init, X2_orb_init, color=:green, label=\"Orbite initiale\")\n",
+    "    plot!(px, X1_orb_arr, X2_orb_arr, color=:blue, label=\"Orbite d'arrivée\")\n",
+    "    plot!(px, [x0[1]], [x0[2]], seriestype=:scatter, color=:green, markersize = 5, label=\"Départ\")\n",
+    "    xf = ode_sol[1:2, end]\n",
+    "    plot!(px, [xf[1]], [xf[2]], seriestype=:scatter, color=:red, markersize = 5, label=\"Arrivée\")\n",
+    "    plot!(px, [0.0], [0.0], color = :blue, seriestype=:scatter, markersize = 25, label=\"Terre\")\n",
+    "\n",
+    "    pu1 = plot(t, u[1,:], color=:red, label=\"u₁(t)\", legend=:best)\n",
+    "    pu2 = plot(t, u[2,:], color=:red, label=\"u₂(t)\", legend=:best)\n",
+    "\n",
+    "    display(plot(pu1, pu2, layout = (1,2), size = (800,400)))\n",
+    "    display(px)\n",
+    "    \n",
+    "end;"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# On affiche la solution pour Fmax = 100\n",
+    "plot_solution(p0_sol_100, tf_sol_100)"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 6:_** Que vaut le temps final $t_f$ (à 5 digits près) ? Combien de révolutions complètes autour de la Terre a réalisé le satellite."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Réponse** (double cliquer pour modifier le texte)\n",
+    "\n",
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:20px;\n",
+    "            background-color:#CFF3F7;\n",
+    "            border:2px solid #063970;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "Ecrire la réponse ici\n",
+    "</div>"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Etude du temps de transfert en fonction de la poussée maximale\n",
+    "\n",
+    "✏️ **_Question 7:_** \n",
+    "\n",
+    "* A l'aide de ce que vous avez fait précédemment, déterminer $t_f$ (attention, penser à bien itinialiser la\n",
+    "méthode de tir) pour\n",
+    "    \n",
+    "$$\n",
+    "    F_\\mathrm{max} \\in \\{100, 90, 80, 70, 60, 50, 40, 30, 20 \\}.\n",
+    "$$\n",
+    "    \n",
+    "* Tracer ensuite $t_f$ en fonction de $F_\\mathrm{max}$ et commenter le résultat."
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "**Réponse** (double cliquer pour modifier le texte et donner votre commentaire)\n",
+    "\n",
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:20px;\n",
+    "            background-color:#CFF3F7;\n",
+    "            border:2px solid #063970;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1em;\"> <!-- il faut laisser une ligne vide après celle-ci -->\n",
+    "\n",
+    "Ecrire la réponse ici\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Les différentes valeurs de poussées\n",
+    "F_max_span = range(100, stop=20, length=11);\n",
+    "γ_max_span = [F_max_span[j]*3600^2/(2000*10^3) for j in 1:size(F_max_span,1)];"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Solution calculée précédemment\n",
+    "y_guess = [p0_sol_100; [tf_sol_100]]\n",
+    "\n",
+    "# Pour le stockage des solutions\n",
+    "tf_sols = zeros(length(γ_max_span))     # vecteur des temps de transfert\n",
+    "p0_sols = zeros(4, length(γ_max_span))  # matrice des co-états initiaux\n",
+    "\n",
+    "#####\n",
+    "##### A COMPLETER\n",
+    "\n",
+    "...\n"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Affichage de tf en fonction de la poussée maximale\n",
+    "plot(F_max_span, tf_sols, aspect_ratio=:equal, legend=:best, label=\"tf(Fmax)\")"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# Plots sol pour F_max = 20N\n",
+    "i = 11\n",
+    "γ_max = γ_max_span[i]\n",
+    "plot_solution(p0_sols[:, i], tf_sols[i])"
+   ]
+  },
+  {
+   "attachments": {},
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "### Animation\n",
+    "\n",
+    "Juste pour s'amuser"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "include(\"space.jl\"); using .Space"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "# solution choice\n",
+    "i = 11\n",
+    "γ_max = γ_max_span[i] # γ_max must be updated for the use of the flow\n",
+    "\n",
+    "# animation\n",
+    "# nFrame = 100; d = 30; fps = floor(Int, nFrame/d) => 2 minutes and 30 seconds of computation\n",
+    "nFrame = 100; d = 30; fps = floor(Int, nFrame/d)\n",
+    "Space.animation(p0_sols[:, i], tf_sols[i], f, γ_max, nFrame=nFrame, fps=fps)"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "<div style=\"width:90%;\n",
+    "            margin:10px;\n",
+    "            padding:8px;\n",
+    "            background-color:#afa;\n",
+    "            border:2px solid #bbffbb;\n",
+    "            border-radius:20px;\n",
+    "            font-weight:bold;\n",
+    "            font-size:1.5em;\n",
+    "            text-align:center;\">\n",
+    "Transfert orbital à consommation minimale\n",
+    "</div>"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "On considère maintenant le problème du transfert d'un satellite d'une orbite initiale à une orbite géostationnaire à temps final fixé en cherchant à minimiser la consommation de carburant. Ce problème s'écrit comme un problème de contrôle optimal sous la forme\n",
+    "\n",
+    "$$\n",
+    "\\left\\lbrace\n",
+    "\\begin{array}{l}\n",
+    "    \\displaystyle \\min J(x, u) = \\int_{0}^{t_f} \\Vert u(t)\\Vert \\mathrm{d}t \\\\[1.0em]\n",
+    "    \\ \\ \\dot{x}_{1}(t) = ~ x_{3}(t)  \\\\[0.5em]\n",
+    "    \\ \\ \\dot{x}_{2}(t) = ~ x_{4}(t)  \\\\[0.5em]\n",
+    "    \\ \\ \\dot{x}_{3}(t) =  -\\dfrac{\\mu\\, x_{1}(t)}{r^{3}(x(t))} + u_{1}(t)  \\\\[1em]\n",
+    "    \\ \\ \\dot{x}_{4}(t) =  -\\dfrac{\\mu\\, x_{2}(t)}{r^{3}(x(t))} + u_{2}(t), ~~ ||u(t)|| \\leq \\gamma_\\mathrm{max}, ~~ t \\in [0,t_f] ~~ \\text{p.p.}, ~~ u(t) = (u_1(t),u_2(t)),  \\\\[1.5em]\n",
+    "    \\ \\ x_{1}(0)=x_{0,1}, ~~ x_{2}(0)=x_{0,2}, ~~ x_{3}(0)=x_{0,3}, ~~ x_{4}(0)=x_{0,4}, \\\\[1em]\n",
+    "    \\ \\ r(x(t_f)) = r_{f}, ~~ x_{3}(t_f)=-\\sqrt{\\dfrac{\\mu}{r_{f}^{3}}}x_{2}(t_f), ~~ x_{4}           (t_f)= \\sqrt{\\dfrac{\\mu}{r_{f}^{3}}}x_{1}(t_f). \\\\\n",
+    "\\end{array}\n",
+    "\\right.\n",
+    "$$\n",
+    "\n",
+    "Toutes les constantes sont identiques au problème précédent. On considéra le problème avec $F_\\mathrm{max} = 100$ et on prendre comme temps final : $t_f = 1.5 T^{100}_{\\min}$, où $T^{100}_{\\min}$ correspond au temps minimal solution du problème précédent pour $F_\\mathrm{max} = 100$.\n",
+    "\n",
+    "**Remarques importantes.** \n",
+    "\n",
+    "* On ne considèrera que des extrémales normales, c'est-à-dire $p^0 = -1$.\n",
+    "* Le problème a de la structure, le contrôle optimal est composé d'arcs où la poussée est nulle $u(t) = 0$ et où la poussée est maximale $\\Vert u(t)\\Vert = \\gamma_\\mathrm{max}$.\n",
+    "* Vous devrez dans un premier temps résoudre le problème avec le coût suivant ce qui permet de le régulariser et ainsi d'utiliser une méthode de tir simple :\n",
+    "\n",
+    "$$\n",
+    "\\int_{0}^{t_f} \\left( \\Vert u(t)\\Vert - \\varepsilon \\left( \\ln(\\Vert u(t)\\Vert) + \\ln(\\gamma_\\mathrm{max}-\\Vert u(t)\\Vert) \\right) \\right) \\mathrm{d}t.\n",
+    "$$"
+   ]
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 8:_** Résoudre via du tir simple le problème régularisé pour différentes valeurs de $\\varepsilon$ suffisamment petites pour déterminer la structure optimale, en commençant avec $\\varepsilon$ suffisamment grand pour faire converger la méthode de tir plus facilement."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  },
+  {
+   "cell_type": "markdown",
+   "metadata": {},
+   "source": [
+    "✏️ **_Question 9:_** Résoudre via du tir multiple le problème de transfert orbital à consommation minimale. Vous utilisez la structure obtenue précédemment et vous donnerez au solveur une bonne condition initiale à l'aide de la question précédente."
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {},
+   "outputs": [],
+   "source": []
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Julia 1.9.0",
+   "language": "julia",
+   "name": "julia-1.9"
+  },
+  "language_info": {
+   "file_extension": ".jl",
+   "mimetype": "application/julia",
+   "name": "julia",
+   "version": "1.9.0"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 4
+}