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


Добавить комментарий

Arduino

Что такое Arduino?
Зачем мне Arduino?
Начало работы с Arduino
Для начинающих ардуинщиков
Радиодетали (точка входа для начинающих ардуинщиков)
Первые шаги с Arduino

Разделы

  1. Преимуществ нет, за исключением читабельности: тип bool обычно имеет размер 1 байт, как и uint8_t. Думаю, компилятор в обоих случаях…

  2. Добрый день! Я недавно начал изучать программирование под STM32 и ваши уроки просто бесценны! Хотел узнать зачем использовать переменную типа…

3D-печать AI Android Arduino Bluetooth CraftDuino DIY IDE iRobot Kinect LEGO OpenCV Open Source Python Raspberry Pi RoboCraft ROS swarm ИК автоматизация андроид балансировать бионика версия видео военный датчик дрон интерфейс камера кибервесна конкурс манипулятор машинное обучение наше нейронная сеть подводный пылесос работа распознавание робот робототехника светодиод сервомашинка собака управление ходить шаг за шагом шаговый двигатель шилд

OpenCV
Робототехника
Будущее за бионическими роботами?
Нейронная сеть - введение