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

  1. #1
    Nouveau Candidat au Club
    Projet terminale en isn, question débutant
    Bonjour, je suis un terminale en spécialité isn et je dois, pour mon projet utiliser le langage C, j'ai pu apprendre les bases du langage. Voici mon projet, j'ai un petit robot (MOWAY) que je dois programmer de sorte qu'il suit une ligne noire, puis s’arrête s'il détecte un obstacle et va attendre 10 secondes pour voir si l'obstacle est toujours présent, dans ce cas il doit faire demi tour et continuer sa route, mais dans le cas où l'obstacle se retire avant les 10 secondes, le robot doit continuer sa route dans ce sens.

    j'ai déjà réussi à faire suivre la ligne noire au robot, ainsi que son arrêt lorsqu'il voit un obstacle. Cependant lorsqu'il détecte un obstacle, il s’arrête 10 secondes et fais demi tout même si l'obstacle a été retiré avant les 10 secondes. Je n'arrive vraiment pas à trouver comment résoudre ce problème, Merci de votre aide par avance.

    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
     
     
    /* Le code exécutable commence ici */
    void main()            // `Debut` (Appelé au RESET)
    {
      SEN_CONFIG();
      MOT_CONFIG();
      do                   // `Début d'itération Répéter..`
      {
        if (SEN_LINE_DIG(LINE_L)==1 && SEN_LINE_DIG(LINE_R)==1) // Faire avancer le robot sur la ligne noire
       {
        MOT_STR(50,FWD,TIME,0); 
     
       } 
     
        else if (SEN_LINE_DIG(LINE_R)==0 && SEN_LINE_DIG(LINE_L)==1) :// Faire dévier le robot vers la gauche quand capteurs de ligne droit voit du blanc
     
        {
         MOT_ROT(50,FWD,CENTER,LEFT,ANGLE,10);
     
        }
     
        else if (SEN_LINE_DIG(LINE_R)==1 && SEN_LINE_DIG(LINE_L)==0) // Faire dévier le robot vers la droite quand capteur ligne gauche voit du blanc
     
         {
     
          MOT_ROT(50,FWD,CENTER,RIGHT,ANGLE,10);
     
         }
     
        else if (SEN_OBS_ANALOG(OBS_SIDE_L)>100 || SEN_OBS_ANALOG(OBS_SIDE_R)>100 || SEN_OBS_ANALOG(OBS_CENTER_L)>100 || SEN_OBS_ANALOG(OBS_CENTER_R)>100) // Arreter le robot si obstacle
     
        {
     
         MOT_STOP();
         PAUSE_SECONDE(10);
         MOT_ROT(100,FWD,CENTER,RIGHT,ANGLE,50);
         while (!MOT_END);
     
        }
     
     
     
     
      }  
     
         while(1);
     
    }                      // Fin de la fonction "main"
    /* Fin du texte */

  2. #2
    Expert éminent sénior
    Bonjour
    Citation Envoyé par pharell1234 Voir le message
    il s’arrête 10 secondes et fais demi tout même si l'obstacle a été retiré avant les 10 secondes. Je n'arrive vraiment pas à trouver comment résoudre ce problème,

    Ben il me semble que tu ne regardes qu'une fois s'il y a un obstacle. Si tu veux détecter que l'obstacle a été retiré, il te faut rechecker sa présence.

    Ta détection d'obstacle est faite d'après cet algo
    Code algo :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    si obstacle, alors
        arrêter robt
        attendre 10s
        faire demi-tour
    fin si


    Elle devrait être faite selon cet algo
    Code algo :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    si obstacle, alors
        arrêter robot
        attendre 10s
        si obstacle alors faire demi-tour
    fin si


    Accessoirement main() n'est pas void mais int. Et tu aurais avantage à créer des fonctions pour factoriser certains traitements. Un souci toutefois est dans le nombre de caractéristiques de ton robot (les OBS_SIDE_R, OBS_CENTER_L et autres) qu'il faudrait passer aux fonctions mais ça peut se régler si tu les regroupes dans une structure. Dans ce cas tu passes simplement la structure aux fonctions qui peuvent alors accéder aux variables qui la composent par ricochet.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  3. #3
    Membre éprouvé
    Hello,

    J'aurais plutot vu cet algorithme, qui permet au robot de repartir si l'obstacle disparait
    Code :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    si obstacle
    alors
    	arrêter le robot
    	tant que l'obstacle est présent et que le temps d'attente est < 10 secondes
    		verifier si l'obstacle est toujours là
    	si obstacle
    		le robot fait demi-tour
    	remettre robot en marche

  4. #4
    Rédacteur/Modérateur

    Plutôt que des wait de partout, ce serait le moment d'introduire un système de machine à état : avance, attente obstacle, ...
    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.

  5. #5
    Nouveau Candidat au Club
    Créer une variable?
    Bonsoir, Merci pour vos réponses, pour faire "attendre" le robot je pensais à créer une variable... De sorte que par exemple "i"=0 et "i" prend la valeur "i+1" chaque seconde..En fait j'aimerai créer une variable et un code qui permet de faire un décompte.. de 0 à 10 .. Afin de dire au robot que si "i"=10 alors faire demi tour..

    J'espère avoir été assez clair, Merci de m'aider par avance.

  6. #6
    Membre éprouvé
    Re,-

    J'écrirais quelque chose du genre
    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
    #include <time.h>
    #inlcude <stdbool.h>
     
    #define MAX_WAIT_DELAY		10		// en secondes
     
    bool obstacleIsPresent(void);
     
    if(obstacleIsPresent()) {
    	robotStop();
    	time_t start_time=time(NULL);
    	while(time(NULL)-start_time<MAX_WAIT_DELAY)
    		if(!obstacleIsPresent())
    			break;
    	if(obstacleIsPresent())
    		robotTurn180Degrees();
    	robotStart();
    }

  7. #7
    Membre régulier
    Bonjour,

    Le code du premier message porte à croire que le compilateur est une implémentation free-standing de C99, il est fort improbable que time.h soit fourni.

  8. #8
    Expert éminent sénior
    Citation Envoyé par pharell1234 Voir le message
    Bonsoir, Merci pour vos réponses, pour faire "attendre" le robot je pensais à créer une variable... De sorte que par exemple "i"=0 et "i" prend la valeur "i+1" chaque seconde..En fait j'aimerai créer une variable et un code qui permet de faire un décompte.. de 0 à 10 .. Afin de dire au robot que si "i"=10 alors faire demi tour..
    Et comment fais-tu pour attendre 1s à chaque itération ? sleep() ? Donc si tu peux attendre 1s tu peux tout aussi bien attendre 10.
    Ton truc serait bien si tu voulais faire un décompte, avec par exemple possibilité d'activer le robot pendant ce décompte. Si c'est juste attendre pour attendre alors autant utiliser une fonction qui fait déjà directement ça.
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  9. #9
    Membre régulier
    Citation Envoyé par Sve@r Voir le message
    Ton truc serait bien si tu voulais faire un décompte, avec par exemple possibilité d'activer le robot pendant ce décompte.
    Bien qu'il ne l'a pas exprimé en toutes lettres, je l'ai compris comme ça.

    Citation Envoyé par pharell1234 Voir le message
    pour faire "attendre" le robot je pensais à créer une variable... De sorte que par exemple "i"=0 et "i" prend la valeur "i+1" chaque seconde..En fait j'aimerai créer une variable et un code qui permet de faire un décompte.. de 0 à 10 .. Afin de dire au robot que si "i"=10 alors faire demi tour..
    Tu peux utiliser une boucle, je t'ai fait un exemple avec "for".
    Voici ton code légèrement remanié de sorte que ça te reste familier, avec un do...while converti en while et sans les else plus ou moins superflus.
    Essaye-le, voir déjà si ça compile, en particulier avec le type bool ...

    En reprenant le code, je me suis retrouvée à faire des prédicats (pas sûr que ça te parle mais pour les autres) et de la gestion d'erreurs pour finir par me rendre compte que j’étais en train d'écrire une bibliothèque.
    Du coup j'ai une autre version, plutôt assez expressive.
    Si je la finis, je la publierai, ça peut être intéressant. En tout cas, ça m'aura permis d’écrire quelques lignes de codes.

    Bien sûr, si tu as l'occasion de faire une petite vidéo, ce ne sera pas de refus.

    Bon courage, à supposer que tu suis toujours cette discussion.


    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
    67
    68
    69
     
    #include <stdbool.h> 
    #include "lib_mot_moway.h"
    #include "lib_sen_moway.h"
     
     
    bool is_forward_obstacle(void) 
    {
        return SEN_OBS_ANALOG(OBS_SIDE_L)>100 
            || SEN_OBS_ANALOG(OBS_SIDE_R)>100 
            || SEN_OBS_ANALOG(OBS_CENTER_L)>100 
            || SEN_OBS_ANALOG(OBS_CENTER_R)>100
            ;
    }
     
    void turn_back(void) 
    {
        MOT_ROT(100,FWD,CENTER,RIGHT,ANGLE,50);
        while (!MOT_END)
            ; // attendre fin rotation
    }
     
    void stop(void)
    { 
        MOT_STOP();   
    }
     
     
    void main(void)
    {
        //Appelé au RESET
        SEN_CONFIG();
        MOT_CONFIG();
     
        while (1) {
     
            // Faire avancer le robot sur la ligne noire 
            if (SEN_LINE_DIG(LINE_L)==1 && SEN_LINE_DIG(LINE_R)==1) {
                MOT_STR(50,FWD,TIME,0); 
            } 
     
            // Faire dévier le robot vers la gauche quand capteurs de ligne droit voit du blanc
            if (SEN_LINE_DIG(LINE_R)==0 && SEN_LINE_DIG(LINE_L)==1) {
                MOT_ROT(50,FWD,CENTER,LEFT,ANGLE,10);
            }
     
            // Faire dévier le robot vers la droite quand capteur ligne gauche voit du blanc
            if (SEN_LINE_DIG(LINE_R)==1 && SEN_LINE_DIG(LINE_L)==0) {
                MOT_ROT(50,FWD,CENTER,RIGHT,ANGLE,10);
            }
     
            // gestion obstacle
            if (is_forward_obstacle()) {
     
                stop();
     
                int wait_limit= 10;
                for (int wait_count=0; wait_count <= wait_limit && is_forward_obstacle(); ++wait_count) {
     
                    if (wait_count == wait_limit)   
                        turn_back();
                    else
                        PAUSE_SECONDE(1);
                } 
            }
     
        }  
     
    }

  10. #10
    Nouveau Candidat au Club
    Bonjour, désolé du retard, merci pour vos réponses je vais essayer ce que vous m'aviez dit, et voir si ca marche pour ce robot. Merci encore.

  11. #11
    Expert éminent sénior
    Citation Envoyé par kaitlyn Voir le message
    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
    void main(void)
    {
        ...
                int wait_limit= 10;
                for (int wait_count=0; wait_count <= wait_limit && is_forward_obstacle(); ++wait_count) {
     
                    if (wait_count == wait_limit)   
                        turn_back();
                    else
                        PAUSE_SECONDE(1);
                } 
            }
     
        }  
    }

    Si je la finis, je la publierai, ça peut être intéressant
    Mouais. Suis pas certain que ce soit publiable.
    Déjà main() est int, pas void. Ensuite avec une boucle allant de 0 (inclus) jusqu'à 10 (inclus) ça fait 11 secondes (ok, on va dire que c'est une erreur d'inattention). Mais surtout c'est quand-même dommage de tester 10 fois une égalité wait_count == wait_limit dont on sait d'avance qu'elle sera systématiquement fausse aux 9 premières itérations !!! C'est cramer du processeur pour rien.
    Code c :Sélectionner tout -Visualiser dans une fenêtre à part
    1
    2
    for (int wait_count=0; wait_count < wait_limit && is_forward_obstacle(); ++wait_count) PAUSE_SECONDE(1);
    if (wait_count == wait_limit) turn_back();


    Et enfin utiliser des globales "pour ne pas se compliquer la vie" c'est la plus mauvaise des mauvaises fausses bonnes idées.

    Accessoirement wait_limit (variable qui ne varie pas) aurait peut-être avantage à devenir macro...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  12. #12
    Rédacteur/Modérateur

    Franchement, une state machine reste de loin la meilleure idée imo, et te rendra les choses bien plus simples par la suite.
    Ça permet de structurer le code et de découper les phases et instructions.
    Ça permet aussi de ne pas bloquer ton code pendant qu'un unique mouvement se réalise.
    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
    enum State {
      State_Avance,
      State_Obstacle,
      State_DemiTour,
    };
    int main()
    {
      ...
      State robotState = State_Avance; // Mettons qu'il commence toujours par avancer
      time_t obstacleStartTime;
      const unsigned ObstacleWait = 10 * 1000; // 10 000 ms = 10s
      do {
        switch (robotState)
        {
        case State_Avance:
        {
          if (obstacle détecté)
          {
            robotState = State_Obstacle;
            obstacleStartTime = time(NULL);
          }
          else (...)
            avance
        } break;
        case State_Obstacle:
        {
          if (obstacle absent)
            robotState = State_Avance;
          else if (
          {
            robotState = State_DemiTour;
          }
        } break;
        case State_Obstacle:
        {
          if (obstacle absent)
            robotState = State_Avance;
          else
          {
            const time_t now = time(NULL);
            const uintmax_t attente = now - obstacleStartTime;
            if (attente >= WaitObstacle)
              robotState = State_DemiTour;
            else
            {
              printf("Face obstacle depuis %.2lf s", attente * 0.001);
              attendre 1s ? sinon on laisse rouler et il se remettra en marche dès que l'obstacle est parti
            }
        } break;
        case State_DemiTour:
        {
          if (demi tour fini)
            robotState = State_Avance;
        } break;
        }
      } while(...);
    }

    C'est rapide mais t'as l'idée. Et comme ça quand tu voudras faire autre chose qu'attendre pendant qu'il se trouve face à un obstacle ou réalise un demi-tour (comme utiliser d'autres capteurs, s'arrêter avant pour raison X ou Y, ...) et bien tu pourras
    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.

  13. #13
    Membre régulier
    Citation Envoyé par Sve@r Voir le message
    ...
    Non, il n'y a pas d'erreur d'inattention.

  14. #14
    Nouveau Candidat au Club
    Contourner un obstacle
    Bonjour, désolé de vous informer que j'ai eu des soucis avec vos propositions précédentes pour mon programme, et puis cela me semble plus compliqué, beaucoup de notion que vous me proposez me dépasse. Cependant j'ai besoin d'aide pour un nouveau programme avec ce même robot, j'aimerai créer un programme qui lorsqu’il capte un obstacle, il le contourne pour pouvoir continuer sa route, j'aimerai qu'on me donne un code de ce programme en "algo", je veux dire en langue française et non de machine pour le moment. (J'ai déjà essayé mais je n'y arrive pas).

    Merci par avance.

  15. #15
    Expert éminent sénior
    Citation Envoyé par pharell1234 Voir le message
    j'aimerai créer un programme qui lorsqu’il capte un obstacle, il le contourne pour pouvoir continuer sa route, j'aimerai qu'on me donne un code de ce programme en "algo", je veux dire en langue française et non de machine pour le moment. (J'ai déjà essayé mais je n'y arrive pas).
    Déjà tu devrais aller voir ce lien car ça correspond exactement à ton TP.

    Ensuite il faudrait préciser: le robot peut-il voir juste devant lui ou bien aussi sur les côtés ? Et une fois qu'il a contourné, il fait quoi ? Il repart à l'aventure ? C'est quoi son but à ce robot en fait ??? Parce que tout ça ça influe sur l'algo. Si par exemple son but est juste de longer un mur (exemple algorithme main gauche/main droite pour traverser un labyrinthe) ce n'est pas pareil qu'avancer dans un espace style prairie en évitant les bosquets...
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site