[Краудкосилка]-газонокосилка, которой может управлять любой желающий через интернет

У Вас есть минутка? Не могли бы Вы покосить мой газон?

Краткая история разработки на коленке робота-газонокосилки. Управлять ей можно с любой точки земли через интернет. Мечтали почувствовать себя оператором марсохода или лунохода? Всего лишь нужно зайти на сайт mowmylawn.ru и Вы сможете управлять газонокосилкой у меня во дворе!

[Краудкосилка]-газонокосилка, которой может управлять любой желающий через интернет

Предыстория

Вся история с газонокосилками началась летом 2015, мой первый пост на GT как раз был о моем опыте реализации робокосилки из того, что было в гараже.

ТВ

Video Thumbnail

Video Thumbnail

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

Я очень хотел организовать конкурс роботов-газонокосилок. Как оказалось дело это нелегкое. Команд было зарегистрировано более 15, но в итоге только трое участников показали ход работ.

Роман Сакович, Минск (Беларусь), 'Belmower'

Шасси: трехколесный робот. Два ведущих колеса, одно свободное.

Электроника: Две платы. Raspberrry Pi — в качестве управляющей системы верхнего уровня. В ее задачи входит планирование маршрута, построение траекторий, и тд. Nucleo stm32 — в качестве исполнительной системы нижнего уровня. В ее задачи входит навигация, опрос датчиков, управление моторами итд.

Навигация: Система комплексирования данных RTK, одометров и ИНС. Это система собственной разработки.

Датчики: Навигационные приемники GPS/GLONASS. Энкодеры моторов для одометрии. Инерциальная система навигации. Ультразвуковые датчики.

Феофанов И.А., Тверь

К сожалению должен сообщить что наша команда, скорее всего, не сможет принять участие в конкурсе. Дело в том что во время первых полевых испытаний в конструкции нашего робота были выявлены определенные недочеты, на исправление которых уйдет некоторое время. Работу над проектом мы приостанавливать не собираемся, но на фоне грядущей сессии, представить даже минимальную версию робота к намеченному сроку — вряд ли сможем(что уж говорить про использование машинного обучения, которое должно было стать нашем сильным преимуществом).

Николай Миронников, Новосибирск

Все усилия по проведению конкурса в Сколково оказались зря. В конце концов оказалось, что свободных газонов для конкурса по робототехнике в Сколково нет. Все возможные спонсоры не хотят связываться с новым конкурсом с неясными перспективами. На письма в муниципальные организации я даже не получил ответ. В итоге у нас была туманная перспектива организовать конкурс для 4 участников из разных городов. Хотя конкурс получался международный, все-таки целесообразней было его отменить, как это не жаль.

Робокосилка 2016. ROS & FUN

Я осваиваю ROS и пишу лаунчер для робокосилки, использую Kinect и SLAM, только на визуальной одометрии робот строит карту и прокладывает маршрут. Kinect в солнечную погоду работает плохо. С ROS Вы за один вечер сделаете «Hello World!», а дальше тьма. Я так и не нашел нормального руководства для новичка как сделать робота, а не просто писать в топики. Кто-нибудь задумывался, почему на карте сообщества ROS нет ВООБЩЕ ни одной точки в РФ? Я открыл группу ВК.

В свободное время прикрутил к тягам своей «рабочей лошадки» два сервопривода, ультразвуковой сенсор и Arduino. Простой тест объезда березы и остановки пройден! А дальше бездна, эту штуку опасно просто так пускать по своему участку! Ее даже не получится пинать как роботов сами знаете откуда.

Video Thumbnail

Оказывается роботы — вещи достаточно скучные в понимании большинства людей, особенно сервисные роботы. Да, знаю о великой дружбе роботов-пылесосов и котиков. Знаю о супер творениях от Boston Dynamics, Darpa и российском боевом роботе-аватаре, это все больше похоже на роботов, чем коробочка, в которой некий алгорим взаимодействует с реальным миром.

В понимании моей дочки роботы — это как минимум трансформеры, а не та еруда, на которую я трачу время. Я принял тяжелое решение и «временно» сделал из робокосилки игрушку на bluetooth управлении.

Управление работает так же как и у снегоуборщика. Оказалось это весело! Особенно для папы.

Video Thumbnail

Видео со снегоуборщиком

Video Thumbnail

Video Thumbnail

Дальше — больше! Меня заинтересовала идея реализации управления не на bluetooth, а через интернет, с телеметрией. Скучно, пресно и идея избитая!

А что если дать возможность любому пользователю интернета управлять моей газонокосилкой? Знаете такие идеи, которые потом трудно выкинуть из головы? Это как раз была такой…Сhallenge accepted!

Краудкосилка

Железо

В волшебную коробочку аккуратно добавлены Raspberry pi, USB хаб, wifi-адаптер, веб-камера.
Из интересных моментов по железу. У меня не оказалось драйвера с нужными характеристиками для двигателей. Обычно в качестве драйвера используют H-мост на полевых транзисторов или (хардкор) на реле. Я выбираю более жесткий вариант, потому что именно реле были в наличии.

Обычная схема подключения подразумевает 4 ключа на каждый двигатель, т.е. 8 на 2 ходовых двигателя.

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

Кроме самого робота установлена на доме камера, которая с частотой 3 кадра/сек. загружает на ftp-сервер в интернете обзорное фото участка для лучшей ориентации. Но впоследствии просто заменил на решение от ivideon.

Программа

Как и прежде Arduino получает по serial-порту сообщения в один символ, которые обозначают необходимое действие. Так же для тестирования и отладки, полученные от raspberry коды отправляются по bluetooth, можно подключить телефон в режиме терминала и получать данные с сервера еще и на телефон.

Скетч Arduino

int m1=2; int m1b=3; int m2=4; int m2b=5; int mk=6; int pis=7;   char a,b;  void setup()   { Serial.begin(9600); Serial1.begin(9600);   while (!Serial) {     ; // wait for serial port to connect. Needed for Leonardo only   }   while (!Serial1) {     ; // wait for serial port to connect. Needed for Leonardo only   }   Serial.println("Start");   pinMode(statpin, OUTPUT);  pinMode(m1, OUTPUT);  pinMode(m1b, OUTPUT);  pinMode(m2, OUTPUT);  pinMode(m2b, OUTPUT);  pinMode(mk, OUTPUT);  pinMode(pis, OUTPUT);  analogWrite(pis,  1000); delay(100); analogWrite(pis,  700); delay(200); analogWrite(pis,  300); delay(300); analogWrite(pis,  1000); delay(100); analogWrite(pis,  100); digitalWrite(pis,  HIGH);  digitalWrite(statpin, LOW); digitalWrite(m1, LOW); digitalWrite(m1b,  LOW); digitalWrite(m2, LOW); digitalWrite(m2b,  LOW); digitalWrite(mk,  LOW); digitalWrite(pis,  HIGH);  }  void loop() // run over and over {    if (Serial.available()){      a=Serial.read();      Serial1.println(a);      if(a=='B'){ digitalWrite(m1, HIGH); digitalWrite(m1b,  LOW); digitalWrite(m2, HIGH); digitalWrite(m2b,  LOW);     }     if(a=='F'){ digitalWrite(m1, HIGH); digitalWrite(m1b, HIGH); digitalWrite(m2, HIGH); digitalWrite(m2b,  HIGH);     }     if(a=='R'){ digitalWrite(m1, HIGH); digitalWrite(m1b, LOW); digitalWrite(m2, HIGH); digitalWrite(m2b,  HIGH);     }     if(a=='L'){ digitalWrite(m1, HIGH); digitalWrite(m1b, HIGH); digitalWrite(m2, HIGH); digitalWrite(m2b,  LOW);     }         if(a=='S'){ digitalWrite(m1, LOW); digitalWrite(m1b, LOW); digitalWrite(m2, LOW); digitalWrite(m2b,  LOW);     }         if(a=='W'){ digitalWrite(mk, HIGH);     }          if(a=='w'){ digitalWrite(mk, LOW);     }            if(a=='V'){ digitalWrite(pis, LOW);     }          if(a=='v'){ digitalWrite(pis, 700);     }           }else{            }    }  

На raspberry работают два python скрипта. Один из скриптов с помощью opencv захватывает видео с веб-камеры, установленной на ровере и загружает ее по ftp на сервер. Так же, с какой-то долью вероятности, фото вместе с рандомным сообщением из списка загружается в twitter-аккаунт.

Первый скрипт

import numpy as np import sys import pygame import pygame.camera from pygame.locals import * from twython import Twython from random import random import ftplib   pygame.init() pygame.camera.init() cam = pygame.camera.Camera("/dev/video0",(550,400)) cam.start()  CONSUMER_KEY = '-------MBZDT1PwibFeIcSp' CONSUMER_SECRET = '-----------------1ZGHgBRz6aEr4YhUVuO84CuEV' ACCESS_KEY = '-----------------4MCjSkny9Y6rJj5I32ulXctISQF' ACCESS_SECRET = '------------------------cDadRY3He5Kv6CXVuqy2Dh' api = Twython(CONSUMER_KEY,CONSUMER_SECRET,ACCESS_KEY,ACCESS_SECRET) api.verify_credentials()  host = "-.--.---.196" ftp_user = "ftp_user" ftp_password = "ftp_password" con = ftplib.FTP(host, ftp_user, ftp_password) con.cwd("/mowmylawn.ru/webcam")  a={0:'Всем привет! Какой чудесный день!',1:'Опять трудовые будни. Скорее бы выходной!',2:'Верблюд может не пить две недели...А у меня бензин заканчивается',3:'Ну почему опять я должен заниматься газоном?',4:'Улыбаемся, снимает скрытая камера!',5:'Работа не волк, а вот я могу в лес убежать :)) !',6:'Врум, врум...стригу газон!',7:'Не плачь, на Марсе тоже жизни нет.',8:'Эйнштейн был прав: выходные - понятие относительное',9:'Самое сложное — не знать, правильно ли ты сделал...',10:'Меня одну волнует этот вопрос: Когда у меня отпуск?',11:'Начинаю обработку территории',11:'Кто-куда, а я работать',12:'Судьба - это то, что мы получаем в результате наших решений и поступков.',13:'— У тебя не все дома! — Конечно, я же на работе!',14:'Хозяин, батарейки на исходе! Сжалься...:(((!',15:'Хочешь меня сделать? robogazon.ru',16:'Всё возможно, пока не сделан выбор!'}  def twit():     image = cam.get_image()     pygame.image.save(image,'webcam.jpg')     photo = open('webcam.jpg','rb')     b = random() * (len(a)-1)     b = int(round(b,0))     #api.upload_media(media=photo)     #api.update_status(status=a[b])     api.update_status_with_media(media=photo, status=a[b])  def ftpimg():     image = cam.get_image()     pygame.image.save(image,'webcam.jpg')     photo = open('webcam.jpg','rb')     send = con.storbinary("STOR "+ 'webcam.jpg', photo)  while 1 :     ftpimg()     b = random() * (500)     b = int(round(b,0))     if b==107:         twit()  con.close 

Второй скрипт по http получает на сервере текущую команду для действия и отправляет эту команду по serial на arduino.

  • «S» — стоп
  • «F» — вперед
  • «B» — назад
  • «L» — влево
  • «R» — вправо
  • «W» — включить двигатели кошения
  • «w» — выключить двигатели кошения
  • «V» — включить сигнал
  • «v» — выключить сигнал
Второй скрипт

import serial,time import urllib3  http = urllib3.PoolManager()   ser = serial.Serial("/dev/ttyUSB0",9600) ser.writelines("S");  olddata=0 countolddata=0 while 1 :     r = http.request('GET', 'http://mowmylawn.ru/1.php')          if r.data!=olddata:         olddata=r.data         countolddata=0     else:         countolddata+=1          if countolddata>20:         ser.writelines("S")     else:         ser.writelines(r.data)  ser.close() con.close 

Веб-сервис

На bootstrap накидал страничку. На странице два .jpg файла, которые обновляются по мере загрузки. Факторов, влияющих на задержки в управлении и телеметрии много, это и Ваша скорость соединения, и канал на сервере, и канал у меня дома.

Код обновления .jpg

 

Максимальная частота обновления, которую удалось добиться мне:

  • камера на ровере 4 Гц;
  • камера на доме 3 Гц.

База данных Mysql состоит из 2 таблиц, в первой хранится одна пара ключ/значение, это команда для робота. Вторая таблица — users.
Когда Вы встаете в очередь на сайте — отправляется ajax get запрос на добавление пользователя, в базу заносится запись с отметкой timestamp, вашим ip и сгенерированным ключом для управления.

Управлять косилкой одновременно может только один человек (кроме меня) — это пользователь с самым маленьким timestamp. Когда приходит Ваша очередь и Вы начинаете управлять косилкой — в базу заносить timestamp начала управления, каждому отведено на управление 60 сек…

Каждый раз когда Вы наводите на кнопки управления отправляется ajax get запрос с командой и Вашим ключом на управление, при этом проверяется разница между текущим временем и временем, когда Вы начали «игру», если разница больше 60 сек, для Вас игра заканчивается, Ваша запись удаляется из базы и Вы опять можете встать в очередь, «игра» переходит к следующему игроку.

Промо видео

Video Thumbnail
Потом думаю, надо снять на английском…и тут Остапа понесло.

Video Thumbnail

Video Thumbnail

Video Thumbnail

Video Thumbnail

Video Thumbnail

Video Thumbnail

Мой первый пост на reddit. Попробуйте управление mowmylawn.ru. В случае большой очереди или хабраэффекта — прошу понять и простить.

P.S.: На забывайте, что Вы можете принять участие в совместном проекте по разработке фитнес-трекер для ударных видов спорта KickBrick. В команде ждут Вас!


Источник

arduino, DIY, diy или сделай сам, raspberry pi, газонокосилка, робот, робот-газонокосилка

Читайте также