» » Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон

 

Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон

Автор: admin от 18-04-2019, 11:10, посмотрело: 333

Для уважаемых читателей GeekTimes очередная (четвёртая) долгожданная статья о том, что будет, если снова замешать ардуинку, ESP8266, WI-FI, приправить смартфоном на Android и посыпать сверх JAVA приложением.



Речь у нас пойдет про роботелегу из позапрошлой статьи, которой пришла пора хотя бы немного поумнеть.



Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон



Кому интересно, добро пожаловать под кат.

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



Поэтому сразу же возникла мысль обеспечить будущего Терминатора органами чувств. Один из самых простых вариантов для этого — использование эхолокатора.



Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон



Алгоритм работы до безобразия простой, одним фронтом запускаем датчик и одновременно какой-либо счетчик микроконтроллера. HC-SR04 начинает пулять ультразвуком вдаль. Ответный сигнал от датчика по другому проводу сигнализирует о конце измерения расстояния, а временной интервал между запуском и ответом пропорционален померенной дистанции. Соответственно в этот момент мы тормозим счётчик и смотрим сколько в нём натикало.



Точность получается примерно до сантиметра, а дальность метров до двух. Не любит ворсистые и шерстяные поверхности (к примеру кота), где безвозвратно тонут любые эхо сигналы.



Зона поражения угол обзора у HC-SR04 невелик, поэтому чтобы знать, что происходит впереди в рамках угла хотя бы градусов девяноста желательно сделать следующее:




  • прикрутить датчик к серво-машинке и смотреть им в разные стороны

  • поставить несколько датчиков.



  • Вначале я реализовал первый вариант, поставив эхолокатор на дешевый сервопривод SG90 и тележка превратилась в марсоход. Уж очень много времени требовалось, чтобы провести хотя бы три измерения, поэтому в основном телега стояла, вращая сервой, затем осторожно двигалась вперед, но не очень далеко (а вдруг сбоку появилось препятствие), и снова несколько секунд ощупывала пространство перед собой. Все-таки звук это вам не свет.



    Поэтому, не мудрствуя лукаво, я поставил на неё сразу три эхолокатора. Телега приобрела хтоничный паучий вид, перестала тупить перед препятствиями, и начала обруливать их на ходу. Но мозгов в итоге хватало только на то, чтобы просто не застревать в дружелюбной среде. Надо было двигаться дальше — к автономности и прогрессу. А здесь без разных органов чувств, как скажет вам даже червь нематода, не обойтись.





    Далее, обычно энтузиасты начинают лепить на свои создания разные новые датчики типа гироскопов-акселерометров-магнитометров и даже датчиков ОГНЯ (всё то, что производят в миллионных количествах для Ардуино безымянные китайцы). И я тоже чуть не пустился было по этой скользкой дорожке, но вовремя одумался. А сделал я это вот почему. В самой дальней перспективе, роботележка должна была получить зрение в виде камеры и к тому же разбираться в том, что видит. Но AVR микроконтроллер c платы Ардуино скажет вам «до свиданья» ещё на этапе получения видео, не говоря уже об его обработке. И внезапно мой взгляд упал на немолодой уже и потрёпанный жизнью смартфон GALAXY S7.



    Такая вычислительная мощь, восемь ядер, 4 гига памяти, две камеры, выход в сеть, что еще нужно для превращения обезьяны в человека?



    А всего лишь нужна небольшая конструкция для того, чтобы наш смартфон держался на тележке и чтобы его легко можно было поставить и снять.



    Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон



    Дальше я полез на сайт разработчиков Android, чтобы узнать какими еще возможностями может одарить нас обычный смартфон. Оказалось, что не малыми. Теоретически вы можете





    Как говорится, чего тут только нет! И действительно, в отношении конкретного GALAXY S7 не было много чего. Например, датчика влажности. И окружающей температуры (хотя я и понимал, что находясь внутри корпуса, он будет показывать температуру самого смартфона). Зато сенсоры давления и освещенности присутствовали. Уже не говоря о гироскопах-акселерометрах, пользуя которые, можно легко определить свое положение в пространстве.



    В итоге созрело решение, пусть смартфон получает и обрабатывает всю информацию верхнего уровня — видео и все эти разнообразные датчики. А платформа Arduino будет ответственна, так сказать, за бессознательное — за всё то, что уже работает и не требует переделки, все эти моторчики, эхолокаторы, герконы и прочее.



    Поскольку непосредственно на смартфоне отлаживать работу программы затруднительно, даже с UDB, я решил, что пусть всё это дело пока передается на нормальный персональный компьютер и там обрабатывается. А уж как-нибудь потом, когда будет рабочая версия, вернём мозги обратно на телегу. Надо начинать с малого, да и вообще интересно же посмотреть на передачу видео с бешеной телеги.



    Данные с сенсоров можно переслать простой строкой, через примитивный клиент-сервер, с этим вообще проблем нет. Но вот с передачей видео, сразу же возникли затруднения. Вообще, мне нужна был потоковая трансляция реального времени с камеры смартфона в окошко приложения на компьютере. Это пока. В будущем на эту картинку в окошке мог глазеть бы не только я, но и какая-нибудь система по распознаванию образов. Например JAVA OpenCV. А может даже нейронная сеть из облака :D. Не знаю, до этого этапа ещё очень далеко. Но вот видеть мир «глазом» роботележки мне бы хотелось.



    Всем известны многочисленные приложения типа «мобильной камеры» из магазина Гугла, где вы ловите видеопоток с камеры смартфона, открыв браузер с нужным IP на компьютере. Поэтому я сначала подумал, что самому реализовать трансляцию с моего GALAXY будет несложно (что было неслабым заблуждением), поэтому сначала надо проверить как будет с её приёмом на компьютере, учитывая то, что кое-как писать я умею только на JAVA.



    Как выяснилось, с воспроизведением видео на JAVA, мягко говоря, не очень хорошо. Когда-то очень давно в 1997 выходил так называемый Java Media Framework — библиотека, облегчающая разработку программ, работающих с аудио и видео от самих создателей JAVA. Но, где-то после 2003 на неё положили большой болт и с тех пор прошло уже заметьте 15 лет. После некоторых экспериментов, мне удалось запустить в окошке один файл не помню уже какой (кажется AVI), но выглядело это зрелище изрядно убого. Файлы с другими расширениями, вообще не желали запускаться, в крайнем случае шла одна звуковая дорожка.



    В Интернете я нашел ещё два альтернативных проекта для работы с видео: Xuggler и Сaprica VLCj. Первый проект был привлекателен по своим возможностям, но тоже сдох уже довольно давно, а вот второй оказался вполне живым и интересен по самой своей идее. Ребята взяли и прикрутили к JAVA всем известный популярный медиа плеер VLC. То есть Сaprica не юзает самописные кодеки, а пользуется уже готовыми от профессионалов. С ней у вас проиграется любой файл. Мудрое решение, но главное состоит в том, чтобы у вас на компьютере уже был установлен этот самый VLC плеер. Ну, а у кого его нет? Единственный нюанс, правда, в том, чтобы у вас совпадали разрядности плеера и JAVA. Я к примеру уже потом с удивлением, выяснил, что у меня на компьютере всё еще проживал 32-разрядный VLC, в отличие от 64-разрядной JAVA. И полдня жизни было потеряно зря.



    На своем сайте разработчики от Сaprica сулят пользователям много чего. И все форматы файлов и запуск в нескольких окнах в JAVA приложении, проигрывание видео с You-Tube, захват «живого» видео потока и так далее. Но суровая реальность расставила всё на свои места. Нет, с файлами не обманули — играется всё. Но вот видео с ютуба уже не хочет. Я сначала не мог понять почему, но потом увидел в логе надпись, что как-то, где-то невозможно запустить некий lua-скрипт и тут же припомнил, что:

    This 'screen-scraping' of the YouTube web page is brittle — if YouTube change the structure of their web-pages then VLC will sometimes fail to find the streaming URL, when this happens you have to wait for a developer to provide a new LUA script and wait for a new version of VLC to be released.
    Короче, видимо Ютуб поменял структуру своей web страницы и мне надо ждать нового релиза. С другой стороны, мне же необходимо «живая» видео трансляция, а не проигрывание файла с сайта. То есть, даже, если бы lua-скрипт работал, сильно бы это мне не помогло.



    А вот обещанного стриминга я вообще не нашёл, хотя и было написано что:



    Network streaming server (e.g. a network radio station or a video on demand server);

    Network streaming client;
    Может это хотелки, а может есть в коммерческой версии, трудно сказать.



    Но файлы проигрываются, повторюсь, без каких-либо нареканий. Например, можно творить, вот такое непотребство





    Сама инсталляция пакета не представляет затруднений и даже подробно описана, к примеру, здесь. Правда, я как-то коряво прописал переменные окружений и теперь мой VLC запускается в первый раз с задержкой секунд в десять, но зато потом сохраняет, что надо в кэше и в дальнейшем в текущей сессии запускаетcя уже без пауз.



    Потом в своем JAVA проекте вы прописываете необходимые зависимости и можете начинать клепать медиа проигрыватели в JAVA окошках работать.



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



    Но здесь меня ждало ещё одно довольно большое разочарование. Прошерстив довольно много сайтов и даже онлайн руководство по ANDROID, я обнаружил, что организовать стриминг в режиме реального времени штатными средствами нельзя. Как и в Caprica, можно только читать уже записанные файлы. То есть, камера включилась, MEDIA RECORDER начал запись, когда нужно остановил. А доступ к данным (и их пересылке )мы можем получить только после остановки.



    Подтверждение своим выводам я нашёл в одной древней статье. Там правда были намеки, что когда-то кому-то удавалось обмануть Android, чтобы он думал, что пишет в файл, а на самом деле ему подсовывали буфер. Но в любом случае, как уже было выяснено ранее, я не мог поймать такой видео поток на стороне ПК в JAVA приложение.



    Поэтому было принято простое, дубовое, временное (хочу подчеркнуть) решение — слать видео поток с камеры кусочками по две секунды. Не марсоход, конечно, но луноход уже получается вполне.



    Остановившись на этом решении я принялся осваивать классы CAMERA и MEDIA RECORDER. В сети лежит довольно много примеров кода для запуска камеры и записи видео файлов, но у меня почему-то не работал ни один из них. Ни на эмуляторе, ни на реальном девайсе. Выяснилось, что причина лежит в permissions, то есть в разрешениях. Оказывается, примеры кода писались в те времена, когда Android был ещё свободен и программист, мог делать всё что хотел, если писал все нужные разрешения в манифесте. А вот моя текущая версия OC этого делать не позволяла. Сначала надо было дать пользователю разрешение писать файл и включать камеру непосредственно после запуска приложения. Это обошлось мне в лишнюю активность, то есть в Activity.





    После этого дела пошли на лад и появился следующий рабочий код. Вторая активити класс Camera_Activity отвечает за работу с камерой и запись видео файлов. Класс Http_server за пересылку (название, конечно, неправильное, но так исторически получилось). Код простой, везде где нужно есть пояснения.



    Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон


    Целиком всё валяется на Гитхабе. Ссылка.







    Суть программы после запуска и включения камеры такова:

    пишем видео две секунды в первый файл,

    пишем видео две секунды во второй файл, а тем временем отправляем первый файл по TCP-IP через местный WI-FI на компьютер,

    снова пишем первый файл, и отправляем тем временем второй,

    и так далее.



    Затем цикл повторяется до тех пор, пока не нажмётся кнопка «стоп» или не сдохнет батарея смартфона. В принципе, можно реализовать аналог нажатия кнопок, командами с компьютера, также по TCP, это не сложно.



    Сначала видео буфер, на всякий случай, состоял из трех файлов формата 3GP, (пишем первый отправляем третий, пишем второй, отправляем первый, пишем третий, отправляем второй), но потом оказалось, что и двух файлов вполне хватает (запись и отправка друг друг не мешают).



    При разрешении камеры 640 на 480, файлы получаются, где-то по 200-300 кБ, что для моего роутера вполне по зубам. Со звуком пока заморачиваться не стал, но там вроде всё несложно: устанавливаешь нужные аудио энкодеры, битрейты, количество каналов и тому подобное.



    Немного позже, когда я отладил передачу видео, я дополнил код еще и передачей информации с датчиков смартфона. Передается всё тривиально одной строкой, но вот передать её через тот же сокет, что и видео мне не удалось. Видимо, классы для передачи строки PrintWriter и передачи двоичных данных BufferedOutputStream используют разные потоки, но зато один выходной буфер, где они успешно гадят друг другу. В итоге видео начинает глючить и сыпаться. К тому же видео файл передается раз в две секунды, а для датчиков этот интервал великоват. Поэтому, было решено разнести их в разные сокеты, чтобы они не мешали друг другу. По этой причине появился новый класс Http_server_Sensors.



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



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



    За это отвечает следующая демонстрационная программа.







    Суть её несложна. Запускается TCP клиент, который начинает ожидать готовности сервера на смартфоне. Получив первый файл, тут же начинается его проигрывание и параллельно ожидается файл номер два. Дальше ожидается либо окончание приема второго файла, либо окончание проигрывания первого. Лучше, всего конечно три звездочки, когда файл скачивается быстрее, чем проигрывается. Если же первый файл проиграли, а второй ещё не получили, то всё — ждемс… Демонстрируем черный экран. Если же нет, быстренько запускаем проигрывание второй файл и параллельно снова качаем первый.

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







    В итоге, получаем этакое мерзкое прерывающееся видео (таким, видимо, узрел мир первый трилобит), где ещё постоянно происходит подстройка резкости. И надо учесть, что видео еще и запаздывает на две секунды. Короче, в продакшн такое я выкладывать не рекомендую. А вот у меня на безрыбье и трилобита, как говорится…



    Резюмируя выше сделанное можно совершенно точно сказать, что:



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



    Передача видео по TCP-IP тоже идея неверная, что бы там не говорили некоторые личности на Хабре о скорости передачи данных по этому протоколу (что мол даже быстрее UDP). Конечно, современные беспроводные интрасети имеют неплохие характеристики, чтобы обеспечить непрерывные рукопожатия TCP серверов и клиентов, да и сам TCP вроде как модернизировали для длинных данных, но все равно затыки между проигрыванием видеокусочков, как можно заметить на демо, периодически появляются.



    Но, по крайней мере, на будущее появились следующие мысли:




  • отправлять покадрово (не видео, а фото) через UDP, а управляющую информацию по TCP,

  • гнать фото кадры все подряд через UDP но с синхросигналами в том же канале.



  • Конечно, здесь пока вопросов больше, чем ответов. Хватит ли скорости на приеме у JAVA с её-то уровнем абстракции в работе с сетью и изображениями? Можно ли на доступном мне уровне в Android делать по 30 нормальных съемок в секунду? Надо ли будет их жать перед отправкой, чтобы снизить битрейт? А тогда хватит ли быстродействия JAVA на упаковку и распаковку? И если, вдруг, что-то получится, то удастся ли пройти следующий шаг, прикрутить сюда систему компьютерного зрения JAVA OpenCV? Самому, конечно, потоковое видео с уровня пола всегда интересно посмотреть, но мы же не должны забывать о высшей цели — роботележке с интеллектом муравья!



    Но, пока имея, то что имеем, вернёмся к текущей телеге. Старая программа из позапрошлой статьи для AVR микроконтроллера на Ардуино платформе почти не изменилась, добавился только выбор по ветвлению — автономная езда или под управлением оператора. Данные, которые тележка (спинной мозг) передает по WI-FI те же — пройденный путь. Чуть позже я приделал еще и передачу температуры критичного элемента — драйвера моторов. Всё это передается и принимается сначала по UART, а уже при выходе в сеть по UDP. Кода не привожу, весь полный разбор в позапрошлой статье.



    Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон


    На два моторчика его (драйвера) ещё хватает более-менее, но с четырьмя через некоторое время он перегревается до неработоспособного состояния. Вначале я пытался использовать простейшие аналоговые температурные датчики на основе стабилитронов, типа LM335, но из этого ничего не вышло. Источника опорного напряжения, сокращенно ИОНа у меня на плате-то не было. А ловить милливольты на садящейся батарее смысла нет. Кстати, о батарее — когда мне надоело постоянно вынимать и вставлять для перезарядки литиевые-аккумуляторы формата 14500, я просто взял запасной аккумулятор от шуруповерта и телега начала ездить непрерывно полтора часа, плюс еще приобрела угрожающий вид и массу (да именно на этой батарее сидят её «глазки»). Посему для измерения температуры я приладил неисправный гироскоп-акселерометр на базе L3G4200D. Температуру он, к счастью, ещё мерил и передавал по шине I2C.



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



    В итоге, приложение на JAVA приобрело такой вид:



    Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон


    Самое смешное, что оно реально похоже на панель управления советским луноходом, только у меня телеэкран сбоку, а у них в центре.



    Эволюция или делаем базу для роботележки на ARDUINO платформе, а сенсоры и видео гоним на компьютер через смартфон


    При включении, сначала соединяемся с телегой и смартфоном на ней, выбираем режим ручного управления или полной автономии — и вперёд! До тех пор, пока окошко температуры драйвера не пожелтеет, а затем не станет красным. Графика!



    Примерно так это выглядит вживую.





    Программу здесь не привожу, поскольку как обычно, построение окошек занимает 95% кода. Её можно найти здесь.



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



    Если хоть-что то получится, обязательно выложу. Спасибо за внимание.

    Источник: Хабр / Интересные публикации

    Категория: Программирование, Android

    Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
    Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

    Добавление комментария

    Имя:*
    E-Mail:
    Комментарий:
    Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
    Введите два слова, показанных на изображении: *