воскресенье, 23 февраля 2014 г.

Робот

Эта статья о простом роботе который старается избегать столкновений с препятствиями. Мозгом конструкции является arduino. Обнаруживает препятствия ИК бампер. Возможных вариантов поведения не счесть.


Для создания ардуино роботов есть множество готовых платформ. Но я решил сделать свою платформу. На фото показаны все необходимые детали.


Роль основы возложена на кусочек стеклотекстолита 10х15 см. В движение платформа будет приводиться двумя электрическими коллекторными моторами постоянного тока с редукторами. Их рабочее напряжение составляет 3 вольта. Максимальный ток составляет 0.5 ампера. Частота вращения вала составляет 52 оборота в минуту. Еще на фото видно два алюминиевых уголка. Они предназначены для крепления моторов. Также есть два переходника для крепления колес. Колеса от радиоуправляемых моделей автомобилей масштаба 1/10. Их диаметр составляет 65 мм. И последняя деталька это опорное колесо.

Собранную платформу можно увидеть на размещенной ниже картинке.


Всё, что может быть приклеено на двусторонний скотч, приклеено на двусторонний скотч :-) Быстро и просто.

Внешний вид полностью собранного робота показан на фотографии прикрепленной ниже.


У меня используется немного необычная версия Arduino Leonardo. Она достаточно компактна и весьма минималистична.

Роль драйвера двигателей выполняет модуль с двумя L9110S. Эта платка подключается к ардуино согласно приведенным ниже рекомендациям.

Arduino --- Motor Driver

GND --- GND
VCC --- VCC
D8 --- B-IB
D9 --- B-IA
D10 --- A-IB
D11 --- A-IA

Электрические моторчики подключить немного сложнее. Левый двигатель подключаются к клеммам MOTOR-A. Правый двигатель подключается к клеммам MOTOR-B. Вот только, какую клемму мотора с какой клеммой драйвера соединить, нужно определять опытным путем.

У L9110S не предусмотрена возможность работы с ШИМ. Поэтому изменять скорость вращения колес проблематично. Это означает, что скорость передвижения робота постоянна. Неплохо было бы её  оценить, хоть приблизительно.

Итак. Длина окружности колеса составляет  0.065 * 3.14 = 0.2041 м. Это то расстояние, которое колесо проедет за один оборот. За секунду колесо сделает около 52 / 60 = 0.87 оборота. Таким образом, скорость составит 0.2041 * 0.87 = 0.177 м/с. За одну секунду робот проедет приблизительно 18 сантиметров.

Важной частью конструкции является датчик препятствий. Я купил готовый ик бампер. С оптимальными настройками этот ик бампер определяет преграды в радиусе 4 сантиметров от своей продольной оси. Ширина собранной мной платформы около 16 сантиметров. Самым простым решением было бы поставить два ик бампера. Только у меня этот датчик один. И судя по всему таких больше не делают. Делают немного другие. Принципиальной разницы между ними нет. Но применять разные ик бампера на одном роботе не очень хотелось. Поэтому я установил ик бампер на сервопривод. Он периодически поворачивает датчик и тем самым увеличивает контролируемую область.

В этом проекте ик бампер подключается к ардуино как написано ниже.

Arduino --- Infrared Obstacle Sensor

GND --- -
VCC --- +
A0 --- S
NC --- EN

Теперь сервопривод. Я использовал HK15288A. Однако, его можно заменить на MG995 или MG996. Подключение. Желтый провод сервопривода соединяется с цифровым выводом 7 ардуино. Красный провод соединяется с VCC. Коричневый провод соединяется с GND.

Всю эту конструкцию обеспечивают энергией три последовательно соединенные батарейки АА.

Скетч робота

////////////////////////
//
// Arduino Leonardo
//
////////////////////////
//
// Sketch: robot
//

// Arduino   ATmega32U4
//
// D13 --- Port C Pin 7
// D12 --- Port D Pin 6
// D11 --- Port B Pin 7
// D10 --- Port B Pin 6
// D9 --- Port B Pin 5
// D8 --- Port B Pin 4
//
// D7 --- Port E Pin 6
// D6 --- Port D Pin 7
// D5 --- Port C Pin 6
// D4 --- Port D Pin 4
// D3 --- Port D Pin 0
// D2 --- Port D Pin 1
// D1 --- Port D Pin 3
// D0 --- Port D Pin 2
//
// A5 --- Port F Pin 0
// A4 --- Port F Pin 1
// A3 --- Port F Pin 4
// A2 --- Port F Pin 5
// A1 --- Port F Pin 6
// A0 --- Port F Pin 7

#include <Servo.h>

const unsigned char SERVO1 = 7; // Digital Pin 7

const unsigned char MOTOR1A = 8; // Digital Pin 8
const unsigned char MOTOR1B = 9; // Digital Pin 9
const unsigned char MOTOR2A = 10; // Digital Pin 10
const unsigned char MOTOR2B = 11; // Digital Pin 11

// Arduino Uno
//const unsigned char SENSOR = 14; // Analog Pin 0

// Arduino Leonardo
const unsigned char SENSOR = 18; // Analog Pin 0

Servo servo1;

unsigned char angle = 60;

void forward( void )
{
    digitalWrite(MOTOR1A, LOW);
    digitalWrite(MOTOR1B, HIGH);
    digitalWrite(MOTOR2A, LOW);
    digitalWrite(MOTOR2B, HIGH);
}

void backward( void )
{
    digitalWrite(MOTOR1A, HIGH);
    digitalWrite(MOTOR1B, LOW);
    digitalWrite(MOTOR2A, HIGH);
    digitalWrite(MOTOR2B, LOW);
}

void left( void )
{
    digitalWrite(MOTOR1A, LOW);
    digitalWrite(MOTOR1B, LOW);
    digitalWrite(MOTOR2A, HIGH);
    digitalWrite(MOTOR2B, LOW);
}

void right( void )
{
    digitalWrite(MOTOR1A, HIGH);
    digitalWrite(MOTOR1B, LOW);
    digitalWrite(MOTOR2A, LOW);
    digitalWrite(MOTOR2B, LOW);
}

void stop( void )
{
    digitalWrite(MOTOR1A, LOW);
    digitalWrite(MOTOR1B, LOW);
    digitalWrite(MOTOR2A, LOW);
    digitalWrite(MOTOR2B, LOW);
}

void setup()
{
    pinMode(SENSOR, INPUT);

    pinMode(MOTOR1A, OUTPUT);
    pinMode(MOTOR1B, OUTPUT);
    pinMode(MOTOR2A, OUTPUT);
    pinMode(MOTOR2B, OUTPUT);

    servo1.attach(SERVO1);
    servo1.write(90);

    delay(2000);
}

void loop()
{
    if ( angle == 60 ) { angle = 120; }
    else { angle = 60; }

    servo1.write(angle);
    delay(300);

    if ( digitalRead(SENSOR) == LOW )
    {
        stop();
        delay(1000);

        if ( angle == 60 ) { left(); }
        else { right(); }

        delay(1000);

        stop();
        delay(1000);
    }
    else
    {
        forward();
    }
}

//
// End
//
////////////////////////

В этой программе реализован простой и не самый хороший алгоритм объезда препятствий. Улучшать его можно бесконечно.

В заключении хочу рассказать о некоторых особенностях ик бампера. Расстояние на котором он определяет препятствие сильно зависит от самого препятствия. Светлое и блестящее препятствие определяется с большого расстояния. А черное и матовое препятствие ик бампер в упор не замечает.

И ещё. Нажатие кнопки бытового ик пульта воспринимается ик бампером как обнаружение препятствия :-)