Industriële fabricage
Industrieel internet der dingen | Industriële materialen | Onderhoud en reparatie van apparatuur | Industriële programmering |
home  MfgRobots >> Industriële fabricage >  >> Manufacturing Technology >> Productieproces

Omnidirectionele Robot voor Veilige Mensenvolging

Onderdelen en Benodigdheden

OnderdeelAantal
L298N Dual Stepper Motor Driver2
LM2596 DC-DC Step Down Voltage Regulator1
Lipo Alarm Battery Checker1
24RPM DC 12V 4mm As Geared Motor3
Arduino Nano R31
Microsoft LifeCam HD-3000 Webcam1
Dupont-draden10
Creator Ci20 (Hoofdcomputer)1
11.1V 3-Cel LiPo Batterij1

Benodigde Tools

  • 3D-printer
  • Solderbout

Apps & Online Services

  • OpenCV (gezichtsdetectie)

Over dit Project

Initiële Inzending

Mijn inzending voor de "Hackster Terminate the Competition" was een robot die mensen zoekt – maar niet om te doden als in Terminator, maar om complimenten te maken! Deze omnidirectionele robot vindt je, detecteert je, navigeert naar je toe en geeft je een compliment.

Mijn eis: alle elektronica moet koopbaar zijn (bijv. eBay), aan elkaar te klikken met vrij beschikbare tutorials, en de behuizing 3D-printbaar (zelf of via 3D Hubs).

Hoe Het Werkt

Omnidirectionele Robot voor Veilige Mensenvolging

Vier hoofdblokken:

  1. Stroombeheer: Batterij → spanningen voor systeem
  2. Ci20 (Hoofdcomputer): Voert OpenCV gezichtsdetectie uit
  3. Arduino Nano: Stuurt motoren aan op basis van Ci20 commando's
  4. Omnidirectionele wielen: 3 wielen voor beweging in elke richting

Stroombeheer

Omnidirectionele Robot voor Veilige Mensenvolging

Volg het schema voor het aansluiten van alle stroomcomponenten.

Arduino Nano ↔ L298N Aansluiten

Volg deze tutorial: Instructables L298N Handleiding.

Als er blauwe LEDjes knipperen en geen blauwe rook: goed om te gaan!

3D-print Je Eigen Behuizing

Ontwerpdoel: er cool uitzien & de Ci20 tonen. Completely 3D-printbaar. Bestanden beschikbaar onder 'Custom Parts'. Print top, bottom & wielen. Geen 3D-printer? Gebruik 3D Hubs.

Omnidirectionele Robot voor Veilige Mensenvolging

Na printen: onderdelen inlijmen (of masking tape). M4 bouten voor motoren.

De Ci20 De Magie Laten Doen

De Ci20 gebruikt OpenCV voor gezichtsdetectie en stuurt via seriële poort commando's naar de Arduino voor motorbesturing.

Stap 1: OpenCV Installeren

Volg deze tutorial: OpenCV installatie handleiding (stap-voor-stap).

Stap 2: Code Compileren & Draaien

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

Bronbestand: FaceTracking.cpp → uitvoerbaar: FaceTracking.

Omnidirectionele Robot voor Veilige Mensenvolging

Ci20 & Arduino Samenwerking

Na het flashen van de Arduino (code in bijlagen), plug de Arduino in de USB-poort van de Ci20 en start de FaceTracker. Webcam aansluiten! Je ziet een camerabeeld; houd je gezicht in het midden en de robot begint vooruit te rijden.

Klaar?

Vanwege tijdtekort deed het nog niet alles. Uitdaging voor jou:

  • Voeg speakers en geluidsbestanden toe: bij groot gezicht in beeld → speel compliment af
  • Geen gezicht gedetecteerd in 1-2 minuten? Laat de robot op zijn as draaien: stuur commando R XX naar Arduino (XX = draaitijd in ms)

Code

Arduino Sketch - Hoofdprogramma

Ontvangt rij-commando's van Ci20 via seriële poort en stuurt motoren correct aan. Oorspronkelijk voor Raspberry Pi, werkt ook op Ci20.

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

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();
  // Buffer logica: stop na 1s geen data
  // if (millis() - startTime > 1000) { x=0; y=0; dominantUltrasonic=0; moveMotor=false; startTime=millis(); }
  // if (moveMotor && x!=0 && y!=0) driveInDirection(x,y);
  // if (x==0 && y==0) driveInDirection(x,y);
  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

Behoort bij hoofdprogramma, in hetzelfde projectbestand.

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 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 = 0; w2 = 0; w3 = 0; }
  Serial.println(w1); Serial.println(w2); Serial.println(w3);
  w1 = constrain(w1, -150, 150); w2 = constrain(w2, -150, 150); w3 = constrain(w3, -150, 150);
  boolean w1_ccw = w1 < 0; boolean w2_ccw = w2 < 0; boolean 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);
  printMotorSpeed(w1_speed, 1); printMotorSpeed(w2_speed, 2); printMotorSpeed(w3_speed, 3);
  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;
  boolean w1_ccw = w1 < 0; boolean w2_ccw = w2 < 0; boolean 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);
  printMotorSpeed(w1_speed, 1); printMotorSpeed(w2_speed, 2); printMotorSpeed(w3_speed, 3);
  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(milliseconds);
  analogWrite(speedPinA, 0); analogWrite(speedPinB, 0); analogWrite(speedPinC, 0);
}

void printMotorSpeed(byte motorSpeed, int motor) {
  Serial.print("Motor"); Serial.print(motor); Serial.print(": "); Serial.println(motorSpeed);
}

FaceTracking C++ voor Ci20

Volg handleiding in 'Over dit project'.

#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include 
#include 
using namespace std; using namespace cv;

CascadeClassifier face_cascade, eyes_cascade;
String window_name = "Face Detection";

#include  #include  #include 
#include  #include  #include 
#include  #include 

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);
    Mat face = frame_gray(faces[i]);
    vector eyes;
    // eyes_cascade.detectMultiScale(face, eyes, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(50,50));
    // if (eyes.size() > 0)
    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) {
      char msg[] = "F 50 50"; sendSerial(msg);
    } else {
      char msg[] = "0 0 "; sendSerial(msg);
    }
  }
  imshow(window_name, frame);
}

int main() {
  char msg[] = "0 0 "; sendSerial(msg);
  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; }
  // eyes_cascade.load("haarcascade_eye_tree_eyeglasses.xml");
  while (cap.read(frame)) {
    detectFaces(frame);
    if (waitKey(30) >= 0) break;
  }
  return 0;
}

Aangepaste Onderdelen & Behuizingen

Basis: Ontworpen om alle onderdelen te passen met deksel.

Deksel: Toont de Ci20 in al zijn glorie.

Omnidirectionele Wielen: Origineel ontwerp van Thingiverse, aangepast voor motoras. Thingiverse link & remix.

Schema's

Zie gedetailleerde beschrijving in projectverhaal.

Omnidirectionele Robot voor Veilige Mensenvolging

Productieproces

  1. Geavanceerde Tafeltennisbal Tracking met OpenCV op Raspberry Pi
  2. Raspoulette: Zonnestroom-gevoede Autonome Koeienpoort Systeem Prototype
  3. DIY Wall-E Geïnspireerde Raspberry Pi CD-Doos Robot
  4. Rollende Alarmrobot: Een Slim, Mobiel Wakker-systeem Aangedreven door Raspberry Pi en Google Calendar
  5. Bouw een Spraak-gestuurde Computer Vision Robot op Windows 10 IoT Core
  6. ROS Robot: Terminal-gecontroleerde Navigatie op Raspberry Pi
  7. Simple Pi Robot – Bouw een 2-WD Autonome Rover met Raspberry Pi
  8. Slim Indoor Navigatie Robot Kit voor Arduino Projecten
  9. Lineaire motoren begrijpen: Van elektrische energie naar nauwkeurige lineaire beweging
  10. Drankrobots begrijpen: technologie, automatisering en rol in drankenindustrie
  11. Servomotoren Uitgelegd: Hoe Ze Werken en Waarom Ze Belangrijk Zijn