IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C++ Discussion :

Utilisation des fonctions pack/unpack code/decode de eerimoq/cantools (motohawk example)


Sujet :

C++

  1. #1
    Membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Mars 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Mars 2006
    Messages : 71
    Points : 63
    Points
    63
    Par défaut Utilisation des fonctions pack/unpack code/decode de eerimoq/cantools (motohawk example)
    Bonjour,

    je souhaite utiliser les fonctions pack/unpack code/decode de l'exemple motohawk.c pour encoder et décoder un message 8 bytes HEX:
    Source: https://github.com/eerimoq/cantools/

    J'ai préparé un exemple qui compile sans erreur avec mingw g++ mais qui ne délivre pas les résultats attendus.

    Le message HEX à décoder est:
    {0x80, 0x4A, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}

    Les fonctions de motohaw.c que j'utilise sont:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    motohawk_example_message_enable_encode
    motohawk_example_message_average_radius_encode
    motohawk_example_message_temperature_encode
    motohawk_example_message_pack
     
    motohawk_example_message_unpack
    motohawk_example_message_enable_decode
    motohawk_example_message_average_radius_decode
    motohawk_example_message_temperature_decode
    Je ne suis pas sur de mon utilisation des pointeurs *dst_p et *src_p dans les fonctions pack/unpack définies dans motohawk.c

    Le résultat après "unpack" et "decode" devrait être:

    Signal: Enable 'Enabled'
    Signal: average_radius 0.0 m
    Signal: temperature 255.92 degK

    Le résultat après "encode" et "pack" devrait être:

    8 Byte message: 80 4A 0F 00 00 00 00 00


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    #include <stdio.h>
    #include <iostream>
    /* Using c-code for motohawk.dbc from CANTOOLS (https://github.com/eerimoq/cantools/) */
    #include "motohawk.h"
    #include "motohawk.c"
     
    int main(void)
    {
    	// PART_1: Unpack 8 bytes message using unpack functions from motohawk.c
    	unsigned char src_p_ID_1F0[8] = {0x80, 0x4A, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}; 
        //   |  0x1F0_enable         	'Enabled'   -	
        //   |  0x1F0_average_radius	0.0			m                    	           
        //   |  0x1F0_temperature		255.92		degK
     
    	struct motohawk_example_message_t dst_p_data;		// Object to unpack the message into.
    	size_t size_src_p_ID_1F0 = 8;				// Size of dst_p Buffer
     
    	// Unpack the source message into dst_p_data
    	motohawk_example_message_unpack(&dst_p_data, src_p_ID_1F0, size_src_p_ID_1F0); 
     
    	// Declare variables to store decoded physical values
    	uint8_t ID_1F0_enable;
    	uint8_t ID_1F0_avg_radius;
    	int16_t ID_1F0_temp;
     
    	ID_1F0_enable = motohawk_example_message_enable_decode(dst_p_data.enable);
    	ID_1F0_avg_radius = motohawk_example_message_average_radius_decode(dst_p_data.average_radius);
    	ID_1F0_temp = motohawk_example_message_temperature_decode(dst_p_data.temperature);
     
    	// To print the content of src_p_data 
    	std::cout << "Decoded_Value_enable:         " << unsigned(ID_1F0_enable) << std::endl;
    	std::cout << "Decoded_Value_average_radius: " << unsigned(ID_1F0_avg_radius) << std::endl;
    	std::cout << "Decoded_Value_temperature:    " << float(ID_1F0_temp) << std::endl;
     
     
    	//  PART_2: Pack value data into a 8 bytes message using pack functions from motohawk.h
     
    	// Declare src_p_data of type motohawk_example_message_t
    	struct motohawk_example_message_t src_p_data;
     
    	// Encode physical values and assign result to src_p_data
    	src_p_data.enable = motohawk_example_message_enable_encode(1u);
    	src_p_data.average_radius = motohawk_example_message_average_radius_encode(0.0);
    	src_p_data.temperature = motohawk_example_message_temperature_encode(255.92);
     
    	// To print the content of src_p_data 
    	std::cout << "Encoded_Hex_enable:         " << std::hex << static_cast<int>(src_p_data.enable) << std::endl;
    	std::cout << "Encoded_Hex_average_radius: " << std::hex << static_cast<int>(src_p_data.average_radius) << std::endl;
    	std::cout << "Encoded_Hex_temperature:    " << std::hex << static_cast<int>(src_p_data.temperature) << std::endl;
     
    	unsigned char dst_p_ID_1F0 = {0};		// Buffer to pack the message into.
    	size_t size_dst_p_ID_1F0 = 8;			// Size of dst_p Buffer
     
    	motohawk_example_message_pack(&dst_p_ID_1F0, &src_p_data, size_dst_p_ID_1F0);
     
    	std::cout << "Packed_message:	" << std::hex << static_cast<int>(dst_p_ID_1F0) << std::endl;
     
    	// To print the 8 bytes message ID_1F0 in HEX format
    	int loop;
    	printf("ID_1F0:	");
    	for(loop=0;loop<8;loop++)
    		printf("%02X ",dst_p_ID_1F0);
    	printf("\n");
     
        return 0;
    }
    Voici ce que mon code retourne pour le décodage (incorrect):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Decoded_Value_enable: 1
    Decoded_Value_average_radius: 0
    Decoded_Value_temperature: 255
    Voici ce que mon code retourne pour l'encodage (incorrect):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Encoded_Hex_enable: 1
    Encoded_Hex_average_radius: 0
    Encoded_Hex_temperature: 24f
    Packed_message: 0
    ID_1F0:	00 00 00 00 00 00 00 00
    Pouvez m'aider s'il vous plait pour la compréhension des fonctions pack/unpack de motohawk.c / motohawk.h et la correction de mon exemple?
    (ligne 19 et 54 dans mon code)


    https://github.com/eerimoq/cantools/...rce/motohawk.c
    https://github.com/eerimoq/cantools/...rce/motohawk.h

    Merci, Chris

  2. #2
    Membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Mars 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Mars 2006
    Messages : 71
    Points : 63
    Points
    63
    Par défaut
    J'ai compris mon erreur dans la partie 1) et trouvée une solution en remplaçant le type uint8 par float pour les variables suivantes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    float ID_1F0_avg_radius;
    float ID_1F0_temp;
    (...)
    std::cout << "Decoded_Value_average_radius: " << std::fixed << std::setprecision(2) << ID_1F0_avg_radius << std::endl;
    std::cout << "Decoded_Value_temperature:    " << std::fixed << std::setprecision(2) << ID_1F0_temp << std::endl;
    Pour la partie 2) l'encodage fonctionne mais pas la fonction motohawk_example_message_pack
    Je ne comprends toujours pas comment utiliser le pointeur *dst_p pour extraire les 3 bytes (dst_p[0], dst_p[1] et dst_p[2])
    Quelqu'un peut m'aider?

    Encoded_Bin_enable: 1
    Encoded_Bin_average_radius: 000000
    Encoded_Bin_temperature: 0010 0100 1111

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    */*
     * Pack message ExampleMessage.
     *
     * @param[out] dst_p Buffer to pack the message into.
     * @param[in] src_p Data to pack.
     * @param[in] size Size of dst_p.
     *
     * @return Size of packed data, or negative error code.
     */
     
    int motohawk_example_message_pack(
        uint8_t *dst_p,
        const struct motohawk_example_message_t *src_p,
        size_t size)
    {
        uint16_t temperature;
     
        if (size < 8u) {
            return (-EINVAL);
        }
     
        memset(&dst_p[0], 0, 8);
     
        dst_p[0] |= pack_left_shift_u8(src_p->enable, 7u, 0x80u);
        dst_p[0] |= pack_left_shift_u8(src_p->average_radius, 1u, 0x7eu);
        temperature = (uint16_t)src_p->temperature;
        dst_p[0] |= pack_right_shift_u16(temperature, 11u, 0x01u);
        dst_p[1] |= pack_right_shift_u16(temperature, 3u, 0xffu);
        dst_p[2] |= pack_left_shift_u16(temperature, 5u, 0xe0u);
     
        return (8);
    }

  3. #3
    Membre éprouvé
    Femme Profil pro
    ..
    Inscrit en
    Décembre 2019
    Messages
    562
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 94
    Localisation : Autre

    Informations professionnelles :
    Activité : ..

    Informations forums :
    Inscription : Décembre 2019
    Messages : 562
    Points : 1 253
    Points
    1 253
    Par défaut
    Bonjour,

    Tu peux essayer ceci si tu veux :
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #include <stdint.h>
    #include <stdio.h>
    #include "motohawk.h"
     
    int main(void)
    {
        uint8_t msg_src[]= 
            {0x80, 0x4A, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00}; 
        for (size_t i=0; i < sizeof(msg_src); ++i)
            printf("0x%02X ", msg_src[i]);
        puts("");
        struct motohawk_example_message_t dt_dst;
        int upk_err= motohawk_example_message_unpack(&dt_dst, msg_src, sizeof(msg_src));
        //if (upk_err != 0) ... //handle unpack error.
        double enbl= motohawk_example_message_enable_decode(dt_dst.enable);
        double avrr= motohawk_example_message_average_radius_decode(dt_dst.average_radius);
        double temp= motohawk_example_message_temperature_decode(dt_dst.temperature);
     
        printf("%.f %.f %.2f", enbl, avrr, temp);
     
        struct motohawk_example_message_t dt_src;
        dt_src.enable= motohawk_example_message_enable_encode(1.0);
        dt_src.average_radius= motohawk_example_message_average_radius_encode(0.0);
        dt_src.temperature= motohawk_example_message_temperature_encode(255.92);
     
        uint8_t msg_dst[8]= {0};
        size_t z= sizeof(msg_dst);
        int pk_err= motohawk_example_message_pack(msg_dst, &dt_src, z);
        //if (pk_err != z) ... //handle pack error.
        puts("");
        for (size_t i=0; i < z; ++i)
            printf("0x%02X ", msg_dst[i]);
    }
     
    /*
    output:
    0x80 0x4A 0x0F 0x00 0x00 0x00 0x00 0x00 
    1 0 255.92
    0x80 0x49 0xE0 0x00 0x00 0x00 0x00 0x00 
    */
    Comme les calculs se font sur des flottants, les résultats peuvent varier mais les ordres de grandeurs sont conservés.

  4. #4
    Membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Mars 2006
    Messages
    71
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique

    Informations forums :
    Inscription : Mars 2006
    Messages : 71
    Points : 63
    Points
    63
    Par défaut
    Merci, j'ai essayer ton code, il fonctionne bien. j'ai juste rajoutée la ligne suivant pour compiler. L'erreur d'arrondi relative a l'utilisation de flottants est assez gênante pour mon application.
    Je vais essayer de traiter les arrondis lors de la conversion de type.

    Le problème que j'avais est résolu et j'ai compris ta solution. Encore merci

  5. #5
    Rédacteur/Modérateur


    Homme Profil pro
    Network game programmer
    Inscrit en
    Juin 2010
    Messages
    7 115
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : Canada

    Informations professionnelles :
    Activité : Network game programmer

    Informations forums :
    Inscription : Juin 2010
    Messages : 7 115
    Points : 32 967
    Points
    32 967
    Billets dans le blog
    4
    Par défaut
    Comment peut-on être ingénieur développement et faire un include d'un .c.. ?
    On n'inclue jamais de .c. C'est la règle #0 du cours de C.
    Si ton .c n'est pas compilé, c'est ton projet qui est mal foutu. Un .c ça se compile et la sortie se link, ça s'inclue pas.
    Pensez à consulter la FAQ ou les cours et tutoriels de la section C++.
    Un peu de programmation réseau ?
    Aucune aide via MP ne sera dispensée. Merci d'utiliser les forums prévus à cet effet.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 0
    Dernier message: 30/03/2012, 17h26
  2. Réponses: 2
    Dernier message: 14/02/2011, 19h30
  3. [hibernate] utilisation des fonctions d'aggregation
    Par osopardo dans le forum Hibernate
    Réponses: 2
    Dernier message: 29/08/2005, 09h41
  4. utilisation des fonctions d'une dll
    Par jackk dans le forum C++
    Réponses: 14
    Dernier message: 15/06/2005, 16h50
  5. Utiliser des fonctions Pascal
    Par Neilos dans le forum C++Builder
    Réponses: 2
    Dernier message: 07/03/2004, 15h43

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo