
Впечатлённый возможностями интеллектуального робота-помощника Baxter от Rethink Robotics, робототехник из США, распечатал на 3D-принтере запчасти для простого манипулятора на базе сервомашинок (с выведенным датчиком положения) и написал простой скетч для контроллера Arduino, который считывает положение сервомашинок и сохраняет его в EEPROM. Сохранённые значения, затем можно воспроизводить, что позволяет «обучить» манипулятор любым движениям.
Как показывает пример робота Baxter — это может быть очень полезно для новых промышленных роботов. Т.к. позволяет «перепрограммировать» робота любому работнику.
Видео работы:
Скетч на гитхабе:
#include <Servo.h>
#include <EEPROM.h>
// Servo declarations
Servo one;
Servo two;
Servo three;
Servo four;
Servo five;
// Calibration values
int minDegOne, minDegTwo, minDegThree, minDegFour, minDegFive;
int maxDegOne, maxDegTwo, maxDegThree, maxDegFour, maxDegFive;
int minFeedOne, minFeedTwo, minFeedThree, minFeedFour, minFeedFive;
int maxFeedOne, maxFeedTwo, maxFeedThree, maxFeedFour, maxFeedFive;
int posOne, posTwo, posThree, posFour, posFive;
int posOne1, posTwo1, posThree1, posFour1, posFive1;
int addr = 0;
boolean recorded = false;
void setup()
{
Serial.begin(9600);
one.attach(8);
two.attach(9);
three.attach(10);
four.attach(11);
five.attach(12);
pinMode(13, OUTPUT); // LED
pinMode(6, INPUT); // Replay Button
pinMode(7, INPUT); // Train Button
delay(100);
// One center to left
for (int i = 90; i > 29; i--)
{
one.write(i);
delay(10);
}
minDegOne = 30;
minFeedOne = analogRead(1);
delay(500);
// One left to right
for (int i = 30; i < 151; i++)
{
one.write(i);
delay(10);
}
maxDegOne = 150;
maxFeedOne = analogRead(1);
delay(500);
// One right to center
for (int i = 150; i > 89; i--)
{
one.write(i);
delay(10);
}
delay(500);
// Two up to forward
for (int i = 90; i > 29; i--)
{
two.write(i);
delay(10);
}
minDegTwo = 30;
minFeedTwo = analogRead(2);
delay(500);
// Two forward to backward
for (int i = 25; i < 151; i++)
{
two.write(i);
delay(10);
}
maxDegTwo = 150;
maxFeedTwo = analogRead(2);
delay(500);
// Two backward to up
for (int i = 150; i > 89; i--)
{
two.write(i);
delay(10);
}
delay(500);
// Three up to forward
for (int i = 90; i > 30; i--)
{
three.write(i);
delay(10);
}
minDegThree = 30;
minFeedThree = analogRead(3);
delay(500);
// Three forward to backward
for (int i = 30; i < 151; i++)
{
three.write(i);
delay(10);
}
maxDegThree = 150;
maxFeedThree = analogRead(3);
delay(500);
// Three backward to up
for (int i = 150; i > 89; i--)
{
three.write(i);
delay(10);
}
delay(500);
// Four up to forward
for (int i = 90; i > 29; i--)
{
four.write(i);
delay(10);
}
minDegFour = 30;
minFeedFour = analogRead(4);
delay(500);
// Four forward to backward
for (int i = 30; i < 151; i++)
{
four.write(i);
delay(10);
}
maxDegFour = 150;
maxFeedFour = analogRead(4);
delay(500);
// Four backward to up
for (int i = 150; i > 89; i--)
{
four.write(i);
delay(10);
}
delay(500);
// Five up to forward
for (int i = 90; i > 19; i--)
{
five.write(i);
delay(10);
}
minDegFive = 20;
minFeedFive = analogRead(5);
delay(500);
// Five forward to backward
for (int i = 20; i < 181; i++)
{
five.write(i);
delay(10);
}
maxDegFive = 180;
maxFeedFive = analogRead(5);
delay(500);
// Five backward to up
for (int i = 180; i > 89; i--)
{
five.write(i);
delay(10);
}
delay(500);
// Center all servos
one.write(90);
two.write(90);
three.write(90);
four.write(90);
five.write(90);
delay(1000);
// Detach to save power and allow human manipulation
one.detach();
two.detach();
three.detach();
four.detach();
five.detach();
/*
// Display minimums and maximums for analog feedback
// Uncomment for debugging
Serial.print("One Min: ");
Serial.println(minFeedOne);
Serial.print("One Max: ");
Serial.println(maxFeedOne);
Serial.print("Two Min: ");
Serial.println(minFeedTwo);
Serial.print("Two Max: ");
Serial.println(maxFeedTwo);
Serial.print("Three Min: ");
Serial.println(minFeedThree);
Serial.print("Three Max: ");
Serial.println(maxFeedThree);
Serial.print("Four Min: ");
Serial.println(minFeedFour);
Serial.print("Four Max: ");
Serial.println(maxFeedFour);
Serial.print("Five Min: ");
Serial.println(minFeedFive);
Serial.print("Five Max: ");
Serial.println(maxFeedFive);
Serial.println();
*/
}
void loop()
{
delay(100);
if (digitalRead(7))
{
recorded = true;
digitalWrite(13, HIGH);
delay(1000);
while (!digitalRead(7))
{
delay(50);
int posOne = map(analogRead(1), minFeedOne, maxFeedOne, minDegOne, maxDegOne);
EEPROM.write(addr, posOne);
addr++;
int posTwo = map(analogRead(2), minFeedTwo, maxFeedTwo, minDegTwo, maxDegTwo);
EEPROM.write(addr, posTwo);
addr++;
int posThree = map(analogRead(3), minFeedThree, maxFeedThree, minDegThree, maxDegThree);
EEPROM.write(addr, posThree);
addr++;
int posFour = map(analogRead(4), minFeedFour, maxFeedFour, minDegFour, maxDegFour);
EEPROM.write(addr, posFour);
addr++;
int posFive = map(analogRead(5), minFeedFive, maxFeedFive, minDegFive, maxDegFive);
EEPROM.write(addr, posFive);
addr++;
if (addr == 512)
{
EEPROM.write(addr, 255);
break;
}
delay(50);
}
EEPROM.write(addr, 255);
}
if (recorded || digitalRead(6))
{
digitalWrite(13, LOW);
// Power up servos
one.attach(8);
two.attach(9);
three.attach(10);
four.attach(11);
five.attach(12);
delay(1000);
// Center servos
one.write(90);
two.write(90);
three.write(90);
four.write(90);
five.write(90);
delay(1000);
// Start playback
addr = 0;
while (1)
{
posOne = EEPROM.read(addr);
posOne1 = EEPROM.read(addr+5);
addr++;
posTwo = EEPROM.read(addr);
posTwo1 = EEPROM.read(addr+5);
addr++;
posThree = EEPROM.read(addr);
posThree1 = EEPROM.read(addr+5);
addr++;
posFour = EEPROM.read(addr);
posFour1 = EEPROM.read(addr+5);
addr++;
posFive = EEPROM.read(addr);
posFive1 = EEPROM.read(addr+5);
addr++;
/*
// Display positions being written to the servos
// Uncomment for debugging
Serial.print("One: ");
Serial.print(posOne);
Serial.print("\t\t\t");
Serial.println(posOne1);
Serial.print("Two: ");
Serial.print(posTwo);
Serial.print("\t\t");
Serial.println(posTwo1);
Serial.print("Three: ");
Serial.print(posThree);
Serial.print("\t\t");
Serial.println(posThree1);
Serial.print("Four: ");
Serial.print(posFour);
Serial.print("\t\t");
Serial.println(posFour1);
Serial.print("Five: ");
Serial.print(posFive);
Serial.print("\t\t");
Serial.println(posFive1);
Serial.println();
*/
// Check for the end of the recorded commands, if so then break out of the infinite loop
if ((posOne == 255) || (posOne1 == 255) || (posTwo == 255) || (posTwo1 == 255) || (posThree == 255) || (posThree1 == 255) || (posFour == 255) || (posFour1 == 255) || (posFive == 255) || (posFive1 == 255))
{
break;
}
// Step from one recording to the next for each servo
if ((posOne1 - posOne) > 0)
{
for (int i = posOne; i < posOne1; i++)
{
one.write(i);
delay(5);
}
}
else if ((posOne1 - posOne) < 0)
{
for (int i = posOne; i > posOne1; i--)
{
one.write(i);
delay(5);
}
}
if ((posTwo1 - posTwo) > 0)
{
for (int i = posTwo; i < posTwo1; i++)
{
two.write(i);
delay(5);
}
}
else if ((posTwo1 - posTwo) < 0)
{
for (int i = posTwo; i > posTwo1; i--)
{
two.write(i);
delay(5);
}
}
if ((posThree1 - posThree) > 0)
{
for (int i = posThree; i < posThree1; i++)
{
three.write(i);
delay(5);
}
}
else if ((posThree1 - posThree) < 0)
{
for (int i = posThree; i > posThree1; i--)
{
three.write(i);
delay(5);
}
}
if ((posFour1 - posFour) > 0)
{
for (int i = posFour; i < posFour1; i++)
{
four.write(i);
delay(5);
}
}
else if ((posFour1 - posFour) < 0)
{
for (int i = posFour; i > posFour1; i--)
{
four.write(i);
delay(5);
}
}
if ((posFive1 - posFive) > 0)
{
for (int i = posFive; i < posFive1; i++)
{
five.write(i);
delay(5);
}
}
else if ((posFive1 - posFive) < 0)
{
for (int i = posFive; i > posFive1; i--)
{
five.write(i);
delay(5);
}
}
}
recorded = false;
addr = 0;
delay(1000);
// Center all servos
one.write(90);
two.write(90);
three.write(90);
four.write(90);
five.write(90);
delay(500);
// Detach them to save power and allow human manipulation
one.detach();
two.detach();
three.detach();
four.detach();
five.detach();
}
}
Ссылки
Learning Robotic Arm
По теме
Программирование Arduino — библиотека Servo
Самодельный манипулятор под управлением Arduino
InMoov — робо-рука под управлением Arduino
Клешня из ПКЛ
Хаки сервомашинок. Переделка в серву постоянного вращения
