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

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

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

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

Предыстория

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

ТВ

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Дальше — больше! Меня заинтересовала идея реализации управления не на 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 сек, для Вас игра заканчивается, Ваша запись удаляется из базы и Вы опять можете встать в очередь, «игра» переходит к следующему игроку.

Промо видео

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

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

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


Источник

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

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