diff --git a/README.md b/README.md index 0822e09cb55cf1de2d3c0237a2393bb5f0b2e0a4..7ef0c340f81e1baffbf5a2c307e39fff235f0681 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ Cours de contrôle optimal de l'ENSEEIHT pour le département Sciences du Numér **CTD** -* [Notes de cours - contrôle optimal](https://gitlab.irit.fr/toc/etu-n7/controle-optimal/-/raw/master/notes-co-2024.pdf) +* [Notes de cours - contrôle optimal](https://gitlab.irit.fr/toc/etu-n7/controle-optimal/-/raw/master/notes-co-2025.pdf) **TP** @@ -24,10 +24,6 @@ Calcul différentiel et équation différentielle ordinaire * [Sujet 4 : tp/derivative.ipynb](tp/derivative.ipynb) - Calcul numérique de dérivées * [Sujet 5 : tp/runge-kutta.ipynb](tp/runge-kutta.ipynb) - Méthodes de Runge-Kutta -Projet - -* [Projet : tp/transfert-orbital.ipynb](tp/transfert-orbital.ipynb) - Transfert orbital - **Notes de cours supplémentaires - ressources** * [Automatique](https://gitlab.irit.fr/toc/etu-n7/controle-optimal/-/raw/master/ressources/notes-autom-2021.pdf) diff --git a/notes-co-2024.pdf b/notes-co-2024.pdf deleted file mode 100644 index dfce5c12fa81761ea4677f082baaf5e585a3972f..0000000000000000000000000000000000000000 Binary files a/notes-co-2024.pdf and /dev/null differ diff --git a/stages/.gitkeep b/stages/.gitkeep deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/stages/2024-stage-M1-cots.pdf b/stages/2024-stage-M1-cots.pdf deleted file mode 100644 index 1852fd0a6d287194f6936b5b5d294b621f4c1673..0000000000000000000000000000000000000000 Binary files a/stages/2024-stage-M1-cots.pdf and /dev/null differ diff --git a/stages/Internship_subject_2.pdf b/stages/Internship_subject_2.pdf deleted file mode 100644 index 3d2e1c2ef95f6887c259b9eeedaabb011ec3f400..0000000000000000000000000000000000000000 Binary files a/stages/Internship_subject_2.pdf and /dev/null differ diff --git a/tp/transfert-orbital.ipynb b/tp/transfert-orbital.ipynb deleted file mode 100644 index 8a157115732debdc5e044490964f131aee8eb1fb..0000000000000000000000000000000000000000 --- a/tp/transfert-orbital.ipynb +++ /dev/null @@ -1,690 +0,0 @@ -{ - "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 -}