В то время, когда на улице широкой поступью гуляет весна, а наш весенний конкурс КиберВесна 2014, наоборот, что-то притих — возникло желание сделать чего-нибудь эдакое. Чисто Just for Fun :)
Думать долго не пришлось и на свет появился проект биоинспирированнго робота, а именно — робо-рыба.
Идея простая — берём первый попавшийся контроллер Arduino Nano, маленькую сервомашинку типа SG-90 и загружаем тестовый скетч библиотеки Servo — Sweep.
Удивительным образом — сервомашинка машет качалкой из стороны в сторону.
Собственно, это и стало основой из которой за 3 дня, при помощи технологии 3D-печати и «выросла» робо-рыба.
Взяв в руки OpenSCAD, я, первым делом, начертил держатель сервомашинки:
Распечатываем и любуемся:
Теперь, переходим к самому интересному — хвосту нашего робота-рыбы.
К этому важному делу я подошёл обстоятельно :) Залез в поиск яндекса по картинкам и стал вбивать все названия рыб, которые приходили в голову.
Поначалу, мне очень понравился хвост тунца:
Такие хищные обводы хвоста никого бы не оставили равнодушным :)
Загрузив хвост в Gimp и выполнив пороговое преобразование, я получил прекрасный шаблон хвоста:
Далее, нагуглилась технология, позволяющая загружать шаблон в OpenSCAD:
подробнее можно почитать здесь: OpenSCAD Tip: Scan into SCAD
Суть простая: сначала картинку нужно импортировать в Inkscape, там векторизовать, далее упростить, потом привести кривые к последовательности прямых, а потом сохранить в *.dxf -файл, который можно загрузить в OpenSCAD командой:
Хвост получился так себе, поэтому я вспомнил про более привычную рыбу — обычного карася:
И быстренько освоив команду hull() начертил хвост самостоятельно:
Результат (сверху и снизу — хвосты тунца):
Теперь, чтобы прикрепить хвост к сервомашинке, нам нужна этакая качалка:
Печатаем:
Вклеиваем хвост в качалку, которую прикручиваем к родной качалке сервомашинки:
Остаётся нарисовать голову/туловище рыбы. У меня получилась вот такая лопата:
Долго печатаем и получаем:
А если накрыть крышкой:
Вот такой большой робот-карасик получился:
Как я уже говорил, программировать роботов — очень здорово и весело. Согласитесь, что программировать что-нибудь жужжащее и шевелящееся — это, как минимум, очень забавно :)
Вот, какой код у меня получился для робота-рыбы; он позвояет рыбе плыть прямо и периодически пытаться повернуть вправо или влево:
/*
* fish_sweep v 0.2
* роборыба: плаваем прямо и переиодически пытаемся поворачивать
*
* http://robocraft.ru
*/
// отладка
#define MY_DEBUG 1
// задерка по-умолчанию (определяет скорость)
#define DEFAULT_DELAY 10
#include <Servo.h>
// типа класс робота
struct RoboFish
{
// у робота есть серва, которая машет хвостом
Servo tail;
// переменная для хранения положения сервомашинки
int pos;
// положения сервомашинки между которыми нужно "махать хвостом"
int pos_0;
int pos_1;
int speed;
void setup(int servo_pin)
{
pos = 0;
speed = 100;
pos_0 = 1;
pos_1 = 180;
tail.attach(servo_pin);
}
int set_speed(int _speed=0)
{
int res = DEFAULT_DELAY;
if(_speed > 0) {
res = 1000/_speed;
}
return res;
}
void swim(int _speed=0)
{
int del = set_speed(_speed);
// переделываем пример Sweep
for(pos = pos_0; pos < pos_1; pos++) {
tail.write(pos);
delay(del);
}
#if MY_DEBUG
Serial.println("<");
#endif
for(pos = pos_1; pos >= pos_0; pos--) {
tail.write(pos);
delay(del);
}
#if MY_DEBUG
Serial.println(">");
#endif
}
void forward(int _speed=0)
{
#if MY_DEBUG
Serial.println("forward");
#endif
pos_0 = 45;
pos_1 = 125;
swim(_speed);
}
void left(int _speed=0)
{
#if MY_DEBUG
Serial.println("left");
#endif
pos_0 = 20;
pos_1 = 60;
swim(_speed);
}
void right(int _speed=0)
{
#if MY_DEBUG
Serial.println("right");
#endif
pos_0 = 120;
pos_1 = 160;
swim(_speed);
}
};
RoboFish robot; // наш робот
int randnum = 0;
bool leftflag = false;
bool rightflag = false;
void setup()
{
#if MY_DEBUG
Serial.begin(9600);
#endif
robot.setup(9);
robot.speed = 100;
// инициализация ГПСЧ
randomSeed(analogRead(0));
}
void loop()
{
#if 0
// тестирование
robot.left(50);
delay(1000);
robot.forward(100);
delay(1000);
robot.right(50);
delay(1000);
#endif
#if 0
// плаваем только прямо (подбор оптимальных углов)
robot.pos_0 = 55;//65
robot.pos_1 = 115;//105
robot.swim( robot.speed+40 );
#endif
#if 1
// плаваем прямо и периодически пытаемся поворачивать
randnum = random(400);
if(randnum > 380) {
randnum = random(400);
if(randnum > 200 && !rightflag)
{
leftflag=true;
robot.left(robot.speed);
}
else
{
rightflag=true;
robot.right(robot.speed);
}
}
else {
leftflag = false;
rightflag = false;
//robot.forward( robot.speed );
robot.pos_0 = 70;
robot.pos_1 = 100;
robot.swim( robot.speed+100 );
}
#endif
}
Запрограммировав робота-рыбу, его нужно вывесить.
Как помним из школьного курса физики, на погруженное тело в жидкости действует сила Архимеда, которая вычисляется по формуле:
Fa = ro*g*V;
Запустим, например, SciLab и очень приблизительно прикинем силу, действующую на нашего робо-карасика:
Fa = 1000 * 9.8 * (90e-3 * 90e-3 * 28e-3) = 2.2 (H)
Чтобы получить массу в кг, силу нужно, соответственно, разделить на g (ускорение свободного падения), равное 9.8.
Получаем, что для того чтобы получить нейтральную плавучесть нам понадобится около 220 грамм груза.
Разумеется, из этой массы нужно вычесть массу самого робота (корпус+электроника+батарейка).
Но, всё равно, становится приблизительно понятно — сколько свинцовых грузиков придётся покупать в ближайшем рыболовном магазине :)
Следующей задачей является герметизация нашего робота.
Самым простым является дополнительная кожа, которую, например, можно соорудить из обычного целлофанового пакета.
Фото с испытаний робота-рыбы (она же рыба-пакет) в корыте:
Итак, за три дня, наша биоинспирированная робот-рыба научилась плавать :)
Получен опыт работы с OpenSCAD и возникла куча идей и мыслей, которые нужно будет учесть при постройке следующих биоинспирированных роботов.
Комментарии (10)
RSS свернуть / развернутьromanvl
noonv
Если возникнет необходимость можно у вас что-нибудь напечатать?
denisator
denisator
Pimkin_Dima
По коменту автора на хабре к статье про этот принтер что у него такой же ;-)
denisator
noonv
За деньги, конечно же :-)
denisator
noonv
denisator
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.