Автономная турель Nerf Sentry
Компоненты и расходные материалы
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 | ||||
| × | 1 |
Необходимые инструменты и машины
| ||||
| ||||
|
Приложения и онлайн-сервисы
| ||||
|
Об этом проекте
Идея
Несколько лет назад я увидел проект, в котором была продемонстрирована полуавтономная башня, которая могла вести огонь самостоятельно после прицеливания. Это натолкнуло меня на идею использовать камеру Pixy 2 для обнаружения целей, а затем автоматически наводить нерф-пушку, которая могла бы прицелиться и стрелять сама по себе.
Компоненты
Для этого проекта пистолету потребуются глаза, поэтому я решил использовать Pixy 2 из-за того, насколько легко он может взаимодействовать с материнской платой. Затем мне понадобился микроконтроллер, поэтому я выбрал Arduino Mega 2560 из-за того, сколько в нем контактов.
Поскольку для пушки требуется две оси, рыскание и тангаж, для нее требуются два шаговых двигателя. Из-за этого DFRobot прислала мне свою двойную плату драйвера двигателя DRV8825.
CAD
Я начал с загрузки Fusion 360 и вставки прикрепленного холста нерфа. Затем я создал твердое тело из этого холста. После того, как ружье было спроектировано, я сделал платформу с несколькими опорами на подшипниках, которые позволили бы ружью вращаться слева направо. Я поставил шаговый двигатель рядом с вращающейся платформой, чтобы управлять им.
Но более серьезный вопрос заключается в том, как сделать шаг вперед и назад. Для этого требовалась система линейного привода с одной точкой, прикрепленной к подвижному блоку, и другой точкой в задней части орудия. Стержень соединит две точки, позволяя ружью поворачиваться вдоль его центральной оси.
Производство деталей
Почти все детали в моем дизайне предназначены для 3D-печати, поэтому я использовал два своих принтера для их создания. Затем я создал передвижную платформу, сначала используя Fusion 360 для создания необходимых траекторий для моего фрезерного станка с ЧПУ, а затем вырезал диск из листа фанеры.
Сборка
После того, как все детали были созданы, пришло время их собирать. Я начал с подсоединения опор подшипников к вращающемуся диску. Затем я собрал узел с линейным шагом, пропустив 6-миллиметровые алюминиевые стержни и стержень с резьбой через детали.
Наконец, я прикрепил сам пистолет Nerf с помощью стального стержня и двух стоек, сделанных из алюминиевых профилей.
Программирование
Теперь самая сложная часть проекта:программирование. Машина для стрельбы снарядами очень сложна, и математика, стоящая за ней, может сбивать с толку. Я начал с написания последовательности операций программы и логики шаг за шагом, подробно описывая, что будет происходить в каждом состоянии машины. Различные состояния выглядят следующим образом:
- Получить цель
- Установите пистолет.
- Размотайте двигатели.
- Стреляйте из пистолета
- Сбросьте моторы.
Для захвата цели необходимо сначала настроить Pixy на отслеживание неоново-розовых объектов в качестве целей. Затем ружье перемещается до тех пор, пока цель не окажется в центре поля зрения Pixy, где затем измеряется ее расстояние от ствола пистолета до цели. Используя это расстояние, можно найти горизонтальные и вертикальные расстояния с помощью некоторых основных тригонометрических функций. В моем коде есть функция get_angle (), которая использует эти два расстояния, чтобы вычислить, какой угол необходим, чтобы поразить эту цель.
Затем пистолет перемещается в это положение и включает двигатели через полевой МОП-транзистор. После того, как он намотается в течение пяти секунд, он перемещает серводвигатель, чтобы нажать на спусковой крючок. Затем полевой МОП-транзистор выключает двигатель, а затем нерф-пушка возвращается к поиску целей.
Развлекается
Я прикрепляю к стене неоновую розовую учетную карточку, чтобы проверить точность пистолета. Все прошло хорошо, так как моя программа калибрует и регулирует угол для измеренного расстояния. Вот видео, демонстрирующее работу пистолета:
Код
- Схема
Схема C / C ++
Загрузить в Arduino Mega#include#include #include "BasicStepperDriver.h" #include #include // X - шаг, Y - yawconst int pins [] ={6,7,8,5,4,12}; // MX STEP, DIR, EN, MY STEP, DIR, ENconst int limit_switch =26, laser_pin =11, spool_pin =10, servo_pin =13, distance_trig =29, distance_echo =30; double velocity =21.336; double velocity_squared =455.225; float current_angle =0,0; float hyp_distance; // расстояние от пушки до цели в метрах # определить X_MID 164 # определить Y_MID 150 # определить DEADZONE 15 # определить G 9.8 # определить STP_PER_DEG_YAW 3.333 # определить STP_PER_DEG_PITCH 184859 # определить MICROSTEPS 32 # определить RPM 120 # определить MOTOR_STEPS_Y 200 # определить MOTOR_STEPS_Y 200 # определить MOTOR_STEPS_Y 200 # определить MOTOR_STEPS_Y 200 # определить MOTOR_STEPS_Y 200 /17.7777 шагов / степень , FIRE, WIND_DOWN, RETURN}; Состояния state =ACQUIRE; void setup () {Serial.begin (115200); init_pins (); задержка (1000); // home_pitch (); pixy.init (); Serial.println ("Готово ...");} void loop () {переключатель (состояние) {case ACQUIRE:Acquire_target (); состояние =ПОЛОЖЕНИЕ; digitalWrite (лазерный_контакт, ВЫСОКИЙ); ломать; case POSITION:Serial.println («позиционирование»); position_gun (); состояние =SPOOL; ломать; case SPOOL:Serial.println («спулинг»); digitalWrite (spool_pin, ВЫСОКИЙ); задержка (5000); состояние =ОГОНЬ; ломать; case FIRE:fire_gun (); состояние =WIND_DOWN; ломать; case WIND_DOWN:Serial.println («сворачивание»); digitalWrite (spool_pin, LOW); задержка (2000); состояние =ВОЗВРАТ; digitalWrite (laser_pin, LOW); состояние =ПРИОБРЕСТИ; ломать; }} void fire_gun () {Serial.println («Стрельба из ружья!»); trigger.write (108); задержка (400); trigger.write (90); задержка (2000);} void position_gun () {float x, y; hyp_distance =пинг (); hyp_distance / =100; в то время как (! hyp_distance) {hyp_distance =ping (); hyp_distance / =100; } Serial.println (hyp_distance); x =cos (текущий_угол) * hyp_distance; y =sin (текущий_угол) * hyp_distance; с плавающей точкой target_angle =get_angle (x, y); целевой_угол / =100; Serial.println (целевой_угол); move_pitch (целевой_угол - текущий_угол); текущий_угол =целевой_угол;} недействительным получить_назначение () {int x =0, y =0; long steps_taken =0; bool lock =false; пока (! блокировка) {pixy.ccc.getBlocks (); если (pixy.ccc.numBlocks) {x =pixy.ccc.blocks [0] .m_x; y =pixy.ccc.blocks [0] .m_y; Serial.print ("Цель видна в местоположении X:"); Serial.print (x); Serial.print (", Y:"); Serial.println (y); if (x <=(X_MID - DEADZONE)) {// Если слишком далеко, переместите пистолет влево move_yaw (1); } иначе, если (x> =(X_MID + DEADZONE)) {move_yaw (-1); } else if (y <=(Y_MID - DEADZONE)) {// слишком высоко, переместите пистолет вверх pitch_stepper.move (33152); steps_taken + =33152; } иначе, если (y> =(Y_MID + DEADZONE)) {pitch_stepper.move (33152); steps_taken + =33152; } еще {блокировка =истина; Serial.print ("Цель заблокирована в местоположении X:"); Serial.print (x); Serial.print (", Y:"); Serial.println (y); Serial.print ("Шаги предприняты:"); Serial.println (steps_taken); }}} текущий_угол =пройденные_шаги / STP_PER_DEG_PITCH; Serial.print ("Текущий угол:"); Serial.println (current_angle);} void init_pins () {pinMode (контакты [2], ВЫХОД); pinMode (контакты [5], ВЫХОД); pinMode (limit_switch, INPUT_PULLUP); pinMode (laser_pin, ВЫХОД); pinMode (spool_pin, ВЫХОД); pinMode (distance_echo, INPUT); pinMode (distance_trig, ВЫХОД); digitalWrite (контакты [2], НИЗКИЙ); digitalWrite (контакты [5], LOW); digitalWrite (laser_pin, LOW); digitalWrite (spool_pin, LOW); trigger.attach (servo_pin); pitch_stepper.begin (об / мин, MICROSTEPS); yaw_stepper.begin (5, МИКРОСТЕПС); trigger.write (90);} void move_yaw (плавающие градусы) {yaw_stepper.move (градусы * STP_PER_DEG_YAW * 32);} void move_pitch (плавающие градусы) {текущий_ угол + =градусы; pitch_stepper.move (градусы * STP_PER_DEG_PITCH);} float get_angle (расстояние поплавка, высота поплавка) {float i =2 * высота * 455,225; поплавок j =G * расстояние * расстояние; я + =j; j =9,8 * i; я =sqrt (pow (квадрат_скорости, 2) - j); return atan ((velocity_squared-i) / (G * distance)) * (180 / PI);} float ping () {Serial.println ("Получение расстояния ..."); большая продолжительность; digitalWrite (distance_trig, LOW); delayMicroseconds (5); digitalWrite (distance_trig, HIGH); delayMicroseconds (10); digitalWrite (distance_trig, LOW); duration =pulseIn (distance_echo, HIGH); длительность возврата / 2 / 29,1; // расстояние в метрах} void home_pitch () {Serial.println (digitalRead (limit_switch)); if (! digitalRead (limit_switch)) {// Если переключатель активен, pitch_stepper.rotate (720); } while (digitalRead (limit_switch)) {//Serial.println(digitalRead(limit_switch)); pitch_stepper.move (-32); } pitch_stepper.rotate (2880 * 2);}
Изготовленные на заказ детали и корпуса
Репозиторий Thingiverse
Файл САПР на сайте thingiverse.comСхема
Производственный процесс
- Шаговые двигатели
- Интегрированные драйверы упрощают разработку шаговых двигателей
- Прототип Raspoulette
- Простой робот Pi
- Библиотека биполярных шаговых двигателей
- Swiper - Auto Tinder / Bumble Swiper
- Автономный домашний робот-помощник
- Серая зона между серводвигателями и шаговыми двигателями
- Что такое линейный двигатель?
- Что такое серводвигатель?