Главная » 2017 » Март » 5 » Робот СУМО
16:02
Робот СУМО

Наша цель построить максимально дешевого робота для сумо.

   

Что вам понадобиться для сборки

  1. Arduino UNO R3
  2. USB кабель
  3. Мини макета
  4. ИК-датчик
  5. Два сервомотора
  6. Держатель для батареи АА
  7. Четыре батареи типа АА
  8. Провода (желательно цветные)

Подключаем ИК-датчик

  

Существует множество датчиков которые можно использовать с Arduinoю. Мы будем использовать GP2Y0A21YK0F для измерения расстояния до объектов. Его диапазон ограничен от 10см до 80см. Этот датчик подключить легко взгляните на схему сверху.

  • питание +5В пин на плате Arduino
  • землю на контактом GND на плате Arduino
  • сигнал на аналоговый пин A0 на плате Arduino

Дальше нам надо откалибровать датчик, это можно сделать с помощью этой программы.

int dist_table[][2] = { // calibration table cm to analog value

  {5, 630}, {10, 500}, {15, 340}, {20, 250}, {25, 200},

  {30, 180}, {35, 170}, {40, 140}, {50, 120}, {55, 115},

  {60, 106}, {65, 102}, {70, 98}, {75, 94}, {80, 90}

};

 

int filter(int prev, int curr) { // filter function

  const float filterVal = 0.1;

  return (int)((float)curr * filterVal + (float)prev * (1 - filterVal));

}

 

int distance(int pin) { // get current distance from sensor

  const int tries = 10, ms = 1;

  int val = analogRead(pin);

  for (int i = 1; i < tries; i++) { // approximate several values taken with delay

    val = filter(val, analogRead(pin));

    delay(ms);

  }

  int len = sizeof(dist_table) / sizeof(dist_table[0]);

  for (int i = 0; i <= len; i++) { // find closest value in table and interpolate if possible

    if (val >= dist_table[i][1]) {

      if (i > 0) {

        return map(val, dist_table[i][1], dist_table[i-1][1], dist_table[i][0], dist_table[i-1][0]);

      } else {

        return dist_table[i][0];

      }

    }

  }

  return dist_table[len - 1][0];

}

 

void setup() {

  pinMode(A0, INPUT);

  Serial.begin(9600);

}

 

void loop() {

  delay(500);

  int curr_dist = distance(A0);

  Serial.print("Analog value: ");

  Serial.print(analogRead(A0));

  Serial.print(". Distance (cm): ");

  Serial.println(curr_dist);

}

Подключаем сервомоторы

  

Существует множество способов заставить робота двигаться, обычно люди используют двигатели постоянного тока. Мы будем использовать серво приводы, но ни кто не мешает вам использовать другие способы.

Сервоприводы,  как правило,  имеют три провода:  питание (красный),  земля (черный или коричневый) и сигнальный (желтый, оранжевый или белый). Подключите их следующим образом как показано на схеме выше:

  • питание +5В пин на плате Arduino
  • землю на контактом GND на плате Arduino
  • сигнал цифровой пин на плате Arduino

Вот программа для калибровки сервомоторов:

#include <Servo.h>

 

#define NEUTRAL 1500 // pulse width for servo at zero speed

#define MAX_SPEED 300 // diff for pulse width between zero and max speed

#define MAX_FORWARD NEUTRAL+MAX_SPEED // pulse width for max counter-clockwise speed

#define MAX_BACKWARD NEUTRAL-MAX_SPEED // pulse width for max clockwise speed

 

Servo servo; // servo object

 

int current = NEUTRAL; // current pulse length of control signal in microseconds

int step = 10;         // change pulse width on "step" microseconds at a time

 

void setup() {

  servo.attach(9); // attach servo to pin 9

  Serial.begin(9600);

  servo.writeMicroseconds(current); // set default speed - servo should stay not moving

  delay(5000);  // for 5 seconds

}

void loop() { // then we start spinning forth and back

  current += step; // changing pulse length

  if (current < MAX_BACKWARD || current > MAX_FORWARD) {

    step = -step;

  }

  servo.writeMicroseconds(current);

  Serial.println(current);

  delay(100);

}

Подключение питания

До этого момента мы использовали USB кабель для питания нашего детища, теперь же подключим батарейки, все подключаем как показано на схеме выше.

Тело робота

Теперь нам нужно построить корпус для будущего сумоиста. Вы можете взять модели из прилепленных файлах или придумать свои.

Скачать

 

  1. Основные части конструкции (вырезать из дерева или оргстекла)
  2. Винты и гайки для фиксации серво, ИК-датчик и колеса (вы, вероятно, нужна, чтобы быть куплены в местном магазине)
  3. Колеса (напечатанный на 3D-принтере)
  4. Шины (резиновые кольца)

Дальше нам нужно склеить все детали нашего робота. Поздравляем робот почти готов, осталось только написать программу, приступим же!!

Программная часть

 

 В нашей программе мы будем двигаться по следующим правилам:

  • избегайте препятствий
  • избегайте краев стола

Робот имеет 2 колеса. Она будет ездить под самый базовым алгоритмом для робота - дифференциальным приводом:

  • ехать прямо оба колеса вперед на равной скорости
  • для привода реверс обоих колесах вернуться на равной скорости
  • чтобы повернуть налево левое колесо движется в обратном направлении и правое колесо движется вперед
  • чтобы повернуть направо правое колесо движется в обратном направлении и левое колесо движется вперед

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

Вот и сама программа:

#include <Servo.h>

 

#define NEUTRAL 1500 // pulse width for servo at zero speed

#define MAX_SPEED 300 // diff for pulse width between zero and max speed

#define MAX_FORWARD NEUTRAL+MAX_SPEED // pulse width for max counter-clockwise speed

#define MAX_BACKWARD NEUTRAL-MAX_SPEED // pulse width for max clockwise speed

 

#define LED 13 // on-board Arduino LED

 

// Move directions

#define UNKNOWN -1

#define FORWARD 0

#define LEFT 1

#define RIGHT 2

#define BACKWARD 3

 

// IR sensor values

#define TOO_FAR 300 // to far to obstacle - probably table edge

#define TOO_CLOSE 500 // too close to obstacle

 

Servo rightServo;

Servo leftServo;

 

void attachServos() {

  if (!rightServo.attached()) { rightServo.attach(9); }

  if (!leftServo.attached()) { leftServo.attach(10); }

}

 

void move(int dir) {

  switch (dir) {

    case FORWARD:

      rightServo.writeMicroseconds(MAX_BACKWARD);

      leftServo.writeMicroseconds(MAX_FORWARD);

      break;

    case LEFT:

      rightServo.writeMicroseconds(MAX_BACKWARD);

      leftServo.writeMicroseconds(MAX_BACKWARD);

      break;

    case RIGHT:

      rightServo.writeMicroseconds(MAX_FORWARD);

      leftServo.writeMicroseconds(MAX_FORWARD);

      break;

    case BACKWARD:

      rightServo.writeMicroseconds(MAX_FORWARD);

      leftServo.writeMicroseconds(MAX_BACKWARD);

      break;

    default:

      rightServo.writeMicroseconds(NEUTRAL);

      leftServo.writeMicroseconds(NEUTRAL);

  }

}

 

int checkDistance() {

  // TODO: implement filter and conversion to cm

  return analogRead(A0);

}

 

void setup() {

  pinMode(A0, INPUT);

  pinMode(LED, OUTPUT);

  attachServos();

  Serial.begin(9600);

}

 

int currentDirection = UNKNOWN;

 

void loop() {

  int sensorValue = checkDistance(); // get value from ir sensor

  // Note: check IR sensor voltage diagram

//  Serial.println(dist); // DEBUG: print distance

  if (sensorValue < TOO_FAR) {

    currentDirection = BACKWARD; // possible table edge - move backward

  } else if (sensorValue > TOO_CLOSE) {

    if (currentDirection == 0) { // too close - rotate

      randomSeed(millis()); // in random direction

      currentDirection = random(1, 3); // LEFT or RIGHT

    }

  } else {

    currentDirection = FORWARD; // otherwise - move forward

  }

  digitalWrite(LED, currentDirection != FORWARD); // indicate danger

  move(currentDirection);

  delay(500); // half-second delay

}

Разработано совместно с @electlab

Просмотров: 3359 | Добавил: mikrobord | Теги: сумо, Arduino, Робот, MikroBord | Рейтинг: 0.0/0
Всего комментариев: 0
avatar