Manufactura industrial
Internet industrial de las cosas | Materiales industriales | Mantenimiento y reparación de equipos | Programación industrial |
home  MfgRobots >> Manufactura industrial >  >> Manufacturing Technology >> Proceso de manufactura

Robot amigable de seguimiento de personas omnidireccional

Componentes y suministros

Módulo de placa controladora de controlador de motor paso a paso dual L298N
Controlador de motor dual capaz de hasta 2A o accionar los motores
× 2
LM2596 Regulador de voltaje reductor ajustable de conmutación CC CC
Para reducir los 12V de la batería a un riel de 5V
× 1
Alarma Lipo a bordo Comprobador de batería Detector de bajo voltaje RC Plane Quadcopter
Se usa para sonar cuando la lipo tiene poco voltaje para garantizar que no se rompa durante el uso.
× 1
Motor con engranaje de eje de 24 RPM CC 12 V 4 mm
Tres por tres ruedas
× 3
Arduino Nano R3
Controlador de motor
× 1
Cámara web Microsoft LifeCam HD-3000
Para detectar caras de personas, puedes usar una cámara más barata, pero esta es la que tenía en la oficina. .
× 1
Cables de puente (genéricos)
Muchos cables de puente para administración de energía y uso de señales
× 10
Creator Ci20
¡Cómo podríamos olvidarnos del cerebro de la operación, el Ci20!
× 1
11.1V 3Cell Lipo Battery
Ejemplo para comprar en ebay adjunto.
× 1

Herramientas y máquinas necesarias

Impresora 3D (genérica)
Soldador (genérico)

Aplicaciones y servicios en línea

OpenCV

Acerca de este proyecto

Envío inicial

Mi presentación inicial a la competencia "Hackster Terminate the Competition" fue crear un robot que buscara humanos pero, a diferencia de los del universo terminator, no andaba matando gente, sino que usaba sus poderes para siempre.

¡Este robot omnidireccional lo encontrará, lo detectará, se centrará en usted y lo felicitará!

Un requisito que me especifiqué a mí mismo es que me aseguraría de que se pudiera hacer sin tener que construir ninguno de los componentes electrónicos usted mismo. Todas las partes del interior de este robot se pueden comprar en eBay, se pueden conectar mediante tutoriales disponibles gratuitamente y deberían funcionar. El estuche se podrá imprimir en 3D para que pueda imprimirlo usted mismo o hacerlo en 3D Hubs. Creo que este proyecto cumple con este objetivo y ahora lo guiaré a través de los pasos para construir su propio Hunter Flatterer Robot

¡Cómo funciona todo!

Así que comencemos con un diagrama de sistema que muestra todas las partes del robot y cómo se conectan. Haremos referencia a esto a lo largo de la compilación y lo marcaremos a medida que avancemos.

No se deje intimidar por este diagrama si nunca antes ha usado motores. Básicamente se reduce a cuatro partes principales:

  • El lado izquierdo se ocupa de tomar la batería y asegurarse de que los voltajes sean los correctos para el sistema.
  • La parte inteligente se hace en el ci20
  • El Arduino se usa para decirle a los motores qué hacer

Las siguientes cuatro secciones reflejarán esta lista y lo guiarán a través de la configuración de cada parte.

Tratar con la electricidad

Así que tienes una batería, ¿qué sigue?

El diagrama anterior muestra cómo conectar todos los componentes para la alimentación, si sigue el cableado en el esquema, esta es la representación de la vida real.

Conectando el Arduino al L298N

Podría explicar esto, pero es mejor seguir el tutorial que hice:http://www.instructables.com/id/Arduino-Modules-L298N-Dual-H-Bridge-Motor-Controll.

Entonces, ahora que ha conectado todo, tiene luces azules parpadeando en todas partes y no hay humo azul, por lo que está listo para comenzar. Vamos a hacer que este chico malo funcione.

Imprimiéndose en 3D usted mismo un estuche

Cuando diseñé esto, decidí que quería que sucedieran dos cosas, se ve bien y muestra el Ci20 lo mejor posible. Quiero decir, este es el objetivo de la competencia, ¿verdad?

Diseñé este robot para que sea completamente imprimible en 3D y los diseños están disponibles a continuación. Básicamente, en este punto, imprima usted mismo la parte superior, inferior y las ruedas. Si no tiene acceso a una impresora 3D, puede visitar www.3dhubs.com para que alguien la imprima por usted. Puede ver los diseños a continuación

Aquí hay un bonito render que hice del diseño para asegurarme de que el ci20 encajaría y estaría en un lugar de honor

Una vez que tenga todo impreso, puede pegar todas las partes como se indica arriba (o usar cinta adhesiva si no se siente seguro. Necesitará un perno M4 para sujetar los motores.

Hacer que el CI20 haga algo de magia

El CI20 es el jefe, el cerebro de la operación. Sin él, el robot se tambaleará. Entonces, ¿qué hace?

Bueno, el ci20 usará OpenCV para detectar tu rostro y luego enviará los comandos apropiados por serie al Arduino para que los motores funcionen en la dirección correcta.

Paso 1:instale OpenCV

Como he dicho a lo largo de esta guía, no estaba tratando de reinventar el carrito de manzanas. Estoy tratando de construir algo que puedas hacer en casa y extenderlo con relativa facilidad. Entonces, para instalar OpenCV, vaya y siga este tutorial:

Le explica paso a paso cómo instalar y ejecutar OpenCV.

Paso 2:ejecuta el código

El código de seguimiento facial deberá compilarse y ejecutarse, ejecute este comando en el archivo del Ci20.

  g ++ -I / usr / local / include / opencv -I / usr / local / include / opencv2 -L / usr / local / lib / -g -o binario main.cpp -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_ml -lopencv_video -lopencv_features2d -lopencv_calib3d -lopencv_objdetect -lopencv_contrib -lopencv_legacy -lopencv_stitching  

El archivo binario que se creará:FaceTracking:main.cpp> Archivo de origen:FaceTracking.cpp

Fácil, ¿verdad?

Ci20 y Arduino Magic

Después de flashear el Arduino con el código en los archivos adjuntos a continuación. Conecte el Arduino al puerto USB del CI20 y ejecute su FaceTracker creado recientemente. Verás aparecer una señal de cámara (Oh, sí, conecta la cámara web) y si pones la cara en el medio, ¡las ruedas del robot comenzarán a hacer que avance!

¿Trabajo hecho?

Ahora, debido a limitaciones de tiempo, no logré que hiciera nada más, así que aquí hay un desafío para cualquiera que haya llegado tan lejos. Hay dos cosas que puedes agregar para que este bot sea súper asombroso:

Agregue un conjunto de parlantes y algunos archivos de sonido para que cuando la cara sea lo suficientemente grande en la pantalla, reproduzca un archivo de sonido para la persona

  • Si el robot no ha detectado una cara en 1-2 minutos, hágalo girar en el lugar. Puede hacer esto enviando el comando "R XX" al Arduino. Reemplace XX con la cantidad de tiempo que desea dar la vuelta.

Código

  • Arduino Sketch - Principal
  • Arduino Sketch - MotorControl
  • FaceTracking C ++ para Ci20
Arduino Sketch - Principal Arduino
Este código Arduino recibe el comando de manejo del Ci20 en serie y asegura que los motores se manejen de la manera correcta para ir en la dirección correcta.

Originalmente escribí esto para una Raspberry Pi pero también funciona con el Ci20
 // Motor 1int dir1PinA =3; int dir2PinA =2; int speedPinA =9; // Debe ser un pin PWM para poder controlar la velocidad del motor // Motor 2int dir1PinB =4; int dir2PinB =5; int speedPinB =8; // Debe ser un pin PWM para poder controlar la velocidad del motor // Motor 3int dir1PinC =6; int dir2PinC =7; int speedPinC =10; // Debe ser un pin PWM para poder controlar la velocidad del motor int x =0; int y =0; int dominanteUltrasonic =0; bool moveMotor =false; int startTime =0; void setup () {Serial.begin (9600); pinMode (dir1PinA, SALIDA); pinMode (dir2PinA, SALIDA); pinMode (speedPinA, SALIDA); pinMode (dir1PinB, SALIDA); pinMode (dir2PinB, SALIDA); pinMode (speedPinB, SALIDA); pinMode (dir1PinC, SALIDA); pinMode (dir2PinC, SALIDA); pinMode (speedPinC, SALIDA); startTime =millis ();} String rpiString; void loop () {readDataFromRPi (); // Esto prueba si hemos recibido un valor del RPi en el último segundo. // Actúa eficazmente como búfer para que no siga deteniéndose y comenzando ya que el comando de movimiento no es continuo // También permite la detención si no llega nada desde el RPi // int elapsedTime =millis () - startTime; // if (elapsedTime> 1000) // {// x =0; // y =0; // dominanteUltrasonic =0; // moveMotor =false; // startTime =millis (); // //} // Envíe X e Y a los motores // if (moveMotor ==true &&(x! =0 &&y! =0)) // {//Serial.println("MovingMotor "); // driveInDirection (x, y); //} // if (x ==0 &&y ==0) // {//Serial.println("ZeroMMotor "); // driveInDirection (x, y); //} // Esto podría ser un sobrante de los ultrasonidos - vacila en eliminar delay (30);} void readDataFromRPi () {// Leer desde Rpi while (Serial.available ()) {delay (3); // demora para permitir que el búfer se llene if (Serial.available ()> 0) {char c =Serial.read (); // obtiene un byte del búfer serie rpiString + =c; // hace que la cadena sea readString if (c =='n') {break; }}} // ENDWHILE // Si se ha leído algo del RPi, póngalo en x, y &domniantUltrasonic if (rpiString.length ()> 0) {Serial.println (rpiString); // ver lo que se recibió String isRotate =getValue (rpiString, '', 0); Cadena xval =getValue (rpiString, '', 1); Cadena yval =getValue (rpiString, '', 2); x =xval.toInt (); y =yval.toInt (); startTime =millis (); if (isRotate =="r") {rotate (x); } else {driveInDirection (x, y); } rpiString =""; } // ENDIF} String getValue (datos de cadena, separador de caracteres, índice int) {int encontrado =0; int strIndex [] ={0, -1}; int maxIndex =data.length () - 1; for (int i =0; i <=maxIndex &&encontrado <=índice; i ++) {if (data.charAt (i) ==separator || i ==maxIndex) {encontrado ++; strIndex [0] =strIndex [1] +1; strIndex [1] =(i ==maxIndex)? i + 1:i; }} retorno encontrado> índice? data.substring (strIndex [0], strIndex [1]):"";} 
Arduino Sketch - MotorControl Arduino
Esto va con el archivo ino principal y debe incluirse en el mismo archivo de proyecto
 / * * Código de control del motor * * Esta clase incluirá código para hacer que el robot vaya en cualquier dirección * y gire alrededor del punto central. * / void driveInDirection (float newX, float newY) {delay (20); flotar x =newX; flotar y =newY; flotante theta =atan2 (y, x); flotante mag =sqrt ((x * x) + (y * y)); flotar vx =mag * cos (theta); flotar vy =mag * sin (theta); flotar w1 =-vx; flotar w2 =0.5 * vx - sqrt (3) / 2 * vy; flotar w3 =0.5 * vx + sqrt (3) / 2 * vy; // Obtener el valor w más grande float wSet [] ={w1, w2, w3}; float largerValue =0.0; for (int i =0; i <3; i ++) {if (abs (wSet [i])> mayorValor) {mayorValor =abs (wSet [i]); }} float speedCoef =(float) 147.0 / largerValue; w1 =w1 * speedCoef; w2 =w2 * speedCoef; w3 =w3 * speedCoef; si (x ==0 &&y ==0) {w1 =0; w2 =0; w3 =0; } Serial.println (w1); Serial.println (w2); Serial.println (w3); w1 =restringir (w1, -150, 150); w2 =restringir (w2, -150, 150); w3 =restringir (w3, -150, 150); booleano w1_ccw =w1 <0? verdadero Falso; booleano w2_ccw =w2 <0? verdadero Falso; booleano w3_ccw =w3 <0? verdadero Falso; byte w1_speed =(byte) mapa (abs (w1), 0, 150, 0, 255); byte w2_speed =(byte) mapa (abs (w2), 0, 150, 0, 255); byte w3_speed =(byte) mapa (abs (w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite (speedPinA, w1_speed); // Establece la variable de velocidad a través de PWM analogWrite (speedPinB, w2_speed); analogWrite (speedPinC, w3_speed); // Establece la variable de velocidad a través de PWM digitalWrite (dir1PinA,! w1_ccw); escritura digital (dir2PinA, w1_ccw); escritura digital (dir1PinB,! w2_ccw); escritura digital (dir2PinB, w2_ccw); escritura digital (dir1PinC, w3_ccw); digitalWrite (dir2PinC,! w3_ccw);} void rotate (float milisegundos) {float w1 =255; flotador w2 =255; flotador w3 =255; booleano w1_ccw =w1 <0? verdadero Falso; booleano w2_ccw =w2 <0? verdadero Falso; booleano w3_ccw =w3 <0? verdadero Falso; byte w1_speed =(byte) mapa (abs (w1), 0, 150, 0, 255); byte w2_speed =(byte) mapa (abs (w2), 0, 150, 0, 255); byte w3_speed =(byte) mapa (abs (w3), 0, 150, 0, 255); printMotorSpeed ​​(w1_speed, 1); printMotorSpeed ​​(w2_speed, 2); printMotorSpeed ​​(w3_speed, 3); analogWrite (speedPinA, w1_speed); // Establece la variable de velocidad a través de PWM analogWrite (speedPinB, w2_speed); analogWrite (speedPinC, w3_speed); // Establece la variable de velocidad a través de PWM digitalWrite (dir1PinA,! w1_ccw); escritura digital (dir2PinA, w1_ccw); escritura digital (dir1PinB,! w2_ccw); escritura digital (dir2PinB, w2_ccw); escritura digital (dir1PinC, w3_ccw); escritura digital (dir2PinC,! w3_ccw); retraso (milisegundos); analogWrite (speedPinA, 0); // Establece la variable de velocidad a través de PWM analogWrite (speedPinB, 0); analogWrite (speedPinC, 0); // Establece la variable de velocidad a través de PWM} void printMotorSpeed ​​(byte motorSpeed, int motor) {Serial.print ("Motor"); Serial.print (motor); Serial.print (":"); Serial.println (motorSpeed); } 
FaceTracking C ++ para Ci20 C / C ++
Siga la guía en Story
 #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); // char msg [] ="50 50"; write (fd , message, strlen (message)); return 0;} / ** * Detecta rostros y dibuja una elipse alrededor de ellos * / void detectFaces (Mat frame) {std ::vector  faces; Mat frame_gray; // Convertir a escala de grises cvtColor (frame, frame_gray, COLOR_BGR2GRAY); // Ecualizar histograma equalizeHist (frame_gray, frame_gray); // Detectar caras face_cascade.detectMultiScale (frame_gray, faces, 1.1, 3, 0 | CASCADE_SCALE_IMAGE, Size (30,30)); // Itera sobre todas las caras para (size_t i =0; i  ojos; // Intenta detectar ojos, dentro de cada rostro // eyes_cascade.detectMultiScale (face, eyes, 1.1, 2, // 0 | CASCADE_SCALE_IMAGE, Size (50, 50)); // if (eyes.size ()> 0) // Dibuja una elipse alrededor de la elipse de la cara (frame, center, Size (faces [i] .width / 2, faces [i] .height / 2), 0, 0, 360 , Escalar (255, 0, 255), 4, 8, 0); if (center.x> frame.cols / 3 &¢er.x  =0) // pausa pausa; } return 0;} 

Piezas y carcasas personalizadas

Esta es la base del robot omnidireccional, diseñado por mí para encajar todas las piezas y tener una tapa adjunta. Esta es la tapa que muestra el Ci20 en todo su esplendor.
Ruedas omnidireccionales
Este es el diseño original de las ruedas omnidireccionales. Usé la mitad de esto con las llantas y luego lo edité para incluir el archivo del eje del motor CAD en thingiverse.com Una rueda remezclada del enlace de thingiverse

Esquemas

Ver una mejor descripción en la sección de historias

Proceso de manufactura

  1. Seguimiento de Raspberry Pi Ball
  2. Prototipo de Raspoulette
  3. Robot de caja de CD Raspberry Pi
  4. Robot de alarma rodante
  5. Abrir CV Robot
  6. Robot ROS
  7. Robot Pi simple
  8. Robot para navegación interior supercogedora
  9. ¿Qué es un motor lineal?
  10. ¿Qué es un robot de bebidas?
  11. ¿Qué es un servomotor?