Aller au contenu


Photo
- - - - -

Besoin d'aide arduino


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

#21 P2B

P2B

    Membre

  • Membres
  • 36 messages

Posté 18 février 2013 - 10:01

Il suffit de tester l'angle de l'obstacle pour savoir de quel côté il est
(angle 0-90, ou 90-180°)
Arrêter la roue du côté opposé à l'obstacle pour tourner et l'éviter, la seconde roue continue normalement.

On peut optimiser le mouvement
* continuer de rouler si c'est un bord de couloir (0-10° et 170-180°) qui ne gène pas encore le robot
* tourner juste un peu si l'obstacle est très latéral (10-45° et 125-170°)
* tourner franchement si c'est devant (45-135°).

Par exemple :
10-45° -> arrêt bref de la roue gauche, pour tourner un peu à droite,
45-80° -> arrêt plus long de la roue gauche, pour tourner nettement à droite,

80-110° -> demi-tour car ça passe pas !

110-135° -> arrêt plus long de la roue droite, pour tourner nettement à gauche,
135-180° -> arrêt bref de la roue droite , pour tourner un peu à gauche.

l'idéal serait de prendre en compte la distance de l'obstacle et l'encombrement du robot pour calculer si ça passe.


Apres quelques tests plus ou moins concluant, le robot arrive a se diriger seul.
Cependant pour qu'il soit encore plus efficace il faudrait comme le dit ChristianR que je prenne en compte l'encombrement du robot.
je cite : "continuer de rouler si c'est un bord de couloir (0-10° et 170-180°) qui ne gène pas encore le robot"

je pensais le rajouter dans la fonction doubleBalayage :

void doubleBalayage()
{
  int angleMin = 40;
  int angleMax = 140;
  int valUltraSon = 0;
  boolean obstacle = false;

    for (byte degre = angleMax; degre >= angleMin ; degre -= 10){
    myCam.write(degre);
    delay(50);
    valUltraSon = distanceObstacle();

    // TESTE LE SEUIL DU CAPTEUR
    if((robotBouge) && (valUltraSon < distanceMinDevant))
    {
      obstacle = true; 
      robotStop();
      break;
    } 
  }
  if(not obstacle)
  {
        for (byte degre = angleMin ; degre <= angleMax; degre += 10)
    {
      myCam.write(degre);
      delay(50);
      valUltraSon = distanceObstacle();

      // TESTE LE SEUIL DU CAPTEUR 
      if((robotBouge) && (valUltraSon < distanceMinDevant))
      {
        obstacle = true; 
        robotStop();
        break;
      }
    }
  } 
}

Mais je ne vois pas trop comment m'y prendre si qq'un a une idee?
Merci

#22 P2B

P2B

    Membre

  • Membres
  • 36 messages

Posté 20 février 2013 - 10:01

Salut,

Je vais laisser de cote pour l'instant "l'optimisation des angles", je ne trouve pas.
Je mets en ligne mon code concernant mon mode automatique si qq'un peut me dire s'il est correct le cas echeant me dire les erreurs ou les modif a faire.

Bien cordialement

P2B.

je n'arrive pas à le mettre en piece jointe alors voici en extrait de code dsl.


/* //////////////////////////////////////////////////////////////////////////////////////////////////////////
 *  PARTIE 2 : MODE AUTO
 * //////////////////////////////////////////////////////////////////////////////////////////////////////////
 *
 * LE 08/002/2013 PAR P2B
 *
 *  PROFIL DU ROBOT :
 *        CHASSIS A CHENILLE AVEC 2 MOTEURS DC 12V
 *        UNE TOURELLE SUR LAQUELLE EST MONTEE UN CAPTEUR A ULTRASONS.
 *
 *  BUT DU PROGRAMME : 
 *        COMME INDIQUE DANS LE TITRE, LE MODE AUTOMATIQUE DU ROBOT.
 *        POUR POUVOIR SE DEPLACER LE ROBOT EFFECTUE UN BALAYAGE CONSTANT DU CAPTEUR JUSQU A RENCONTRER UN OBSTACLE.
 *        LORSQU'UN OBSTACLE EST DETECTE A UN SEUIL DE 40 CM, LE ROBOT EFFECTUE UN SECOND BALAYAGE PLUS LENT
 *        AVEC UNE LECTURE DU CAPTEUR TOUS LES 10 DEGRES.
 *        ENSUITE, LE ROBOT RECUPERE LA VALEUR DU CAPTEUR LA PLUS HAUTE AINSI QUE L'ANGLE CORRESPONDANT.              
 *
 * //////////////////////////////////////////////////////////////////////////////////////////////////////////
 *  CONFIGURATION
 */////////////////////////////////////////////////////////////////////////////////////////////////////////

// ********  BIBLIOTHEQUE(S) UTILISEE(S)  ********
#include <Servo.h>

// ********  LES ENTREES ET SORTIES  ********
int dPinSRF05 = 2;
int dPinServoCam = 3;
int dPinBuzzer = 4;
int dPinRelaisMoteurs = 7;
int dPinMoteurG = 11;
int dPinMoteurD = 10;

// ********  OBJETS SERVO POUR LE CONTROLE DES MOTEURS  ********
Servo myCam; // SERVO QUI SUPPORTE LE CAPTEUR
Servo myMoteurG;    // LE MOTEUR GAUCHE
Servo myMoteurD;    // LE MOTEUR DROIT

// ********  VARIABLES GLOBALES  ********
int valUltraSon = 0;    // LE CAPTEUR SRF05
int valServoCam = 0;    // VALEUR DE L ANGLE DU SERVO QUI SUPPORTE LE CAPTEUR
int servoCamMax = 0;    // VALEUR MAXI DE L ANGLE DU SERVO QUI SUPPORTE LE CAPTEUR

// SEUILS DE SECURITE DU CAPTEUR
int distanceMinDevant = 30;
int distanceMinCote = 15;
int distanceSecurite = 15;

int vitGStop = 100;   // MOTEUR GAUCHE A L'ARRET
int vitDStop = 100;   // MOTEUR DROIT A L ARRET
int vitG = vitGStop;  // VITESSE DU MOTEUR GAUCHE
int vitD = vitDStop;  // VITESSE DU MOTEUR DROIT

boolean robotBouge = false;

/* /////////////////////////////////////////////////////////////////////////////////////////////////////////
 *  INITIALISATION
 */////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup()
{
  Serial.begin(9600);

  pinMode(dPinServoCam, OUTPUT);
  pinMode(dPinBuzzer, OUTPUT);
  pinMode(dPinRelaisMoteurs, OUTPUT); 
  pinMode(dPinMoteurG, OUTPUT);
  pinMode(dPinMoteurD, OUTPUT);

  myCam.attach(dPinServoCam);
  myMoteurG.attach(dPinMoteurG);  
  myMoteurD.attach(dPinMoteurD);

  Serial.println("*********************************************");
  Serial.println("                  i ROBOT ");
  Serial.println("*********************************************");
  Serial.println(" ");
  delay(100);  

  // PETITES NOTES AU DEMARAGE
  for (int i = 1; i <= 3 ; i++) {
    playNote('c', 100); 
    playNote('d', 100);  
    delay(50);
  }
  //  ALLUMAGE DU RELAIS MOTEURS
  digitalWrite(dPinRelaisMoteurs, HIGH);
  Serial.println("RELAIS MOTEURS 'ON'");

  // CALCULE DE L ESPACE DEGAGE
  positionCentrale();
  simpleBalayage();
  robotPivoteVersDegagement();
  positionCentrale();
  robotAccelere(20, 20);
}

/* /////////////////////////////////////////////////////////////////////////////////////////////////////////
 *  PROGRAMME
 */////////////////////////////////////////////////////////////////////////////////////////////////////////

void loop()
{
  doubleBalayage();

  // DISTANCE DE SECURITE (REGLE A 15 CM)
  if(valUltraSon <= distanceSecurite) {
    valUltraSon = distanceObstacle();
    robotRecule(60, 60);
    delay(500);
    robotStop();
  }
  // SI LE ROBOT NE BOUGE PAS
  if (!robotBouge) {
    simpleBalayage();
    robotPivoteVersDegagement();    
    robotAccelere(20, 20);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// SIMPLE BALAYAGE DU CAPTEUR AVEC ANALYSE DE L ESPACE LE PLUS DEGAGE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void simpleBalayage()
{
  int valUltraSonMax = 0;
  int angleMin = 0;
  int angleMax = 180;  

  Serial.println("");
  Serial.println("     CALCULE DE L ANGLE DE DEGAGEMENT");
  Serial.println("");

  // BOUCLE POUR INCREMENTER LE SERVO "myCam" DE 0 A 180 DEG
  for (byte degre = angleMin ; degre <= angleMax; degre += 5) {
    myCam.write(degre);
    valUltraSon = distanceObstacle();

    // DISTANCE DE SECURITE (REGLE A 15 CM)
    if(valUltraSon <= distanceSecurite) {
      robotRecule(60, 60);
      delay(500);
      robotStop();
    }
    // TESTE LE SEUIL DU CAPTEUR (REGLE A 40 CM), ET AFFICHE UNIQUEMENT LES VALEURS SUPERIEUR AU SEUIL
    if(valUltraSon > distanceMinDevant) {
      afficheAngleDegage("LECTURE DU CAPTEUR", degre, valUltraSon);

      // COMPARAISON DE CHAQUE VALEUR MESURE 'valUltraSon' AVEC 'valUltraSonMax' ET ON RECUPERE LA PLUS GRANDE
      if(valUltraSon > valUltraSonMax) {
        valUltraSonMax = valUltraSon;
        servoCamMax = degre;
      }
    }
  }
  Serial.println(" ");
  Serial.println("*********************************************");
  Serial.print("  ANGLE DE DEGAGEMENT    : ");
  Serial.print(servoCamMax); 
  Serial.println(" DEG");
  Serial.print("  DISTANCE DE DEGAGEMENT : ");
  Serial.print(valUltraSonMax);
  Serial.println(" CM");
  Serial.println("*********************************************");
  Serial.println(" ");
  delay(100);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////
// DOUBLE BALAYAGE DU CAPTEUR AVEC DETECTION D OBSTACLE : SEUIL A 40 CM DEVANT ET 10 CM SUR LES COTES
///////////////////////////////////////////////////////////////////////////////////////////////////////

void doubleBalayage()
{
  int angleMin = 30;
  int angleMax = 135;
  boolean obstacle = false;

  // BOUCLE POUR DECREMENTE DE 140 A 40 DEGRE AVEC UN PAS DE 10
  for (byte degre = angleMax; degre >= angleMin ; degre -= 10) {
    myCam.write(degre);
    valUltraSon = distanceObstacle();

    // TESTE LE SEUIL DU CAPTEUR "distanceMinDevant" 
    if((robotBouge) && (valUltraSon < distanceMinDevant)) {
      obstacle = true; 
      robotStop();
      break;
    }
  }
  if(not obstacle) {
    // BOUCLE POUR INCREMENTER DE 40 A 140 DEGRE AVEC UN PAS DE 10
    for (byte degre = angleMin ; degre <= angleMax; degre += 10) {
      myCam.write(degre);
      valUltraSon = distanceObstacle();

      // TESTE LE SEUIL DU CAPTEUR
      if((robotBouge) && (valUltraSon < distanceMinDevant)) {
        obstacle = true; 
        robotStop();
        break;
      }
    }
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// EFFECTUER UNE MESURE AVEC LE CAPTEUR A ULTRASONS
///////////////////////////////////////////////////////////////////////////////////////////////////////////

int distanceObstacle() 
{
  int duree = 0;
  int distance = 0;
  
  pinMode(dPinSRF05, OUTPUT);              
  digitalWrite(dPinSRF05, LOW);         
  delayMicroseconds(2);
  digitalWrite(dPinSRF05, HIGH);      
  delayMicroseconds(10);
  digitalWrite(dPinSRF05, LOW);       
  pinMode(dPinSRF05, INPUT);
  
  duree = pulseIn(dPinSRF05, HIGH);              
  distance = duree / 58;

  if (distance < distanceMinDevant) { 
    playNote('c', 10);
  }    
  delay(50); // ON DOIT ATTENDRE 50 ms AVANT LE PROCHAIN TRIGGER (VOIR DOC FABRICANT)
  return(distance);                     
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// CALCULE DE L ESPACE DEGAGE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotPivoteVersDegagement()
{
  // LE ROBOT EFFECTUE UN TOUR SUR LUI MEME LORSQUE :
  // vitReferenceG = 40, vitReferenceD = 60, dureeReference = 3150  
  int angleRotation;
  float dureeRotation;
  int vitReferenceG = 40;       
  int vitReferenceD = 60;       
  int dureeReference = 3150; 

  // VERIFIER LES BROCHES MOTEUR G ET MOTEUR D
  // SI L ANGLE EST INFERIEUR A 90 LE ROBOT PIVOTE A GAUCHE
  if (servoCamMax < 90) {
    angleRotation = (89 - servoCamMax); 
    dureeRotation = (angleRotation / 360.0) * dureeReference;
  }
  // SI L ANGLE EST SUPERIEUR A 90 LE ROBOT PIVOTE A DROITE
  else if (servoCamMax > 90) {
    angleRotation = (servoCamMax - 89);
    dureeRotation = (angleRotation / 360.0) * dureeReference;
  }
  if (servoCamMax < 90) {
    robotPivoteG(vitReferenceG, vitReferenceD, dureeRotation);
  }
  else if (servoCamMax > 90) {
    robotPivoteD(vitReferenceG, vitReferenceD, dureeRotation);
  }
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// POSITION CENTRALE DU CAPTEUR
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void positionCentrale()
{
  myCam.write(90);
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// LE ROBOT PIVOTE A GAUCHE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotPivoteG(int G, int D, float duree)
{
  vitG = vitGStop - D;
  vitD = vitDStop + G;
  afficheVitesse("TOURNE A GAUCHE", vitG, vitD);
  myMoteurG.write(vitG);
  myMoteurD.write(vitD);
  delay(duree);
  robotStop();
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// LE ROBOT PIVOTE A DROITE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotPivoteD(int G, int D, float duree)
{  
  vitG = vitGStop + G;
  vitD = vitDStop - D;
  afficheVitesse("TOURNE A DROITE", vitG, vitD);
  myMoteurG.write(vitG);
  myMoteurD.write(vitD);
  delay(duree);
  robotStop();  
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// LE ROBOT EST A L ARRET
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotStop()
{
  vitG = vitGStop;
  vitD = vitDStop; 
  myMoteurG.write(vitG); 
  myMoteurD.write(vitD); 
  robotBouge = false;  
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// LE ROBOT ACCELERE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotAccelere(int vitG, int vitD)
{
  vitG = vitGStop + vitG;
  vitD = vitDStop + vitD;
  myMoteurG.write(vitG);
  myMoteurD.write(vitD);
  Serial.println("");
  afficheVitesse("MARCHE AVANT : ", vitG, vitD);
  robotBouge = true;  
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// LE ROBOT RECULE
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void robotRecule(int vitG, int vitD)
{
  vitG = vitGStop - vitG;
  vitD = vitDStop - vitD;
  myMoteurG.write(vitG);
  myMoteurD.write(vitD);
  afficheVitesse("MARCHE ARRIERE : ", vitG, vitD);
  robotBouge = true;  
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// AFFICHAGES
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void afficheVitesse(char commentaire[ ], int vitG, int vitD)
{
  Serial.println (commentaire);
  Serial.print ("G => ");
  Serial.println (vitG);
  Serial.print ("D => ");
  Serial.println (vitD);
}

void afficheAngleDegage(char commentaire[ ], int angle, int distance)
{
  //Serial.println (commentaire);
  Serial.print("  ANGLE =>    ");
  Serial.print (angle);
  Serial.print (" DEG");
  Serial.print ("    DISTANCE => ");
  Serial.print (distance);
  Serial.println (" CM");         
}

///////////////////////////////////////////////////////////////////////////////////////////////////////////
// PARAMETRES DU PIEZO
///////////////////////////////////////////////////////////////////////////////////////////////////////////

void playNote(char note, int duration)
{
  char names[ ] = { 
    'c', 'd', 'e', 'f', 'g', 'a', 'b', 'C'   };  // Do Ré Mi Fa Sol La Si Do
  int tones[ ] = { 
    1915, 1700, 1519, 1432, 1275, 1136, 1014, 956   };  // Demi-période en ms
  // Play the tone corresponding to the note name
  for (int i = 0; i < 8; i++)
  {
    if (names[i] == note) {
      playTone(tones[i], duration);
    }
  }
}

void playTone(int tone, int duration)
{
  for (long i = 0; i < duration * 1000L; i += tone * 2) {
    digitalWrite(dPinBuzzer, HIGH);
    delayMicroseconds(tone);
    digitalWrite(dPinBuzzer, LOW);
    delayMicroseconds(tone);
  }
}

[code]

Y a une chose que je n'arrive pas a comprendre c'est pourquoi mon capteur de temps a autre ne me renvois pas la bonne distance? Ca fausse tout





























































































































#23 P2B

P2B

    Membre

  • Membres
  • 36 messages

Posté 23 février 2013 - 08:17

Bonjour,
Désole d'incister, mais qq'un pourrait'il jeter un coup d'oeil a mon code et me dire si c'est ok.
J'ai besoin de savoir pour avancer, car la suite de mon projet est de fusionner le mode manuel avec ce mode auto?.

Bon week end a tous.
Bien cordialement.
P2B

#24 thermo_nono

thermo_nono

    Membre chevronné

  • Membres
  • PipPipPipPip
  • 825 messages

Posté 24 février 2013 - 08:18

Ce n'est pas évident à vérifier : le prog est long et complexe ce qui fait que même si il est remarquablement bien documenté il va être difficile d'y trouver les éventuelles erreurs (à première vue ça m'a l'air impeccable).

En ce qui concerne les erreurs de mesure, peut être qu'en ajoutant un ou deux "delay()" ça arrangerait le problème.. mais je dis ça et je ne dis rien car c'était juste une idée en passant. ^^

Edit : bravo pour les annotations c'est un détail mais ça aide beaucoup pour la relecture.

#25 P2B

P2B

    Membre

  • Membres
  • 36 messages

Posté 24 février 2013 - 09:42

Ce n'est pas évident à vérifier : le prog est long et complexe ce qui fait que même si il est remarquablement bien documenté il va être difficile d'y trouver les éventuelles erreurs (à première vue ça m'a l'air impeccable).

En ce qui concerne les erreurs de mesure, peut être qu'en ajoutant un ou deux "delay()" ça arrangerait le problème.. mais je dis ça et je ne dis rien car c'était juste une idée en passant. ^^

Edit : bravo pour les annotations c'est un détail mais ça aide beaucoup pour la relecture.

Merci pour ta réponse.
Après avoir pas mal cherché il semblerait que le probleme venait de là :
Dans la fonction "robotPivoteVersDegagement()"

 if (servoCamMax < 90) { 
    angleRotation = (91 - servoCamMax);  // ici j'avais mis 90 à la place de 91 et lorsque j'avais un angle de 90 ca faisait (90 - 90)
    dureeRotation = (angleRotation / 360.0) * dureeReference;  // et ici le resultat donnait : (0/360) * 3150 
Avant de continuer j'aimerai "ameliorer" un peut le code. Je voudrais que le robot continue de rouler si c'est un bord de couloir (0-10° et 170-180°) qui ne gène pas encore le robot.
Parceque pour l'instant ça fonctionne mais il met du temps a passer un seuil de porte.

J'ai pensé faire qq chose comme ca :

if((degre < 10) && (valUltraSon >= distanceMinCote))
// continue d'avancer

Merci

#26 P2B

P2B

    Membre

  • Membres
  • 36 messages

Posté 25 février 2013 - 03:12

ou bien ca ?


 // OPTIMISATION DE L ANGLE
    if((degre < 30 && degre > 150) && (valUltraSon < distanceMinCote)) {
      
    }






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

0 members, 0 guests, 0 anonymous users