Cours:MindstormStructuresDeControle

De troyesGEII
Aller à : navigation, rechercher
Retour à la liste des Tps
Vous trouverez sur la page listant les énoncés de TP un lien vers l'ensemble des fonctions spécifique à la programmation de la brique lego EV3.

Travail préparatoire : affichage de variable

Nous avons vu comment déclarer et donner une valeur à une variable de type entier dans le 1er TP, exemple :

  int a = 5;

Il est intéressant d'afficher sa valeur avec la fonction LcdPrintf. Pour cela, on prépare le texte souhaité, et on place %d dans la chaîne de caractère (délimitée par des " ") à l'endroit où on souhaite afficher la valeur de la variable. On ajoute ensuite un paramètre dans l'appel de fonction.

Bon c'est plus simple avec un exemple :

#include <ev3.h>
int main(void)
{
   // on déclare une variable prix
   int prix = 100;

   InitEV3();

   LcdPrintf(1, "le produit coute %d euros\n", prix);

   Wait(SEC_5);
   FreeEV3();
   return 0;
}

On peut afficher la valeur de plusieurs variables en ajoutant des %d :

#include <ev3.h>
int main(void)
{
   // on déclare 2 variables prixDepart et redution
   int prixDepart = 100;
   int reduction = 10;

   InitEV3();

   LcdPrintf(1, "le produit coute %d euros avant reduction, la remise est de %d euros\n", prixDepart, reduction);

   Wait(SEC_5);
   FreeEV3();
   return 0;
}

On peut bien sûr effectuer des opérations sur les variables , par exemple :

   ...
   int prixDepart = 100;
   int reduction = 10;
   // on n'affecte pas de valeur, on va la calculer par la suite
   int prixFinal;
   // modification de la valeur de la variable prixFinal :
   prixFinal = prixDepart - reduction;
   ...

Question.jpg Modifier votre programme pour qu'il affiche le prix avant et après réduction.


Question.jpg Faire un programme qui :

  • déclare 2 variables :
    • a de valeur 5
    • b de valeur 6
  • calcul le produit et met le résultat dans une variable resultat
  • affiche le calcul effectué et le résultat

Affichage de l'état d'un capteur

Tout système possède des entrées et des sorties.

Les sorties sont les actionneurs et génèrent donc une action :

  • produire un son
  • émettre de la lumière
  • produire une action mécanique
  • ...

Les entrées permettent d’interagir avec l'environnement et l'utilisateur, ils observent/mesurent quelque chose :

  • capteur de contact/collision
  • microphone
  • capteur de couleur
  • ...

Sur la brique programmable EV3, le nom des connecteurs donne la fonction :

  • 1 2 3 4 : ce sont les entrées
  • A B C D : ce sont les sorties

Principe pour 1 capteur

Les capteurs pouvant être connectés sur la brique EV3 étant tous différents, il est nécessaire d'indiquer sur quelle broche nous avons connecté le/les capteur(s) utilisé(s).

Pour cela vous devez utilisez la fonction :

setAllSensorMode

Le détail de cette fonction sera à consulter dans la documentation.

Todo.jpg Voici un exemple d'utilisation à suivre pour tester le capteur de contact ( touch sensor in English !) :

#include <ev3.h>
int main(void)
{
   // on déclare une variable etatTouchSensor pour "enregistrer" l'état du capteur
   int etatTouchSensor = 0;

   InitEV3();
   // on configure la sortie 1 comme capteur de contact
   // et les sorties 2,3,4 sont indiquées sans capteur (NO_SEN)
   setAllSensorMode(TOUCH_PRESS, NO_SEN, NO_SEN, NO_SEN);
   // on peut alors lire l'état du capteur sur l'entrée 1
   // et mettre sa valeur dans la variable etatTouchSensor
   etatTouchSensor = readSensor( IN_1 );
   // on affiche alors sa valeur
   LcdPrintf(1, "valeur du capteur : %d \n", etatTouchSensor);

   Wait(SEC_5);
   FreeEV3();
   return 0;
}

A vous

Vous voici près à lire l'état des différents capteurs.

Question.jpg En vous servant du tableau avec la liste des entrées sur la page des énoncés, modifier votre programme pour observer l'état des différents capteurs

Remarque :

  • Pensez à changer le nom de la variable en fonction du nom du capteur
  • Vous pouvez bien sûr lire l'état de tous les capteurs dans le même programme
  • Vous pouvez lire plusieurs fois l'état du même capteur dans votre programme :
   ...
   etatTouchSensor = readSensor( IN_1 );
   LcdPrintf(1, "valeur du capteur : %d \n", etatTouchSensor);
   Wait(SEC_5);
   // on recommence :
   etatTouchSensor = readSensor( IN_1 );
   LcdPrintf(1, "valeur du capteur : %d \n", etatTouchSensor);
   Wait(SEC_5);
   // on recommence :
   etatTouchSensor = readSensor( IN_1 );
   LcdPrintf(1, "valeur du capteur : %d \n", etatTouchSensor);
   Wait(SEC_5);
   // on recommence :
   ...

Structure de contrôle

Structure de répétition

La structure de répétition en informatique s'appelle une boucle. La boucle est le seul moyen de remonter vers le début (plutôt vers le haut) d'un programme ! La boucle permet donc de refaire les choses plusieurs fois.

Lorsque vous désirez faire les choses plusieurs fois vous êtes dans deux situations différentes qui appellent une solution différente :

  1. vous savez d'avance combien de fois vous voulez répéter la boucle
  2. vous ne savez pas combien de fois vous voulez exécuter la boucle mais vous connaissez une condition (booléenne) à son arrêt

Nous allons traiter ces deux situations maintenant les unes après les autres.

répéter x fois

Principe

Nous sommes typiquement dans le cas où on connaît le nombre de boucles que l'on veut faire. C'est x. Pour être précis, le nombre en question peut être dans une variable.

  • je connais le nombre et je l'écris directement. Regardez le 5 ci-dessous, pour l'écrire il faut le connaître !
int i;
...
for (i=0;i<5;i++) {
  // faire quelque chose 5 fois
}
...
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!!!!!!!  Pas de ; après le for  !!!!!!!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  • je sais que le nombre de répétitions est dans une variable
int i,nbIterations;
...
nbIterations=10;
...
for (i=0;i<nbIterations;i++) {
  // faire quelque chose nbIterations fois avec nbIterations= 10 dans le cas présent
}
...

Travail à faire

On utilisera dans cette partie le capteur de couleurs (Light sensor dans le mode COL_REFLECT)

Question.jpg Modifier votre programme précédent pour utiliser une "boucle for" à la place de réécrire plusieurs fois la même chose dans votre programme :

#include <ev3.h>
int main(void)
{
   // on déclare une variable niveauGris pour "enregistrer" l'état du capteur
   int niveauGris = 0;
   int i;

   InitEV3();
   setAllSensorMode(....);
   for (i=0;i<???;i++) {
      niveauGris = ....;
      LcdPrintf(1, ..... );
      Wait(SEC_5);
   }
   FreeEV3();
   return 0;
}

Même si le robot ne bouge pas, la valeur retournée par le capteur peut varier (bruit de mesure ....). Il est donc intéressant d'effectuer une moyenne des valeurs retournées :

  • initialiser une variable somme
  • répéter plusieurs fois
    • faire une nouvelle mesure
    • ajouter la nouvelle valeur à la variable somme
  • calculer la moyenne : somme/nbItérations

Question.jpg Ecrire un programme qui affiche la moyenne de 5 mesures sur le capteur, puis de 10 mesures

faire ... tant que

Principe

L'écriture est la suivante :

...
do {
  // faire quelque chose plusieurs fois jusqu'à ce que la condition devienne fausse.
  // dis autrement
  // faire quelque chose plusieurs fois tant que la condition est vraie
} while( condition );

Un exemple plus concret :

 ....
 do {
   etatCapteur = ....;
   .....
 } while ( etatCapteur != 100);
 ....

On recommence la lecture du capteur tant que sa valeur est différente de 100.

Les opérateurs de comparaisons sont :

Opérateur Utilisation Signification
== ( a == b ) vrai si a et b identiques
 != ( a != b ) vrai si a et b différents
> ( a > b ) vrai si a supérieur strict à b
< ( a < b ) vrai si a inférieur strict à b
>= ( a >= b ) vrai si a supérieur ou égal à b
<= ( a <= b ) vrai si a inférieur ou égal à b
&& ( (condition1) && (condition2) ) vrai si la condition1 et la condition2 sont vraies en même temps
|| ( (condition1) || (condition2) ) vrai si au moins une des 2 conditions est vrai

Travail à faire

On utilisera ici le capteur de contact.

Question.jpg Ecrire un programme qui :

  • affiche le message "demarrage du programme"
  • répète en boucle
    • lire l'état du capteur de contact
    • affiche la valeur du capteur
    • attend 0,5s
  • tant que le robot ne touche pas un obstacle
  • affiche le message "obstacle rencontré

Question.jpg Une fois ce fonctionnement obtenu, modifier votre programme pour que le robot s'arrête lorsqu'il touche un obstacle :

  • mettre les moteurs en marche
  • répéter
    • lire le capteur
  • tant qu'il n'y a pas d'obstacles
  • arrêter les moteurs

Question.jpg Modifier votre programme pour que le robot avance tant qu'il se trouve sur une surface blanche et s'arrête lorsqu'il se trouve sur du noir.

Remarque : Essayer les 2 modes pour le capteur : COL_COLOR ou COL_REFLECT

Structure de test

if ... else

La structure de test est un élément indispensable en informatique.

Il s'agit, suivant une condition, d'effectuer une action ou une autre :

....
if ( condition ) {
  //action si condition est vraie
}
else {
  //action si condition est fausse
}
...

On peut éventuellement faire des tests successifs en utilisant un "else if"

....
if ( condition1 ) {
  //action si condition1 est vraie
}
else if ( condition2 ) {
  //action si condition2 est vraie
}
else if ( condition3 ) {
  //action si condition3 est vraie
}
else if....
else {
   // action dans tous les autres cas
}
...

Il n'y a pas de limite au nombre de "else if" utilisé


1er test

On souhaite afficher un message indiquant l'état du capteur de contact.

La plupart des programmes que nous écrirons auront la structure suivante :

#include <ev3.h>

int main(void)
{
//variables

InitEV3();
//initialisation capteurs ...
do {
   // on répète ces instructions jusqu'à la fermeture du programme
   ...
} while (condition pour continuer le programme);

FreeEV3();
return 0;
}

Commençons par écrire un programme qui se quitte lorsqu'on appuie sur un bouton.

Il va vous falloir utiliser au choix :

  • ButtonIsUp
  • ButtonIsDown

Question.jpg Ecrire un programme qui se termine lorsqu'on appuie sur le bouton Center (BTNCENTER)


Maintenant que nous pouvons terminer notre programme facilement, nous allons pouvoir afficher l'état d'un capteur :

Question.jpg Ecrire un programme qui affiche le cas échéant (en fct du capteur de contact :

  • obstacle détecté
  • pas d'obstacle

Remarque : pensez à mettre un wait pour limiter la vitesse d'affichage

Programme plus avancé

On souhaite utiliser 2 capteurs :

  • le capteur d'obstacle qui permettra d'arrêter le programme lorsque le robot touche qqch
  • le capteur de couleur

Chaque fois que le capteur arrive sur une ligne noire, il devra faire 1/2tour, sinon il doit avancer en ligne droite.

Question.jpg Ecrire un programme répondant au cahier des charges