mOLOID - необычный робот-питомец на Arduino


Jan Ingo Haller и Lorin Samija в рамках семинара по вычислительному дизайну и цифровому производству в магистерской программе «Интеграционные технологии и исследования архитектурного дизайна» (ITECH) в Штутгартском университете создали необычного робота-питомца, которого назвали mOLOID.

mOLOID (moving OLOID) — двигается очень необычным образом. Когда внутреннее устройство робота спрятано под тканевым покрытием, то кажется, что робот сам собой перекатывается, словно какое-то непонятное существо.

В основе этого необычного робота-питомца лежит оригинальный геометрический объект — олоид.
Олоид — трёхмерный криволинейный геометрический объект, открытый Paul Schatz в 1929 году. Это выпуклая оболочка каркаса, сделанного из двух соединённых конгруэнтных окружностей в перпендикулярных плоскостях, так что центр каждой окружности лежит на другой окружности. Расстояние между центрами окружностей равно радиусу окружностей. Одна треть периметра каждого круга лежит внутри выпуклой оболочки, поэтому одна и та же форма может быть также сформирована как выпуклая оболочка двух оставшихся круглых дуг, каждая из которых охватывает угол 4π/3.



Подобная структура, состоящая из двух окружностей, расположенных под углом 90° к друг-другу, приходит в движение при помощи двух сервомашинок, которые перемещают грузы по периметру каждого круга, что изменяет центр тяжести робота и заставляет его катиться вперёд или назад.

Мозг робота — контроллер Arduino Uno, к которому подключены не только сервомашинки, но и инфракрасный датчик движения HC-SR501 (позволяет роботу реагировать на окружающую среду), Bluetooth-модуль HC-05 (через него осуществляется управление роботом через SerialPortPorfile (SPP)) и небольшой динамик (обеспечивает звуковую обратную связь).

Код скетча — 200713_mOLOID.ino

///Libraries

#include <SoftwareSerial.h>
#include <Servo.h>
#include <pitches.h>

////

/// Custom Functions

//Smooth servo movement
void MoveCts(Servo serv, int aim, int delayTime){
    int stepSize = 1;
    //int delayT = 20;
    int delayT = delayTime;
    int current = serv.read();
    int diff = aim - current;
    if (diff < 0) diff = -1*diff;
    int steps = diff/stepSize;
    
    if(aim > current){
        for(int i = 1; i < steps + 1; i++){
            serv.write(current + i * stepSize);
            delay(delayT); 
        }
    }
    else if (aim < current){
        for(int i = 1; i < steps + 1; i++){
            serv.write(current - i * stepSize);
            delay(delayT); 
        }
    }
}

//Making the OLOID move, i.e. into an mOLOID
void  Move(bool dir, int velocity, Servo serv1, Servo serv2){
    int vel = 0;
    vel = velocity;
    if (dir == 0){
        
        
        MoveCts(serv1,0, vel);
        delay(vel);
        
        MoveCts(serv2,90, vel);
        
        MoveCts(serv2,180, vel);
        delay(vel);
        
        MoveCts(serv1,90, vel);
        
        MoveCts(serv1,180, vel);
        delay(vel);
        
        MoveCts(serv2,90, vel);
        
        MoveCts(serv2,0, vel);
        delay(vel);
        
        MoveCts(serv1,90, vel);
        delay(vel);
    }
    
    else {
        MoveCts(serv1,180, vel);
        delay(vel);
        
        MoveCts(serv2,90, vel);
        
        MoveCts(serv2,180, vel);
        delay(vel);
        
        MoveCts(serv1,90, vel);
        
        MoveCts(serv1,0, vel);
        delay(vel);
        
        MoveCts(serv2,90, vel);
        
        
        MoveCts(serv2,0, vel);
        delay(vel);
        
        MoveCts(serv1,90, vel);
        delay(vel);

    }
}

////

///Variables


#define rxPin 11 ///blue
#define txPin 12 ///green
#define buzz 7 //buzzer
#define sens 13 //sensor


bool power = 0;
bool dir = 0;
int motState = LOW;
int sensVal = 0;
Servo serv1;
Servo serv2;
int delayT = 10;


SoftwareSerial btSerial(rxPin, txPin);
String btData;

// Sound Setup
int melody1[] = {
    NOTE_G7, NOTE_G7, NOTE_AS7, NOTE_G7
}; //switch on

int melody2[] = {
    NOTE_AS7, NOTE_AS7, NOTE_G7, NOTE_AS7
}; //sensor triggered movement

int melody0[] = {
    NOTE_AS7, NOTE_AS7, NOTE_G7
}; //switch off

int durations1[] = {
    4,4,8,8
};

int durations2[] = {
    4,4,8,8
};

int durations0[] = {
    4,4,4
};

int songLength1 = sizeof(melody1)/sizeof(melody1[0]);

int songLength2 = sizeof(melody2)/sizeof(melody2[0]);

int songLength0 = sizeof(melody0)/sizeof(melody0[0]);

////

///Setup

void setup() {
    serv1.attach(6);
    serv2.attach(8);
    
    pinMode(buzz, OUTPUT);
    pinMode(sens, INPUT);
    btSerial.begin(9600);
    btSerial.println("bluetooth available");
    
}

////

///Loop

void loop() {
    if (btSerial.available()) {
        btData = btSerial.readString();
        if(btData == "off") {
            power = 0;
            
            for (int thisNote = 0; thisNote < songLength0; thisNote++){
                int duration = 3000/ durations0[thisNote];
                tone(buzz, melody0[thisNote], duration);
                // pause between notes
                int pause = duration * 0.3;
                delay(pause);
                // stop the tone
                noTone(buzz);
            }
            
            MoveCts(serv1, 90, delayT);
            MoveCts(serv2, 0, delayT);
            btSerial.println("Device is off.");
            
            //serv1.write(90);
            //serv2.write(0);
        }
        else if (btData == "on") {
            power = 1;
            
            for (int thisNote = 0; thisNote < songLength1; thisNote++){
                int duration = 3000/ durations1[thisNote];
                tone(buzz, melody1[thisNote], duration);
                // pause between notes
                int pause = duration * 0.3;
                delay(pause);
                // stop the tone
                noTone(buzz);
            }
            
            MoveCts(serv1, 90, delayT);
            MoveCts(serv2, 0, delayT);
            btSerial.println("Device is on.");
            
            //serv1.write(90);
            //serv2.write(0);
        }
        
        else {
            int btNumb = btData.toInt();
            if (btNumb == 0) btNumb = 10;
            
            if (btNumb < 0) {
                dir = 1;
                delayT = -btNumb;
                
            }
            else {
                delayT = btNumb;
                dir = 0;
            }
            
            //btSerial.println("Input unknown. Only on/off.");
        }
    }
    if (power){
        sensVal = digitalRead(sens);
        
        if (sensVal == HIGH){
            if (motState == LOW){
                btSerial.println("Motion detected!");
                motState = HIGH;
                
                for (int thisNote = 0; thisNote < songLength2; thisNote++){
                    int duration = 3000/ durations2[thisNote];
                    tone(buzz, melody2[thisNote], duration);
                    // pause between notes
                    int pause = duration * 0.3;
                    delay(pause);
                    // stop the tone
                    noTone(buzz);
                }
                for(int i = 0; i < 3; i++){
                    Move(dir, delayT, serv1, serv2);
                }
            }
        }
        
        else{
            
            MoveCts(serv1, 90, delayT);
            MoveCts(serv2, 0, delayT);
            //serv1.write(90);
            //serv2.write(0);
            if (motState == HIGH){
                btSerial.println("Motion ended!");
                motState = LOW;
            }
        }
    }
    
    
}

////


Ссылки
The Moving OLOID — a Different Pet in Different Times

По теме
Sneaky — интерактивный змееподобный робот
MORPH — робот гуляющий по парку
Робот-червяк на базе Arduino
Halfbug — ползающий робот на Arduino
  • 0
  • 6 августа 2020, 13:16
  • admin

Комментарии (0)

RSS свернуть / развернуть

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.