Répondre à la discussion
Affichage des résultats 1 à 9 sur 9

Comment communiquer les distances à mon robot ?



  1. #1
    dav1307

    Comment communiquer les distances à mon robot ?


    ------

    Bonjour,

    Je suis en train de faire un programme sous LabVIEW qui doit communiquer avec une brique Lego Mindstorms (brique qui sert à contrôler un robot fait en Lego) (La communication labview/brique se fait par infrarouges). Cette brique contient un programme esclave (programmé en C). Pour communiquer avec cette brique, je dois lui envoyer des ordres sous forme de chaînes de caractères depuis Labview. A chaque chaîne de caractères reçue correspond une partie du programme à exécuter (le programme esclave interprète les infos envoyées par Labview).
    Explications : le programme esclave est fait de la manière suivante (en gros):


    #define toto "AVANCE" /* toto est le nom de la chaîne lorsque la brique reçoit l'orde AVANCE depuis labview */
    #define tata "STOP"
    int variable;

    ...blablabla...

    if ( strcmp(msg, toto) == 0 ) /* là on test si le message reçu est toto (ou AVANCE c'est pareil) */
    {
    variable = 0;
    }


    int main (void) /* programme principal */
    {

    if (variable == 0)
    {
    le robot va en avant;
    }
    }

    Bon, ça c'est pas un problème.
    Maintenant je voudrais envoyer non seulement des ordres (avance, stop, tourne à droite,…) mais aussi des consignes (ex: stop quand distance parcourue = 15mm). Le problème est que la brique ne doit recevoir que des chaînes de caractères. Faudrait donc que je convertisse cette distance en chaîne (sous labview). Le problème c'est que je n'ai pas envie de déclarer une chaîne (dans mon programme esclave) pour chaque distance à parcourir…

    Comme solution, je pensais à ça : je décompose la distance en unités, dizaines, centaines… je converti les unités en chaîne (ex: 0=A, 1=B,…,9=I) que j'envoie à la brique. Le programme esclave se charge ensuite de reconvertir cette chaîne en nombre décimal. Idem pour les dizaines et centaines. Ensuite je fais la somme et je retrouve ma distance à parcourir.

    Que pensez vous de cette idée ?
    Y'a pas moins farfelu ?

    Merci

    (si j'ai pas été assez clair sur certains détails, dites le moi).

    -----

  2. Publicité
  3. #2
    Towl

    Re : Comment communiquer les distances à mon robot ?

    Pourrais tu donner des exemples de chaines de commande avec distance que l'on peut envoyer ?
    Par exemple, est ce qu'une chaine comme ceci pourrait être envoyée facilement :
    STOP DISTANCE 15 MM
    Le but serait d'avoir un mini protocole, qui serait sous la forme
    Commande condition param1 param2.
    Tu pourrais ainsi faire des trucs comme
    GAUCHE OBSTACLE
    AVANCE
    ...

    Le but étant de facilement décomposer tes chaines, et la sscanf est ton ami
    Dans mon pseudo protocole :

    Code:
    Lecture du premier chaine --> obtention de la commande
    si condition existe
         recuperation de la commande
         si commande == distance
              lecture de arg1 et arg2
         fin si
    fin si
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  4. #3
    dav1307

    Post Re : Comment communiquer les distances à mon robot ?

    Plutôt que de traiter la distance en unité, dizaine et centaine, je devrais envoyer une chaine dans ce genre "DISTANCE_273" ?
    Ensuite le programme esclave cherche si à l'intérieur de cette chaîne il y a "DISTANCE", si oui il extrait les 3 derniers caractères.

    Code:
    int test;  
    msg = (char * ) malloc((len+1) * sizeof(char));  /*copie du message reçu*/
    
     for (i=0; i < len; i++)
         msg[i] = data[i];
         msg[len] = '\0';
    
      test= strstr(msg,"DISTANCE"); /*là je cherche si "DISTANCE" est dans msg*/
     
      if (test != NULL)
        {
        le programme extrait alors les 3 dernières valeurs de la chaîne msg.
        }
    Mais je ne sais pas comment extraire les 3 dernières valeurs d'une chaine. Quelle fonction utiliser ?

    Pourrais tu donner des exemples de chaines de commande avec distance que l'on peut envoyer ?
    Ben justement, je ne sais pas....

    merci pour l'aide.

  5. #4
    Towl

    Re : Comment communiquer les distances à mon robot ?

    En fait je te conseillais de faire avec des espaces car cela peut facilement etre parsé :
    Code:
    nb_elem_lu = sscanf("STOP DISTANCE 15 MM", "%s %s %s %s", cmd, cond, param1, param2);
    if(strcmp(cond, "DISTANCE") == 0)
    {
        int dist = atoi(param1);
        ...
    }
    Mais si tu ne peux pas envoyer des chaines composées d'espace (une des raison pour lesquelles je te demandais le type de commande que tu peux transmettre), alors oui, il faut trouver un autre moyen.

    La première idée qui me vienne à l'esprit serait de faire un truc du genre :
    Code:
    char *szChaine = "DISTANCE_312";
    char *szDistance = NULL;
    int iDistance = 0;
    
    /* On place le pointeur sur le début de 312 via de joli calcul de pointeurs ;) */
    szDistance = szChaine + strlen("DISTANCE_");
    iDistance = atoi(szDistance);
    Il y a surement plus joli, mais cela peut te donner une idée

    PS : mon code est surement à retravaillé, je ne l'ai pas testé ni compilé, il est juste la pour donner des pistes
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  6. #5
    dav1307

    Re : Comment communiquer les distances à mon robot ?

    Je pense que ça doit pouvoir marcher avec des espaces.
    J'ai fait un ptit programme comme tu m'as montré:

    Code:
    #include<stdlib.h>
    #include<stdio.h>
    #include<string.h>
    
    
    int main (void)
    {
        char chaine, cmd, cond[9], param1, param2;
                
        chaine = scanf("STOP DISTANCE 15 MM", "%s %s %s %s", cmd, cond, param1, param2);
        
        if (strcmp(cond,"DISTANCE") == 0)
        {
           printf("bon");
           printf("\n");
        }
           else
           {
            printf("pas bon");
            printf("\n");
           }
     
    system("pause");
    return 0;
    }
    Ensuite lorsque j'exécute le programme, je tape "STOP DISTANCE 15 MM"
    Mais le problème c'est qu'à chaque fois le programme me dit "pas bon". Donc cond n'est pas égale à "DISTANCE" … pourtant si.

    En fait je ne comprends pas bien cette partie :
    chaine = scanf("STOP DISTANCE 15 MM", "%s %s %s %s", cmd, cond, param1, param2);
    Normalement scanf c'est pour lire une valeur saisie par l'utilisateur ?
    Mais en fait là, j'imagine que ça sert à initialiser chaine…je me trompe ?

    Autre question: y'a-t-il une différence entre "scanf" et "scanf" tout comme "sprintf" et "ssprintf" ? Moi on m'a appris avec 1 seul s.

  7. A voir en vidéo sur Futura
  8. #6
    dav1307

    Re : Comment communiquer les distances à mon robot ?

    Autre truc: quand je tape le programme dans DevC++ et lorsque je met mon curseur sur cmd, une petite affiche s'ouvre et m'indique "WORD cmd", alors que si je mets le curseur sur cond , l'affiche m'indique "char cond" (idem pour param1 et param2).
    Apparemment cmd n'est pas reconnu comme une chaine de caractères.?

  9. Publicité
  10. #7
    Towl

    Re : Comment communiquer les distances à mon robot ?

    chaine, cmd, cond[9], param1, param2 doivent être des chaines de caractère et non des caractères. La déclaration devrait donc être :
    Code:
    char *chaine, *cmd, cond[9], *param1, *param2;
    if( ! (chaine = (char *)malloc(256 * sizeof(char)))
    {
        printf ("Not enough memory\n";
        exit(-1);
    }
    ...
    Suivit de malloc pour préciser la taille des chaines

    Sinon tu peux fixer la taille de tes chaines dès l'initialisation:
    Code:
    char chaine[256], cmd[256].....


    Normalement scanf c'est pour lire une valeur saisie par l'utilisateur ?
    Mais en fait là, j'imagine que ça sert à initialiser chaine…je me trompe ?
    oui scanf permet de lire une valeur saisie sur l'entrée standard (et donc généralement saisie par l'utilisateur).
    Mais la j'utilise sscanf (il y a 2 s au début), qui ne lit plus une valeur sur l'entrée standard, mais dans une variable de type chaine de caractere, donnée en premier argument). Ensuite, cela s'utilise comme un scanf classique. On s'en sert majoritairement pour parser des variables.

    Dans mon exemple, ma variable à parser est "STOP DISTANCE 15 MM". Dans le futur, si cette méthode te convient, cela deviendra la commande de ta brique lego et donc donnera un truc du genre :
    Code:
    nb_elem_lu = sscanf(cmd_lego, "%s %s %s %s", cmd, cond, param1, param2);
    Pour plus d'information sur les fonctions que je t'ai fournit, rien ne vaut les pages man :
    tappes man sscanf dans google par exemple, ou man malloc ...

    Bon courage
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

  11. #8
    dav1307

    Re : Comment communiquer les distances à mon robot ?

    int dist = atoi(param1);
    Au début je croyais que "atoi" ça voulait dire "à toi de jouer pour cette partie du programme" ... !
    Mais j'ai découvert aujourd'hui cet outil...dont je ne peux pas me servir car le logiciel Bricx ne comprend pas ce que c'est, pourtant stdlib.h est bien inclus.
    Et quand j'essaie avec strtol c'est idem. Apparemment il manque des fichiers dans la librairie de Brixc.
    Dommage parce que ça à l'aire bien utile ce "atoi" pour convertir une chaîne en nombre.

    Donc j'ai fait un truc pour convertir une chaîne en nombre (plutôt un morceau de chaine en nombre) :

    Code:
    #include <stdlib.h>
    #include<stdio.h>
    #include <string.h>
    
    
    int main (void)
    {
    int u,d;
    u=0;					/ *u représente les unités */
    d=0;	/*d représente les dizaines*/
    char msg[] = "DISTANCE123";
    char concat[10];
    char dist[10];
    char dizaine[10];
    
        concat[0] = msg[0];		/* ça à la rigueur ça ne sert à rien, c'est juste pour "déconcaténer" msg et obtenir"DISTANCE" */
        concat[1] = msg[1];
        concat[2] = msg[2];
        concat[3] = msg[3];
        concat[4] = msg[4];
        concat[5] = msg[5];
        concat[6] = msg[6];
        concat[7] = msg[7];
        concat[8] = '\0';
     
        strcpy(dist, msg+8);		/* avec ça on obtient juste les 3derniers caractères */
        
        dizaine[0]=dist[1]; 			/* définition de dizaine */
        dizaine[1]='\0';
        
        printf("concat = %s \n",concat);
        printf("dist = %s \n",dist);
        printf("dizaine = %s \n",dizaine);
        
      
      
      
      if (strcmp(dist+2, "0") == 0)             /* recherche de l'unité */
         {u=0;
         }    
              else
              {
               if (strcmp(dist+2, "1") == 0)
               {u=1;
               }    
                       else
                       {
                        if (strcmp(dist+2, "2") == 0)
                        {u=2;
                        }
                                else
                                {
                                 if (strcmp(dist+2, "3") == 0)
                                 {u=3;
                                 }   
    /* blablabla … Je fais pareil jusqu'à 9...*/ 
                                }
                       }
              }
              
              
              
              
              
              
              if (strcmp(dizaine, "0") == 0)             /* recherche de la dizaine */
              {d=0;
              }    
              else
              {
               if (strcmp(dizaine, "1") == 0)
               {d=1;
               }    
                       else
                       {
                        if (strcmp(dizaine, "2") == 0)
                        {d=2;
                        }
                                else
                                {
                                 if (strcmp(dizaine, "3") == 0)
                                 {d=3;
                                 }    
                                }
                       }
              }
     /* suffit de faire les mêmes tests pour obtenir les centaines*/
              
              printf("u = %d \n",u);
              printf("d = %d \n",d);  
    /* et voilà, j'ai mes unités et mes dizaines ! */                              
    
    system("pause");
    return 0;
    }
    Bon ok, c'est un peu de la bidouille, mais ça marche .

  12. #9
    Towl

    Re : Comment communiquer les distances à mon robot ?

    Bon ok, c'est un peu de la bidouille, mais ça marche .
    Ah vi effectivement, c'est un peu de la bidouille Mais tant que ca marche, c'est le principal.

    Pour information, et découvrir les astuces du C : voici une version atoi faite par moi en 2sec (pas testé, faut vraiment que je me reinstalle un compilo )

    Code:
            int
    atoi(char *szNumber)
    {
            int iNumber = 0;
            while(*szNumber >= '0' && *szNumber <= '9')
            {
                    iNumber =  iNumber * 10 + (*szNumber - '0');
                    szNumber++;
            }
            return iNumber;
    }
    Explication :
    szNumber est un pointeur sur un tableau de caractère. Donc szNumber[0] correspond au premier caractere, et ainsi de suite.
    *szNumber correspond à la valeur pointée par szNumber. Il s'agit donc du premier élément du tableau.
    szNumber++ : j'incrémente de 1 mon pointeur. Donc szNumber ne pointe plus sur la premiere case, mais la seconde. Ainsi lors de l'itération suivante, *szNumber sera le second élément du tableau.

    Ensuite, il y a quelquechose de très pratique à savoir sur les caractère : '0' donne le code ASCII de 0 (qui vaut 0x30). Il se trouve que 1 à pour code 0x31 etc.
    Donc si je fait szNumber[i] - '0' avec szNumber[i] = '3', j'obtiens 0x33 - 0x30 soit 3.

    A chaque itération, je multiplie donc mon nombre par 10 et lui ajoute le chiffre suivant . Cela donne
    Code:
    szNumber       iNumber
    123\0          0
    23 \0          1
    3\0            12
    \0             123

    Sinon, une autre solution serait, si tu connais ta chaines de s'amuser avec sscanf (et oui, encore lui )
    Code:
    int iDistance = 0;
    szCommande = "DISTANCE123";
    sscanf(szCommande, "DISTANCE%d", &i);
    The only limiting factor of the Linux operating system, is his user. - Linus Torvalds

Sur le même thème :

Discussions similaires

  1. Utiliser une clef USB pour communiquer avec mon PC !
    Par yomapoitiers dans le forum Électronique
    Réponses: 3
    Dernier message: 02/12/2006, 23h04
  2. Réponses: 10
    Dernier message: 11/08/2006, 15h46
  3. Robot sapiens, mon meilleur ami
    Par Glast dans le forum Discussions scientifiques
    Réponses: 4
    Dernier message: 15/04/2005, 13h31
  4. problème avec les distances.
    Par sylvainix dans le forum Mathématiques du supérieur
    Réponses: 3
    Dernier message: 14/10/2004, 19h52
  5. comment faire communiquer 2 pc en utilisant le cable?
    Par syham dans le forum Internet - Réseau - Sécurité générale
    Réponses: 3
    Dernier message: 29/01/2004, 21h03