Aller au contenu


Photo
- - - - -

utiliser le contenu d'une variable

contenu variable

  • Veuillez vous connecter pour répondre
6 réponses à ce sujet

#1 cerisier

cerisier

    Nouveau membre

  • Membres
  • 9 messages

Posté 09 août 2017 - 05:11

Je récupère dans libAction le libellé d'une action extrait d'une table "actions"

String libAction = actions[action1];
   Serial.print(" Action i :");
   Serial.print( action1);
   Serial.print(" libAction :");
   Serial.println(libAction);

il s'agit en  l'occurence d'une commande pour un robot : avance(AFONDX);   laquelle appelle une routine qui fonctionne

libAction contient bien cette valeur comme le prouve l’exécution du  Serial.print : 

Action  i  :2        libAction    :avance(AFONDX)
 

mais comment faire en sorte que le programme comprenne qu' à la lecture de libAction il doit exécuter la routine  : avance(AFONDX)  c'est à dire le contenu de libAction ?

il faudrait avoir l'équivalent de ce que l'on trouve dans d'autres langages :  libAction.value

Merci de votre aide



#2 arobasseb

arobasseb

    Membre passionné

  • Membres
  • PipPipPip
  • 343 messages
  • Gender:Male
  • Location:BORDEAUX (33)
  • Interests:Informatique, robotique et sciences technique en générale.

Posté 09 août 2017 - 05:33

N'ayant pas plus d'information je dirai ceci : 

 

tu écris  :

String libAction = actions[action1];

Executer(libAction);

void Executer(string action)
{
    switch(action) {
        case "avance(AFONDX)" : 
            avance(AFONDX);
            break;
        case "avance(AFONDY)" : 
            avance(AFONDY);
            break;
        .... 
    }
}

car je ne pense pas que tu puisse appeler une fonction à la voler (il faut nous dire avec quoi tu développe et éventuellement nous mettre plus de code).

 

 

Edit : Si c'est du C++ je ne suis pas sûr que le switch fonctionne avec un string. j'attend plus d'info :)


Modifié par arobasseb, 09 août 2017 - 05:39 .


#3 R1D1

R1D1

    Modérateur et Membre passionné

  • Modérateur
  • PipPipPipPip
  • 883 messages
  • Gender:Male
  • Location:Autriche

Posté 09 août 2017 - 06:18

N'ayant pas plus d'information je dirai ceci : 

 

tu écris  :

String libAction = actions[action1];

Executer(libAction);

void Executer(string action)
{
    switch(action) {
        case "avance(AFONDX)" : 
            avance(AFONDX);
            break;
        case "avance(AFONDY)" : 
            avance(AFONDY);
            break;
        .... 
    }
}

car je ne pense pas que tu puisse appeler une fonction à la voler (il faut nous dire avec quoi tu développe et éventuellement nous mettre plus de code).

 

 

Edit : Si c'est du C++ je ne suis pas sûr que le switch fonctionne avec un string. j'attend plus d'info :)

Nope, en C/C++, switch/case ne marche pas avec des strings. Juste des char ou des int. Mais tu peux envoyer une commande moins explicite du genre "1 50" et utiliser la première valeur dans ton switch case et la deuxième comme paramètre (de vitesse ici j'imagine).


R1D1 - Calculo Sed Ergo Sum
Avatar tiré du site bottlebot
"Qui a dit 'Programmation" ?"

#4 cocothebo

cocothebo

    Membre occasionnel

  • Membres
  • Pip
  • 144 messages
  • Gender:Male

Posté 09 août 2017 - 09:10

Salut,

 

en C, tu peux aussi faire des pointeurs sur fonction et donc un tableau de pointer sur fonction. Si c'est de l'arduino je ne sais pas en revanche si ça fonctionne.

De mémoire par contre il faut que toutes les fonctions aient le même nombre de paramètre.

 

Une recherche sur gogole permet de trouver plein d'exemples de pointeurs de fonctions (et donc de tableau de pointeurs de fonction):

 

La déclaration est du style:

type_retour (*nom_de_mon_pointeur)(typedeparam,  ..., typedeparam)

Ce qui donne sur ton exemple un truc genre: (considérant que avance est déclaré style int avance(int ordre)

int (*mon_pointeur_avance)(int) = avance

ou

int (*mon_pointeur_avance)(int) = &(avance)

pour un pointeur sur la fonction avance qui prend un int en entrée (et retourne un int)

 

Après faut faire le tableau de ces pointeurs, ce qui se fait par exemple:

typedef int (*fptr)(int); //le typedef permet d'être plus compréhensible je trouve
fptr action[4]; //on déclare un tableau nommé "action" de 4 éléments pointeurs sur fonction comme montrer avant

L'avantage c'est que ça évite le switch ou autre, comme ton action est déjà un tableau, un simple action[action1]() ferra l'appel de fonction pour toi.

on initialise le tableau d'abord:

action[0] = &stop
action[1] = &recule
action[2] = &avance
...

ou d'ailleurs sinon on peut faire définition et init en une ligne mais c'est moins lisible je trouve:

int (*action[]) () = {&stop, &recule, &avance, ...}; 

A l(utilisation, tu fais comme dans ton exemple:

 action[action1]();

ou une façon que j'aime beaucoup grâce au tableau (même si c'est pas super lisible):

(**(action+action1))();

On utilise beaucoup ce genre de "techniques" pour faire juste des "switch case" qui s’exécutent en temps constant, que ce soit le premier ou dernier choix, on fait juste un saut dans un tableau, ça permet aussi d'optimiser pas mal les perfs dans ce genre de cas.



#5 cerisier

cerisier

    Nouveau membre

  • Membres
  • 9 messages

Posté 09 août 2017 - 09:12

Merci pour la réponse rapide

je viens de reprendre le principe que tu me donnes mais au lieu de passer par libAction je fais directement le switch sur action1 qui est un integer

c'est bien plus simple et cela fonctionne

// cette table me fournit pour les 3 premières colonnes les données d'un SR04 (60° 90° 120°)
// puis 3 colonnes d'actions possibles  si 000 obstacle proche dans les 3 directions
//3 actions :  arret, recule, tourneDroite

int zonesActions[8][6]=
{
  0,0,0,6,5,3,
  0,0,1,6,4,0,
  0,1,0,1,0,0,
  0,1,1,4,0,0,
  1,0,0,5,3,0,
  1,0,1,5,3,0,
  1,1,0,3,0,0,
  1,1,1,2,0,0
  };

void setup{
}

void loop
{
      action1 = zonesActions[i][3];  // recherche action 1 correspondant  aux mesures SR04
                                        
      rechAction(action1);  
}
void rechAction( int act)
{
     switch(act)
            {
              case 0:               
                 break;
              case 1:
                 avance(PRUDENTX); 
                 break;
              case 2:                                         
                 avance(AFONDX); 
                 break;
              case 3:
                 tourneGauche(NORMALX);
                 break;  
              case 4:
                 tourneDroite(NORMALX);
                 break;  
              case 5:
                 recule(PRUDENTX);
                 break;
              case 6:
                 arret;
                 break;
            } 


#6 cerisier

cerisier

    Nouveau membre

  • Membres
  • 9 messages

Posté 12 août 2017 - 09:23

Merci à COCOTHEBO pour l'info, je ne suis pas familier avec les pointeurs mais cela va être l'occasion d'apprendre.

 

j'aurais une autre question :

je voudrais enregistrer les données issues du SR04 sur l'ordinateur, j'ai trouvé une info conseillant d'utiliser terminalbpp, je l'ai téléchargé mais je ne trouve aucune aide : comment préciser que les données ne doivent pas être envoyées sur le moniteur série et où les envoyer ?



#7 maximusk

maximusk

    Habitué

  • Membres
  • PipPip
  • 258 messages
  • Gender:Male
  • Location:Le Mans

Posté 12 août 2017 - 09:42

Les données doivent être envoyées sur le port série. Après, tu peux les lires sous windows avec le moniteur série arduino ou hyperterminal, ou sous linux avec screen, minicom, ... .

Pour les enregistrer, il te faudra un programme côté PC. Le problème est que le port série ne s'utilise pas de la même façon sous linux/mac et sous windows.






0 utilisateur(s) li(sen)t ce sujet

0 members, 0 guests, 0 anonymous users