Envoie de commande servomoteur sur une carte Arduino depuis un Raspberry pi 3.

Fermé
Bamba63 Messages postés 6 Date d'inscription samedi 29 mai 2021 Statut Membre Dernière intervention 24 juin 2021 - Modifié le 23 juin 2021 à 12:06
baladur13 Messages postés 46385 Date d'inscription mercredi 11 avril 2007 Statut Modérateur Dernière intervention 19 avril 2024 - 24 juin 2021 à 13:30
Bonjour à tout le monde,
En fait, j'ai un Project qui consiste à faire parcourir mon robot autonome dans un labyrinthe. Une fois sorti du premier parcourt, se mette en position de tire à l'aide de la picamera de Raspberry pi avec à OpenCV (pour la détection de couleur des cibles à abattre).
Je suis parti sur la base que les servomoteurs sont pilotés par l'Arduino(langage C) et la camera par le Raspberry (avec python).
Mon plus grand problème ici est comment dire à Arduino depuis le Raspberry que la couleur rouge par exemple est détectée donc arrêtes toi et tires sur la cible.
J'ai cherché partout mais j'ai pas vu quelque part oùon explique cette partie surtout avec la commende des servomoteurs (les deux roues, l'actionneur pour le tire et le moteur pour l'angle d'inclinaison) .
Donc je suis venu ici pour que vous m'iadiez pour avancer sur mon Project .
Merci d'avance pour tout aide.

Voici le code python pour la detection d'image ici bleue et rouge pour nos deux cibles.

import cv2
import numpy as np

cap = cv2.VideoCapture(0)


def getContours(img):
  contours,hierarchy = cv2.findContours(img,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE)
  for cnt in contours:
      area = cv2.contourArea(cnt)

      if area > 500:
          cv2.drawContours(red_mask, cnt, -1, (0, 255, 255), 2)
          peri = cv2.arcLength(cnt,True)
          approx = cv2.approxPolyDP(cnt,0.02*peri,True)
          x, y, w, h = cv2.boundingRect(approx)
          


while True:
    _, frame = cap.read()
    hsv_frame = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)

    # Couleur rouge
    low_red = np.array([119, 121, 75])
    high_red = np.array([179, 255, 255])
    red_mask = cv2.inRange(hsv_frame, low_red, high_red)
    red = cv2.bitwise_and(frame, frame, mask=red_mask)    
    getContours(red_mask)

    # Couleur bleue
    low_blue = np.array([110, 152, 11])
    high_blue = np.array([126, 255, 255])
    blue_mask = cv2.inRange(hsv_frame, low_blue, high_blue)
    blue = cv2.bitwise_and(frame, frame, mask=blue_mask)
    getContours(blue_mask)


    # Toutes les couleurs sauf blanc
    low = np.array([0, 42, 0])
    high = np.array([179, 255, 255])
    mask = cv2.inRange(hsv_frame, low, high)
    result = cv2.bitwise_and(frame, frame, mask=mask)
    #getContours(mask)
    
    
    
    cv2.imshow("Frame", frame)
    cv2.imshow("Red", red)
    cv2.imshow("Blue", blue)
    cv2.imshow("Result", result)

    key = cv2.waitKey(1)
    if key == 27:
        break



Code Arduino pour piloter les deux roues jusqu'à sortie du premier parcour(On a bien sur utiliser le temps meme si c'est pas trop précis car on a pas d'odometre :) )
#include <Servo.h>                           // Include servo library
Servo servoLeft;                             // Declare left and right servos
Servo servoRight;

byte wLeftOld;                               // Previous loop whisker values
byte wRightOld;                              
byte counter;                                // For counting alternate corners

unsigned long myTime;
int temps1 = 20000; //18500;
int duree2 = 10000;
int duree3 = 4000;

int interval1 = 1370;
int temps2 = temps1 + interval1 + duree2;


void setup()                                 // Built-in initialization block
{ 
  Serial.begin(9600);
  pinMode(3, INPUT);                         // Set right whisker pin to input
  pinMode(2, INPUT);                         // Set left whisker pin to input  
  pinMode(13,OUTPUT);

  servoLeft.attach(10);                      // Attach left signal to pin 13 
  servoRight.attach(9);                     // Attach right signal to pin 12

  wLeftOld = 0;                              // Init. previous whisker states
  wRightOld = 1;  
  counter = 0;  
}
 
void loop()                                  // Main loop auto-repeats
{
  
  byte wLeft = digitalRead(2);               // Copy left result to wLeft  
  byte wRight = digitalRead(3);              // Copy right result to wRight
  myTime = millis();
 //Serial.println(temps3);
 Serial.println(myTime);


    // Corner Escape

  if(wLeft != wRight)                        // One whisker pressed?
  {                                          // Alternate from last time?
    if ((wLeft != wLeftOld) && (wRight != wRightOld))  
    {                                       
      counter++;                             // Increase count by one
      wLeftOld = wLeft;                      // Record current for next rep
      wRightOld = wRight;
      if(counter == 4)                       // Stuck in a corner?
      {
        wLeft = 0;                           // Set up for U-turn
        wRight = 0;
        counter = 0;                         // Clear alternate corner count
      }
    }  
    else                                     // Not alternate from last time
    {
      counter = 0;                           // Clear alternate corner count
    }
  } 

 

  
  // Whisker Navigation

  if((wLeft == 0) && (wRight == 0))          // If both whiskers contact
  {
   // backward(1000);                          // Back up 1 second
    turnRight(1300); // Turn left about 120 degrees
    
  }
  else if(wLeft == 0)                        // If only left whisker contact
  {
    //backward(1000);                          // Back up 1 second
    turnRight(1000);                          // Turn right about 60 degrees
  }
  else if(wRight == 0)                       // If only right whisker contact
  {
    //backward(1000);                          // Back up 1 second
    turnLeft(450);                           // Turn left about 60 degrees    distance>=1.25 temps>=18000
  }

  if(myTime >= temps1 && myTime <= temps1+interval1) {
    turnLeft(450);
  } 
  else if (myTime >= temps2 && myTime <= temps2+interval1){
    turnLeft(450);  
  }
  else if(myTime >= 36740 && myTime <= 36740+interval1) {
    turnRight(450);
  }
  else if (myTime >= 36740 +interval1+2000) {
    stop();
  } 
  else                                       // Otherwise, no whisker contact
  {
    forward(20);                             // Forward 1/50 of a second   
  }
}

void forward(int time)                       // Forward function
{
  servoLeft.writeMicroseconds(1220);         //(1000);  Left wheel counterclockwise
  servoRight.writeMicroseconds(2000);        // Right wheel clockwise
  delay(time);                 // Maneuver for time ms      
}

void turnLeft(int time)                      // Left turn function
{
  servoLeft.writeMicroseconds(1000);         // Left wheel clockwise
  servoRight.writeMicroseconds(1000);        // Right wheel clockwise
  delay(time);                               // Maneuver for time ms
}

void turnRight(int time)                     // Right turn function
{
  servoLeft.writeMicroseconds(2000);         // Left wheel counterclockwise
  servoRight.writeMicroseconds(2000);        // Right wheel counterclockwise
  delay(time);                               // Maneuver for time ms
  
}

void backward(int time)                      // Backward function
{
  servoLeft.writeMicroseconds(2000);         // Left wheel clockwise
  servoRight.writeMicroseconds(1230);         //(1000); Right wheel counterclockwise
  delay(time);                               // Maneuver for time ms
}

void stop()                      // Backward function
{
  servoLeft.writeMicroseconds(1550);         // Left wheel clockwise
  servoRight.writeMicroseconds(1500);        // Right wheel counterclockwise  
}


Labyrinthe:




Base de du robot:



Et en dernier la conception du reste:


Message modifié par la modération
Pour une lecture plus facile du code, à l'avenir utilisez les balises, VOIR CETTE PAGE
A voir également:

1 réponse

baladur13 Messages postés 46385 Date d'inscription mercredi 11 avril 2007 Statut Modérateur Dernière intervention 19 avril 2024 13 212
24 juin 2021 à 13:30
Bonjour
Puisque vous dites dans une alerte avoir résolu le problème par vous-même, il serait gentil de votre part de nous donner la solution.
Cette dernière pouvant, qui sait, servir à d'autres internautes confrontés à ce type de problème.
Merci d'avance pour eux.
0