Fabrication industrielle
Internet des objets industriel | Matériaux industriels | Entretien et réparation d'équipement | Programmation industrielle |
home  MfgRobots >> Fabrication industrielle >  >> Manufacturing Technology >> Processus de fabrication

Robot Omnidirectionnel pour Suivi de Personne en Sécurité

Composants et fournitures

ComposantQuantité
Driver moteur double L298N (stepper/DC)2
Régulateur abaisseur LM2596 (12V → 5V)1
Alarme batterie LiPo (détecteur basse tension)1
Moteur DC 12V 24 tr/min arbre 4mm (réducteur)3
Arduino Nano R31
Webcam Microsoft LifeCam HD-30001
Fils de liaison (beaucoup !)1 lot
Carte Ci20 (IMagination Technologies)1
Batterie LiPo 11,1V 3 cellules1

Outils nécessaires

Applications et services en ligne

À propos du projet

Soumission initiale

Pour le concours « Hackster Terminate the Competition » : un robot qui cherche les humains mais pour les complimenter, pas les éliminer ! Robot omnidirectionnel qui vous détecte, vous suit et vous flatte.

Contrainte auto-imposée : aucune électronique à fabriquer soi-même. Tout s'achète sur eBay, s'assemble avec tutos publics. Châssis imprimable 3D (soi-même ou via 3D Hubs).

Architecture système

Robot Omnidirectionnel pour Suivi de Personne en Sécurité

4 blocs principaux :

  1. Gestion alimentation (batterie → 5V/12V)
  2. Ci20 = cerveau (OpenCV détection visage)
  3. Arduino Nano = contrôle moteurs (réception commandes série Ci20)
  4. Moteurs + roues omnidirectionnelles

Gestion alimentation ("Électrickery")

Robot Omnidirectionnel pour Suivi de Personne en Sécurité

Schéma complet : batterie LiPo 3S → LM2596 (5V pour Ci20/Arduino) → L298N (12V direct pour moteurs) + alarme basse tension.

Connexion Arduino → L298N

Suivre ce tutoriel : Instructables L298N. Une fois câblé : lumières bleues, pas de fumée bleue = c'est bon !

Impression 3D du châssis

Design : look cool + mise en valeur du Ci20. Fichiers STL dispo dans PIÈCES PERSONNALISÉES : base, couvercle, roues omnidirectionnelles (remix Thingiverse). Assemblage : colle ou ruban adhésif, vis M4 pour moteurs.

Robot Omnidirectionnel pour Suivi de Personne en Sécurité

Magie du Ci20 (OpenCV)

  1. Installer OpenCV : suivre tutoriel standard (compilation depuis sources)
  2. Compiler & lancer le tracking facial :
    g++ -I/usr/local/include/opencv -I/usr/local/include/opencv2 -L/usr/local/lib/ -g -o binary main.cpp \
    -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video \
    -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib \
    -lopencv_legacy -lopencv_stitching
    
Robot Omnidirectionnel pour Suivi de Personne en Sécurité

Ci20 + Arduino : Communication série

Flasher l'Arduino (code ci-dessous), le brancher en USB sur le Ci20, lancer le FaceTracker, brancher la webcam. Si votre visage est centré → le robot avance !

Travail restant (défis ouverts)

Codes

Arduino - Principal (réception commandes Ci20 → moteurs)

// Moteur 1
int dir1PinA = 3, dir2PinA = 2, speedPinA = 9; // PWM
// Moteur 2
int dir1PinB = 4, dir2PinB = 5, speedPinB = 8; // PWM
// Moteur 3
int dir1PinC = 6, dir2PinC = 7, speedPinC = 10; // PWM

int x = 0, y = 0, dominantUltrasonic = 0;
bool moveMotor = false;
unsigned long startTime = 0;
String rpiString;

void setup() {
  Serial.begin(9600);
  pinMode(dir1PinA, OUTPUT); pinMode(dir2PinA, OUTPUT); pinMode(speedPinA, OUTPUT);
  pinMode(dir1PinB, OUTPUT); pinMode(dir2PinB, OUTPUT); pinMode(speedPinB, OUTPUT);
  pinMode(dir1PinC, OUTPUT); pinMode(dir2PinC, OUTPUT); pinMode(speedPinC, OUTPUT);
  startTime = millis();
}

void loop() {
  readDataFromRPi();
  delay(30);
}

void readDataFromRPi() {
  while (Serial.available()) {
    delay(3);
    if (Serial.available() > 0) {
      char c = Serial.read();
      rpiString += c;
      if (c == 'n') break;
    }
  }
  if (rpiString.length() > 0) {
    Serial.println(rpiString);
    String isRotate = getValue(rpiString, ' ', 0);
    String xval = getValue(rpiString, ' ', 1);
    String yval = getValue(rpiString, ' ', 2);
    x = xval.toInt(); y = yval.toInt();
    startTime = millis();
    if (isRotate == "r") rotate(x);
    else driveInDirection(x, y);
    rpiString = "";
  }
}

String getValue(String data, char separator, int index) {
  int found = 0, strIndex[] = {0, -1}, maxIndex = data.length() - 1;
  for (int i = 0; i <= maxIndex && found <= index; i++) {
    if (data.charAt(i) == separator || i == maxIndex) {
      found++; strIndex[0] = strIndex[1] + 1;
      strIndex[1] = (i == maxIndex) ? i + 1 : i;
    }
  }
  return found > index ? data.substring(strIndex[0], strIndex[1]) : "";
}

Arduino - Contrôle Moteurs (cinématique omnidirectionnelle 3 roues)

void driveInDirection(float newX, float newY) {
  delay(20);
  float x = newX, y = newY;
  float theta = atan2(y, x);
  float mag = sqrt(x*x + y*y);
  float vx = mag * cos(theta), vy = mag * sin(theta);
  float w1 = -vx;
  float w2 = 0.5 * vx - sqrt(3)/2 * vy;
  float w3 = 0.5 * vx + sqrt(3)/2 * vy;
  float wSet[3] = {w1, w2, w3};
  float largestValue = 0;
  for (int i = 0; i < 3; i++) if (abs(wSet[i]) > largestValue) largestValue = abs(wSet[i]);
  float speedCoef = 147.0 / largestValue;
  w1 *= speedCoef; w2 *= speedCoef; w3 *= speedCoef;
  if (x == 0 && y == 0) { w1 = w2 = w3 = 0; }
  w1 = constrain(w1, -150, 150);
  w2 = constrain(w2, -150, 150);
  w3 = constrain(w3, -150, 150);
  bool w1_ccw = w1 < 0, w2_ccw = w2 < 0, w3_ccw = w3 < 0;
  byte w1_speed = map(abs(w1), 0, 150, 0, 255);
  byte w2_speed = map(abs(w2), 0, 150, 0, 255);
  byte w3_speed = map(abs(w3), 0, 150, 0, 255);
  analogWrite(speedPinA, w1_speed); analogWrite(speedPinB, w2_speed); analogWrite(speedPinC, w3_speed);
  digitalWrite(dir1PinA, !w1_ccw); digitalWrite(dir2PinA, w1_ccw);
  digitalWrite(dir1PinB, !w2_ccw); digitalWrite(dir2PinB, w2_ccw);
  digitalWrite(dir1PinC, w3_ccw);  digitalWrite(dir2PinC, !w3_ccw);
}

void rotate(float milliseconds) {
  float w1 = 255, w2 = 255, w3 = 255;
  byte w1_speed = map(abs(w1), 0, 150, 0, 255);
  byte w2_speed = map(abs(w2), 0, 150, 0, 255);
  byte w3_speed = map(abs(w3), 0, 150, 0, 255);
  analogWrite(speedPinA, w1_speed); analogWrite(speedPinB, w2_speed); analogWrite(speedPinC, w3_speed);
  digitalWrite(dir1PinA, LOW); digitalWrite(dir2PinA, HIGH);
  digitalWrite(dir1PinB, LOW); digitalWrite(dir2PinB, HIGH);
  digitalWrite(dir1PinC, HIGH); digitalWrite(dir2PinC, LOW);
  delay(milliseconds);
  analogWrite(speedPinA, 0); analogWrite(speedPinB, 0); analogWrite(speedPinC, 0);
}

Ci20 - FaceTracking C++ (OpenCV)

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
#include 
#include 
#include 

using namespace std; using namespace cv;
CascadeClassifier face_cascade;
String window_name = "Face Detection";

int sendSerial(char* message) {
  int fd = open("/dev/ttyUSB0", O_RDWR);
  if (fd == -1) { perror("dev/ttyUSB0"); return 1; }
  struct termios tios; tcgetattr(fd, &tios);
  tios.c_iflag = IGNBRK | IGNPAR; tios.c_oflag = 0; tios.c_lflag = 0;
  cfsetspeed(&tios, B9600); tcsetattr(fd, TCSAFLUSH, &tios);
  usleep(1000); write(fd, message, strlen(message)); return 0;
}

void detectFaces(Mat frame) {
  vector faces; Mat frame_gray;
  cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
  equalizeHist(frame_gray, frame_gray);
  face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, 0|CASCADE_SCALE_IMAGE, Size(30,30));
  for (size_t i = 0; i < faces.size(); i++) {
    Point center(faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2);
    ellipse(frame, center, Size(faces[i].width/2, faces[i].height/2), 0, 0, 360, Scalar(255,0,255), 4, 8, 0);
    if (center.x > frame.cols/3 && center.x < frame.cols/3*2) sendSerial("F 50 50");
    else sendSerial("0 0 ");
  }
  imshow(window_name, frame);
}

int main() {
  sendSerial("0 0 ");
  VideoCapture cap(0);
  cap.set(CV_CAP_PROP_FRAME_WIDTH, 480);
  cap.set(CV_CAP_PROP_FRAME_HEIGHT, 240);
  Mat frame;
  if (!face_cascade.load("haarcascade_frontalface_default.xml")) { cout << "classifier"; return -1; }
  while (cap.read(frame)) {
    detectFaces(frame);
    if (waitKey(30) >= 0) break;
  }
  return 0;
}

Pièces personnalisées (STL)

Schémas

Robot Omnidirectionnel pour Suivi de Personne en Sécurité

Description détaillée dans la section "Histoire" du projet original.

Processus de fabrication

  1. Suivi avancé de balle de ping-pong sur Raspberry Pi avec OpenCV
  2. Raspoulette : Prototype de système autonome de porte de poulailler à énergie solaire
  3. Robot DIY inspiré de Wall‑E : Raspberry Pi dans une boîte de CD recyclée
  4. Robot réveil roulant : Système mobile intelligent piloté par Raspberry Pi et Google Calendar
  5. Construire un robot vision par ordinateur piloté par la parole sur Windows 10 IoT Core
  6. Robot ROS : Navigation pilotée par terminal sur Raspberry Pi
  7. Simple Pi Robot – Construire un rover autonome 2 roues motrices avec Raspberry Pi
  8. Kit de robot de navigation intérieure intelligente pour projets Arduino
  9. Comprendre les moteurs linéaires : de l'énergie électrique au mouvement linéaire précis