Эту простую роборыбу, можно повторить самостоятельно — достаточно немного изоляционного материала, нескольких сервомашинок и контроллера Arduino.
Для тела рыбы используются куски полистирола, который применяется в качестве изоляционного материала для стен.
Чтобы рыба плавала более реалистично, её тело разбивается на три сегмента и хвостовой плавник.
Для движения сегментов, используются обычные сервомашинки, которыми очень легко управлять при помощи микроконтроллера.
Таким образом, тело рыбы делится на центральную часть + два сегмента, каждый из которых перемещается с помощью сервомашинки + хвостовой плавник из переработанной пластмассы.
Гибкий плавник позволяет придать ещё больше реализма движению рыбы.
Для получения колебательного движения, сервомашинка крепится своему сегменту, а качалка сервомашинки приклеивается к следующему.
Для распознавания препятствий, можно использовать два инфракрасных датчика, например Sharp GP2Y0D805PCB. Они могут обнаруживать объекты до 5 см и довольно просты в управлении. Если заключить их в пластиковый пакет, то они смогут работать и в воде.
Датчики установлены на носу рыбы, с наклоном 45°, по одному с левой и с правой стороны.
Затем, в носовом сегменте вырезается место для контроллера и аккумуляторов.
Авторы отмечают, что о весе компонентов можно не беспокоиться, например, в представленном прототипе, даже пришлось добавить дополнительные 460 грамм груза, чтобы обеспечить нужную плавучесть.
Электрическая схема
В качестве выключателя, можно использовать магнитный контакт (геркон), т.о. рыбу можно будет включить просто вставив ей в голову магнит (видно на видео).
Скетч
// ROBOFISH
// di Segatello Mirco
#include
Servo Servo1, Servo2, Servo3; // create servo object to control a servo
int i, time, obstacle;
int pos1, pos2, pos3; // posizione del servo RAW
int pos1R, pos2R, pos3R; // posizione del servo
int phase=45; // fase (0°-90°)
int velocity=2000; // velocità (msec for 360°)
int maxDeflexion=20; // gradi massimi di flessione
int maxDefobs=20; // deflessione aggiunta durante un ostacolo
int actualTime;
float shift;
const int center1=98; // posizione centrale
const int center2=90;
const int center3=105;
const int sens_SX=5; // Sensore sinistro
const int sens_DX=6; // Sensore destro
const int lostTime=3000; // tempo ritardo ripartenza da osatcolo (in millesimi)
void setup()
{
Servo1.attach(4); // tronco
Servo2.attach(3); // coda
Servo3.attach(2); // pinna
pinMode(sens_SX, INPUT);
pinMode(sens_DX, INPUT);
pinMode(13, OUTPUT);
time=velocity/360;
shift=0;
/*
// usare questo spezzone di codice per
// tarare la posizione di centro dei servi
Servo1.write(center1);
Servo2.write(center2);
Servo3.write(center3);
delay(10000);
*/
}
void loop()
{
for (i=0; i<360; i++) {
pos1 = i+2*phase;
pos2 = i+phase;
pos3 = i;
if (pos1>359) pos1-=360;
if (pos2>359) pos2-=360;
if (pos3>359) pos3-=360;
if (pos1>179) pos1=360-pos1; // 180° in avanti e 180° indietro
if (pos2>179) pos2=360-pos2; // 180° in avanti e 180° indietro
if (pos3>179) pos3=360-pos3; // 180° in avanti e 180° indietro
// scalo la posizione dei servi
pos1R=map(pos1,0,180,center1-maxDeflexion-obstacle,center1+maxDeflexion-obstacle);
pos2R=map(pos2,0,180,center2-maxDeflexion-obstacle,center2+maxDeflexion-obstacle);
pos3R=map(pos3,0,180,center3-maxDeflexion-obstacle,center3+maxDeflexion-obstacle);
Servo1.write(pos1R); // posizionamento Servo1
Servo2.write(pos2R); // posizionamento Servo2
Servo3.write(pos3R); // posizionamento Servo3
delay(time); // ritardo che definisce il tempo di ciclo
obstacle=int(shift);
if (digitalRead(sens_DX)==0) { // rilevato ostacolo sulla destra
if (obstacle<maxdefobs) shift="shift+0.05;" traslo="" lentamente="" il="" neutro="" dei="" servi="" actualtime="millis();" }="" if="" (digitalread(sens_sx)="=0)" {="" rilevato="" ostacolo="" sulla="" sinistra="" (obstacle=""> (-maxDefobs)) shift=shift-0.05; // traslo lentamente il neutro dei servi
actualTime=millis();
}
// ritorno alla navigazione regolare dopo un certo tempo
if (digitalRead(sens_SX)==1 && digitalRead(sens_SX)==1 && obstacle!=0)
if (millis()>actualTime+lostTime) {
if (shift>0) shift=shift-0.05;
if (shift<0) shift=shift+0.05;
}
}
}
Нетрудно догадаться, что для движения прямо — сегменты рыбы должны совершать колебательные движения, относительно центральной линии (нейтральное положения сервомашинок) — это даёт волнообразное колебание:
А для поворота — сервомашинка головного сегмента смещается в сторону, противоположную препятствию, что приводит к выгибанию рыбы и отклонению в сторону:
Перед тестированием робота в воде, сначала необходимо тщательно проверить каждое механическое и электрическое соединение.
Проверьте целостность полиэтиленового пакета (можно вдохнуть внутрь воздух, чтобы увидеть — есть ли отверстия — их можно заклеить скотчем).
Чтобы пакет был плотно прижат к телу рыбы, можно использовать канцелярские резиновые ленты.
Комментарии (1)
RSS свернуть / развернутьСидишь себе не берегу водоема и тут к тебе такое вот подплывает и молвит человеческим голосом — Мужик! У тебя зарядное есть?
:)
source
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.