Промышленное производство
Промышленный Интернет вещей | Промышленные материалы | Техническое обслуживание и ремонт оборудования | Промышленное программирование |
home  MfgRobots >> Промышленное производство >  >> Manufacturing Technology >> Производственный процесс

Всенаправленное отслеживание людей дружелюбного робота

Компоненты и расходные материалы

Модуль платы контроллера двойного шагового двигателя L298N
Двойной драйвер двигателя, способный приводить двигатели до 2 А
× 2
LM2596 DC DC Импульсный регулируемый понижающий регулятор напряжения
Чтобы понизить напряжение 12 В от батареи до шины 5 В
× 1
Бортовой Lipo Alarm Battery Checker Детектор низкого напряжения RC Самолет Квадрокоптер
Используется для звука, когда на липо-липосакции падает напряжение, чтобы гарантировать, что он не сломается во время использования.
× 1
Мотор-редуктор с валом 4 мм, 12 В постоянного тока, 24 об / мин
Три на три колеса
× 3
Arduino Nano R3
Контроллер двигателя
× 1
Веб-камера Microsoft LifeCam HD-3000
Для распознавания лиц людей вы можете использовать более дешевую камеру, но это та, что была у меня в офисе .
× 1
Перемычки (общие)
Множество перемычек для управления питанием и использования сигнала
× 10
Creator Ci20
Как мы могли забыть мозг операции, Ci20!
× 1
11,1 В 3Cell Lipo Battery
Прилагается пример покупки на ebay.
× 1

Необходимые инструменты и машины

3D-принтер (общий)
Паяльник (общий)

Приложения и онлайн-сервисы

OpenCV

Об этом проекте

Первоначальная отправка

Моя первоначальная заявка на конкурс «Хакстер Прекрати соревнование» заключалась в создании робота, который разыскивал людей, но в отличие от роботов из вселенной терминаторов, он не убивал людей, а использовал свои силы во благо.

Этот всенаправленный робот найдет вас, обнаружит вас, приедет к вам и сделает вам комплимент!

Одно требование, которое я сформулировал для себя, состоит в том, что я должен гарантировать, что это можно будет сделать без необходимости сборки какой-либо электроники самостоятельно. Каждую часть внутри этого робота можно купить на eBay, подключить вместе с помощью свободно доступных руководств, и они должны работать. Затем корпус можно будет распечатать на 3D-принтере, так что вы сможете либо распечатать его самостоятельно, либо сделать на 3D Hubs. Я думаю, что этот проект отвечает этой цели, и теперь я проведу вас через этапы создания вашего собственного робота-охотника-льстца .

Как все это работает!

Итак, давайте начнем с системной схемы, которая показывает все части робота и то, как они соединяются вместе. Мы будем ссылаться на это на протяжении всей сборки и отмечать это по мере продвижения.

Не пугайтесь этой диаграммы, если вы никогда раньше не использовали моторы. В основном это сводится к четырем основным частям:

  • Левая часть связана с извлечением аккумулятора и проверкой напряжения, соответствующего системе.
  • Еще одна хитрость - в ci20
  • Arduino сообщает двигателям, что им делать.

Следующие четыре раздела будут отражать этот список и проведут вас через настройку каждой части.

Работа с электричеством

Итак, у вас есть аккумулятор, что дальше?

На приведенной выше диаграмме показано, как подключить все компоненты для подачи питания, если вы проследите за проводкой на схеме, это реальное представление.

Подключение Arduino к L298N

Я мог бы это объяснить, но лучше просто следовать руководству, которое я сделал:http://www.instructables.com/id/Arduino-Modules-L298N-Dual-H-Bridge-Motor-Controll.

Итак, теперь вы все подключили, у вас повсюду мигают синие огни и нет синего дыма, так что вам хорошо. Давай заставим этого плохого парня работать.

3D-печать футляра

Когда я его спроектировал, я решил, что хочу, чтобы произошли две вещи:он выглядел круто и как можно лучше подчеркивал Ci20. Я имею в виду, что в этом суть соревнования, верно?

Я спроектировал этого робота так, чтобы его можно было полностью распечатать в 3D, и все конструкции доступны ниже. В основном на этом этапе распечатайте верх, низ и колеса. Если у вас нет доступа к 3D-принтеру, вы можете зайти на сайт www.3dhubs.com, чтобы попросить кого-нибудь напечатать его для вас! Вы можете ознакомиться с дизайнами ниже

Вот красивый рендер дизайна, который я сделал, чтобы убедиться, что ci20 подходит и занимает почетное место

После того, как вы напечатали все это, вы можете склеить все детали, как указано выше (или использовать малярную ленту, если вы не чувствуете себя уверенно. Вам понадобится болт M4, чтобы удерживать двигатели.

Заставить CI20 творить чудеса

CI20 - это босс, мозг операции. Без него робот будет барахтаться. Так что же он делает?

Что ж, ci20 будет использовать OpenCV для обнаружения вашего лица, а затем отправлять соответствующие команды через последовательный порт на Arduino, чтобы двигатели работали в правильном направлении.

Шаг 1. Установите OpenCV

Как я уже говорил в этом руководстве, я не пытался заново изобрести тележку для яблок. Я пытаюсь создать что-то, что вы могли бы делать дома и с относительной легкостью расширять. Итак, чтобы установить OpenCV, следуйте этому руководству:

В нем приведены пошаговые инструкции по настройке и запуску OpenCV.

Шаг 2. Запустите код

Код отслеживания лица необходимо скомпилировать и запустить, выполните эту команду для файла на Ci20.

  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  

Создаваемый двоичный файл:FaceTracking:main.cpp> Исходный файл:FaceTracking.cpp

Легко, правда?

Ci20 и Arduino Magic

После прошивки Arduino с кодом в приложениях ниже. Подключите Arduino к USB-порту на CI20 и запустите недавно созданный FaceTracker. Вы увидите всплывающее окно с камерой (о да, подключите веб-камеру), и если вы вставите лицо посередине, колеса робота должны начать двигаться вперед!

Работа выполнена?

Теперь из-за нехватки времени я не смог заставить его делать что-либо еще, так что это вызов для всех, кто зашел так далеко. Есть две вещи, которые вы можете добавить, чтобы сделать этого бота супер крутым:

Добавьте набор динамиков и несколько звуковых файлов, чтобы, когда лицо на экране достаточно велико, он воспроизводил звуковой файл для человека

  • Если робот не обнаружил лицо в течение 1-2 минут, заставьте его вращаться на месте. Вы можете сделать это, отправив команду «R XX» на Arduino. Замени XX на количество времени, которое вы хотите изменить.

Код

  • Скетч Arduino - Основное
  • Эскиз Arduino - MotorControl
  • FaceTracking C ++ для Ci20
Arduino Sketch - Главная Arduino
Этот код Arduino получает команду привода от Ci20 по последовательному каналу и гарантирует, что двигатели работают правильно, чтобы двигаться в правильном направлении.

Изначально я написал это для Raspberry Pi, но он работает и с Ci20
 // Motor 1int dir1PinA =3; int dir2PinA =2; int speedPinA =9; // Должен быть выводом ШИМ для управления скоростью двигателя // Двигатель 2int dir1PinB =4; int dir2PinB =5; int speedPinB =8; // Должен быть выводом ШИМ для управления скоростью двигателя // Двигатель 3int dir1PinC =6; int dir2PinC =7; int speedPinC =10; // Должен быть выводом ШИМ для управления скоростью двигателя int x =0; int y =0; int dominantUltrasonic =0; bool moveMotor =false; int startTime =0; void setup () {Serial.begin (9600); pinMode (dir1PinA, ВЫХОД); pinMode (dir2PinA, ВЫХОД); pinMode (speedPinA, ВЫХОД); pinMode (dir1PinB, ВЫХОД); pinMode (dir2PinB, ВЫХОД); pinMode (speedPinB, ВЫХОД); pinMode (dir1PinC, ВЫХОД); pinMode (dir2PinC, ВЫХОД); pinMode (speedPinC, ВЫХОД); startTime =millis ();} String rpiString; недействительный цикл () {readDataFromRPi (); // Это проверяет, получили ли мы значение от RPi за последнюю секунду. // Он эффективно действует как буфер, так что он не останавливается и не запускается, поскольку команда перемещения не является непрерывной // Он также позволяет останавливаться, если от RPi не поступает ничто // int elapsedTime =millis () - startTime; // if (elapsedTime> 1000) // {// x =0; // y =0; // dominantUltrasonic =0; // moveMotor =false; // startTime =millis (); // //} // Отправьте X и Y двигателям // if (moveMotor ==true &&(x! =0 &&y! =0)) // {//Serial.println("MovingMotor "); // driveInDirection (x, y); //} // if (x ==0 &&y ==0) // {//Serial.println("ZeroMMotor "); // driveInDirection (x, y); //} // Это могло быть просто оставлено от ультразвука - не решается удалить задержку (30);} void readDataFromRPi () {// Прочитать из Rpi while (Serial.available ()) {delay (3); // задержка для заполнения буфера if (Serial.available ()> 0) {char c =Serial.read (); // получает один байт из последовательного буфера rpiString + =c; // делает строку readString if (c =='n') {break; }}} // ENDWHILE // Если что-то было прочитано из RPi, поместите это в x, y и domniantUltrasonic if (rpiString.length ()> 0) {Serial.println (rpiString); // посмотреть, что получено String isRotate =getValue (rpiString, '', 0); Строка xval =getValue (rpiString, '', 1); Строка yval =getValue (rpiString, '', 2); х =xval.toInt (); у =yval.toInt (); startTime =миллис (); если (isRotate =="г") {поворот (х); } else {driveInDirection (x, y); } rpiString =""; } // ENDIF} String getValue (данные строки, разделитель символов, индекс int) {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)? я + 1:я; }} возврат найден> индекс? data.substring (strIndex [0], strIndex [1]):"";} 
Эскиз Arduino - MotorControl Arduino
Это относится к основному ino-файлу и требует включения в тот же файл проекта
 / * * Код управления двигателем * * Этот класс будет включать код, чтобы заставить робота двигаться в любом направлении * и вращаться вокруг центральной точки. * / void driveInDirection (float newX, float newY) {delay (20); float x =newX; float y =newY; float theta =atan2 (y, x); float mag =sqrt ((х * х) + (у * у)); float vx =mag * cos (тета); float vy =mag * sin (тета); float w1 =-vx; float w2 =0,5 * vx - sqrt (3) / 2 * vy; float w3 =0,5 * vx + sqrt (3) / 2 * vy; // Получить наибольшее значение w float wSet [] ={w1, w2, w3}; float наибольшее значение =0,0; для (int я =0; я <3; я ++) {если (абс (wSet [я])> наибольшее значение) {наибольшее значение =абс (wSet [я]); }} float speedCoef =(float) 147.0 / наибольшее значение; w1 =w1 * speedCoef; w2 =w2 * speedCoef; w3 =w3 * speedCoef; если (х ==0 &&у ==0) {w1 =0; w2 =0; w3 =0; } Serial.println (w1); Serial.println (w2); Serial.println (w3); w1 =ограничение (w1, -150, 150); w2 =ограничение (w2, -150, 150); w3 =ограничение (w3, -150, 150); логическое 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); 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 миллисекунды) {float w1 =255; поплавок w2 =255; поплавок w3 =255; логическое 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); 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); задержка (миллисекунды); analogWrite (speedPinA, 0); // Устанавливаем переменную скорости через ШИМ analogWrite (speedPinB, 0); analogWrite (speedPinC, 0); // Устанавливает переменную скорости через ШИМ} void printMotorSpeed ​​(byte motorSpeed, int motor) {Serial.print ("Motor"); Серийный принт (мотор); Serial.print (":"); Serial.println (скорость двигателя); } 
FaceTracking C ++ для Ci20 C / C ++
Следуйте руководству в Истории
 #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); если (fd ==-1) {ошибка (" 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;} / ** * Обнаруживает лица и рисует вокруг них эллипс * / void detectFaces (Mat frame) {std ::vector  faces; Мат 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)); // Перебираем все грани для (size_t i =0; i  глаза; // Пытаемся обнаружить глаза внутри каждого лица // eyes_cascade.detectMultiScale (face, eyes, 1.1, 2, // 0 | CASCADE_SCALE_IMAGE, Size (50, 50)); // if (eyes.size ()> 0) // Рисуем эллипс вокруг эллипса лица (рамка, центр, размер (faces [i] .width / 2, faces [i] .height / 2), 0, 0, 360 , Скаляр (255, 0, 255), 4, 8, 0); если (center.x> frame.cols / 3 &¢er.x  =0) // пауза break; } return 0;} 

Изготовленные на заказ детали и корпуса

Это основа всенаправленного робота, разработанная мной, чтобы вместить все детали и прикрепить крышку. Это крышка, которая демонстрирует Ci20 во всей красе.
Всенаправленные колеса
Это оригинальная конструкция всенаправленных колес. Я использовал половину этого с ободами, а затем отредактировал его, включив в него файл CAD вала двигателя на сайте thingiverse.com Ремикс колеса из thingiverse ссылка

Схема

См. Лучшее описание в разделе истории

Производственный процесс

  1. Отслеживание Raspberry Pi Ball
  2. Прототип Raspoulette
  3. Робот-бокс для компакт-дисков Raspberry Pi
  4. Робот с подвижной сигнализацией
  5. Робот для открытия резюме
  6. Робот ROS
  7. Простой робот Pi
  8. Робот для супер-крутой навигации внутри помещений
  9. Что такое линейный двигатель?
  10. Что такое робот для напитков?