CraftDuino v2.0
  • - это CraftDuino - наш вариант полностью Arduino-совместимой платы.
  • CraftDuino - настоящий конструктор, для очень быстрого прототипирования и реализации идей.
  • Любая возможность автоматизировать что-то с лёгкостью реализуется с CraftDuino!
Просто добавьте CraftDuino!

Экзоскелет для таракана

таракан Мёртвая голова и CraftDuino
В нашей лаборатории, с некоторых пор, живут тараканы. Если конкретнее — тараканы «Мёртвая голова» (Blaberus craniifer) (см. справку про данный вид таракана в конце статьи).

И решил я сделать для них экзоскелет.
Идея экзоскелета состоит в том, чтобы при помощи камеры отслеживать движения таракана и в соответствии с его перемещением — выдавать команды управления на моторы мобильной платформы.

За основу экзоскелета, взял шасси из конструктора Makeblock от робота Элвина.

В дело пошёл контроллер CraftDuino с мотор-шилдом, который был изготовлен из прото-шилда с прикрученным мотор-модулем на базе микросхемы L298.
DC-DC преобразователь с кнопкой включения, который используется для преобразования 12В от литий-ионного аккумулятора в 5В для питания одноплатного компьютера Raspberry Pi.
И разумеется, на роботе закрепил Raspberry Pi с модулем камеры и USB-хабом и Wi-Fi-свистком (для удалённого доступа к компьютеру).

Кроме того, на роботе присутствуют 2 ИК-датчика и 1 ультазвуковой дальномер, но в данный момент они не используются.

Получилась вот такая мобильная платформа и она же — экзоскелет для таракана:
экзоскелет для таракана

На переднюю балку шасси (прямо под камерой), при помощи двухстороннего скотча закрепил пустое ведро от ПКЛ-а.
пустая передняя балка
ведро на передней балке
Это ведро будет рабочим пространством для таракана-водителя.
Чтобы таракан контрастнее выделялся на фоне — на дно ведра вырезал круг из белой бумаги, а чтобы таракан не убежал, края бортов ведра смазал вазелином (почерпнул этот метод у американских исследователей [1]).

Делаем несколько тестовых снимков таракана, чтобы на них подобрать пороги для его детектирования.
таракан-водитель в банке
таракан-водитель в банке
таракан-водитель в банке
таракан-водитель в банке

Напишем простой скрипт на Питоне, который использует открытую библиотеку компьютерного зрения OpenCV и адаптивное пороговое преобразования (cv2.adaptiveThreshold()) для детектирования таракана.
Подберём пороги при помощи ползунков, а для улучшения быстродействия выделем прямоугольник (зелёная рамка на скриншоте), где вообще нужно искать таракана (ROI).

findroach_test.py

def find_roach(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    blockSize = cv2.getTrackbarPos('blockSize', 'roacha')
    C = cv2.getTrackbarPos('C', 'roacha')
    
    if blockSize % 2 == 0:
        blockSize = blockSize+1
    
    print("blockSize: {0} C: {1}".format(blockSize, C))
    bina = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, blockSize, C)
    cv2.imshow('roacha', bina)  


подобрали параметры для детектирования таракана

тестовая картинка для поиска таракана:
тестовая картинка для поиска таракана

Таракана нет:
тестовая картинка где нет таракана

Таракан есть:
тестовая картинка для поиска таракана

Таракан обнаружен:
таракан обнаружен

После порогового преобразования, выполняем поиск контуров (cv2.findContours()) и для найденного контура вычисляем прямоугольник, которым его можно обвести (cv2.boundingRect()).
findroach.py

def find_roach(img):
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    
    blockSize = 109
    C = 53
    
    x1 = 55
    y1 = 16
    x2 = 258
    y2 = 219
    
    print("blockSize: {0} C: {1}".format(blockSize, C))
    bina = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_MEAN_C, cv2.THRESH_BINARY_INV, blockSize, C)
    cv2.imshow('roacha', bina) 
    
    roi = bina[y1:y2, x1:x2]
    cv2.imshow('roach', roi)
    
    roi2 = img[y1:y2, x1:x2]
    
    contours, hierarchy = cv2.findContours(roi, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
    # Choose largest contour
    best = 0
    maxsize = 0
    count = 0
    for cnt in contours:
        if cv2.contourArea(cnt) > maxsize :
            maxsize = cv2.contourArea(cnt)
            best = count
        count = count + 1
    x,y,w,h = cv2.boundingRect(contours[best])
    cv2.rectangle(roi2, (x,y), (x+w,y+h), (0,255,0), 2)
    cv2.circle(roi2, (x+w/2, y+h/2), 2, (0, 255, 0), -1)
    
    cv2.imshow('roi2', roi2) 


Результат — наш таракан найден и обведён рамкой:
обнаружили таракана

Теперь напишем скетч для контроллера CraftDuino, который принимает управляющие команды через последовательный порт и выдаёт соответствующие команды на управление моторами (вперёд-назад, вправо-влево, стоп).
Команды соответствуют стандартным для геймеров клавишам упавления движением: 'w', 's', 'a', 'd' и ' ' — пробел для остановки.

roach_driver.ino

void loop() 
{
    // read message from serial
    int c = 0;
    if(Serial.available()) {
        c = Serial.read();
        if(c == 'w') {
            motor_drive(0, SPEED);
            motor_drive(1, SPEED);
        }
        else if(c == 's') {
            motor_drive(0, -SPEED);
            motor_drive(1, -SPEED);
        }
        else if(c == 'a') {
            motor_drive(0, SPEED);
            motor_drive(1, -SPEED);
        }
        else if(c == 'd') {
            motor_drive(0, -SPEED);
            motor_drive(1, SPEED);
        }
        else if(c == ' ') {
            motor_drive(0, 0);
            motor_drive(1, 0);
        }
    }
}


Т.о., если скетч считает из последовательного порта символ 'w', то на моторы выдаётся команда «вперёд», и так далее.
Осталось адаптировать питоноский скрипт для работы не с картинкой, а с видеокамерой и добавить взаимодействие с CraftDuino через последовательный порт — при помощи модуля serial.

Итоговый скрипт — отслеживает таракана и выдаёт команды в последовательный порт:
roach_follow.py

 prev_x = -1
    prev_y = -1
    
    while True:
        ret, frame = cap.read()
        #cv2.imwrite("frame.png", frame)
        x,y = find_roach(frame)
        print("x: {0} y: {1}".format(x, y))
        if x != -1 and y != -1:
            if prev_x == -1 and prev_y == -1:
                prev_x = x
                prev_y = y
            if abs(prev_x - x) > 2 or abs(prev_y - y) > 2 :
                if x > prev_x :
                    print("left")
                    ser.write("a")
                elif prev_x > x :
                    print("right")
                    ser.write("d")
                if y > prev_y :
                    print("back")
                    ser.write("s")
                elif prev_y > y:
                    print("forward")
                    ser.write("w")
            else:
                print("stop")
                ser.write(" ")
            prev_x = x
            prev_y = y
        
        ch = cv2.waitKey(150)
        if ch == 27:
            break


Для обнаружения в какую сторону двигается наш таракан-водитель, скрипт запоминает — где он был задетектирован на прошлом кадре и, таким образом, определяет в какую сторону он сместился.

В результате, получился такой вот замечательный экзоскелет для таракана:
экзоскелет для тараканаэкзоскелет для тараканаэкзоскелет для таракана

Делать и программировать этакую био-механическую кибер-штуковину было очень забавно.
Ни один таракан при изготовлении и испытании экзоскелета не пострадал.

Через некоторое время таракан, вернее, как оказалась — тараканиха — даже разродилась потомством.
роды у таракана

Вот такой вот счастливый вышел финал.

Ссылки:
проект на гитхабе — roach_driver

Справка о таракане:
Blaberus craniifer
Blaberus craniifer — вид южноамериканского таракана сем. Blaberidae рода Blaberus.
Название «Мёртвая голова» получил из-за рисунка находящегося на переднеспинке, который напоминает череп.
Ареал обитания — тропики Центральной и Южной Америки. Живет в лесной подстилке.
В дневное время суток насекомое скрывается в опавшей листве или около корней деревьев.
Активно избегают света. Питаются, в основном, листовым опадом.
Имеет крылья, которые позволяют таракану планировать.
Условия содержания: температура +28...39 градусов Цельсия, влажность воздуха от 60 до 70%.
В домашних условиях живёт от 1 до 2.5 лет.
В основном, приобретается как декоративное и кормовое насекомое (на корм паукам, ящерицам, хамелеонам, игуанам, змеям и т.п.).
Используются на тараканьих бегах.
Один из самых крупных тараканов: длина взрослой особи составляет 60—75 мм (крупные самки иногда до 80 мм).
Самки отличаются от самцов срастающимися последними сегментами брюшка с нижней стороны (характерный признак семейства).
Живородящи (яйцеживорождение), одна самка приносит до 30 нимф. Оотека инкубируется от 60 до 90 дней (в зависимости от температуры).
Личинка широкая, плоская, 6-7 мм в длину. После рождения, зарываются в субстрат и проводят в нём большую часть времени.
Личинки проходят от 9 до 13 стадий в развитии. Линяют, сидя на вертикальной поверхности. Время превращения нимфы во взрослое насекомое занимает 4-5 месяцев.

Википедия:
Blaberus craniifer
Blaberus


Литература:
1. Brian R Tietz (2012) Models of Cockroach Shelter Seeking Implemented on a Robotic Test Platform (PDF)

По теме:
OpenCV шаг за шагом. Обработка изображения — пороговое преобразование
OpenCV шаг за шагом. Нахождение контуров и операции с ними
RoboCraft на HackDay #34 в Калининграде
Сборка мощного моторшилда (на базе L298)
OpenCV шаг за шагом. Захват видео с камеры
Питание для Raspberry Pi
Подключение Raspberry Pi к Wi-Fi
Подключение модуля камеры к Raspberry Pi
Аквариум на колёсах на базе Arduino и Beagleboard
  • +1
  • 6 мая 2015, 18:34
  • noonv

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

RSS свернуть / развернуть
+
0
А видео есть?
avatar

denisator

  • 9 мая 2015, 16:34
+
+2
В нашей лаборатории, с некоторых пор, живут тараканы. Если конкретнее — тараканы «Мёртвая голова»

Сенсация! По лаборатории RoboCraft разгуливают тараканы-нацисты. Шокирующие эксперименты российских учёных.
avatar

burjui

  • 13 мая 2015, 09:24

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