Rider Pi: Сборка ИИ-робота на Raspberry Pi с OpenCV и Mius-UI | Гайд 2026 | AiManual
AiManual Logo Ai / Manual.
20 Фев 2026 Гайд

Rider Pi: как собрать первое воплощение ИИ в физическом теле с Raspberry Pi, OpenCV и Mius-UI

Пошаговый гайд по созданию первого воплощения ИИ в физическом теле. Raspberry Pi 5, OpenCV, MJPEG-стрим, Mius-UI дашборд и управление движением. Актуально на фе

Зачем ИИ нужно тело? (Спойлер: без него он просто болтает)

Все эти LLM в облаках — они как философы в башне из слоновой кости. Умные, эрудированные, но дверь открыть не могут. Embodiment — это когда ИИ получает руки, ноги и глаза. Когда он может взаимодействовать с физическим миром, а не просто генерировать текст про него.

Rider Pi — это минимальный жизнеспособный продукт в мире воплощенного ИИ. Не робот-гуманоид за миллион долларов, а простая платформа на колесах, которая видит, думает и двигается. И самое главное — вы можете собрать ее за выходные.

Важно: Этот проект не про супер-сложные нейросети. Мы используем Raspberry Pi 5, а не сервер с восемью H100. Здесь главное — архитектура, а не вычислительная мощность. Если нужны тяжелые модели — смотрите гайд про подключение eGPU к Raspberry Pi.

Что внутри коробки (и почему Mius-UI — темная лошадка)

Список компонентов выглядит скромно, но каждый элемент выбран не просто так:

  • Raspberry Pi 5 (8GB) — мозг системы. Pi 4 тоже сойдет, но с Pi 5 OpenCV работает в 2-3 раза быстрее.
  • Камера Raspberry Pi HQ Camera — 12.3 МП, сменные объективы. Можно и обычную V2, но HQ дает больше деталей.
  • Двигатели с энкодерами + драйвер L298N — базовый набор для движения. Если хочется плавности — берите драйверы на DRV8833.
  • Аккумулятор 12V + понижающий преобразователь до 5V — питание для моторов и Pi.
  • Шасси с колесами — любое, где помещается электроника.

А теперь про Mius-UI. Это не просто "еще один дашборд". Это TypeScript-фреймворк для embedded-интерфейсов, который работает на чем угодно — от Raspberry Pi до Radxa RK3588. Легкий (десятки килобайт), быстрый, с native-подобным рендерингом. И да, он умеет в MJPEG-стримы из коробки.

💡
Mius-UI появился как ответ на Electron для embedded-устройств. Разработчики устали от 200MB Chrome в каждом устройстве. Сейчас это один из самых перспективных фреймворков для IoT-интерфейсов.

1 Собираем железо: где ошибаются 90% новичков

Схема подключения простая, но есть три критических момента:

  1. Раздельное питание — моторы кушают 12V, Raspberry Pi — 5V. Если запитать все от одного источника без преобразователя, Pi умрет от скачков напряжения при старте моторов.
  2. Земля (GND) — общая земля между драйвером моторов и Pi обязательна. Без этого ШИМ-сигналы будут плавать.
  3. Охлаждение Pi 5 — без радиатора или кулера процессор троттлится через 2 минуты работы с OpenCV.

Собирайте в таком порядке: шасси → моторы → драйвер → аккумулятор → преобразователь → Raspberry Pi → камера. Так проще переделывать, если что-то пошло не так.

2 Настройка Raspberry Pi: не просто apt-get install

Ставим Raspberry Pi OS Lite (64-bit). Desktop не нужен — все равно работаем через SSH и веб-интерфейс.

# Обновляемся до актуальных версий на февраль 2026
sudo apt update && sudo apt full-upgrade -y

# Устанавливаем Python 3.11 (в последних версиях Raspberry Pi OS он по умолчанию)
sudo apt install python3.11 python3.11-venv python3-pip -y

# Устанавливаем OpenCV 4.10 (последняя стабильная на 2026 год)
sudo apt install libopencv-dev python3-opencv -y

# Проверяем установку
python3 -c "import cv2; print(f'OpenCV version: {cv2.__version__}')"

Теперь включаем камеру и I2C/SPI для будущих датчиков:

sudo raspi-config
# Interface Options → Camera → Enable
# Interface Options → I2C → Enable
# Interface Options → SPI → Enable

Предупреждение: Не устанавливайте OpenCV через pip (opencv-python) на Raspberry Pi. Сборка из исходников займет 6 часов, а готовая версия из репозитория оптимизирована под ARM. Разница в скорости — до 40%.

3 Пишем ядро: камера + движение + стрим

Создаем файл rider_core.py. Здесь будет три потока: захват видео, обработка кадров, управление моторами. Не пытайтесь сделать все в одном потоке — камера будет тормозить.

import cv2
import threading
import time
from flask import Flask, Response
import RPi.GPIO as GPIO

class RiderCore:
    def __init__(self):
        # Настройка GPIO для моторов
        self.MOTOR1_PIN1 = 17
        self.MOTOR1_PIN2 = 18
        self.MOTOR2_PIN1 = 22
        self.MOTOR2_PIN2 = 23
        
        GPIO.setmode(GPIO.BCM)
        GPIO.setup([self.MOTOR1_PIN1, self.MOTOR1_PIN2, 
                   self.MOTOR2_PIN1, self.MOTOR2_PIN2], GPIO.OUT)
        
        # Инициализация камеры
        self.camera = cv2.VideoCapture(0)
        self.camera.set(cv2.CAP_PROP_FRAME_WIDTH, 640)
        self.camera.set(cv2.CAP_PROP_FRAME_HEIGHT, 480)
        
        self.latest_frame = None
        self.frame_lock = threading.Lock()
        
        # Флаг для остановки потоков
        self.running = True
        
    def camera_thread(self):
        """Поток захвата видео"""
        while self.running:
            ret, frame = self.camera.read()
            if ret:
                with self.frame_lock:
                    self.latest_frame = frame
            time.sleep(0.03)  # ~30 FPS
            
    def generate_mjpeg_stream(self):
        """Генератор MJPEG потока для веб-интерфейса"""
        while self.running:
            with self.frame_lock:
                if self.latest_frame is not None:
                    # Кодируем кадр в JPEG
                    ret, jpeg = cv2.imencode('.jpg', self.latest_frame, 
                                             [cv2.IMWRITE_JPEG_QUALITY, 70])
                    if ret:
                        yield (b'--frame\r\n'
                               b'Content-Type: image/jpeg\r\n\r\n' + 
                               jpeg.tobytes() + b'\r\n')
            time.sleep(0.03)
            
    def move_forward(self, duration=1.0):
        """Движение вперед"""
        GPIO.output(self.MOTOR1_PIN1, GPIO.HIGH)
        GPIO.output(self.MOTOR1_PIN2, GPIO.LOW)
        GPIO.output(self.MOTOR2_PIN1, GPIO.HIGH)
        GPIO.output(self.MOTOR2_PIN2, GPIO.LOW)
        time.sleep(duration)
        self.stop()
        
    def stop(self):
        """Остановка моторов"""
        GPIO.output(self.MOTOR1_PIN1, GPIO.LOW)
        GPIO.output(self.MOTOR1_PIN2, GPIO.LOW)
        GPIO.output(self.MOTOR2_PIN1, GPIO.LOW)
        GPIO.output(self.MOTOR2_PIN2, GPIO.LOW)
        
    def cleanup(self):
        """Корректное завершение"""
        self.running = False
        self.camera.release()
        GPIO.cleanup()

# Flask сервер для MJPEG стрима
app = Flask(__name__)
rider = RiderCore()

@app.route('/video_feed')
def video_feed():
    return Response(rider.generate_mjpeg_stream(),
                    mimetype='multipart/x-mixed-replace; boundary=frame')

@app.route('/move/')
def move(direction):
    if direction == 'forward':
        rider.move_forward(1.0)
        return 'Moving forward'
    return 'Unknown direction'

if __name__ == '__main__':
    # Запускаем поток камеры
    cam_thread = threading.Thread(target=rider.camera_thread)
    cam_thread.daemon = True
    cam_thread.start()
    
    # Запускаем Flask сервер
    app.run(host='0.0.0.0', port=5000, threaded=True)

Это базовая версия. В реальном проекте добавьте обработку ошибок, логирование и конфигурационный файл. И да, используйте threading, а не multiprocessing — на Raspberry Pi разница в накладных расходах заметна.

4 Mius-UI дашборд: где интерфейс весит меньше картинки

Создаем папку mius-dashboard и инициализируем проект:

npm init -y
npm install mius-ui@latest

Файл src/app.tsx:

import { MiusApp, Widget, VideoStream, Button } from 'mius-ui';

const RiderDashboard = () => {
  const handleMove = (direction: string) => {
    fetch(`http://${window.location.hostname}:5000/move/${direction}`)
      .catch(err => console.error('Movement error:', err));
  };

  return (
    
      
        
      
      
      
        

CPU Temperature: --°C

Uptime: --

Camera: Active

); }; export default RiderDashboard;

Собираем и запускаем:

npm run build
# Копируем файлы в /var/www/html или запускаем через serve
npx serve -s build -l 3000

Теперь открываем браузер на http://raspberry-pi-ip:3000 и видим интерфейс с видео-стримом и кнопками управления. Весит это удовольствие ~150KB против 50MB у Electron-аналога.

А теперь добавляем ИИ (но не тот, о котором вы подумали)

Самый частый вопрос: "Какую нейросеть поставить?". Ответ: сначала — самую простую. Не пытайтесь запустить AlpamayoR1 или Youtu-VL-4B-Instruct на Raspberry Pi без eGPU. Начните с классического компьютерного зрения.

Добавляем в rider_core.py обнаружение лиц (как пример):

def detect_faces(self, frame):
    """Обнаружение лиц с помощью Haar cascades"""
    gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    face_cascade = cv2.CascadeClassifier(
        cv2.data.haarcascades + 'haarcascade_frontalface_default.xml'
    )
    faces = face_cascade.detectMultiScale(gray, 1.1, 4)
    
    for (x, y, w, h) in faces:
        cv2.rectangle(frame, (x, y), (x+w, y+h), (0, 255, 0), 2)
    
    return frame, len(faces)

# В потоке камеры после захвата кадра:
processed_frame, face_count = self.detect_faces(frame)
with self.frame_lock:
    self.latest_frame = processed_frame

Это работает на Raspberry Pi 5 со скоростью 15-20 FPS. Достаточно для демонстрации. Когда освоите базовый пайплайн — можно подключать легкие модели типа MobileNet или LFM2-350M через Femtobot.

Пять ошибок, которые сломают ваш Rider Pi

Ошибка Что происходит Как исправить
Нет общей земли Моторы не слушаются, GPIO ведут себя странно Соединить GND драйвера моторов с GND на Raspberry Pi
Питание моторов от 5V пинов Pi Raspberry Pi перезагружается при движении Использовать отдельный источник 12V для моторов
Блокировка основного потока Flask Интерфейс "зависает" при движении Выносить длительные операции в отдельные потоки
MJPEG стрим без буферизации Видео тормозит с несколькими клиентами Использовать queue.Queue для кадров
Отсутствие охлаждения Pi 5 Троттлинг через 2-3 минуты работы Установить радиатор или активное охлаждение

Куда развивать проект (если не надоело)

Базовый Rider Pi — это холст. Вот что можно добавить:

  • Навигация по AR-меткам — распознавание AprilTags или ArUco markers для точного позиционирования
  • Голосовое управление — Whisper для распознавания команд + локальный TTS
  • Автономная навигация — SLAM с помощью Intel RealSense (тяжело для Pi, но возможно)
  • Манипулятор — добавить руку как в проекте мобильного робота-манипулятора
  • Локальная VLM — запуск легкой vision-language модели для описания окружения
💡
Самый интересный эксперимент — подключить Rider Pi к PEVA (Prediction-Enhanced Vision Agent). Робот будет не просто видеть, но и предсказывать, что произойдет в следующий момент. Это уже близко к тому, как видят мир люди.

Философский вопрос: это уже ИИ или еще нет?

Rider Pi в текущей версии — это инструмент. Умный инструмент, но инструмент. Настоящее воплощение ИИ начинается, когда система:

  1. Имеет внутреннюю модель мира (не только текущий кадр, но и память о предыдущих)
  2. Способна к простейшему планированию ("чтобы объехать препятствие, нужно сначала отъехать назад")
  3. Может обучаться на своих ошибках (если врезался в стену — запомнить это место)

Но даже в текущем виде Rider Pi делает главное — соединяет код с физическим миром. Из абстрактных чисел в Python — в реальное движение в пространстве. И это, черт возьми, впечатляет.

Собирайте. Экспериментируйте. Ломайте. Чините. Именно так, а не через API-вызовы к ChatGPT, и рождается настоящее понимание того, что такое искусственный интеллект в физическом теле.

P.S. Если ваш Rider Pi научится приносить пиво из холодильника — считайте, что вы опередили Boston Dynamics лет на пять. Шучу. Но попробовать можно.