Forum Flightgear France

Une communauté prend son envol

Vous n'êtes pas identifié(e).

Annonce

Futur nouvel inscrit, tu dois au préalable lire l'intégralité des 10 articles des règles, s'il te plaît. Tout nouveau compte qui ne respecte pas les règles sera supprimé par l'administration.

#1 3/02/2021 19:27:56

exCorbac
Membre
Lieu : Felletin (23500)
Inscription : 6/02/2019
Messages : 26

Calculatrice spéciale FlightGear

Bonjour à tous,

Dans ce post, je vous propose un script bash (utilisable sous Ubuntu, Linux Mint) pour automatiser un certain nombre de calculs utiles pour FlightGear, que ce soit "en route" ou avant le vol. Ces calculs sont :

- Conversion de coordonnées géodésiques en ° décimal (sous la forme ##.##°) vers ° ' " ou l'inverse,
- Conversion de pression atmosphérique en hecto-Pascal (hPa, donnée METAR) vers pouce de mercure (in. Hg, unité que certains aéronefs utilisent pour calibrer l'altimètre, comme le Cessna 172p),
- Calcul de cap et de distance entre deux points géodésiques déterminés (exprimés en ° décimal ou ° ' ") ,
- Calcul de cap et de distance entre deux point distants de l'aéronef, par leurs coordonnées polaires (explication ci-dessous)
- Variations de cap et de vitesse à appliquer en fonction du vent (qui a déjà fait l'objet d'un post, mais le script présenté ne concernait que ce module de calcul),
- Calcul pour anticiper un virage standard. (qui a également fait l'objet d'un post),

Ce script fonctionne avec les paquets zenity, pour afficher des boîtes de dialogue à partir de script bash, et bc, qui permet des calculs basiques. Ces paquets doivent donc être installés pour que le script fonctionne (je crois qu'ils le sont par défaut).

Explication pour le quatrième module de calcul : la carte de FlightGear peut donner le cap et la distance entre l'emplacement actuel de l'aéronef et un point choisi, en cliquant-droit sur la carte. Cependant, l'affichage du cap et de la distance entre deux points dont aucun ne correspond à l'emplacement de l'aéronef n'est pas implémenté. Mais on peut s'en sortir en considérant que les distances et les caps de ces deux points par rapport à la position de l'aéronef (origine) correspondent à des coordonnées polaires. Je vous épargne les détails de ces calculs, mais vous pouvez fouiner dans le code pour le savoir.

Il suffit de télécharger le code suivant, de l'enregistrer dans un fichier "Calculs_FG.sh" (ou ce que vous voulez), de rendre ce dernier exécutable (chmod +x Calculs_FG.sh) puis de lancer le script.

#!/bin/bash

#fonctions
calc () {
    eval "$1=$(echo "$2" | bc -l)"
}

conv_degre_decim () {
    eval "$1=$(echo "scale=4; $2 + $3/60 +$4/3600" | bc -l)" 
}

conv_decim_degre () {
    eval "$1=$(echo "$2" |cut -f1 -d".")"
}

conv_decim_minut () {
    eval "$1=$(echo "($2 - $3)*60" | bc -l | cut -f1 -d".")"
}

conv_decim_secon () {
    eval "$1=$(echo "($2 - $3 - ($4/60))*3600" | bc -l | cut --complement -c5-)"
}

val_valid () {
Erreur=1
while [ $Erreur = "1" ]
do
    Erreur_decim=1
    while [ $Erreur_decim = "1" ]
    do 
        value=$(zenity --entry --title="Entrer la valeur" --text="$3" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R
        fi        
        if [ ! $value = "" ]; then
            okdeci=$(echo "$4/1" | bc)
            if (( $okdeci == 0 )); then
                echo $value | grep ,
                point=$(echo "$?" | bc)
                if [[ $point = 0 ]]; then
                    zenity --warning --title="Erreur !" --text="Cette valeur doit être entière (sans partie décimale)" 2>/dev/null
                    if [ ! $? = 0 ]; then annul R
                    fi               
                else
                    Erreur_decim=0       
                fi
            else
                Erreur_decim=0
            fi
        fi
    done
    abss1=$(echo "sqrt($2^2) - sqrt($value^2)" | bc)
    if [[ "$abss1" < "0" ]]; then
        zenity --warning --title="Erreur !" --text="Cette valeur doit être comprise entre -"$2" et "$2 2>/dev/null
        if [ ! $? = 0 ]; then annul R
        fi    
    else
        Erreur=0
        eval "$1=$(echo "$value")"
    fi
done
}

annul () {
    if [ "$1" = R ]; then
        ttr="Annulation"
        txt="Le script a été interrompu par l'utilisateur.
Relancer ?"
        zenity --question --title="$ttr" --width=230 --height=100 --text="$txt" 2>/dev/null  
    else
        zenity --warning --title="-=< ERREUR ! >=-" --width=230 --height=100 --text="Erreur du programme !
Valider pour relancer, sinon fermer cette fenêtre." 2>/dev/null  
    fi
    if [ ! $? = 0 ]; then
        unset all; exit 0
    else
        principal
    fi
}

choix_unit_cgeo () {
if [ "$2" = "conv" ]; then
    cdesc0=" à convertir"
    cdesc1=" vers D° M' S\""
    cdesc2=" vers D.dddd°"
else
    cdesc0=""
    cdesc1=""
    cdesc2=""
fi
text="Choisir l'unité des coordonnées géodésiques"$cdesc0
desc1="Coordonnées géodésiques décimales : D.dddd°"$cdesc1
desc2="Coordonnées géodésiques en ° ' \" : D° M' S\""$cdesc2     
REPEATchoix_unit_geo=1
while [ $REPEATchoix_unit_geo = "1" ]
do
    OPTION=$(zenity --list --radiolist --hide-column=2 --print-column=2 --width=450 --height=170\
    --title="Choix de l'unité des coordonnées géodésiques" \
    --text="$text" \
    --column="Choix" --column="blnDecimal" --column="Description"\
    "TRUE"  "bDec" "$desc1"\
    "FALSE" "bDeg" "$desc2" 2>/dev/null)
    if [ $? = 0 ]; then
        REPEATchoix_unit_geo=0
        eval "$1=$(echo "$OPTION")"
    else
        annul R
    fi
done
}

function conv_coord_geo {
choix_unit_cgeo cgeo "conv"
if [ $cgeo = "bDec" ]; then
    val_valid pgeo "90" "Coordonnée géodésique décimale :" 1
    conv_decim_degre intpgeo $pgeo
    conv_decim_minut minpgeo $pgeo $intpgeo
    conv_decim_secon secpgeo $pgeo $intpgeo $minpgeo
    zenity --info --title="Résultat" --width=200 --height=130\
    --text="Coordonnée géodésique en ° ' \" :
 "$intpgeo"° "$minpgeo"' "$secpgeo"\"" 2>/dev/null
elif [ $cgeo = "bDeg" ]; then
    val_valid pgeodeg "90" "Coord. géod. composante Degrés   :" 0 
    val_valid pgeomin "60" "Coord. géod. composante Minutes  :" 0
    val_valid pgeosec "60" "Coord. géod. composante Secondes :" 1
    conv_degre_decim pgeo $pgeodeg $pgeomin $pgeosec
    zenity --info --title="Résultat"  --width=200 --height=130\
    --text="Coordonnée géodésique décimale  :
$pgeo" 2>/dev/null 
else
    annul       
fi
}

var_cap_vit () {
    REPEATvitv=1
    while [ $REPEATvitv = "1" ]
    do
        VV=$(zenity --entry --title="Vitesse du vent" \
        --text="Vitesse du vent en noeuds (knot) :" \
        --entry-text="10" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $? = "" ]; then
            REPEATvitv=0
        fi
    done
    REPEATprov=1
    while [ $REPEATprov = "1" ]
    do
        capv=$(zenity --entry --title="Provenance du vent" \
        --text="Provenance du vent en degrés (donnée METAR) :" \
        --entry-text="0" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $? = "" ]; then
            REPEATprov=0
        fi
    done
    REPEATvita=1
    while [ $REPEATvita = "1" ]
    do
        VA=$(zenity --entry --title="Vitesse de l'aéronef" \
        --text="Vitesse de l'aéronef en noeuds (knot) :" \
        --entry-text="100" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $? = "" ]; then
            REPEATvita=0
        fi
    done
    capa=$1
    if [ $capa = "nul" ]; then
        REPEATcapa=1
        while [ $REPEATcapa = "1" ]
        do
            capa=$(zenity --entry --title="Cap de l'aéronef" \
            --text="Cap souhaité de l'aéronef en dégrés :" \
            --entry-text="0" 2>/dev/null)
            if [ ! $? = 0 ]; then annul R; fi
            if [ ! $? = "" ]; then
                REPEATcapa=0
            fi
        done
    fi
    calc capv "$capv-180"
    calc alpha "($capa - $capv)*$pi/180"
    calc VP "scale=3; sqrt($VA^2 + $VV^2 - 2*$VA*$VV*c ($alpha))"
    calc tau "scale=4; (a (($VV*s ($alpha))/($VA-($VV*c ($alpha)))))*180/$pi"
    calc nHDG "scale=4; $capa+$tau"
    zenity --info --title="Résultats" --width=450 --height=130\
    --text="Vitesse de l'aéronef (pratique)                               = "$VP" kt
Variation d'angle Tau entre les caps théorique et pratique  = "$tau"°
Cap de l'aéronef à appliquer                                  = "$nHDG"°" 2>/dev/null
}

function cap_dist {
    zenity --info --width=450 --height=130 --title="CALCUL DE CAP ET DISTANCE A PARTIR DES COORDS GEODESIQUES" \
    --text="Rappels : Caps N = 0°, E = 90°, S = 180° et W = 270°
signe de la latitude : + au Nord de l'équateur, - au Sud
signe de la longitude : + à l'Est de Greenwich, - à l'Ouest" 2>/dev/null
    choix_unit_cgeo cgeocd ""
    REPEATnomd=1
    while  [ $REPEATnomd = "1" ]
    do
        depart=$(zenity --entry --title="Nom du DEPART"\
        --text="Donner un nom au DEPART ? (sans espace)"\
        --entry-text="DEPART" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $depart = "" ]; then
            REPEATnomd=0
        fi
    done
    REPEATnoma=1
    while  [ $REPEATnoma = "1" ]
    do
        arrivee=$(zenity --entry --title="Nom de l'ARRIVEE"\
        --text="Donner un nom à l'ARRIVEE ? (sans espace)"\
        --entry-text="ARRIVEE" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $arrivee = "" ]; then
            REPEATnoma=0
        fi
    done
    if [ $cgeocd = "bDeg" ]; then
        val_valid dlatdeg "90" "$depart, Lat. Degrés   :" 0
        val_valid dlatmin "60" "$depart, Lat. Minutes  :" 0
        val_valid dlatsec "60" "$depart, Lat. Secondes :" 1
        conv_degre_decim dlat $dlatdeg $dlatmin $dlatsec
        zenity --info --title="" --text="Latitude décimale de "$depart" : "$dlat 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

        val_valid dlondeg "90" "$depart, Lon. Degrés   :" 0
        val_valid dlonmin "60" "$depart, Lon. Minutes  :" 0
        val_valid dlonsec "60" "$depart, Lon. Secondes :" 1
        conv_degre_decim dlon $dlondeg $dlonmin $dlonsec
        zenity --info --title="" --text="Longitude décimale de "$depart" : "$dlon 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

        val_valid alatdeg "90" "$arrivee, Lat. Degrés   :" 0 
        val_valid alatmin "60" "$arrivee, Lat. Minutes  :" 0
        val_valid alatsec "60" "$arrivee, Lat. Secondes :" 1
        conv_degre_decim alat $alatdeg $alatmin $alatsec
        zenity --info --title="" --text="Latitude décimale de "$arrivee" : "$alat 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

        val_valid alondeg "90" "$arrivee, Lon. Degrés   :" 0
        val_valid alonmin "60" "$arrivee, Lon. Minutes  :" 0
        val_valid alonsec "60" "$arrivee, Lon. Secondes :" 1
        conv_degre_decim alon $alondeg $alonmin $alonsec
        zenity --info --title="" --text="Longitude décimale de "$arrivee" : "$alon 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

    else
        val_valid dlat "90" "Latitude de "$depart" :" 1
        conv_decim_degre intdlat $dlat
        conv_decim_minut mindlat $dlat $intdlat
        conv_decim_secon secdlat $dlat $intdlat $mindlat
        zenity --info --width=200 --title="" --text="Latitude de "$depart" : 
"$intdlat"° "$mindlat"' "$secdlat"\"" 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi
        
        val_valid dlon "90" "Longitude de "$depart" :" 1
        conv_decim_degre intdlon $dlon
        conv_decim_minut mindlon $dlon $intdlon
        conv_decim_secon secdlon $dlon $intdlon $mindlon
        zenity --info --width=200 --title="" --text="Longitude de "$depart" : 
"$intdlon"° "$mindlon"' "$secdlon"\"" 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

        val_valid alat "90" "Latitude de "$arrivee" :" 1
        conv_decim_degre intalat $alat
        conv_decim_minut minalat $alat $intalat
        conv_decim_secon secalat $alat $intalat $minalat
        zenity --info --width=200 --title="" --text="Latitude de "$arrivee" : 
"$intalat"° "$minalat"' "$secalat"\"" 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi

        val_valid alon "90" "Longitude de "$arrivee" :" 1
        conv_decim_degre intalon $alon
        conv_decim_minut minalon $alon $intalon
        conv_decim_secon secalon $alon $intalon $minalon
        zenity --info --width=200 --title="" --text="Longitude de "$arrivee" : 
"$intalon"° "$minalon"' "$secalon"\"" 2>/dev/null
        if [ ! $? = 0 ]; then annul R; fi
    fi
    calc diflat "scale=4; $alat - $dlat"
    calc diflon "scale=4; $alon - $dlon"
    calc hdg "scale=4; (a($diflat/$diflon))*180/$pi"
    calc distnm "scale=4; 60*sqrt($diflat^2+$diflon^2)"
    calc distkm "scale=4; $distnm*1.852"
    if [ $(echo "$diflon >= 0" | bc) -eq 1 ]; then
        hdgc=$(echo "scale=4; 90 - $hdg" | bc -l)
    else
        hdgc=$(echo "scale=4; 270 - $hdg" | bc -l)
    fi
    zenity --info --width=500 --title="Résultats" --text="Pour "$depart" -> "$arrivee", prendre le cap (HDG) = $hdgc
La distance entre "$depart" et "$arrivee" est de "$distnm" nm ("$distkm" km)" 2>/dev/null

    zenity --question --title="Calculer la variation du cap due au vent ?" \
           --text="Calculer la variation du cap en fonction du vent et de la vitesse ?" 2>/dev/null
    if [ $? = 0 ]; then var_cap_vit $hdgc; fi
}

function cap_dist2 {
    zenity --info --width=450 --height=130 --title="CALCUL DE CAP ET DISTANCE ENTRE DEUX POINTS DISTANTS" \
    --text="Rappels : Caps N = 0°, E = 90°, S = 180° et W = 270°
signe de la latitude : + au Nord de l'équateur, - au Sud
signe de la longitude : + à l'Est de Greenwich, - à l'Ouest" 2>/dev/null
    REPEATnomd=1
    while  [ $REPEATnomd = "1" ]
    do
        depart=$(zenity --entry --title="Nom du DEPART"\
        --text="Donner un nom au DEPART ? (sans espace)"\
        --entry-text="DEPART" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $depart = "" ]; then
            REPEATnomd=0
        fi
    done
    REPEATnoma=1
    while  [ $REPEATnoma = "1" ]
    do
        arrivee=$(zenity --entry --title="Nom de l'ARRIVEE"\
        --text="Donner un nom à l'ARRIVEE ? (sans espace)"\
        --entry-text="ARRIVEE" 2>/dev/null)
        if [ ! $? = 0 ]; then annul R; fi
        if [ ! $arrivee = "" ]; then
            REPEATnoma=0
        fi
    done
    ddep=$(zenity --entry --title="Coordonnées polaires de "$depart --text="Distance au point de "$depart 2>/dev/null)
    val_valid adep "360" "Angle au point de "$depart" :" 0
    darr=$(zenity --entry --title="Coordonnées polaires de "$arrivee --text="Distance au point de "$arrivee 2>/dev/null)
    val_valid aarr "360" "Angle au point de "$arrivee" :" 0
    calc alpha "scale=4; (sqrt (($aarr-$adep)^2))*$pi/180"
    calc hdg "scale=4; $aarr-(a (($ddep*s ($alpha))/($darr-$ddep*c ($alpha))))*180/$pi"
    calc dist "scale=4; sqrt (($ddep*s ($alpha))^2+($darr-$ddep*c ($alpha))^2)"
    zenity --info --width=400 --title="Résultat" --text="Distance entre les points "$depart" et "$arrivee" (nm) : "$dist"
Cap pour relier les points "$depart" et "$arrivee" : "$hdg 2>/dev/null 
    if [ ! $? = 0 ]; then annul R; fi
}


function virage_std {
    zenity --info --width=500 --title="CALCULS POUR VIRAGE STANDARD" --text="Ce module permet de calculer le rayon, la distance et l'arc entre le début et la fin d'un virage standard et de l'anticiper. Entrer les valeurs demandées dans les boîtes de dialogue suivantes."
    if [ ! $? = 0 ]; then annul R; fi
V=$(zenity --entry --title="Vitesse de l'aéronef :" --text="Vitesse de l'aéronef en noeuds (knot) :" \
    2>/dev/null)
    if [ ! $? = 0 ]; then annul R; fi
    capi=$(zenity --entry --title="Radiale de départ" --text="Radiale D (°) :" 2>/dev/null)
    capf=$(zenity --entry --title="Radiale d'arrivée" --text="Radiale A (°) :" 2>/dev/null)
    calc Ry "scale=4; $V/(60*$pi)"
    calc alpha "scale=4; (sqrt (($capi-$capf)^2))*$pi/180"
    calc AD "scale=4; 2*$Ry*s ($alpha/2)"
    calc ARC "scale=4; $Ry*$alpha"
    calc DIST "scale=4; sqrt (($Ry*s ($alpha/2)/c ($alpha/2))^2)"
    zenity --info --width=500 --title="Résultats" --text="Rayon du cercle dans lequel s'inscrit le virage (nm) : "$Ry"
Distance entre le départ D et l'arrivée du virage A (nm) : "$AD"
Longueur de l'arc de cercle entre le départ D et l'arrivée du virage A (nm) : "$ARC"
Distance entre le départ du virage D et l'intersection des deux caps (nm) : "$DIST 2>/dev/null
    if [ ! $? = 0 ]; then annul R; fi
}

function conv_pression {
    hPa=$(zenity --entry --width=290 --height=130 --title="CONVERSION PRESSION hPa -> in. Hg" --text="Pression (hPa) = " 2>/dev/null)
    if [ ! $? = 0 ]; then annul R; fi
    calc inHg "scale=2; $hPa*0.75006375541921/25.4"
    zenity --info --width=230 --height=130 --title="CONVERSION PRESSION hPa -> in. Hg" --text=$hPa" hPa = "$inHg" in. Hg." 2>/dev/null
    if [ ! $? = 0 ]; then annul R; fi
}

function principal {
unset all
calc pi "scale=10; 4*a(1)"
REPEAT=1
while [ $REPEAT = "1" ]
do
    OPTION=$(zenity --list --radiolist --hide-column=2 --print-column=2 --width=480 --height=260\
    --title="Choix de la procédure de calcul" \
    --text="Sélectionner le calcul souhaité :" \
    --column="" --column="" --column="Description"\
    "TRUE"  "conv"  "Conversion coordonnées géodésiques décimales <-> ° ' \"" \
    "FALSE" "cpre"  "Conversion de pression atmosphérique hPa -> in. Hg" \
    "FALSE" "cahd"  "Calcul du cap et distance entre deux points géodésiques" \
    "FALSE" "capol" "Calcul du cap et distance entre deux points distants (coords polaires)" \
    "FALSE" "vacv"  "Variations de cap et vitesse en fonction du vent"\
    "FALSE" "vstd"  "Calculs pour un virage standard" 2>/dev/null)
    if [ ! $? = 0 ]; then
        annul R
        asked=1
    fi
    if [ "$OPTION" = "conv" ]; then     
        conv_coord_geo
    elif [ "$OPTION" = "vacv" ]; then
        var_cap_vit nul
    elif [ "$OPTION" = "cahd" ]; then
        cap_dist
    elif [ "$OPTION" = "capol" ]; then
        cap_dist2
    elif [ "$OPTION" = "vstd" ]; then
        virage_std
    elif [ "$OPTION" = "cpre" ]; then
        conv_pression
    fi
    if [ ! "$asked" = "1" ]; then
        zenity --question --title="Relancer le script ?" --text="Voulez-vous relancer le script ?" 2>/dev/null
        if [ ! $? = 0 ]; then REPEAT=0; fi
        asked=0
    fi
done
}

#Main
principal
unset all
exit

J'espère que ce script vous sera utile.

Bons vents et vols à tous smile

Dernière modification par exCorbac (7/02/2021 21:17:42)


-=exCorbac=-
"The owls are not what they seem. Especially in FlightGear." (David Lynch & exCorbac)
Version FG: next, OS: Linux Mint 20.2 64-bit (cinnamon 5.0.7), GC: AMD Radeon R9 380X 4Go, CPU: AMD FX8350 8-core 4GHz, RAM: 12Go DDR3 1333MHz, Ecrans: Samsung U28E590DS 2560x1440 (Freesync, DP), Dell 2407WFP-HC 1920x1200 (DVI), Thrustmaster T.Flight Stick X

Hors ligne

Pied de page des forums