Робот iRobot Create - программируемый робот. В 2007 году разработан компанией iRobot на базе платформы робота пылесоса Roomba
Электронный интерфейс включает 7 pin mini-DIN и DB-25 разъемы для обмена данными, электронные датчики, световые индикаторы. Программный интерфейс позволяет управлять поведением робота. Он позволяет считывать информацию с сенсоров при помощи серии команд, включает команды режима, команды привода, звуковые команды, демонстрационные команды и команды опроса сенсоров. Эти команды можно посылать на последовательный порт робота с компьютера или микроконтроллера. Есть кое-какие задумки, но пока для тренировки в ROS (операционная система для роботов - описание ) сделаем управление iRobot Сreate c планшета Android по Bluetooth. Android -> Arduino Duemilanovo+HC05 -> ROS(на нетбук с Ubuntu 11.10) -> iRobot create
iRobot crete подсоединен к USB порту нетбука за неимением переходников через DB-25 и плату Arduino Nano 1(Rx) – Rx Arduino 2(Tx) – Tx Arduino 14(GND) – GND Arduino
Получилась такая конструкция
Вот результат недельных трудов – робот по имени Роберт управление клавишами акселерометром голосом
Еще сыровато и есть много непонятных моментов. Буду делать немного по-другому – (напрямую Android – ROS библиотека rosjava), но опыт какой-то получен.
Необходимо было реализовать следующее 1) программа на Android для преобразования нажатий на кнопки управления, показаний акселерометра и голосового управления в серию команд для iRobot create и отправка по Bluetooth в Arduino Duemilanovo; 2) скетч на Arduino для создания узла ROS, получения данных по Bluetooth из Android-устройства и публикация сообщений в тему Theme_arduino1; 3) создание пакета vp_arduino1, где созданим subscriber для получения сообщений(пользовательский тип сообщений) по теме Theme_arduino1 и отправка данных в сервисы пакета iRobot_create_2_1.
Заказывал в конце мая (под заказ) DFRduino Ethernet Shield (Support Mega and SD) - 1160 руб (под заказ) Sealed Membrane 4*4 button pad with sticker - 195 руб (под заказ) DFRduino Player - 980 руб Там у Вас возникали проблемы с доставкой Сейчас у меня проблемы с почтовым ящиком victoruni@km.ru, через который Вам заказывал (нет доступа) Может товар уже пришел, а я не в курсе если нет - стоит ли ждать вообще? - тогда я выкуплю уже пришедшее - DFRduino Player
Гусеницы,платформа,двигатели Tamiya Автономное питание 4х1,5В батарейки в держателе батареи 3-AA из магазина + куча частей из такого чудного китайского набора и вот что получилось
Кроме этого еще стоят датчики дальности Pololu 10см на Sharp GP2Y0D810Z0F ,смотрящие вниз,чтобы не падал с обрыва, серво для крепления датчика дальности Sharp GP2Y0A21YK0F 10-80см но это все будет потом, как появится время Теперь скетч.
Код
//
#include <IRremote.h>
#include <Servo.h>
//вход ИК приемника
int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long ir_dt, old_ir;
long ir_kod;
unsigned long ir_time1, ir_time2;
// коды клавиш ИК пульта (marmitek)
#define FORWARD 1936
#define BACK 3984
#define SPEED_UP 144 //ch+
#define SPEED_DOWN 2192 //ch-
#define LEFT 3472
#define RIGHT 1424
#define CIRCLE_LEFT 3216 //vol+
#define CIRCLE_RIGHT 1168 //vol-
#define STOP 2320 //0
// состояние моторов робота
struct POZ // структура для хранения статусов моторов
{
int poz1; // позиция для 1 мотора
int poz2; // позиция для 2 мотора
int direction12; // направление до поворота
};
// моторы
struct MOTOR // структура для хранения номеров pin-ов, к которым подключены моторчики
{
int in1; // INPUT1
int in2; // INPUT2
int enable; // ENABLE1
};
// определяем порты, к которым подключены моторчики
MOTOR MOTOR1 = { 13, 12, 5 };
MOTOR MOTOR2 = { 7, 8, 6 };
// начальная позиция робота
// 1,2 мотор - выключены
POZ POZ12={7,7,7};
// массив возможных состояний моторов
// max down -> min down -> stop -> min up -> max up
int arrpoz[9][17]={
// in1 первого мотора
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
// in2 первого мотора
{1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
// скорости (enable1) первого мотора
{250,230,210,190,170,150,130,0,130,150,170,190,210,230,250},
// in3 второго мотора
{0,0,0,0,0,0,0,0,1,1,1,1,1,1,1},
// in4 второго мотора
{1,1,1,1,1,1,1,0,0,0,0,0,0,0,0},
// скорости (enable2) второго мотора
{250,230,210,190,170,150,130,0,130,150,170,190,210,230,250},
// скорость++
{0,-1,-1,-1,-1,-1,-1,0,1,1,1,1,1,1,0},
// скорость--
{-1,-1,-1,-1,-1,-1,-1,0,1,1,1,1,1,1,1},
// кружение влево-вправо
{14,12,10,8,6,4,2,0,-2,-4,-6,-8,-10,-12,-14}
};
void setup()
{
// последовательный порт
Serial.begin(9600);
// включить приемник
irrecv.enableIRIn();
// прерывания для ИК
ir_time1=0;ir_time2=0;
attachInterrupt(0, get_ir_kod, FALLING);
// настраиваем выводы для моторов
pinMode(MOTOR1.in1, OUTPUT);
pinMode(MOTOR1.in2, OUTPUT);
pinMode(MOTOR2.in1, OUTPUT);
pinMode(MOTOR2.in2, OUTPUT);
// начальная позиция - робот стоит
go12(POZ12.poz1,POZ12.poz2);
}
void loop()
{
// обработка кода нажатия
if(ir_kod>0)
{
ir_go(ir_kod);
ir_kod=0;
}
}
// получить код переданный с ИК пульта
void get_ir_kod()
{
detachInterrupt(0); // отключить прерывание 0
if (irrecv.decode(&results))
{
if (results.value > 0 && results.value < 0xFFFFFFFF)
{
ir_dt = results.value;
ir_time2=millis();
if (ir_time2-ir_time1>1000)
{ir_kod = ir_dt;ir_time1=ir_time2;}
else
ir_kod = 0;
}
irrecv.resume();
}
attachInterrupt(0, get_ir_kod, CHANGE);
}
// переустановка моторов
void go12(int poz1,int poz2)
{
digitalWrite(MOTOR1.in1, arrpoz[0][poz1]);
digitalWrite(MOTOR1.in2, arrpoz[1][poz1]);
analogWrite(MOTOR1.enable, arrpoz[2][poz1]);
digitalWrite(MOTOR2.in1, arrpoz[3][poz2]);
digitalWrite(MOTOR2.in2, arrpoz[4][poz2]);
analogWrite(MOTOR2.enable, arrpoz[5][poz2]);
Serial.print(arrpoz[0][poz1]);Serial.print(" ");
Serial.print(arrpoz[1][poz1]);Serial.print(" ");
Serial.print(arrpoz[2][poz1]);Serial.print(" ");
Serial.print(arrpoz[3][poz2]);Serial.print(" ");
Serial.print(arrpoz[4][poz2]);Serial.print(" ");
Serial.print(arrpoz[5][poz2]);Serial.print("\n");
}
// обработка кода нажатия
void ir_go(long kod)
{
Serial.print(kod);
Serial.print("\n");
switch(kod)
{
case FORWARD : // направление вперед
Serial.print("forward\n");
POZ12.direction12=max(POZ12.direction12,8);
POZ12.poz1=POZ12.direction12;
POZ12.poz2=POZ12.direction12;
go12(POZ12.poz1,POZ12.poz2);
break;
case BACK : // направление назад
Serial.print("back\n");
POZ12.direction12=min(POZ12.direction12,6);
POZ12.poz1=POZ12.direction12;
POZ12.poz2=POZ12.direction12;
go12(POZ12.poz1,POZ12.poz2);
break;
case SPEED_UP : // скорость++
Serial.print("speed++\n");
POZ12.direction12=POZ12.direction12+arrpoz[6][POZ12.direction12];
POZ12.poz1=POZ12.direction12;
POZ12.poz2=POZ12.direction12;
go12(POZ12.poz1,POZ12.poz2);
break;
case SPEED_DOWN : // скорость--
Serial.print("speed--\n");
POZ12.direction12=POZ12.direction12-arrpoz[7][POZ12.direction12];
POZ12.poz1=POZ12.direction12;
POZ12.poz2=POZ12.direction12;
go12(POZ12.poz1,POZ12.poz2);
break;
case LEFT : // влево
Serial.print("left\n");
if(POZ12.direction12>6)
{
POZ12.poz1=POZ12.poz1-1;POZ12.poz1=max(POZ12.poz1,0);
POZ12.poz2=POZ12.direction12;
}
else
{
POZ12.poz1=POZ12.poz1+1;POZ12.poz1=min(POZ12.poz1,14);
POZ12.poz2=POZ12.direction12;
}
go12(POZ12.poz1,POZ12.poz2);
break;
case RIGHT : // вправо
Serial.print("right\n");
if(POZ12.direction12>6)
{
POZ12.poz2=POZ12.poz2-1;POZ12.poz2=max(POZ12.poz2,0);
POZ12.poz1=POZ12.direction12;
}
else
{
POZ12.poz2=POZ12.poz2+1;POZ12.poz2=min(POZ12.poz2,14);
POZ12.poz1=POZ12.direction12;
}
go12(POZ12.poz1,POZ12.poz2);
break;
case CIRCLE_RIGHT : // кружение вправо
Serial.print("circle_right\n");
POZ12.poz1=POZ12.direction12;
POZ12.poz2=POZ12.direction12+arrpoz[8][POZ12.direction12];
go12(POZ12.poz1,POZ12.poz2);
break;
//case 3216 : // кружение влево
case CIRCLE_LEFT : // кружение влево
Serial.print("circle_left\n");
POZ12.poz1=POZ12.direction12+arrpoz[8][POZ12.direction12];
POZ12.poz2=POZ12.direction12;
go12(POZ12.poz1,POZ12.poz2);
break;
case STOP : // стоп
Serial.print("stop\n");
POZ12.poz1=7;
POZ12.poz2=7;
POZ12.direction12=7;
go12(POZ12.poz1,POZ12.poz2);
break;
default:
break;
}
}
Вся информация занесена в массив состояний int arrpoz[9][17]
Робот в начале разработки - пока только радиоуправляемая машинка Craftduino+tamiya+TSOP31236 Похож на http://www.robototehnika.ru/communication/forum/forum4/topic20/ отличия - скорость регулируется +/- - повороты влево-вправо плавно регулируютcя уменьшением скорости вращения одного из двигателей - есть вращение на месте в обе стороны Для работы с ИК нашел библиотеку IRremote скачать >> Поддерживаемые протоколы: NEC, Sony SIRC, Philips RC5, Philips RC6. Пульт использовал Marmitek для Умного дома X10 Назначениеклавиш: ↑ – движение вперед; ↓ – движение назад; ← – поворот влево; → – поворот вправо; - CH – увеличение скорости при движении вперед-назад; CH+ – уменьшение скорости при движении вперед-назад; -VOL – круговое движение на месте влево; VOL+ – круговое движение на месте вправо; 0 – остановка робота.
Прием кодов - по прерыванию 0 Скетч для приема и обработки кодов + проверка выбора кодов
Код
// подключение библиотеки
#include <IRremote.h>
//вход ИК приемника
int RECV_PIN = 2;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long ir_dt, old_ir;
long ir_kod;
unsigned long ir_time1, ir_time2;
// коды клавиш ИК пульта (marmitek)
#define FORWARD 1936
#define BACK 3984
#define SPEED_UP 144 //ch+
#define SPEED_DOWN 2192 //ch-
#define LEFT 3472
#define RIGHT 1424
#define CIRCLE_LEFT 3216 //vol+
#define CIRCLE_RIGHT 1168 //vol-
#define STOP 2320 //0
void setup()
{
// последовательный порт
Serial.begin(9600);
// включить приемник
irrecv.enableIRIn();
// прерывания для ИК
ir_time1=0;ir_time2=0;
attachInterrupt(0, get_ir_kod, FALLING);
}
void loop()
{
// обработка кода нажатия
if(ir_kod>0)
{
Serial.println(ir_kod);
ir_go(ir_kod);
ir_kod=0;
}
}
// получить код переданный с ИК пульта
void get_ir_kod()
{
detachInterrupt(0); // отключить прерывание 0
if (irrecv.decode(&results))
{
if (results.value > 0 && results.value < 0xFFFFFFFF)
{
ir_dt = results.value;
ir_time2=millis();
if (ir_time2-ir_time1>1000)
{ir_kod = ir_dt;ir_time1=ir_time2;}
else
ir_kod = 0;
}
irrecv.resume();
}
attachInterrupt(0, get_ir_kod, CHANGE);
}
void ir_go(long kod)
{
switch(kod)
{
case FORWARD : // направление вперед
Serial.print("forward\n");
break;
case BACK : // направление назад
Serial.print("back\n");
break;
case SPEED_UP : // скорость++
Serial.print("speed++\n");
break;
case SPEED_DOWN : // скорость--
Serial.print("speed--\n");
break;
case LEFT : // влево
Serial.print("left\n");
break;
case RIGHT : // вправо
Serial.print("right\n");
break;
case CIRCLE_RIGHT : // кружение вправо
Serial.print("circle_right\n");
break;
case CIRCLE_LEFT : // кружение влево
Serial.print("circle_left\n");
break;
case STOP : // стоп
Serial.print("stop\n");
break;
default:
break;
}
}
В следующем посте продолжение - управление моторами + фото+видео
Я готов заказать: 2)DFRduino Ethernet Shield (Support Mega and SD) - 1160 руб (под заказ) 3)Sealed Membrane 4*4 button pad with sticker - 195 руб (под заказ) на вид разъем вроде 2.54 мм
DFRduino Ethernet Shield (Support Mega and SD) - 1160 руб (под заказ)- правильно я понимаю - подходит не только под Mega, но и под Arduino Duemilanove (Atmega 328)?