Industrielle Fertigung
Industrielles Internet der Dinge | Industrielle Materialien | Gerätewartung und Reparatur | Industrielle Programmierung |
home  MfgRobots >> Industrielle Fertigung >  >> Manufacturing Technology >> Herstellungsprozess

Omnidirektionaler Roboter für sicheres Personentracking

Bauteile und Zubehör

L298N Dual-Schrittmotortreiber (bis 2 A)2
LM2596 DC-DC Step-Down-Regler (12 V → 5 V)1
LiPo-Akku-Alarm (Unterspannungswarner)1
24 U/min DC 12 V Getriebemotor (4 mm Welle)3
Arduino Nano R3 (Motorsteuerung)1
Microsoft LifeCam HD-3000 (Gesichtserkennung)1
Jumper-Kabel (diverse)10
Creator Ci20 (Hauptprozessor, OpenCV)1
11,1 V 3S LiPo-Akku1

Benötigte Werkzeuge

Apps und Online-Dienste

Über das Projekt

Ursprüngliche Idee

Für den „Hackster Terminate the Competition“-Wettbewerb: Ein Roboter, der Menschen sucht – aber nicht wie im Terminator tötet, sondern Gutes tut. Dieser omnidirektionale Roboter findet Sie, erkennt Ihr Gesicht, fährt auf Sie zu und komplimentiert Sie!

Ziel: Alles aus kaufbaren Modulen (eBay) zusammensteckbar, Gehäuse 3D-druckbar (selbst oder via 3D Hubs).

Funktionsweise

Omnidirektionaler Roboter für sicheres Personentracking

Vier Hauptbereiche:

  1. Stromversorgung: LiPo → LM2596 → 5 V Rail, LiPo-Alarm.
  2. Ci20: Gesichtserkennung per OpenCV, sendet Steuerbefehle seriell an Arduino.
  3. Arduino Nano: setzt Befehle in Motortreiber-Signale um (3× L298N für 3 Omni-Räder).
  4. Mechanik: 3D-gedrucktes Chassis, Omni-Räder.

Stromversorgung

Omnidirektionaler Roboter für sicheres Personentracking

Dem Schaltplan folgen – keine blauen Rauchzeichen!

Arduino an L298N anschließen

Anleitung: Instructables L298N Tutorial.

3D-Druck des Gehäuses

Designziele: cool aussehen, Ci20 präsentieren. Alle Teile (Deckel, Boden, Räder) druckbar. STL-Dateien unten. M4-Schrauben für Motorbefestigung.

Omnidirektionaler Roboter für sicheres Personentracking

Ci20: OpenCV Gesichtserkennung

  1. OpenCV installieren: Schritt-für-Schritt-Tutorial (Link im Original).
  2. Code kompilieren & ausführen:
    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
    
    Binärdatei: FaceTracking (Quelle: main.cpp / FaceTracking.cpp).
Omnidirektionaler Roboter für sicheres Personentracking

Ci20 & Arduino zusammenführen

Arduino mit untenstehendem Sketch flashen, per USB an Ci20 anschließen, FaceTracker starten, Webcam einstecken. Erkennt das Gesicht in der Bildmitte, fährt der Roboter vorwärts.

Fertig? Herausforderungen

Code

Arduino Sketch – Main

Empfängt Fahrbefehle (X, Y, Rotation) von Ci20 per Serial, steuert 3 Motoren omnidirektional.

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

int x = 0, y = 0, dominantUltrasonic = 0;
bool moveMotor = false; int startTime = 0;

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();
}

String rpiString;
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; int strIndex[] = {0, -1}; int 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 Sketch – MotorControl

Berechnet Radgeschwindigkeiten für omnidirektionale Fahrt (3 Räder, 120° versetzt).

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[] = {w1, w2, w3};
  float largest = 0;
  for (int i=0;i<3;i++) if (abs(wSet[i]) > largest) largest = abs(wSet[i]);
  float speedCoef = 147.0 / largest;
  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 ms) {
  float w1=255, w2=255, w3=255;
  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);
  delay(ms);
  analogWrite(speedPinA,0); analogWrite(speedPinB,0); analogWrite(speedPinC,0);
}

FaceTracking C++ für Ci20

Nutzt OpenCV Haar-Cascade für Gesichtserkennung, sendet Steuerbefehle per Serial (/dev/ttyUSB0, 9600 Baud) an Arduino.

#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 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;
}

Benutzerdefinierte Teile & Gehäuse

Schaltplan

Omnidirektionaler Roboter für sicheres Personentracking

Details siehe Story-Abschnitt.

Herstellungsprozess

  1. Fortgeschrittenes Tischtennisball-Tracking mit Raspberry Pi und OpenCV
  2. Raspoulette: Solar-betriebenes autonomes Hühnerklappen-System Prototyp
  3. DIY Wall-E-inspirierter Raspberry Pi CD-Box-Roboter
  4. Rolling Alarm Robot: Intelligentes, mobiles Wecksystem mit Raspberry Pi und Google Kalender
  5. Sprachgesteuerter Computer-Vision-Roboter auf Windows 10 IoT Core bauen
  6. ROS Roboter: Terminal-gesteuerte Navigation auf Raspberry Pi
  7. Simple Pi Robot: 2-WD Autonomer Rover mit Raspberry Pi bauen
  8. Smartes Indoor-Navigations-Roboter-Kit für Arduino-Projekte
  9. Linearmotoren verstehen: Von elektrischer Energie zur präzisen Linearbewegung
  10. Getränkeroboter: Technologie, Automatisierung und Rolle in der Getränkeindustrie