Variable P3D avec "units" Mask

Programmation LUA, Macros FSUIPC, logiciel LINDA
et codage en LUA des gauges Air Manager

Variable P3D avec "units" Mask

Messagede arcc » Jeu 10 Sep 2020 15:10

Bonsoir à tous.

Je cherche à déclarer une variable qui à comme unité "Mask" dixit le SDK de P3D

Simulation Variable : AMBIENT PRECIP STATE
Description : Precip state (bit field)
2 = None
4 = Rain
8 = Snow
Units : Mask

Dans le script de Air Manager je ne sais pas comment ecrire l'unité

fsx_variable_subscribe("AMBIENT PRECIP STATE", "? ? ? ?", Precip_state)


pour la renseigner dans le script

function Precip_State(Precipitation)
if Precipitation == 2 then


Quant c'est "bool" "Enum" "Position" ou autre ca va mais la "Mask" ...

Merci
Christian
Un ancien sous-marinier qui a pris de la hauteur.
Avatar de l’utilisateur
arcc
 
Messages: 715
Inscription: 16/12/13
Localisation: La ou fini la terre (Finistere)

Re: Variable P3D avec "units" Mask

Messagede altack » Ven 11 Sep 2020 14:12

Bonjour Christian,
je vais tenter une explication mais je serai certainement maladroit aussi, tous, n'hésitez pas à me corriger...
Lorsque une info n'est contenue que dans un seul bit (0 ou 1) il est tentant de la regrouper avec d'autres infos de même nature ( et de même taille) dans un octet pour faciliter son exploitation, avec par exemple :
les différents feux/lumières d'un avion: Strobes éteints ou allumés...0 ou 1, phare d'atterrissage éteint ou allumé...0 ou 1 etc...
La variable P3D "LIGHT ON STATES" est construite ainsi: son bit de poid le plus faible représente les "Nav lights", le second le Beacon etc.. jusqu'au dernier les "Cabin lights"
Si je ne m’intéresse qu'aux feux de Nav, à l'exclusion des autres, je dois appliquer un masque pour filtrer les bits qui ne m’intéressent pas et ne garder que celui le plus à droite dans la séquence. On applique alors un "&" logique à la variable LIGHT ON STATES avec la valeur 0x0001 et son résultat devient alors 0 ou 1 selon que les Navs soient allumés ou éteints.
Si je veux savoir comment sont les Cabin Lights, je fais la même manip avec la valeur 0x0200 et consulte la réponse (0 ou 512)...

Pour revenir à Air manager, je te suggère de t'abonner à la variable qui t'intéresse sous forme "number" puis d'effectuer l'opération de masque pour enfin connaitre l'état de chaque bit...

Afin d'illustrer je te livre ci-dessous tel quel un script lua pour des afficheurs liés aux GPS Garmin 530 de RXP.
Je m'abonne à la variable locale "L:rxp.gps.discrete_out" que j'utilise ensuite dans la fonction "set_nav_source_fsx" avec différents masques: 0x00080000, 0x00080004, 0x00080010 etc..

Ais-je pu t'apporter une réponse utile ?
Bon courage cligneoeil
François

Code: Tout sélectionner
img_add_fullscreen("nav_gps_annunciator_background.png")
img_vloc_light = img_add("vloc_light.png", 0, 0, 150, 90)
img_gps_light = img_add("gps_light.png", 0, 90, 150, 90)
img_term_light = img_add("term_light.png", 150, 0, 150, 90)
img_apr_light = img_add("apr_light.png", 150, 90, 150, 90)
img_wpt_light = img_add("wpt_light.png", 300, 0, 150, 90)
img_msg_light = img_add("msg_light.png", 300, 90, 150, 90)
img_intg_light = img_add("intg_light.png", 450, 90, 150, 90)

visible(img_vloc_light, false)
visible(img_gps_light, false)
visible(img_term_light, false)
visible(img_apr_light, false)
visible(img_wpt_light, false)
visible(img_msg_light, false)
visible(img_intg_light, false)


local test = 0
local state_test = false

p_mask = img_add_fullscreen("Bigdimoverlay_Emilie.png")

---------------------------------------------
--   Functions                             --
---------------------------------------------
opacity (p_mask, 0)

function dim_button_pressed()
        opacity (p_mask, 1)   
end

function dim_button_released()
        opacity (p_mask, 0)     
end
 
function test_button_pressed()
        test = 1
        print("bouton D30 press") 
end

function test_button_released()
        test = 0
        print("bouton D30 released") 
end
 
-- Function for FSX and Prepar3D


function set_nav_source_fsx(discrete_output, bus_volts)

   power = bus_volts > 16

        test_bit_instr_tst =  math.floor( discrete_output & 0x00080000 )
        print ("test_bit_instr_tst", test_bit_instr_tst)
        if test_bit_instr_tst == 524288 or test == 1 then state_test = true else state_test = false
        end

        if state_test == true then
      visible(img_vloc_light, power)
                visible(img_gps_light, power)
                visible(img_term_light, power)
                visible(img_apr_light, power)
                visible(img_wpt_light, power)
                visible(img_msg_light, power)
                visible(img_intg_light, power)
       else
       
-- GPS source selected (if not vloc displayed)
        test_bit_gps =  math.floor( discrete_output & 0x00080004 )
       -- print ("test_bit_gps", test_bit_gps)
        if test_bit_gps == 4 then state_gps = true else state_gps = false
        end
   visible(img_vloc_light, not state_gps and power)
   visible(img_gps_light, state_gps and power)

-- TERM displayed   
        test_bit_term =  math.floor( discrete_output & 0x00080010 )
       -- print ("test_bit_term", test_bit_term)
        if test_bit_term == 32 then state_term = true else state_term = false
        end
        visible(img_term_light, state_term and power)

-- APR displayed   
        test_bit_apr =  math.floor( discrete_output & 0x00080200 )
        --print ("test_bit_apr", test_bit_apr)
        if test_bit_apr == 128 then state_apr = true else state_apr = false
        end
        visible(img_apr_light, state_apr and power)

-- WPT displayed   
        test_bit_wpt =  math.floor( discrete_output & 0x00080008 )
       -- print ("test_bit_wpt", test_bit_wpt)
        if test_bit_wpt == 16 then state_wpt = true else state_wpt = false
        end
        visible(img_wpt_light, state_wpt and power)

-- MSG displayed   
        test_bit_msg =  math.floor( discrete_output & 0x00080100 )
       --print ("test_bit_msg", test_bit_msg)
        if test_bit_msg == 256 then state_msg = true else state_msg = false
        end
        visible(img_msg_light, state_msg and power)

-- INTG displayed   
        test_bit_intg =  math.floor( discrete_output & 0x00080080 )
       -- print ("test_bit_intg", test_bit_intg)
        if test_bit_intg == 64 then state_intg = true else state_intg = false
        end
        visible(img_intg_light, state_intg and power)
      end
end


fsx_variable_subscribe("L:rxp.gps.discrete_out", "number",
                       "ELECTRICAL MAIN BUS VOLTAGE", "Volts", set_nav_source_fsx)

-- Button function for GPS NAV switch

function button_GPS_NAV_SWITCH_pressed()

   fsx_event("TOGGLE_GPS_DRIVES_NAV1")

end

--Button Hardware section
--++++++++++++++++++++++++++++--
--Xnn
hw_button_add("Button_GPS_NAV_SWITCH", button_GPS_NAV_SWITCH_pressed)
hw_button_add("Dim button", dim_button_pressed, dim_button_released)
hw_button_add("Test button", test_button_pressed, test_button_released) 
                   
...ou quelqu’un d’autre
altack
 
Messages: 119
Inscription: 31/07/20

Re: Variable P3D avec "units" Mask

Messagede arcc » Ven 11 Sep 2020 18:24

Déjà merci pour ta réponse. Il va falloir que je regarde ca de très prêt. Je ne suis pas très habitué avec ce type de langage.
J'ai réussi à faire toutes mes jauges pour mon cockpit de Twin mais je marche beaucoup en m'aidant de ce que les autres ont fait (en ligne dans Air manager) et aussi avec l'aide des membres du forums qui manipule le langage LUA avec facilité.

Je vais donc décortiqué tout ca, si ca prend un peu de temps, ne m'en veux pas,.

A+
Chrisitan
Un ancien sous-marinier qui a pris de la hauteur.
Avatar de l’utilisateur
arcc
 
Messages: 715
Inscription: 16/12/13
Localisation: La ou fini la terre (Finistere)

Re: Variable P3D avec "units" Mask

Messagede PapaLima » Mar 15 Sep 2020 22:55

Bonsoir Christian,

la réponse de François est très bien, je vais en rajouter une couche si çà peut t'aider je serais ravi :

L'utilisation d'un masque permet de ne conserver QUE les valeurs binaires (bit) qui nous intéressent.
Pour ce faire on fait un ET logique (AND)

la table du AND c'est:

0 ET 0 = 0
0 ET 1 = 0
1 ET 0 = 0
1 ET 1 = 1

On voit bien que l'on ne conserve QUE le bit de la valeur si il correspond à 1 avec son homologue du masque

Le masque sert à ne conserver que la ou les positions binaires voulues.
C'est comme si tu appliquais un filtre sur une valeur d'entrée.

Je pense que c'est l'écriture qui peut perturber car en LUA on programme souvent en donnant des valeurs en hexadécimal (pour éviter d'aligner des 0) et on l'écrit 0x<valeur> et on trouve aussi les valeurs décimales.... çà peut embrouiller.

Exemple sur un octet = byte = 8 bits

Code: Tout sélectionner
Binaire      Décimal    Hexadécimal
(base 2)    (base 10)       (base 16)
00000000       0             0x00
00000001       1             0x01
00000010       2             0x02
00000100       4             0x04       0*16+4=4
00001000       8             0x08
00001001       9 (8+1)       0x09
00001010      10 (8+2)       0x0A       0*16+10=10 en base 10 (la notre avec nos dix doigts)
00001011      11 (8+2+1)     0x0B
00001100      12 (8+4)       0x0C
00001101      13 (8+4+1)     0x0D
00001110      14 (8+4+2)     0x0E
00001111      15 (8+4+2+1)  0x0F

tu continues la même chose sur les 4 premières positions et le premier chiffre hexa va bouger

00010000     16                 0x10    1*16 + 0 = 16 (base 10)
00010001     17                 0x11    1*16 + 1 = 17 (base 10)

(...)

11111111    255                0xFF   


Si par exemple tu ne veux conserver que les 4 bits de droite (genre les 4 valeurs lumière que tu veux filtrer)

Tu fais valeur AND 0x0F ou valeur AND 15 (je trouve moins facile à lire les masques lorsqu'ils sont exprimés en décimal mais çà marchera) et le résultat n'aura que les valeurs des 4 bits de droite soit des valeurs de de 0 à 15 en décimal

Dans ton exemple (on a bien 'bit field' dans la doc)
2 = None 0010 rien
4 = Rain 0100 pluie
8 = Snow 1000 neige

l'histoire ne dit pas si on peut avoir une combinaison mais d'un point de vue binaire c'est possible
de la neige "fondue en pluie" ou de la "pluie surfondue" avec la valeur 1100 8+4=12 sourirebis

Sous Windows 10, la calculette peux être basculée en mode "programmeur" et tu as accès aux opérateurs logiques.
9à pourrait être pratique dans le cas où tu te retrouves avec un gros nombre sur 16/32/64 bits encodés et nécessitant un masque...

a+
Philippe

j'espère ne pas m'être égaré là .... mince j'aurais abusé de la bière ? lolaffiche
Avatar de l’utilisateur
PapaLima
 
Messages: 816
Inscription: 14/04/16
Localisation: LFPG

Re: Variable P3D avec "units" Mask

Messagede arcc » Jeu 17 Sep 2020 18:49

Bonsoir Philippe.

Je n'ai pas tellement avancé (trop de boulot).
J'ai quand même suivi le premier conseil de François
Pour revenir à Air manager, je te suggère de t'abonner à la variable qui t'intéresse sous forme "number" puis d'effectuer l'opération de masque pour enfin connaitre l'état de chaque bit.

Avec "number" j'ai déjà directement la valeur 0 pour rien, 4 quand il pleut....
J'en suis là pour l'instant et si ça fonctionne avec "number" chouettedoights

Je pense faire un vol ce week end en cherchant une météo adéquat, une variable qui passes de 0 à 4 et vice versa pour voir si ça fonctionne.


Christian
Un ancien sous-marinier qui a pris de la hauteur.
Avatar de l’utilisateur
arcc
 
Messages: 715
Inscription: 16/12/13
Localisation: La ou fini la terre (Finistere)


Retourner vers LUA, Linda, Macros & gauges Air Manager





Qui est en ligne

Utilisateurs parcourant ce forum: Aucun utilisateur enregistré et 7 invités

cron