Робот удаленного наблюдения

Dorrin
Offline
Зарегистрирован: 06.12.2014
 
Потребовалось срочно разработать рабочий концепт роботизированной системы телеметрии для диплома. Так что забирайте если что)
 
 
 
Жена заканчивала университет и настало время писать диплом.
 
Так как я не программист по образованию, то пришлось делать действующую модель , а не программный продукт.
 
Первичный концепт формы был разработан довольно быстро- шар на трехколесной опоре. Шар был выбран по соображениям прочности формы и легкости изготовления на глаз, а трехколесная платформа- для удобства управления(впоследствии была изменена на четырехколесную).
  
 
Были заказаны 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;

}
 
После всего вышеперечисленного ставим на нетбук ТимВивер или Радмин, запускаем наш код и понеслась) можно так же включить двустороннюю аудиосвязь в ТимВивере и пообщаться с роботом.
 
 
Ну и в конце сам диплом, вдруг кому пригодится.
 
 
Dorrin
Offline
Зарегистрирован: 06.12.2014

Модер, я попутал ветку( прошу перенести в проекты.

An25
Offline
Зарегистрирован: 19.09.2014

А что за вуз. И сколько жена получила за диплом?

Dorrin
Offline
Зарегистрирован: 06.12.2014

мгупи, оценка отлично, но это на фоне еще более слабых работ.

An25
Offline
Зарегистрирован: 19.09.2014

Спасибо. Это филиал какой или сама Москва?

Dorrin
Offline
Зарегистрирован: 06.12.2014

А с какой целью интересуетесь?

An25
Offline
Зарегистрирован: 19.09.2014

Диплом какой-то слабый, откровенно говоря. Тока без обид, вы спросили я честно ответил.

Я закончил учиться в универе по специальности радиотехника 15 лет назад с мешком троек за спиной (потом, лет через 10 была еще была одна вышка - экономическая, где я понял что или экономисты дураки или уровень преподавания падает). Не представляю что сейчас в институах творится. Неужели все так плохо и мои догадки верны?

Dorrin
Offline
Зарегистрирован: 06.12.2014

вы правы, все плохо(