Сергей Коба

Сергей Коба

Веб, блокчейн, мобильная разработка и интернет вещей

Веб тимлид в MobiDev. Цель: изучать и учить чему-то новому без остановки. Основные языки: PHP и Ruby. Также интересно: блокчейн, мобильная разработка, IoT и DevOps. Жизненное кредо: я жив, пока я учу что-то новое.

Строим WiFi робота c камерой (Часть 3 - Веб сервер)

10 июля 2017 18:00

На данный момент Плуто уже умеет принимать команды и, выполняя их, ездить вперед-назад, влево-вправо. Пока он делает это не очень далеко (насколько позволяет длинна usb кабеля, подсоединенного к компьютеру). Настала пора подарить Плуто свободу и подсоединить к нему Raspberry Pi с WiFi модулем и веб-сервером на Python.

Картинка выше прдставляет собой принципиальную схему работы робота. Идея заключается в том, что браузер обрабатывает действия пользователя и посылает AJAX запросы к веб серверу Flask, установленному на Raspberry Pi. Тот в свою очередь пересылает по SerialPort эти команды Arduino.

Я использовал новенький Raspberry Pi 3, начать советую с установки операцинной системы Raspbian на флеш карту (детально про этот процесс можно почитать тут - "Установка операционной системы Raspbian на Raspberry Pi", второй вариант). Сразу предупреждаю, что вам понадобится монитор с HDMI выходом, USB клавиатура и мышка. В дальнейшем мы будем подключаться к Raspberry по ssh и vnc. Таким образом, для работы будет достаточно просто подать питание на Raspberry, а вся работа с ним будет происходить с Вашего ПК.

После успешной установки ОС на Raspberry Pi подключаемся к WiFi сети и в системных настройках включаем следующие интерфейсы: Camera, SSH и VNC. 

Перегружаем Raspberry Pi. Чтобы избавится от лишних монитора, мышки и клавиатуры и удаленно подключатся к Raspberry Pi необходимо узнать его IP адрес, для этого выполните в терминале команду 

ifconfig

IP адрес будет находится в секции wlan0. Относим монитор, мышку и клавиатуру в кладовку. Включаем Ваш рабочий ПК и набираем в терминале команду для подключения по ssh

ssh pi@192.168.20.10

IP адрес Вашего Raspberry Pi естественно должен отличаться от "192.168.20.10". Пароль по-умолчанию для пользователя pi "raspberry". Далее запускаем VNC сервер

vncserver

Теперь установим и запустим VNC Viewer на нашем рабочем ПК скачав его отсюда. Запускайте VNC Viewer и подключайтесь к VNC серверу Raspberry Pi по адресу, который вернула команда "vncserver". Пользователь - "pi", пароль - "raspberry". После успешного соединения Вы должны увидеть рабочий стол Вашего Raspberry PI

Для простоты я решил организовать взаимодействие Arduino и Raspberry Pi через Serial Port, заодно и обеспечить питание для Arduino. 

Чтобы протестировать коммуникацию двух плат напишем простой скрипт на Python. Создайте файл test.py в любом месте Вашего Raspberry Pi со следующим содержанием

import serial
import time
ser = serial.Serial('/dev/ttyUSB0', 9600)
time.sleep(5)
print('Go Forward')
ser.write('1,0,80,80')
time.sleep(5)
print('Go backward')
ser.write('1,1,80,80')
time.sleep(5)
print('Stop')
ser.write('0')

Запустите скрипт следующим образом

python test.py

Робот должен 5 секунд покрутить колеса вперед, 5с - назад и остановиться.

Итак, наш proof-of-concept рабоатет (я надеюсь у Вас тоже). Приступим к разработке веб-приложения на фреймворке Flask (краткий туториал). Для начала создадим главный файл приложения app.py

from flask import Flask, render_template, request, Response
import serial, time
app = Flask(__name__)
state_msg = 'Hello, Telerobot is ready to operate, have fun!'
try:
ser = serial.Serial('/dev/ttyUSB0', 9600)
except serial.serialutil.SerialException:
state_msg = 'Telerobot is disconnected (please connect Arduino to Raspberry Pi)'
@app.route('/')
def index():
return render_template('index.html', state_msg=state_msg)
@app.route('/move/<direction>')
def move(direction):
if direction == 'forward':
ser.write('1,0')
if direction == 'backward':
ser.write('1,1')
if direction == 'left':
ser.write('1,3')
if direction == 'right':
ser.write('1,2')
return '{}'
@app.route('/set_speed/<speed>')
def set_speed(speed):
ser.write('2,' + speed)
return '{}'
@app.route('/stop')
def stop():
ser.write('0')
return '{}'
if __name__ == '__main__':
app.run(debug=True, host='0.0.0.0')

Говоря простыми словами, данный веб-сервер получает запросы по адресам, указанным с помощью метода @app.route и обрабатывает их с помощью методов ниже. Например, запрос http://your_robot_ip:5000/move/forward вызовет метод сервера move(direction), который пошлем Arduino команду '1,0' через Serial порт.

Панель управления роботом будет доступна по коренвому адресу http://your_robot_ip:5000/, который обрабатывается методом index. Данный метод, читает файл index.html из папки templates/ и возвращает его содержимое клиенту (браузеру). Разработкой страницы index.html мы и займемся дальше. Примерный код страницы может выглядеть так:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Pluto the Robot</title>
<script src="https://code.jquery.com/jquery-3.1.1.min.js" integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8=" crossorigin="anonymous"></script>
</head>
<body>
<h1>{{ state_msg }}</h1>
Set speed:<br /><br />
<input type="range" max="150" value="100" step="10" min="100" id="set-speed"> <br />
<button type="button" class="btn btn-default" id="move-left"> < </button>
<button type="button" class="btn btn-default" id="move-forward"> ^ </button>
<button type="button" class="btn btn-default" id="move-backward"> v </button>
<button type="button" class="btn btn-default" id="move-right"> > </button>
<button type="button" class="btn btn-danger" id="stop">Stop</button>
<script>
$('#stop').on('click', function(){
$.get('/stop');
});
$('#move-forward').on('click', function(){
$.get('/move/forward');
});
$('#move-backward').on('click', function(){
$.get('/move/backward');
});
$('#move-left').on('click', function(){
$.get('/move/left');
});
$('#move-right').on('click', function(){
$.get('/move/right');
}); $("set-speed").on('change', function(){ $.get('/set_speed/' + this.value); });
</script>
</body>
</html>

На странице управления роботом мы разместили 5 кнопок управления (ехать влево, вперед, назад, вправо и стоп - "move-left", "move-forward", "move-backward", "move-right", "stop" - соответственно) и ввод для регулировки скорости "set-speed". Нажатия на элементы управления обрабатываются с помощью javascript, который посылает AJAX запросы на веб сервер под управлением Raspberry Pi.

Сохраните все редактируемые файлы. Чтобы запустить сервер выполните команду python app.py. Flask запуститься на 5000 порту. Чтобы зайти на страницу управления введите в браузере http://YOUR_RASPBERRY_PI_IP:5000.

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

Для этого пропишите в конце файла /etc/profile следующий код

sudo python /home/pi/pluto-wifi-robot/raspberry_pi/web/app.py &

Путь к файлу app.py для Вашего Raspberry может отличаться. Не забудьте в конце '&', т.к. этот символ позволяет запустить веб-сервер в фоновом режиме, что не блокирует выполнение остальных скриптов.

Pluto практически готов к своему первому пилотируемому запуску. Для этого осталось только отсоединить его от компьютера и подать питание от аккумулятора на microUSB Rapberry Pi. Так как у меня аккумулятор 12V а USB ожидает на входе 5V, то я купил DC-DC преобразователь и подключил аккумулятор через него.

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

В следующей статье я расскажу о том, как подключить к Raspberry Pi камеру и организовать real-time видео трансляцию в браузер.


Полный рабочий код вы можете найти здесь.

Все статьи о Плуто доступны по следующим ссылкам:

Строим WiFi робота c камерой (Часть 1 - Ходовая)

Строим WiFi робота c камерой (Часть 2 - Первая поездка)

Строим WiFi робота c камерой (Часть 3 - Веб сервер)

Строим WiFi робота c камерой (Часть 4 - Камера)

Назад