Мобильный сторож на Raspberry pi (h.264)
Темы использования Raspberry pi для FPV управления и мониторинг движения в кадре по векторам H.264 не новы. Разработка не претендует на оригинальность, да и времени на нее было потрачено относительно не много (с июля по выходным. иногда.).
Но, возможно, мой опыт (и исходники) окажутся кому ни будь полезными.
Мысль о том, что нужно сделать видео наблюдение в квартире, возникала после того как сосед сказал, что кто-то копался в замке двери.
Первое что было сделано на скорую руку — это установка известной программы motion на Raspberry pi zero c камерой v1.3. В принципе, задачу решает. Если устраивает оповещение через почту и fps=4–5.
Но это показалось не интересным. Под рукой была платформа с колесами и обвязкой от старых экспериментов и аккумуляторы 16850 от старых ноутов.
В результате получилась забавная смесь мобильного видеонаблюдения и детектора движения.
Поскольку у меня есть арендованный VPS, то проблем доступом извне (домашняя сетка за NAT) не было. Время автономной работы около 4-х суток если не злоупотреблять ездой и фарой.
Можно поездить по квартире, удаленно управляя как камерой, так и платформой и оставить в режиме «сторож» (motion detect) в любом нужном месте.
Все «железо» можно разделить на две части, первая из которых от второй не зависит и может использоваться отдельно:
Модуль видео наблюдения.
- Raspberry pi zero
- USB WiFi Dongle
- Raspberry pi camera v1.3
- 2x stepper motors 28BYJ-48 + ULN2003 driver
Мобильная платформа, управляемая через SPI от малины.
- 4S 16×18650 Li-ion + 4S 30A Li-ion 18650 (BMS) board + DC-DC зарядка со стабилизацией тока и напряжения
- dc-dc step down converter (15v →5v).
- stm32f103c8t6 board
- 4x gear motors + L298N board
- 12v LED lamp (фара) + управление на IRF3205 (+smd pnp и npn)
Образ Raspbian был настроен в режим read only. В такой конфигурации, малина легко переживает неожиданные выключения питания, поскольку SD карт на запись не использует вообще.
ПО состоит из 3-х отдельных компонент.
Android приложение (проверено на LG6 Oreo и старом Samsung S5 Lollipop)
Режим FPV
- Показ видеопотока H.264 с камеры в указанном разрешении и bitrate
- Элементы управление камерой и платформой
- Запись видео и фото с потока.
Режим Android service
- Опрос хоста (с указанной периодичность)
- Загрузка фото событий «движение» в кадре по событию.
Хост Raspberry pi на python (picamera + spidev + RPi.GPIO)
Режим FPV
- Трансляция H.264 потока (с указанными Android приложением параметрами)
- прием управляющих команд для шаговых двигателей и управление ими.
- Трансляция управляющих команд по SPI (если включен режим)
Режим отслеживания движение в кадре.
- Детектирование движения в кадре (по указанным Android приложением параметрам)
- Прием запросов «а нет ли движения в кадре» и выгрузка фото по запросу
- Отправка на хост (не зависимо от приложения) фото движений в кадре.
Простейшая прошивка на stm32f103
- Прием команд по SPI
- Управление направлением вращения колес и ШИМ двигателей.
- Управление включением фары.
Отслеживание по векторам h.264 оказалось весьма капризным и склонным к ложным срабатывания. В сети гуляют очень мало вариантов реализации детектирования движения для H.264. Я перепробовал их всех.
Самый примитивный вариант — это подсчет количества векторов длинна которых превышает некое пороговое значение. И если каких векторов больше порогового, то это сигнал, что в кадре есть движение.
Увы. Этот вариант годится только для демонстрации принципа. Ошибочных срабатываний слишком много. Особенно на поверхностях однородного цвета и текстуры.
Все остальные варианты либо то же дают слишком много ошибочных срабатываний, либо просто не проходят критерий по производительности: «должно обработаться за время кадра».
В результате выбрал свой вариант. Он хоть практически не дает ложных срабатываний, но требует движения в нескольких кадрах подряд. Но лучше уж так, чем ложные тревоги несколько раз в день из за изменения освещенности или вообще по непонятным «движениям» в кадре по «решению» камеры. Тема алгоритмов надежного детектирования по mv Н.264 вообще отдельная сложная тема. Алгоритмы требуют много времени на практическую отладку и имею жестки лимиты на время выполнения.
Пример векторов движения (служебные режимы snapshot):
По событиям «движение в кадре» порождаются нотификации.
в принципе, для моих целей оказалось достаточно гарантированного срабатывание при движении фигуры человека (>15% кадра) в течении минимум 2-х сек. При таком загрублении чувствительности, ложных срабатываний просто не видел вообще.
Управление движением.
Управление платформой «по тракторному». Т.е. управление ШИМ и направлением вращения левой и правой стороны. Управляющие элементы (полоски) под большими пальцами обеих рук. Это оказалось наиболее естественным для меня.
Управление камерой — две полоски касание которых выдает команду повернуться на определенный угол (чем дальше от центра полоски — тем больше угол). Непрерывное управление как для моторов оказалось неудобным (опять же субъективно для меня).
Лаги FPV.
Лаги видео оказались относительно небольшими (
Для управления колесной платформой с максимальной скоростью 3–4 км/ч на 100% ШИМ лаг в 0.6 сек — это вполне нормально и почти не замечается.
Однако, мне кажется, что даже 0.3 сек лага для, например, квадрокоптера — это много.
Тесты показали, что реализация трансляции на python вносит в лаг где-то 50–70ms, по сравнение с выдачей такого же H.264 потока через rapivid. Для меня эти 70ms не принципиальны. Но если кто хочет выжать максимум, то должен это учитывать.
При работе через «локальный WiFi» (телефон как access point) лаг составляет 350…600ms. Но не более 0.6 сек и стабильно в этом диапазоне. Хотя, 50–70 метров дальности на открытой местности — это только поиграться. А на большем расстоянии WiFi c телефона не работает.
Стоит заметить, что это в очень «RF зашумленной» среде многоквартирных домов, с множеством WiFi сетей в округе.
Удивил меня результат в конфигурации «Роутер WiFi → провайдер по витой паре → VPS → MTC 4G на телефоне» через ssh port forwarding c малины на VPS.
Типичный лаг оказался даже чуть лучше, чем через локальный WiFi (!)
Даже на ходу в машине или рядом с крупным гипермаркетом лаг всего 300ms.
Однако, иногда (довольно редко и не предсказуемо), лаг становился до нескольких секунд. Помогает переконект. Наверное, это какие-то особенности 4G/МТС/провайдеров в цепочке и т.д.
После того как все заработало, появилось желание подключить звуковой канал в обе стороны. Технически это возможно и даже не очень сложно. Но возится с паяльником уже не хочется.
Если бы не было под рукой «лишнего» Rasberry pi, то вместо него проще было бы использовать старый телефон в качестве хоста видеонаблюдения и управления платформой. Единственное преимущество малины перед старым телефоном — меньший вес. И, может быть, меньшее энергопотребление (не сравнивал).
Все исходники: github.com/mmMikeKn/Rpi-Android-VideoStreamAndMotionDetect