-- -- Ce programme rend visite à plusieurs aéroports européens. -- with Assert ; with Gada.Text_IO ; with Avion_Sol, INSA_Air ; with Train, Tour, Pilote_Automatique, Carburant ; with Cartographie ; procedure Mission3 is package Txt renames GAda.Text_IO ; package IA renames INSA_Air ; package AS renames Avion_Sol ; package PA renames Pilote_Automatique ; package Carto renames Cartographie ; procedure Rouler_KA is begin Tour.Attendre_Autorisation_Roulage ; AS.Rouler_Vers ( Dest => 'L') ; AS.Rouler_Vers ( Dest => 'M') ; AS.Rouler_Vers ( Dest => 'E') ; AS.Rouler_Vers ( Dest => 'A') ; end Rouler_KA ; procedure Rouler_DK is begin AS.Rouler_Vers ( Dest => 'N') ; AS.Rouler_Vers ( Dest => 'P') ; AS.Rouler_Vers ( Dest => 'M') ; AS.Rouler_Vers ( Dest => 'L') ; AS.Rouler_Vers ( Dest => 'K') ; AS.Freiner ; end Rouler_DK ; Angle_Tour : constant Float := 360.0 ; Demi_Tour : constant Float := Angle_Tour / 2.0 ; -- -- DELTA_CAP -- -- Calcule la différence entre deux caps, modulo 360 -- Le résultat est dans ]-180 ; 180] function Delta_Cap (Cap_Actuel : Float ; Cap_Voulu : Float) return Float is Resultat : Float ; begin Resultat := Cap_Voulu - Cap_Actuel ; -- Si c'est trop grand, on enlève un tour if Resultat > Demi_Tour then Resultat := Resultat - Angle_Tour ; -- Si c'est trop petit, on ajoute un tour elsif Resultat < - Demi_Tour then Resultat := Resultat + Angle_Tour ; end if ; return Resultat ; end Delta_Cap ; -- -- CAPS_EGAUX -- -- Indique si deux caps sont égaux à 5 degrés près. -- function Caps_Egaux (Cap1 : Float ; Cap2 : Float) return Boolean is Tolerance : constant Float := 5.0 ; begin return abs (Delta_Cap ( Cap_Actuel => Cap1, Cap_Voulu => Cap2)) < Tolerance ; end Caps_Egaux ; -- -- ORIENTER_EN_VOL -- -- Fait tourner l'avion jusqu'à ce que son cap soit le cap demandé. procedure Orienter_En_Vol (Cible : Float) is begin Assert.Failif (Cond => Cible < 0.0 or Cible > Angle_Tour, Message => "Orienter_En_Vol : cap incorrect = " & Float'Image(Cible)) ; while not (Caps_Egaux (Cap1 => Cible, Cap2 => IA.Cap_Courant)) loop if Delta_Cap (Cap_Actuel => IA.Cap_Courant, Cap_Voulu => Cible) < 0.0 then INSA_Air.Positionner_Gouverne_A_Gauche ; else INSA_Air.Positionner_Gouverne_A_Droite ; end if ; end loop ; INSA_Air.Positionner_Gouverne_A_Zero ; end Orienter_En_Vol ; -- -- Affiche des infos sur un aéroport -- procedure Infos_Aeroport (Code : String) is Pos : Carto.T_Coords ; begin Pos := Carto.Coords_Aeroport (Code) ; -- Affiche par exemple "Aeroport LFBO = Toulouse Blagnac" -- " Lat. = 40.0000 Long. = -2.0000" -- (En fait, les nombres sont affichés en notation scientifique) -- Txt.Put(Aff => "Aeroport " & Code & " = " & Carto.Nom_Aeroport(Code)) ; Txt.Put_Line (Aff => " Lat. = " & Float'Image(Pos.Lat) & " Long. = " & Float'Image(Pos.Long)) ; end Infos_Aeroport ; procedure Tester_Carto is begin Infos_Aeroport (Code => "LFBO") ; Infos_Aeroport (Code => "EGLL") ; Infos_Aeroport (Code => "LFPG") ; end Tester_Carto ; -- Calcule la distance entre deux points function Dist (P1 : Carto.T_Coords ; P2 : Carto.T_Coords) return Float is -- Distance correspondant à un degré de longitude/latitude (par abus) One_Degre : constant Float := 111.600 ; Dist2 : Float ; begin Dist2 := (P1.Lat - P2.Lat)**2 + (P1.Long - P2.Long)**2 ; return One_Degre * (Carto.Sqrt (Dist2)) ; end Dist ; procedure Tester_Dist is begin Txt.Put_Line (Aff => "Distance entre Blagnac et Heathrow en km : " & Float'Image(Dist(P1 => Carto.Coords_Aeroport(Code => "LFBO"), P2 => Carto.Coords_Aeroport(Code => "EGLL")))) ; end Tester_Dist ; -- Calcule le cap de l'aéroport indiqué, selon la position actuelle de l'avion. function Cap_Cible (Code : String) return Float is Aero : Carto.T_Coords ; Avion : Carto.T_Coords ; begin Aero := Carto.Coords_Aeroport (Code) ; Avion := Carto.Coords_Avion ; return Carto.Cap_Vecteur (DX => Aero.Long - Avion.Long, DY => Aero.Lat - Avion.Lat) ; end Cap_Cible ; procedure Tester_Cap_Cible is begin Txt.Put_Line (Aff => "Cap_Cible vers Heathrow : " & Float'Image (Cap_Cible(Code => "EGLL"))) ; end Tester_Cap_Cible ; -- Renvoie le numéro de l'aéroport le plus proche hors de France function Reperer_Plus_Proche return Integer is -- Distance de l'aéroport le plus proche (hors de France) trouvé Dist_Min : Float := 100000.0 ; -- Numéro de l'aéroport le plus proche (hors de France) trouvé No_Min : Integer := 1 ; -- Variable temporaire ADist : Float ; begin for No in 1..Carto.Nb_Aeroports loop ADist := Dist(P1 => Carto.Coords_Aeroport(Code => Carto.Code_Aeroport(Numero => No)), P2 => Carto.Coords_Avion) ; if ADist < Dist_Min and Carto.Pays_Aeroport(Code => Carto.Code_Aeroport(Numero => No)) /= "FR" then Dist_Min := ADist ; No_Min := No ; end if ; end loop ; return No_Min ; end Reperer_Plus_Proche ; -- Vole jusqu'à un aéroport -- Calcule en même temps la moyenne demandée procedure Naviguer_Vers (Code : String) is Dist_Min : constant Float := 100.0 ; Nb_Echantillons : Integer ; Somme_Distances : Float ; Moyenne : Float ; Aero_Plus_Proche : Integer ; begin Nb_Echantillons := 0 ; Somme_Distances := 0.0 ; -- Vol tant que la distance à l'aéroport est > 100km while Dist(P1 => Carto.Coords_Avion, P2 => Carto.Coords_Aeroport(Code)) > Dist_Min Loop Orienter_En_Vol (Cible => Cap_Cible(Code)) ; -- Marquer l'aéroport le plus proche Aero_Plus_Proche := Reperer_Plus_Proche ; Carto.Placer_Marque (Point => Carto.Coords_Aeroport(Code => Carto.Code_Aeroport(Numero => Aero_Plus_Proche))) ; -- Somme de "la distance au plus proche", pour en calculer la moyenne ensuite Somme_Distances := Somme_Distances + Dist(P1 => Carto.Coords_Aeroport(Code => Carto.Code_Aeroport(Numero => Aero_Plus_Proche)), P2 => Carto.Coords_Avion) ; Nb_Echantillons := Nb_Echantillons + 1 ; end loop ; Moyenne := Somme_Distances / Float(Nb_Echantillons) ; Txt.Put_Line (Aff => "La moyenne de la distance à l'aéroport le plus proche vaut " & Float'Image(Moyenne) & " km") ; end Naviguer_Vers ; -- Effectue un vol en Europe procedure Vol_Demo is Reacteur_Decollage : constant Integer := 8 ; Reacteur_Vol_Croisiere : constant Integer := 6 ; Reacteur_Atterrissage : constant Integer := 3 ; begin -- Rejoindre la piste et décoller Carburant.Faire_Le_Plein ; IA.Donner_Nom_Compagnie(Nom => "INSA-Air") ; Rouler_KA ; Tour.Attendre_Autorisation_Decollage ; IA.Regler_Reacteur (Force => Reacteur_Decollage) ; PA.Decoller ; -- Vol de croisière Train.Deplacer_Train (Sens => False) ; IA.Regler_Reacteur (Force => Reacteur_Vol_Croisiere) ; -- Faire un petit tour en Europe Naviguer_Vers (Code => "EGLL") ; Naviguer_Vers (Code => "LFRB") ; Naviguer_Vers (Code => "LIPZ") ; -- Retour à Toulouse Naviguer_Vers (Code => "LFBO") ; -- Atterrissage et retour au hangar IA.Regler_Reacteur (Force => Reacteur_Atterrissage) ; Train.Deplacer_Train (Sens => True) ; Tour.Attendre_Autorisation_Atterrissage ; PA.Atterrir ; Rouler_DK ; end Vol_Demo ; begin Tester_Carto ; Tester_Dist ; Tester_Cap_Cible ; Vol_Demo ; end Mission3 ;