Робот удаленного наблюдения
- Войдите на сайт для отправки комментариев
Пнд, 08/12/2014 - 22:05
Потребовалось срочно разработать рабочий концепт роботизированной системы телеметрии для диплома. Так что забирайте если что)
Жена заканчивала университет и настало время писать диплом.
Так как я не программист по образованию, то пришлось делать действующую модель , а не программный продукт.
Первичный концепт формы был разработан довольно быстро- шар на трехколесной опоре. Шар был выбран по соображениям прочности формы и легкости изготовления на глаз, а трехколесная платформа- для удобства управления(впоследствии была изменена на четырехколесную).
Были заказаны 4 колеса из магазина Robocraft.
И примотаны синей изолентой к корпусу, ибо вытачивать крепления оказалось проблематично, а заказывать готовые поздно.
Для управления колесами были закуплены драйверы двигателей L293D(ибо простота и удобство). Делать отдельную плату не посчитал нужным и распаял все на макетке, отдельно добавил радиатор для температурной стабилизации.
<em>Да, при прохождении тока плата нагревается и ее характеристики плывут</em>
<em>Советую использовать быстросъемную панель для микросхемы(но у них иногда пропадает контакт)</em>
Отдельными ножками выведены 4 входа, 4 выхода и питание.
Но просто катающийся робот не тянет ни на систему телеметрии, ни на диплом.
Добавим ему манипулятор для взаимодействия с внешним миром.
Возьмем оргстекло(легко обрабатывается) и дешевые сервы за 300р. Выточим консоли(овальные проще изготовить) и вырежем крепежные отверстия. Теперь вырежем заготовку верхнего крепежа и согнем ее под 90 градусов.
Тесты показали что может приподнять сам себя и немножко воды в пластиковом стакане, ну и в котов тыкать тоже можно.
Теперь добавим возможность наблюдения, но просто камера тоже не пойдет - нет возможности обернуться или посмотреть в лицо собеседнику.
Для этого соберем модуль поворотной камеры "Глаз Саурона" из полосового алюминия и минисервоприводов за 150р, с 4 степенями сворбоды.
Так же смонтируем ArduinoMega к драйверам двигателей в распаечную коробку представляющую силовую часть.
Изменениям подвергнется и ходовая часть- она трехколесная и не позволяет развернуться на месте, это печалило руководителя диплома. В итоге ее сменили на четырехколесную- 2 ведущих по бокам и 2 всенаправленных спереди и сзади.
Наконец был смонтирован мозг- старенький нетбук, предоставляющий доступ к WiFi,интернету, возможности писать свой интерфейс и удаленный доступ. Вот такой вот мегашилд к ардуине.
Покупать аккумулятор+зарядное оказалось дороговато, поэтому он питался от розетки. На защите диплома это преподносилось как физическая защита от взлома- отъехал дальше положенного и выключился.
Теперь перейдем к коду ардуины и интерфейса.
Разработка программного обеспечения контроллера
Для написания исполняемого кода будем использовать Arduino IDE, в нем реализованы все необходимые библиотеки и функционал.
Далее я буду описывать написание кода с подробными комментариями о выполняемых действиях и выборе решений.
//Подключим стандартную библиотеку для обмена с компьютером #include <SoftwareSerial.h> //Подключим библиотеку управления сервоприводами #include <Servo.h> //Создадим две переменные для эмуляции сторожевого таймера, так как использование метода delay(time) останавливает исполнение остального кода. unsigned long time1; unsigned long time2; //Создадим объекты класса Servo для сервоприводов камеры и манипулятора Servo cam2; Servo cam; Servo man1; Servo man2; Servo man3; Servo man4; //Создадим переменные для хранения значений положения сервопроводов камеры и манипулятора int posman1=20; int posman2=90; int posman3=90; int posman4=90; int poscam=100; int poscam2=100; //Опишем исходные параметры запуска void setup() { //Создадим объект класса Serial для общения на скорости 9600 бод Serial.begin(9600); //Сконфигурируем отдельные ножки для управления двигателями на выход pinMode(2,OUTPUT); pinMode(3,OUTPUT); pinMode(4,OUTPUT); pinMode(5,OUTPUT); //Опишем присоединение управления каждым сервоприводом на отдельную ножку man1.attach(8); man2.attach(9); man3.attach(10); man4.attach(7); cam.attach(11); cam2.attach(12); //Установим управляющие сигналы в логическую единицу заранее, чтобы робот не двигался без входящей команды digitalWrite(2,1); digitalWrite(3,1); digitalWrite(4,1); digitalWrite(5,1); } //Начало исполняемого цикла void loop() { //Установим сервоприводы манипулятора в экпериментально установленные положения. man1.write(posman1); man2.write(posman2); man3.write(posman3); man4.write(posman4); //Установим сервоприводы камеры в экпериментально установленные положения. cam.write(poscam); cam2.write(poscam2); //Для защиты от лишней нагрузки поставим условие, что код будет выполняться только если в порт пришла какая либо информация. if(Serial.available()) { //Создадим переменную, содержащую символ управления int input=Serial.read(); //Если входящим символом является «w» в ASCII формате, то включим обоим моторам движение вперед if(input==119) { //Запись в порт управляющего сигнала digitalWrite(3,0); digitalWrite(2,0); //Запомним время прошедшее с момента включения микроконтроллера, это необходимо в дальнейшем, чтобы через определенный промежуток остановить действие. time1=millis(); //Для тестирования выведем в порт надпись «вперед» Serial.println("forward"); } //Назад if(input==115) { digitalWrite(5,0); digitalWrite(4,0); time1=millis(); Serial.println(" back"); } //Для поворота робота моторы включаются разнонаправленно, что позволяет ему развернуться на любой угол на месте. if(input==97) { digitalWrite(5,0); digitalWrite(2,0); time1=millis(); Serial.println(" left"); } //Право if(input==100) { digitalWrite(3,0); digitalWrite(4,0); time1=millis(); Serial.println("right"); } //Для управления сервоприводами нужно передать им значение угла поворота if(input==121) { //Поступление каждого управляющего символа изменяет угол поворота на 3 градуса, но максимальный угол поворота 180 градусов, поэтому предусмотрим условие ограничивающее его. if(posman1<180) { posman1+=3; } man1.write(posman1); Serial.println(" up "); Serial.print(posman1); } if(input==104) { if(posman1>0) { posman1-=3; } man1.write(posman1); Serial.println(" down "); Serial.print(posman1); } if(input==117) { if(posman2<180) { posman2+=3; } man2.write(posman2); Serial.println(" up "); Serial.print(posman2); } if(input==106) { if(posman2>0) { posman2-=3; } man2.write(posman2); Serial.println(" up "); Serial.print(posman2); } if(input==105) { if(posman3<180) { posman3+=3; } man3.write(posman3); Serial.println(" up "); Serial.print(posman3); } if(input==107) { if(posman3>0) { posman3-=3; } man3.write(posman3); Serial.println(" up "); Serial.print(posman3); } if(input==111) { if(posman4<180) { posman4+=3; } man4.write(posman4); Serial.println(" up "); Serial.print(posman4); } if(input==108) { if(posman4>0) { posman4-=3; } man4.write(posman4); Serial.println(" up "); Serial.print(posman4); } //Управление сервоприводами камеры //Камера вниз if(input==114) { if(poscam>0) { poscam-=3; } cam.write(poscam); Serial.println(" cam down "); Serial.print(poscam); } //Камера вверх if(input==102) { if(poscam<180) { poscam+=3; } cam.write(poscam); Serial.println("cam up "); Serial.print(poscam); } //Камера вправо if(input==118) { if(poscam2>0) { poscam2-=3; } cam2.write(poscam2); Serial.println(" cam right "); Serial.print(poscam2); } //Камера влево if(input==99) { if(poscam<180) { poscam2+=3; } cam2.write(poscam2); Serial.println(" cam left "); Serial.print(poscam2); } } //Повторно возьмем время работы микроконтроллера time2=millis(); //И если разница больше 100 миллисекунд, то остановим движение всех моторов. if(time2-time1>100) { digitalWrite(2,1); digitalWrite(3,1); digitalWrite(4,1); digitalWrite(5,1); } }
Интерфейс пользователя
Изначально хотелось написать свою полноценную дуплексную связь, но скилов не хватило, поэтому взял готовое решение(ТимВивер).Для связи с ардуино используем язык Processing(весьма красочный и удобный).
//Добавим стандартные библиотеки работы с видеоизображением и последовательным портом. import processing.video.*; import processing.serial.*; //Создадим объект класса «Видеозахват» Capture cam; //Создадим объект класса «Последовательный порт» Serial myPort; //Создадим переменую хранящую последнюю нажатую клавишу int whichKey = -1; //Создадим переменную для хранения ответа микроконтроллера int inByte = -1; void setup() { //Зададим размер окна приложения size(640, 480); //Для тестирования выведем список всех доступных портов println(Serial.list()); //По умолчанию единственный доступный на обмен информацией порт стоновится первым, поэтому возьмем его название. String portName = Serial.list()[0]; //Создадим объект класса последовательных портов. myPort = new Serial(this, portName, 9600); //Создадим объект класса захвата видеоизображения с заданным разрешением. cam = new Capture(this, 640,480); //Запустим захват видеоизображения cam.start(); //Установим частоту смены изображения 30 кадров в секунду. frameRate(30); } //Начнем отрисовку окна приложения void draw() { //Установим условие, что действие произойдет, если камера работоспособна if (cam.available() == true) { //Прочтем массив пикселей из камеры cam.read(); } //Если камера не отвечает выведем паническое сообщение. else { fill(255,0,0); text(“PANIC!!!! CAMERA DIE!!!”,320,240); } //Выведем кадр изображения с камеры в окно приложения image(cam, 0, 0); //Отобразим последнюю нажатую клавишу fill(0); //Так как символы управления приходят в цифровом формате, переведем полученное значение в символ. text("Последнее нажатие " + char(whichKey), 10, 30); //Для большей информативности и наглядности увеличим размер текста. textSize(30); //А так же раскрасим различные группы клавиш управления, придав эффект полупрозрачности. fill(0,255,0,50); //Круглые клавиши воспринимаются мягче, поэтому сделаем их таковыми ellipse(30,430,50,50); ellipse(80,430,50,50); ellipse(130,430,50,50); ellipse(80,380,50,50); fill(0); text('A',20,440); text('S',70,440); text('D',120,440); text('W',70,390); //Камера fill(255,255,0,50); ellipse(200,430,50,50); ellipse(200,380,50,50); ellipse(250,405,50,50); ellipse(300,405,50,50); fill(0); text('R',190,390); text('F',190,440); text('C',240,415); text('V',290,415); //Манипулятор fill(255,83,0,50); ellipse(400,380,50,50); ellipse(450,380,50,50); ellipse(500,380,50,50); ellipse(550,380,50,50); ellipse(400,430,50,50); ellipse(450,430,50,50); ellipse(500,430,50,50); ellipse(550,430,50,50); fill(0); text('Y',390,390); text('U',440,390); text('I',500,390); text('O',540,390); text('H',390,440); text('J',440,440); text('K',490,440); text('L',540,440); } //Прочтем пришедшую с микроконтроллера информацию void serialEvent(Serial myPort) { //Поместим в переменную полученную информацию inByte = myPort.read(); } //Создадим стандартную функцию слежения за нажатием клавишь. void keyPressed() { //Запишем в последовательный порт символ управления, являющийся нажатой клавишей. myPort.write(key); whichKey = key; }
После всего вышеперечисленного ставим на нетбук ТимВивер или Радмин, запускаем наш код и понеслась) можно так же включить двустороннюю аудиосвязь в ТимВивере и пообщаться с роботом.
Ну и в конце сам диплом, вдруг кому пригодится.
Модер, я попутал ветку( прошу перенести в проекты.
А что за вуз. И сколько жена получила за диплом?
мгупи, оценка отлично, но это на фоне еще более слабых работ.
Спасибо. Это филиал какой или сама Москва?
А с какой целью интересуетесь?
Диплом какой-то слабый, откровенно говоря. Тока без обид, вы спросили я честно ответил.
Я закончил учиться в универе по специальности радиотехника 15 лет назад с мешком троек за спиной (потом, лет через 10 была еще была одна вышка - экономическая, где я понял что или экономисты дураки или уровень преподавания падает). Не представляю что сейчас в институах творится. Неужели все так плохо и мои догадки верны?
вы правы, все плохо(