МАРСОХОД

Open Source Hardware Project

Проекты Altera Quartus II для платы Марсоход

Управлять Марсоходом из браузера

Машинка под управлением телефона с ОС Android

В моих недавних экпериментах (здесь начало, еще тут и тут) я зажигал светодиоды платы Марсоход по команде из телефона c ОС Android. Плата соединялась через аудио разъем телефона и определяла звуковой тон, играемый на телефоне, который и служил командой. На телефоне запускалась простая управляющая программа в виде скрипта на Python (SL4A). Теперь я хочу поместить плату Марсоход и телефон на гусенечное шасси, и удаленно включать и выключать коллекторные моторчики и, таким образом, управлять машинкой через WiFi. Более того, было бы интересно удаленно получить изображение с камеры телефона и сделать полное управление машинкой из браузера.

Итак, вот еще пара фотографий машинки:

Шасси машинки для управления через WiFi

Вот фронтальный вид:

Машинка управляемая через WiFi и с помощью платы Марсоход

Дальше нужно сделать проект для ПЛИС Альтера платы Марсоход. Проект должен определать частоту подаваемого аудио сигнала и интерпретировать эти сигналы как команды. Собственно такой проект у меня уже есть готовый (там же и детальное описание куда и как подавать аудио сигнал на ПЛИС). Только в том проекте просто зажигались светодиоды. Сейчас нужно еще добавить управление моторчиками. Собственно это я и сделал. По схеме плата Марсоход имеет шесть мощных контактов F0, F1, F2, F3, F4, F5 как раз для прямого подключения игрушечных моторчиков - на каждом таком контакте по 10 параллельных выходов ПЛИС (тока моторчикам хватит). Один моторчик подключается к двум контактам, например F0 и F1. Если на F0 единица, а на F1 ноль то вращается в одну сторону. Если на F1 единица, а на F0 ноль, то вращается в другую сторону. Оба контакта в нуле - стоит. Вся логика описана в проекте на Verilog HDL с помощью конструкции case-encase. Ничего сложного там нет.

Весь проект для среды Altera Quartus II можно взять здесь:

После того, как проект будет откомпилирован в Altera Quartus II и прошит в плату можно собирать всю машинку.

Дальше самое  сложное для меня - написание скрипта для Python для телефона. Опыта у меня не очень много, но читая описания и примеры на сайте SL4A (Script Layer For Android) мне удалось сделать задуманное.

Скрипт на питоне, работающий на телефоне, делает следующее:

  • Реализует WebServer, работающий на телефоне с Android (собственно это я уже делал здесь). TCP порт 9090.
  • WebServer отдает три разных HTML страницы (их текст закодирован прямо в теле скрипта Python). Первая главная html страница описывает 2 фрейма, которые делят экран браузера на 2 окна, две другие html страницы - собственно для двух html фреймов.
  • В верхнем фрейме будет окно трансляции с камеры телефона.
  • В нижнем фрейме будет форма с кнопками вроде "start", "stop", "left", "right". По нажатию на кнопки html формы нижнего фрейма будет отсылаться HTTP-GET запрос на телефон.
  • WebServer принимает и обрабатывает HTTP-GET запросы и согласно запросу воспроизводит короткий звуковой ролик с синусоидой нужной тональности. Плата Марсоход распознает частоту звука и интерпретирует ее как команду ехать, повернуть влево или вправо, остановиться и т.д.
  • Еще важная функция скрипта - инициировать вещание с камеры телефона. Вещание ведется на TCP порту 9091.
  • Деление окна браузера на два фрейма нужно, чтобы вещание не прекращалось пока идет HTTP-GET запрос на управление машинкой. Фреймы независимы друг от друга.

Собственно тект скрипта вот такой:


"""HTTP server"""

import android
import BaseHTTPServer
import socket
import urlparse

HOST_NAME   = ''
PORT_NUMBER = 9090

droid = android.Android()

PAGE_TEMPLATE = '''
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>DroidBot Remote Control</title>
</head>
<FRAMESET ROWS="50%,50%">
<FRAME SRC="frame_a.html">
<FRAME SRC="frame_b.html">
</FRAMESET>
</html>
'''

PAGE_TEMPLATE_A = '''
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>DroidBot Remote Control</title>
</head>
<body>
<h1>Marsohod Remote Control</h1>
<iframe width="640" height="480" src ="http://%s:9091">No iframes?</iframe>"
</body>
</html>
'''


PAGE_TEMPLATE_B = '''
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>DroidBot Remote Control</title>
<style type="text/css">
#action {
background:yellow;
border:0px solid #555;
color:#555;
width:0px;
height:0px;
padding:0px;
}
</style>
<script>
function AddText(text)
{
document.myform.action.value=text;
}
</script>
</head>
<body>
<form name="myform" method="get">
<textarea id="action" name="action">start</textarea>
<input id="button1" type="submit" value="Start" OnClick='javascript:AddText ("start")' />
<input id="button2" type="submit" value="Stop"  OnClick='javascript:AddText ("stop")'  />
<input id="button3" type="submit" value="Back"  OnClick='javascript:AddText ("back")'  />
<input id="button4" type="submit" value="Left"  OnClick='javascript:AddText ("left")'  />
<input id="button5" type="submit" value="Right" OnClick='javascript:AddText ("right")' />
</form>
</body>
</html>
'''


def play( id ):
 if   (id=='start'):
  droid.mediaPlay('/mnt/sdcard/media/audio/s1000.wav')
 elif (id=='back'):
  droid.mediaPlay('/mnt/sdcard/media/audio/s1200.wav')
 elif (id=='left'):
  droid.mediaPlay('/mnt/sdcard/media/audio/s1400.wav')
 elif (id=='right'):
  droid.mediaPlay('/mnt/sdcard/media/audio/s1600.wav')
 elif (id=='stop'):
  droid.mediaPlay('/mnt/sdcard/media/audio/s1800.wav')

class DroidHandler(BaseHTTPServer.BaseHTTPRequestHandler):


 def do_HEAD(s):

  s.send_response(200)
  s.send_header("Content-type", "text/html; charset=utf-8")
  s.end_headers()

 def do_GET(s):
  s.send_response(200)

  my_full_addr = s.headers.get('Host')

  my_addr = my_full_addr.split(":",2)
  my_ip_addr = my_addr[0]

  url = urlparse.urlsplit(s.path)

  print url.path
  if url.path == '/frame_a.html':
   s.send_header("Content-type", "text/html; charset=utf-8")
   s.end_headers()
   html = PAGE_TEMPLATE_A % my_ip_addr
   s.wfile.write(html)
   return
  elif url.path == '/frame_b.html':
   s.send_header("Content-type", "text/html; charset=utf-8")
   s.end_headers()

   query = url.query

   args = urlparse.parse_qsl(query)

   action = ''

   for arg in args:
    if arg[0] == 'action':
     action = arg[1].strip().replace('\r', '')
     print(action)
     play(action)
     break

   html = PAGE_TEMPLATE_B
   s.wfile.write(html)
   return

   s.send_header("Content-type", "text/html; charset=utf-8")
   s.end_headers()

   html = PAGE_TEMPLATE
   s.wfile.write(html)

print 'web server running on port %s' % PORT_NUMBER
droid.wakeLockAcquireBright()
droid.webcamStart(0,10,9091)
droid.webcamAdjustQuality(0,10)
my_srv = BaseHTTPServer.HTTPServer((HOST_NAME, PORT_NUMBER), DroidHandler)
my_srv.serve_forever()


Вот этот скрипт нужно перенести на телефон и запускать из программы SL4A.

Не забудьте перед запуском скрипта посмотреть текущий IP адрес телефона. У меня дома WiFi точка и телефон похоже всегда берет один адрес 192.168.1.200. У вас конечно может быть другой.

Еще фишка - почему-то Firefox не хочет нормально смотреть трансляцию с телефона. А вот с Google Chrome все нормально. Трансляция видео не очень живая, но я думаю это из-за того, что мой телефон довольно слаб. Нужно попробовать что-то помегагерцнее...

В строке браузера набираете адрес телефона и номер порта 9090 через двоеточие: вот снимок экрана

Вид с камеры машинки Марсоход

Ну и наконец демонстрация работы, фото и видео:

car_ctrl2

Вот еще фотка:

car_ctrl1

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

В помещении видно чуть получше:

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

 

 

Комментарии  

-3 #8 mr.serg.1998 24.07.2015 10:02
Хм... управление звуковым сигналом это конешно круто, но вот raspberry pi намного практичней будет, т.к. там полноценный линукс, а следовательно и питон плюс к этому там 40 портов GPIO, и плат расширения, которые позволяют управдять шаговоми моторами очень много. И ещё raspberry pi имеет полную совместимость с ardruino.
+2 #7 Алексей 20.04.2013 14:27
Чтобы отображалось видео необходим потоковый сервер. В sl4a очень много ограничений по Python и webCamStart. Во первых min level api 8. https://code.google.com/p/android-scripting/wiki/ApiReference#webcamStart То есть Android 2.2 , ну и другие ограничения. Проще всего скачать программу под Android которая является нормальным сервером висит на каком либо порту и отдает изображение нам на страницу. Таких программ множество например IP Webcam.
Идея о связи между марсоходом и андроидом посредством звуковыx частот классная. Главное что работает.
0 #6 Егорати 09.01.2013 10:06
скоро выйдет в продажу проект virt2real.ru (плата управления+WIFI + камера + все необходимое ПО)..у моих многих знакомых(и судя по коментариям не только у моих) не заработал скрипт на питоне, предложенный вами, у тех у кого заработал жуткие тормоза.. думаю если бы был готовое приложение .APK, марсоход бы составил конкуренцию этому проекту.. а так сыро, господа...
0 #5 Никита 07.08.2012 02:30
Цитирую Denis:
Цитирую Никита:
При запуске скрипта на Python выдает ошибки
java.lang.RuntimeException: setParameters failed
java.lang.IllegalStateException: Webcam not streaming
Телефон Sony Ericsson Xperia Active
Android 2.3.4


У меня такая же ошибка.
Телефон: GT-S5360
Android: 2.3.5




нашел способ решить проблему, напиши мне на ящик nik_romanoff@mail.ru
0 #4 Denis 04.08.2012 20:33
Цитирую Никита:
При запуске скрипта на Python выдает ошибки
java.lang.RuntimeException: setParameters failed
java.lang.IllegalStateException: Webcam not streaming
Телефон Sony Ericsson Xperia Active
Android 2.3.4


У меня такая же ошибка.
Телефон: GT-S5360
Android: 2.3.5
+1 #3 Никита 24.07.2012 15:49
При запуске скрипта на Python выдает ошибки
java.lang.RuntimeException: setParameters failed
java.lang.IllegalStateException: Webcam not streaming
Телефон Sony Ericsson Xperia Active
Android 2.3.4
0 #2 nckma 29.06.2012 05:57
Цитирую Сергей:
Скрипт на телефоне запускается.. через браузер на вебСервер тоже могу зайти...в браузере все отображается(названия, кнопочки)... кроме видео...во фрейме где должно появится видео пишется - "Веб страница не доступна"...

какой телефон? какой браузер?
0 #1 Сергей 26.06.2012 16:24
Скрипт на телефоне запускается.. через браузер на вебСервер тоже могу зайти...в браузере все отображается(на звания, кнопочки)... кроме видео...во фрейме где должно появится видео пишется - "Веб страница не доступна"...

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


Защитный код
Обновить


GitHub YouTube Twitter
Вы здесь: Начало Проекты Проект Марсоход Управлять Марсоходом из браузера