Code GRAY

Python est le langage de prédilection du Raspberry Pi

Modérateurs : Francois, Manfraid

Bud Spencer
Raspinaute
Messages : 722
Enregistré le : lun. 15 août 2016 21:38

Re: Code GRAY

Message par Bud Spencer » ven. 7 févr. 2020 18:43

Salut Artemus.

La subtilité du code gray, c'est surtout que l'incrémentation ou la décrémentation de 1 ne modifie jamais qu'un seul bit alors que pour le binaire l'ensemble des bits peuvent changer. Par exemple pour passer de 7 a 8 en binaire, il faut modifier tous les bits (4). C'est un peu déroutant quand on ne fait que du binaire, mais le gray est tout aussi rationnel et très facile a utiliser quand on s'y habitue.

Si on parle en terme de codage, le plus simple à toujours été l'xor. C'est meme marrant de voir que des tas gens s'inventent des algos (comme ici) de toutes sortes pour ça alors que le gray n'est que l'interprétation d'une logique booléenne bien définie et qui a l'origine avait juste pour but de permettre la transposition d'effets mécaniques en logique (avec les moyens de l'époque).
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » sam. 8 févr. 2020 09:36

Bonjour ,

Ça avance !

J'ai donc encodé les positions girouette sur le code gary , puis j'en ai fait une conversion pour m'éviter les calculs gray à binaire .

Ça donne ça :

Image

Le code , pour ceux que ça intéresse :

Code : Tout sélectionner

def bin2gray (n):        # Bin 2 Gray
    g = n ^ (n >> 1)
    return g

def gray2bin (n):        # Gray 2 Bin
    b = n
    while n :
        n >>= 1
        b ^= n
    return b

dec2bin = lambda n,bits=0 : "0" * (bits - n.bit_length()) + bin(n)[2:] * bool(n)


rosace = (' N ', 'NNE', ' NE', 'ENE',\
          ' E ', 'ESE', ' SE', 'SSE',\
          ' S ', 'SSO', ' SO', 'OSO',\
          ' O ', 'ONO', ' NO', 'NNO')   # Table gray

g2b_rosace = 16 * ['']                  # Table binaire

for n in range (16):                    # conversion table
    g = bin2gray (n)
    b = gray2bin (g)
    g2b_rosace[g] = rosace[b]    

#
# Test 
#

for n in range (16):
    if not(n) : print ("Dec , Gray , Dec ,  Binaire , --> ,    Gray , -->")
    g = bin2gray (n)
    b = gray2bin (g)
    print ("%3i , %4i , %3i , %8s , %3s ,%8s , %3s"\
        %(n, g, b, dec2bin(n), g2b_rosace[n], dec2bin(g), rosace[n] ))
Avec une variante conversion gray2bin (dit autrement).
Et une utilisation de la fonction lambda pour convertir les nombres décimaux en binaire , avec le nombre de bits souhaités .


Les masques pour le disque CD (pas à l'échelle) qu'il faut choisir en fonction de l'orientation du disque (lecture dessus ou dessous) :
le LSB (bit 0) est sur le périmètre extérieur .

Image

Image

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » sam. 8 févr. 2020 12:11

Ou plus simple , 4 disques empilés du diamètre que l'on veut , ça prendra moins de place. .
On vient alors lire sur la tranche

Image

Image

Image

Image

Bud Spencer
Raspinaute
Messages : 722
Enregistré le : lun. 15 août 2016 21:38

Re: Code GRAY

Message par Bud Spencer » dim. 9 févr. 2020 10:45

ou tout simplement :
rosace.png
rosace.png (25.51 Kio) Vu 122 fois
:lol: ;)
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » lun. 10 févr. 2020 09:02

Bonjour ,

Oui c'est plus simple . :D
Je suis plutôt brouillon , j'ai laissé pas mal de code inutile (affichage).

La partie test peut être remplacée par le code suivant :

Code : Tout sélectionner

print ("\nListe rosace :\n" , rosace)
print ("\nListe convertie :\n " , g2b_rosace)
print ("\n")
Il affiche alors que les deux listes ; d'où je suis parti à là où je voulais arriver .
Image
En lisant le code Gray sur les disques , appliqué à la liste converti (celle du bas) , je devrais voir s'afficher la suite logique de la liste du dessus .


La liste pourra être complétée par les noms des vents ci-dessous :
Image

Il existe d'autres vents intermédiaires , si vous voulez compléter ....
http://ecolegrandpre.blogspot.com/2012/ ... vents.html

... , mais il faudra ajouter un 5eme bit sur le disque / disque supplémentaire pour passer de 16 à 32 points cardinaux .

Bud Spencer
Raspinaute
Messages : 722
Enregistré le : lun. 15 août 2016 21:38

Re: Code GRAY

Message par Bud Spencer » lun. 10 févr. 2020 15:51

MSG a écrit :
lun. 10 févr. 2020 09:02
Je suis plutôt brouillon , j'ai laissé pas mal de code inutile (affichage).
Bha, tu sais l’auto-apprentissage de la programmation n’a jamais mené aux meilleures méthodes du premier coup, mais tout ce qui est appris par expérimentation reste appris et forcement un jour ou l’autre, ça sert. Tu as déjà le reflexe de rechercher à chaque fois une solution ‘logique’ et c’est plutôt une bonne chose.
MSG a écrit :
lun. 10 févr. 2020 09:02
La liste pourra être complétée par les noms des vents ci-dessous :
Tout à fait, et c’est là tout l’intérêt des listes. Dans l’exemple que je t’ai donné, c’est un tuple de tuple et tu pourrais très bien ajouter d’autre valeurs :

Code : Tout sélectionner

rosace = (('N',0, 'La Tramontane'),('NNE',1, 'La Tramontane Grecque'), ….
Le nom du vent aurait la position [2] dans chaque tuple de la liste.
Tu pourrais aussi aller plus loin en définissant tes vents comme des objets d’un objet girouette (exemple d’évolution du de codage ici)

A titre d’info, voila quelques exemples pour recherche dans les listes. Il y a une foule de façons de le faire, mais tu peux voir ici un des vrais intérêts des lambda qui permettent de passer la fonction dans une instruction.
rosace2.png
rosace2.png (74.66 Kio) Vu 83 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » mar. 11 févr. 2020 13:37

Bonjour ,

Je n'ai pas besoin de faire de recherche aussi complexe , mais merci , c'est bon à connaître .
J'ai juste besoin de décoder le binaire gray des position , le plus simplement possible :

Code : Tout sélectionner

rosace = [' N ', 'NNE', 'ENE', ' NE',\
          'SSE', ' SE', ' E ', 'ESE',\
          'NNO', ' NO', ' O ', 'ONO',\
          ' S ', 'SSO', 'OSO', ' SO']
          
dec2bin = lambda n,bits=0 : "0" * (bits - n.bit_length()) + bin(n)[2:] * bool(n)

girouette = (0, 1, 3, 2, 6, 7, 5, 4, 12, 13, 15, 14, 10, 11, 9, 8)
print ("girouette sens horaire :" , girouette)

print ("\nLa girouette tourne dans le sens horaire :")
for n in range(32) :
    g = girouette [n % 16]
    print ("%2i , %s , %s" % (g, dec2bin(g,4), rosace[g]))
    
    

print ("\nLa girouette tourne dans le sens anti-horaire :")
for n in range (32,0,-1) :
    g = girouette [n % 16]
    print ("%2i , %s , %s" % (g, dec2bin(g,4), rosace[g]))

Bud Spencer
Raspinaute
Messages : 722
Enregistré le : lun. 15 août 2016 21:38

Re: Code GRAY

Message par Bud Spencer » mar. 11 févr. 2020 16:22

MSG a écrit :
mar. 11 févr. 2020 13:37
J'ai juste besoin de décoder le binaire gray des position , le plus simplement possible :
Alors soit pragmatique et ne complique pas ton code avec des trucs totalement inutiles

1 - tu t’embarrasses avec 2 listes, alors qu’une seule suffit et ça simplifie tout le reste de code.

2 – ta fonction dec2bin fais tout un tas d’opération bien inutile à chaque conversion. Un simple format de string suffirait pour ajouter des ‘0’ à gauche (avec rjust par exemple)

3 – Faire un range 32 pour ensuite faire un modulo sur la taille de la liste n’a aucun sens. En plus de faire 32 opérations pour rien, ta boucle fait le double de rotation pour rien. Si tu veux prévoir la possibilité d’ajouter d’autres directions plus tard, ne le quantifie surtout pas dans ton code. La taille de la liste est elle-même explicite et ça te permet d’ajouter ou de supprimer autant d’élément que tu veux sans aucune incidence sur le reste du code
gir.png
gir.png (26.05 Kio) Vu 56 fois
Le premier ennemi de la connaissance n’est pas l’ignorance, c’est l’illusion de la connaissance (S. Hawking).

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » mer. 12 févr. 2020 20:11

Bonsoir ,

Je sais , c'est brouillon mais c'est juste pour tester que la conversion rosace se fait sans accroc dans les deux sens .

1°) La seconde liste "Roue" c'est pour émuler les code que me renverra la roue encodée Gray
2°) j'avais trouvé cette solution pour afficher les 0 à gauche , mais c'est vrai qu'avec rjust c'est plus propre .
3°) j'aurais du codé en while au lieu de for pour donner un nombre de pas dans un sens et l'autre .
le modulo % c'est pour m'éviter de sortir de la liste Rosace .

je te l'accorde , j'ai pas fait simple .

Je me suis amusé à ajouter des valeur au tableau .
La encore des listes à n'en plus finir ... :D ... pas taper !!!

Je m'explique :
J'ai prévu des roses_des_vents pour du 16 et 32 points cardinaux et donc les roue_code qui vont avec .
Le 16 points devrait tenir dans un tube de un peu moins de 4cm de diamètre (35,65mm = 16 x 7mm / pi)
Le 32 points devrait tenir dans un tube de un peu moins de 8cm de diamètre (71,30mm = 32 x 7mm / pi)
7mm c'est la largeur du capteur optique CNY70
http://www.vishay.com/docs/83751/cny70.pdf
En fonction de ce que je trouverais comme tuyau de récup .
Les roulements , c'est des soldes sur des accessoires planches à roulettes (D_ext=22mm et D_in= 8mm env - pour de la tige fileté de 8mm maxi).

Code : Tout sélectionner

rose_des_vents32 = ((' N ', '  0.00', 'Tramontane')     ,\
                    (' N ', ' 11.25', 'Vent droit')     ,\
                    (' NE', ' 33.75', 'Brise noire')    ,\
                    ('NNE', ' 22.50', 'Montagnère')     ,\
                    ('  E', ' 78.75', 'Auro-bruno')     ,\
                    ('ENE', ' 67.50', 'Levant grégale') ,\
                    (' NE', ' 45.00', 'Gregale')        ,\
                    (' NE', ' 56.25', 'Lombarde')       ,\
                    (' S ', '168.75', 'Embat')          ,\
                    ('SSE', '157.50', 'Simoun')         ,\
                    (' SE', '135.00', 'Autan')          ,\
                    (' SE', '146.25', 'Sirocco')        ,\
                    ('  E', ' 90.00', 'Levant')         ,\
                    ('  E', '101.25', 'Auro-rosso')     ,\
                    (' SE', '123.75', 'Levèche')        ,\
                    ('ESE', '112.50', 'Vent blanc')     ,\
                    (' N ', '348.75', 'Auro-drecho')    ,\
                    ('NNO', '337.50', 'Brise')          ,\
                    ('NO ', '315,00', 'Mistral')        ,\
                    ('NO ', '326.25', 'Traverse haute') ,\
                    ('O  ', '270.00', 'Ponent')         ,\
                    ('O  ', '281.25', 'Traverse')       ,\
                    ('NO ', '303.75', 'Galerne')        ,\
                    ('ONO', '292.50', 'Maestro')        ,\
                    (' S ', '180,00', 'Marin')          ,\
                    (' S ', '191.25', 'Vent de bas')    ,\
                    ('SO ', '213.75', 'Vent du large')  ,\
                    ('SSO', '202.50', 'Chili')          ,\
                    ('O  ', '258.75', 'Cierco')         ,\
                    ('OSO', '247.50', 'Garbi')          ,\
                    ('SO ', '225,00', 'Labech')         ,\
                    ('SO ', '236,25', 'Libeccio')       )

rose_des_vents16 = ((' N ', '  0.00', 'Tramontane')     ,\
                    ('NNE', ' 22.50', 'Montagnère')     ,\
                    ('ENE', ' 67.50', 'Levant grégale') ,\
                    (' NE', ' 45.00', 'Gregale')        ,\
                    ('SSE', '157.50', 'Simoun')         ,\
                    (' SE', '135.00', 'Autan')          ,\
                    ('  E', ' 90.00', 'Levant')         ,\
                    ('ESE', '112.50', 'Vent blanc')     ,\
                    ('NNO', '337.50', 'Brise')          ,\
                    ('NO ', '315,00', 'Mistral')        ,\
                    ('O  ', '270.00', 'Ponent')         ,\
                    ('ONO', '292.50', 'Maestro')        ,\
                    (' S ', '180,00', 'Marin')          ,\
                    ('SSO', '202.50', 'Chili')          ,\
                    ('OSO', '247.50', 'Garbi')          ,\
                    ('SO ', '225,00', 'Labech')         )

roue_codes32 = ( 0,  1,  3,  2,  6,  7,  5,  4  ,\
                12, 13, 15, 14, 10, 11,  9,  8  ,\
                24, 25, 27, 26, 30, 31, 29, 28  ,\
                20, 21, 23, 22, 18, 19, 17, 16  )

roue_codes16 = ( 0,  1,  3,  2,  6,  7,  5,  4  ,\
                12, 13, 15, 14, 10, 11,  9,  8  )


def Test_rose_des_vents (rose, roue):
    l = len(rose)
    n = 0
    print (" g , bin_r , azimut , -----> , vent")
    while n <= l :
        g = roue [n % l]
        bin_r = bin(g)[2:].rjust(5,'0')     # binaire justifié à droite
        valeurs = rose[g]
        direction = valeurs[0]
        azimut = valeurs[1]
        vent = valeurs[2]
        print ("%2i , %s , %6s , %6s , %s°"\
            % (g, bin_r, azimut, direction, vent ))
        n += 1                              # tourne sens horaire
    n -= 1


# Rose des vents 16
#--------------------
rose = rose_des_vents16
roue = roue_codes16
print ("Rose des vents 16 points")
Test_rose_des_vents (rose, roue)


# Rose des vents 32
#--------------------
rose = rose_des_vents32
roue = roue_codes32
print ("Rose des vents 32 points")
Test_rose_des_vents (rose, roue)
C'est que du code test , pour le moment , afin de vérifier les listes .
Il y a certainement moyen d'utiliser que la liste 32 points pour faire du 16 points , mais là c'est le cerveau qui fume et pas envie de compliquer le code .

PS ; ce coup-ci , j'ai juste fait un tour complet Nord à Nord .
PS2: peut-être devrais-je ouvrir un autre sujet pour traiter la construction et faire le lien avec celui-ci pour expliquer le codage des roues .

MSG
Messages : 56
Enregistré le : ven. 26 déc. 2014 18:31

Re: Code GRAY

Message par MSG » mer. 12 févr. 2020 20:35

Les disques que j'ai redessiné pour ajouter un 5eme bit d'encodage .
Ils ne sont pas à l'échelle , faudra les agrandir sûrement , avec GIMP c'est un jeu d'enfant ... pour qui connais bien sûr .

Bit 4 (MSB)
Image

Bit 3
Image

Bit 2
Image

Bit 1 [LSB 16 points cardinaux]
Image

Bit 0 [LSB 32 points cardinaux]
Image

Répondre

Retourner vers « Python »