Когда зрение должно жить внутри устройства — робота-курьера, киоска, умного шкафа — начинается встраиваемая реальность: ограниченное питание, один USB-контроллер на всё и процессоры, которые в разы слабее десктопа. Связка компактной камеры глубины Astra Mini и Raspberry Pi — рабочий и дешёвый вариант такого узла: камера отдаёт глубину, Pi считает логику, всё помещается в ладонь. Задача гайда — довести эту пару до устойчиво работающего пайплайна: собрать pyorbbecsdk на ARM64, не наступить на питание и USB, снизить нагрузку до реального FPS и прикрутить типовую задачу «детектор + дистанция». Сразу про ожидания: на Pi мы не гоним полный поток 30 Гц с детекцией — мы строим систему, где каждая подсистема получает ровно столько кадров, сколько ей нужно.
Первое развилочное решение — Pi или Jetson. Критерий простой: если инференс нейросети обязателен и нужен на частоте 10+ Гц — берите Jetson-класс, GPU там делает за Pi то, что тот не сделает никогда. Если же задача — навигация по глубине, счётчики, пороги, редкая детекция «раз в секунду», Pi выигрывает по цене, энергопотреблению и доступности. Ошибка новичка — стартовать с Pi и пытаться выжать из него видеореальную детекцию: либо задача переформулируется под редкие проверки, либо меняется платформа, и это лучше решить на макете, а не в серии.
Что понадобится
- Raspberry Pi 4/5 с 64-битной Raspberry Pi OS (обязательно 64-bit — это главное условие сборки SDK);
- блок питания 5 В и 3 А для Pi, отдельная логика — не запитывать камеру от хаба;
- камера Orbbec Astra Mini (компактный модуль структурированного света);
- карта microSD A2-класса или NVMe-шляпа: сборка и запись данных не должны упираться в диск;
- радиатор или корпус с обдувом: Pi под детектором греется;
- Python 3.9+, pip, git, cmake для сборки pyorbbecsdk.
Пошаговая настройка
Шаг 1. Система, зависимости, сборка pyorbbecsdk
Ставим 64-битную Raspberry Pi OS, обновляемся и ставим инструментальную базу:
sudo apt update && sudo apt full-upgrade -y
sudo apt install -y git cmake build-essential python3-dev python3-pip
git clone https://github.com/orbbec/pyorbbecsdk.git
cd pyorbbecsdk
pip install -r requirements.txt # если файла нет в вашей ревизии — см. README
bash build.sh # собирает wheel и ставит его
python3 -c "import pyorbbecsdk; print('ok')"
Если pyorbbecsdk ставите впервые и хочется увидеть рабочий минимум кода до встраивания, у нас есть короткий квикстарт по Python и OpenCV — каркас открытия камеры там совпадает с тем, что ниже.
Сборка на Pi занимает заметное время — это нормально. Сверьте шаги сборки с README вашей ревизии репозитория: процедура периодически меняется (то wheel, то setup.py, то venv-инструкции). Если import падает с ошибкой про несовпадение архитектуры — вы почти наверняка на 32-битной ОС; переустановите систему в 64-битном варианте, лечить это пересборкой бесполезно.
Два практичных замечания к сборке. Первое: компиляция на Pi — час процесса и пара гигабайт на диске, поэтому карта памяти должна быть быстрой, а лучше пусть будет NVMe-шляпа — сборка и последующая запись данных скажут спасибо. Второе: работайте в venv, а не в системном Python — обновление системы не должно ломать окружение работающего узла; собранный wheel можно сохранить в артефакты и переиспользовать на однотипных узлах, чтобы не собирать каждый заново.
Шаг 2. Питание и USB — до первой камеры, а не после
Камере глубины нужен USB 3.0: у Pi 4 это два синих порта (контроллер VL805), у Pi 5 — свои линии. Подключайте камеру напрямую в порт Pi, без хабов. Питание Pi — только фирменный блок 5 В 3 А (или PoE-шляпа с запасом): просадки питания при старте камеры — самая частая причина «загадочных» отключений и warning-сообщений в dmesg. Проверка здоровья питания: vcgencmd get_throttled возвращает ноль на здоровой системе; ненулевой бит — ищите просадку. Если USB-устройство периодически отваливается — начните с кабеля и блока питания, а не с переустановки SDK.
Шаг 3. Пайплайн с пониженной нагрузкой
Для встраиваемого сценария сознательно берём меньшее разрешение и частоту:
import numpy as np
import cv2
from pyorbbecsdk import Pipeline, Config, OBStreamType
pipeline = Pipeline()
config = Config()
config.enable_stream(OBStreamType.OB_STREAM_DEPTH)
config.enable_stream(OBStreamType.OB_STREAM_COLOR)
# выберите лёгкий профиль потока средствами SDK —
# точный API выбора профиля сверьте с examples вашей версии
pipeline.start(config)
while True:
frames = pipeline.wait_for_frames(100)
if frames is None:
continue
d = frames.get_depth_frame()
c = frames.get_color_frame()
if d is None or c is None:
continue
dh, dw = d.get_height(), d.get_width()
depth = np.asarray(d.get_data(), dtype=np.uint16).reshape(dh, dw)
# грубая зона интереса вместо обработки всего кадра:
h, w = depth.shape
center = depth[h//4:3*h//4, w//4:3*w//4]
valid = center[center > 0]
nearest = np.percentile(valid, 5) if valid.size else 0 # мм
print(f"nearest in ROI: {nearest} mm")
if cv2.waitKey(1) == 27:
break
pipeline.stop()
Шаг 4. Типовая задача: детектор плюс дистанция
Логика «YOLOv8n по RGB + расстояние из depth» на Pi работает, если отдать каждой подсистеме свой ритм: детекция — 3–5 Гц, чтение глубины — каждый кадр. Веса yolov8n.pt, кадр для модели можно уменьшать. Экономика такая: детекция — самая дорогая операция, глубина — копеечная, отрисовка на headless-узле вообще не нужна. Первым делом отключите графический вывод и замерьте чистый FPS пайплайна; только потом решайте, нужна ли оптимизация дальше (экспорт в ONNX уменьшит накладные расходы, TensorRT на Pi недоступен — это уже территория Jetson).
Шаг 5. Автозапуск: systemd-юнит
Встраиваемый узел обязан подниматься сам после подачи питания. systemd-юнит с рестартом закрывает и ретраи открытия камеры — USB-хост поднимается позже файловой системы:
[Unit]
Description=Orbbec vision node
After=multi-user.target
StartLimitIntervalSec=0
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/vision
ExecStart=/home/pi/vision/venv/bin/python3 vision_node.py
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
В коде узла заложите цикл повторных попыток открытия камеры с паузой — связка «Restart=always плюс ретраи в коде» переживает и холодный старт, и передёргивание питания камеры на месте. Логи узла смотрите через journalctl -u: там же увидите, на какой попытке камера наконец открылась — полезная метрика для диагноза питания.
Разбор кода
Три решения в каркасе специфичны именно для слабых плат. Первое — зона интереса вместо полного кадра: вырезать центральный регион NumPy-срезом и считать статистику только по нему в разы дешевле, чем по всей матрице, а для задачи «ближайшее препятствие перед устройством» зона интереса честнее всего соответствует смыслу. Второе — перцентиль, а не минимум: одиночный пиксель-выброс не должен диктовать решение («остановить робота»), 5-й перцентиль по валидным точкам устойчив и ближе всего к «реальному ближайшему объекту». Третье — wait_for_frames(100) с обработкой None: на Pi тайминги USB и планировщик дают рваные интервалы, и жёсткое ожидание кадра превращает кратковременную паузу в исключение и падение сервиса.
Про глубину и цвет: для задач навигации и подсчёта часто вообще не нужен color-поток — каждый поток это полоса USB и память. Включайте color только там, где он реально нужен детектору; глубина и color по USB не «бесплатны» даже на Pi 5.
Память — второй тихий ресурс, который кончается раньше CPU. Каждый кадр глубины полного разрешения — это мегабайт на матрицу; три-четыре одновременно живых буфера в очередях и копиях — уже счёт на десятки мегабайт, а на Pi с 2–4 ГБ ОЗУ это заметный кусок. Правила простые: копировать кадр только тогда, когда он реально нужен дальше по коду; освобождать ссылки на старые кадры; не накапливать кадры в списках «на обработку позже» — на слабой плате это дорожает вдвойне, потому что позже означает «уже неактуально».
| Плата | Чего ожидать в связке с Astra Mini | Кому подходит |
|---|---|---|
| Raspberry Pi 4 | глубина 10–15 Гц, детекция 2–5 Гц | навигация, счётчики, киоски |
| Raspberry Pi 5 | заметный запас: детекция 5–10 Гц | более плотные сценарии, несколько потоков |
| Jetson (Persee N1: камера+Jetson Nano) | GPU-инференс, видеореальные FPS | роботы и изделия с детекцией в реальном времени |
Цифры — порядок величин для планирования: фактический FPS зависит от разрешения профилей, сцены и вашей логики, поэтому бенчмаркьте на своём макете.
Если макет показал, что детекция нужна чаще, чем позволяет плата, есть третий путь между «ужать логику» и «менять платформу»: перенести инференс на сервер в помещении, оставив на Pi только захват и предобработку. Для одиночного узла это лишняя сеть, для парка из десятка узлов — стандартная архитектура с одним GPU-хостом. Выбирайте по экономике проекта, а не по любви к определённому железу.
Частые проблемы
Камера не видится или отваливается во время работы
Иерархия проверок: lsusb видит устройство? lsusb -t показывает 5000M на его линии? dmesg чистый от USB-ошибок? Если устройство пропадает под нагрузкой — почти всегда питание: замените блок, уберите хаб, проверьте кабель. Отдельный грех — стартовать камеру раньше, чем Pi поднял USB-хост; добавьте в сервис паузу и ретраи открытия устройства. Для автозапуска логичнее systemd-юнит с рестартом, а не цикл в rc.local.
pyorbbecsdk не собирается на Pi
Проверка №1 — архитектура: uname -m должен показать aarch64. На armv7 (32-бит) сборка не имеет смысла. Дальше — версия Python: SDK ориентируется на Python 3.x из репозитория, но venv с системным интерпретатором обязателен, иначе pip собирает не туда. Не хватает заголовков — доустановите python3-dev; не хватает cmake новее системного — ставьте через pip (pip install cmake). Точные шаги всё равно сверяйте с README вашей ревизии — процедура сборки обновляется чаще, чем любые инструкции в интернете.
Служба не находит камеру после перезапуска Pi
Типовая последовательность: система загрузилась, юнит стартует через две секунды, USB-хост ещё не поднял камеру — открытие падает, Restart поднимает юнит снова, и через пару попыток всё работает. Хуже, если код при неудаче делает sys.exit без ретраев, а лимит перезапусков останавливает юнит навсегда. Лечится связкой: StartLimitIntervalSec=0 (без лимита попыток), пауза и ретраи открытия в коде, и проверка lsusb в логах перед стартом. Отдельный случай — «камера зависла после мягкого ребута»: USB-порты Pi не умеют выключать питание устройства, поэтому зависшую камеру спасает только полный цикл питания; решается умной розеткой или реле в изделии.
Троттлинг и падение FPS через несколько минут
Pi под инференсом греется и сбрасывает частоту: vcgencmd measure_temp покажет 80+ градусов, get_throttled — биты троттлинга. Лечение: радиатор с обдувом, открытое размещение, снижение частоты кадров камеры (меньше работы USB и памяти). Планируйте тепловую диаграмму изделия заранее: узел зрения в закрытом корпусе без вентилятора — это не «потом разберёмся», а гарантированная деградация через полчаса работы.
Компоненты для встраиваемого зрения есть в каталоге Orbbec на luwam.ru. Для компактных узлов берут Astra 2 и модули линейки Astra Mini, а если нужен GPU-инференс без отдельного хоста — посмотрите Persee N1 (камера и Jetson Nano в одном корпусе). Консультация по SDK, счёт для юрлица, гарантия 1 год.
Камеры Orbbec в наличии на LUWAM
- Orbbec Femto Bolt — iToF 4K, замена Azure Kinect — 99 900 ₽
- Orbbec Gemini 335L — стерео для роботов и SLAM — 99 900 ₽
- Orbbec Astra 2 — структурированный свет, сканирование помещений — 99 900 ₽
Весь каталог Orbbec · консультация по SDK · счёт для юрлица в день обращения · гарантия 1 год.

