
Mirte — это недорогая полностью open-source платформа учебного мобильного робота, где ученик проходит путь «от телеуправления и Blockly до Python, SSH и полноценного ROS», задуманная как единый «трек» обучения от начальной школы до университета, оставаясь на одном и том же роботе и в одной и той же среде. Идея Mirte в образовании — не прятать “настоящую” робототехнику за игрушечными абстракциями, а сделать к ней удобный, поэтапный вход.
Представьте урок, на котором школьник за 5 минут впервые в жизни запускает робота с ноутбука: сначала — обычным телеуправлением в браузере, затем — собирает программу из блоков, заглядывает «под капот» в сгенерированный Python, а через пару недель уже заходит по SSH, открывает VS Code на самом роботе, запускает Jupyter Notebook и пишет собственную ROS‑ноду.
И всё это — с одним и тем же роботом, на одной и той же платформе. Это и есть Mirte.
Зачем Mirte вообще появился
Создатели Mirte сформулировали задачу очень жёстко: образовательный робот должен быть одновременно дешёвым, полностью open‑source, без массы кастомных деталей и пригодным от начальной школы до университета.

Большинство наборов решают только один фрагмент картины:
либо это игрушка для начальной школы с закрытой прошивкой,
либо серьёзный набор для вуза, куда школьника просто не пустишь,
либо «конструктор по программированию», где нет реальной механики и электроники.

Mirte решает всё разом:
одно семейство роботов (Basic/Light/Pioneer/Master) — разный «уровень возможностей» под возраст и задачи;
одна линейка софта — от браузерного Blockly до ROS;
единая философия Open Education / Open Science: все механические файлы, схемы, код, учебные материалы открыты и развиваются сообществом.
Это не просто «ещё один робот», это тре́к обучения инженерии, который можно растянуть на годы.
Как устроена лестница Mirte: от teleop и Blockly до ROS
Основная педагогическая идея Mirte: несколько слоёв сложности в одной среде, чтобы каждый ученик входил туда, где ему комфортно, и мог шаг за шагом подниматься выше. В документации это сформулировано прямо: цель Mirte — «чтобы все могли учиться робототехнике», поэтому доступны несколько уровней сложности программирования.
1. Первый контакт: веб‑интерфейс и телеуправление
Учитель включает робота. Mirte поднимает Wi‑Fi и web‑интерфейс; ученику достаточно открыть браузер и перейти по адресу Mirte (обычно вида http://mirte.local).
Что видит ученик:
панель управления роботом,
блоки Blockly,
и (чуть ниже) генерируемый Python‑код.
Первый сценарий — телеуправление (teleop): робот ездит по командам с клавиатуры/кнопок в интерфейсе. Для ученика это просто «робот поехал». На самом деле под капотом уже работает ROS: есть нода, публикующая команды движения (Twist) в топик cmd_vel, а драйвер привода превращает это в скорости колёс.

2. Blockly: визуальное программирование как мост, а не тупик
Следующая ступень — Blockly. В документации прямо сказано: «Самый простой способ программировать Mirte — использовать Blockly».
Ученик перетаскивает блоки:
начать программу;
двигаться вперёд N секунд;
если сработал датчик — повернуть;
повторять в цикле и т.п.
Сверху — «контрольная панель»: запустить, поставить на паузу, выполнить пошагово, остановить.
Важно, что при остановке программы Mirte автоматически выключает моторы — встроенная педагогическая «страховка».
Главное — это не игрушечный блок‑редактор:
под полотном Blockly виден Python‑код, сгенерированный по этим блокам;
этот код можно отредактировать и запустить теми же кнопками, что и блоки.
То есть Blockly в Mirte — не отдельный мир, а зеркало текстового кода. В материалах по Mirte прямо описано: «Блоки можно открыть, чтобы увидеть Python‑код ниже, который построен поверх ROS».

3. Python в браузере: первый шаг в «настоящем» коде
Когда ученик «наигрался» с блоками, учитель показывает следующую магию:
«Видишь этот Python под блоками? Давай уберём блоки и будем писать прямо здесь».
Документация Mirte описывает два способа программировать на Python:
Из веб‑интерфейса — редактируя код, сгенерированный Blockly, и управляя его запуском той же панелью.
Через Python API + ROS — когда Mirte становится частью ROS‑сети, а код подписывается, например, на cmd_vel и управляет моторами через вызовы API.
Пример из документации: Python‑скрипт, который слушает сообщения Twist и по ним задаёт скорости моторам через mirte_robot API — без дополнительной ROS‑инициализации, встроенной в robot.createRobot().

4. SSH: вход во «взрослый» Linux мира робототехники
Дальше ученику (или одному‑двум мотивированным в группе) дают следующий инструмент — терминал.
Mirte официально поддерживает подключение по SSH, о чём прямо сказано в документации Accessing the interface:
два интерфейса: web и Linux‑терминал через SSH;
web даёт Blockly и Python, SSH — Python и ROS.
Команды становятся инженерными:
ssh mirte@mirte.local (первый логин с паролем по умолчанию);
просмотр каталогов, mirte_ws с ROS‑workspace;
-
управление сервисами:
sudo service mirte-ros stop/start — перезапуск bringup робота;
sudo service mirte-jupyter start — запуск Jupyter (по умолчанию он выключен, чтобы не съедать RAM).
чтение логов через journalctl -u mirte-ros -f, если что‑то пошло не так.
Это момент, когда ученик впервые чувствует: «я не просто клацаю кнопки, я администрирую настоящего робота».

5. VS Code и Jupyter на самом роботе
Для комфортной разработки Mirte предлагает «IDE на роботе»:
на роботе запускается VS Code / code-server, к которому заходят через браузер;
Jupyter Notebook работает как отдельный сервис, по адресу вроде http://mirte.local:8888, с примерами на базе Jupyter‑ROS.
Практически это выглядит так: ученик открывает в браузере VS Code, но весь workspace — на самом роботе. Не нужно настраивать Python, ROS, расширения на каждом ученическом ноутбуке — инфраструктура уже внутри робота Mirte.

6. ROS: Mirte как часть настоящей экосистемы
На верхнем уровне Mirte — полноценный участник ROS/ROS2‑мира. Документация описывает:
системные сервисы, поднимающие ROS ноды(программы) при старте;
ROS‑workspace ~/mirte_ws, где можно создавать свои пакеты и ноды;
Python API, который можно комбинировать с ROS‑сообщениями и сервисами;
В исследованиях TU Delft подчёркивается, что MIRTE Pioneer массово используется в бакалаврских курсах, где более 300 студентов в год строят и программируют этих роботов, а архитектура специально сделана модульной и открытой для расширения.

Mirte раскрывает ROS‑архитектуру: ученики могут увидеть, как их код взаимодействует с другими ROS нодами.
Как выглядит учебный процесс глазами ученика
Первый урок: «робот оживает»
Ученик достаёт Mirte, включается WIFI точку доступа / подключается к сети, открывает браузер. Робот появляется как web‑страница. Никаких установок SDK, драйверов, несовместимых версий.
Он нажимает на кнопки управления — робот ездит, поворачивает, реагирует на команды. Через пару минут преподаватель показывает вкладку Blockly:
«Смотри, давай теперь не вручную, а программой заставим его проехать квадратом».
Ученик собирает простую программу: вперёд — повернуть — вперёд — повернуть… Нажимает Run — робот крутит квадрат вокруг стола.
Вторая ступень: «из блоков — в код»
Учитель нажимает «показать код под блоками». На экране появляется Python.
— «Это то же самое, что ты сделал блоками. Попробуем заменить число 2 на 4, чтобы он дольше ехал».
Ученик меняет константу прямо в коде, снова запускает — видит результат.
Постепенно он начинает двигать логику из блоков в текст: сначала меняет параметры, потом добавляет новое условие, потом вообще убирает часть блоков и дописывает Python код руками.
Третья ступень: «я админ своего робота»
Через несколько занятий учитель показывает SSH:
как подключиться;
как зайти в папку с рабочим пространством;
как запустить/остановить сервисы;
как прочитать лог, если робот не реагирует.
Ученик, который ещё вчера перетаскивал блоки, сегодня пишет catkin_create_pkg, редактирует CMakeLists.txt и запускает rosrun.
Четвёртая ступень: проект
К концу модуля у него может быть вполне взрослый проект:
ROS нода, которая читает данные ЛИДАРа или ультразвуковых датчиков;
алгоритм, который решает — ехать вперёд или объехать препятствие;
программирование в Jupyter Notebook, графики в ноутбуке, настройка PID, анализ поведения.
И всё это — на том же Mirte, который он впервые включил через браузер.
Выгода для ученика
1. Понятная траектория роста
Mirte снял одно из главных противоречий школьной робототехники: либо слишком легко и скучно, либо слишком сложно и «для олимпиадников».
Здесь есть непрерывная лестница:
Teleop → Blockly быстрый успех, мгновенный «вау‑эффект»;
Blockly → Python в браузере: переход от визуального мышления к текстовому коду, но в знакомой среде;
Python → SSH/VS Code/Jupyter: освоение инструментов инженерной работы;
SSH/IDE → ROS‑архитектура: понимание профессиональной экосистемы, с которой работают реальные инженеры.
Ученик не «перескакивает» с платформы на платформу — он расширяет горизонт на одной и той же базе до профессионального востребованного робототехника.
2. Реальные, переносимые навыки
Mirte учит не только программированию. Он учит инженерному способу думать:
Linux, терминал, SSH, сервисы— базовые навыки DevOps/робототехники;
работа с ROS: топики, ноды, пакеты, конфигурация, отладка — фундамент ROS‑разработчика;
Исследования по Mirte в инженерном образовании подчёркивают именно это: робот задуман так, чтобы будущее инженерное обучение было непрерывным и практико‑ориентированным, а не набором разрозненных лабораторных работ.
3. Мотивация через прозрачность и «взрослость»
Поскольку Mirte полностью открыт, ученик всегда может пойти глубже:
открыть файлы робота и увидеть, что именно запускается при старте;
заглянуть в схему/PCB и понять, куда идут провода;
скачать исходники web‑интерфейса и модифицировать его под себя.
Это даёт очень сильное чувство «я вхожу в реальный мир технологий, а не играю в укороченную версию».
Выгода для учителя
1. Один робот — весь спектр образования
В университетских материалах TU Delft прямо говорится: MIRTE Pioneer используется в бакалавриате массово (более 300 роботов в год), а Light/Basic — в школе и колледже.
Практически это означает:
школе или вузу не нужно закупать разные наборы под каждый курс;
преподаватель может строить длинный сквозной курс (или несколько лестниц сложности) на одной платформе;
переход учащегося из школы в вуз не ломает всё: Mirte остаётся знакомой базой, меняется глубина задач.
2. Гибкость под разный уровень группы
В одном классе всегда есть «быстрые» и «медленные» ученики. Mirte позволяет работать с этим не через «занижение планки», а через разный уровень доступа:
новичкам достаточно браузера и Blockly — они спокойно осваивают базовые идеи алгоритмов;
уверенные быстро переходят в Python (но всё ещё в веб‑интерфейсе, без сложной установки IDE и ROS);
мотивированные получают SSH, VS Code, ROS — и превращают лабораторные работы в мини‑проекты.
Таким образом, учитель может дать общее задание («робот должен проехать маршрут с обходом препятствий»), а уровень реализации — адаптировать под ученика: от «если расстояние < X — поверни» на Blockly до собственной ROS‑ноды с логированием и настройкой параметров.
3. Снижение операционной боли
Типичные проблемы робототехники в образовании:
«у меня не ставится драйвер»,
«эта версия Python конфликтует с ROS»,
«на Windows всё иначе»,
«у нас 20 ноутбуков, и на каждом всё по‑разному»,
«не получается установить linux и ROS»,
Mirte снимает это за счёт того, что вся сложность живёт на роботе:
доступ через браузер, без установки софта на ученических ПК;
одна и та же среда для всех — учителю не нужно разруливать зоопарк конфигураций;
обновления можно проводить централизованно, а не по машинам.
4. Сообщество и открытые материалы
Mirte разворачивается как проект открытого образования и открытой науки:
партнёры (TU Delft, University of Groningen, прикладные вузы) используют Mirte в своих курсах и публикуют материалы открыто;
университеты в других странах берут дизайн и строят собственные роботы, адаптируя их под свои программы.
Полностью открытый исходный код, список компонентов для покупки, инструкции по сборке, документация.
Для учителя это означает: он не один. Можно брать готовые сценарии, уроки, лабораторные, адаптировать и возвращать в общее поле.
Почему это действительно инновация (и почему «всех нужно учить так»)
Mirte соединяет сразу несколько тенденций современного образования в инженерии:
Открытая наука и open‑source.
Mirte — полностью открытый: от железа до кода и учебных материалов. Это означает, что:
образовательные учреждения не зависят от жизненного цикла коммерческого набора («сняли с производства» — и всё пропало);
студенты и преподаватели становятся со‑разработчиками, а не просто потребителями.
2. Сквозная инженерная подготовка.
Мир робототехники в жизни — это не отдельная дисциплина, а узел механики, электроники, программирования, сетей, UX и исследования. Mirte целенаправленно сделан как платформа, где можно учить всё это по спирали: сначала очень просто, потом всё сложнее, но на тех же объектах.
3. Фокус на реальных компетенциях.
Исследования по инженерной педагогике подчёркивают: наиболее эффективны те методики, где студенты делают «настоящие вещи» с понятной им связью с реальным миром. Mirte как раз об этом — это не симуляция, а реальный робот, который ведёт себя как система.
4. Сопряжение с индустрией.
ROS/ROS2 — де‑факто стандарт в академии и индустрии робототехники. Mirte с самого начала встроен в эту экосистему, а не в закрытую “игровую” среду. Значит, студенту потом проще войти в любые реальные проекты — от мобильных роботов до манипуляторов.
5. Масштабируемость и устойчивость.
Благодаря открытому дизайну, Mirte можно:
производить локально;
удешевлять и адаптировать под местные учебные планы;
объединять усилия разных университетов, школ, кружков.
Именно поэтому, когда разработчики Mirte говорят о «семействе открытых образовательных роботов», это не маркетинг. Это попытка построить общий стандарт инженерного образования через роботов, в котором любой учитель и ученик могут стать участниками, а не клиентами.
Выводы
Так как все выложено в open-source то проект может служить отправной точкой для переиспользования различных технологий, наработок и идей. Чтобы погрузиться лучше начать с просмотра видео доклада рассказанного на образовательном блоке конференции ROSCON в Великобритании. Сайт проекта. Документация.
Обсудить статью можно в ROS чате.
Народный курс по ROS2 на степике.
Как понять, что образовательный подход и образовательный робот приносит пользу? Главный критерий готовит ли он кадры с необходимыми знаниями и опытом для бизнеса и государства, именно поэтому были разработаны ROS2 соревнования которые пройдут на ROS meetup 21-22 марта 2026 года. Задача соревнований максимально приближена к той которую решает мобильная манипуляция в сервисной и промышленной робототехнике. Победители соревнования могут претендовать на вавакансии в ведущих робототехнических компаниях. О этих соревнованиях вы можете прочитать подробную статью на Хабре.
Четыре уровня программирования Mirte: от PWM к архитектуре
Введение: одна задача, разные инструменты
Представьте простую задачу: робот должен проехать вперёд на 1 метр и остановиться.
На первый взгляд, это простое требование. Но на Mirte можно написать этот код четырьмя принципиально разными способами — от управления отдельными пинами микроконтроллера до полноценной ROS архитектуры. И каждый способ открывает новый уровень понимания того, как на самом деле работает робот.
Это не просто "разные способы написать то же самое". Это четыре разных парадигмы мышления инженера. И именно поэтому в образовательном процессе нужно учить все четыре подхода.
Уровень 1: управление пинами PWM (быстрый результат)
Код
import time
from mirte_robot import robot
def level_1_move_forward_pwm():
"""
Уровень 1: управляем пинами микроконтроллера напрямую через PWM.
PWM (Pulse Width Modulation) - быстрое переключение напряжения
для управления мощностью мотора.
"""
mirte = robot.createRobot()
print("=" * 70)
print("УРОВЕНЬ 1: Управление пинами PWM (низкоуровневый подход)")
print("=" * 70)
# На Mirte моторы подключены к GPIO пинам
left_motor_pin = 'GP19'
right_motor_pin = 'GP18'
# Задаём PWM значение (0-255, где 255 = 100% мощности)
pwm_power = 150 # примерно 60% мощности
print(f"\n1. Устанавливаем оба мотора на PWM = {pwm_power} (60% мощности)")
mirte.setAnalogPinValue(left_motor_pin, pwm_power)
mirte.setAnalogPinValue(right_motor_pin, pwm_power)
print("2. Гадаем, сколько времени нужно для проезда 1 метра...")
print(" (зависит от батареи, веса, состояния пола...)")
time.sleep(5) # ждём 5 секунд
print("3. Останавливаем моторы")
mirte.setAnalogPinValue(left_motor_pin, 0)
mirte.setAnalogPinValue(right_motor_pin, 0)
print("\n" + "!" * 70)
print("РЕЗУЛЬТАТ: Робот вероятно проехал примерно 1 метр, но мы НЕ ЗНАЕМ ТОЧНО!")
print("!" * 70)
print("\nПРОБЛЕМЫ этого подхода:")
print(" ❌ Точность: ± 50 см (сильно зависит от условий)")
print(" ❌ Нет обратной связи - не знаем, где робот на самом деле")
print(" ❌ Если один мотор сильнее - робот едит КРИВО")
print(" ❌ Если батарея разрядилась - робот едит медленнее")
print(" ❌ Мы просто ГАДАЕМ на основе времени")
if __name__ == '__main__':
level_1_move_forward_pwm()
Что происходит под капотом
Python: mirte.setAnalogPinValue('GP19', 150)
↓
ROS API преобразует в сервис-вызов
↓
Telemetrix протокол отправляет по USB
↓
RP2040 микроконтроллер (Pico) получает команду
↓
Pico устанавливает GPIO19 в режим PWM
↓
PWM 150/255 ≈ 59% → мотор вращается на 59% мощности
Плюсы этого уровня
✅ Максимально быстрый результат — робот реагирует мгновенно
✅ Очень простой код — всего 3-4 строки для движения
✅ Видна прямая причинно-следственная связь — код → поведение робота
✅ Ученик видит физику — как работают электроника и моторы
Минусы этого уровня
❌ Нет обратной связи
❌ Неточно (гадание по времени)
❌ Не масштабируется (добавить датчик = переписать код)
❌ Работает только для Mirte
Когда его использовать
? Возраст 8-10 лет — первые уроки программирования и робототехники
? Когда нужен быстрый результат — ученик должен увидеть, что его код работает
? Для понимания базовой физики — как работает электроника
Ключевой вопрос ученика на этом уровне:
"Почему робот не ездит прямо? Почему один раз проехал 1 метр, а другой раз 0.8 метра?"
Этот вопрос ведёт к следующему уровню.
Уровень 2: управление скоростью через PID (инженерный контроль)
Код
import time
from mirte_robot import robot
def level_2_move_forward_with_pid():
"""
Уровень 2: управляем СКОРОСТЬЮ моторов, не PWM.
За кулисами работает PID контроллер:
1. Читает энкодеры (датчики вращения колёс)
2. Вычисляет текущую скорость каждого мотора
3. Сравнивает с желаемой скоростью
4. Автоматически корректирует PWM для синхронизации
Результат: оба мотора крутятся СИНХРОННО, робот ездит РОВНО.
"""
mirte = robot.createRobot()
print("=" * 70)
print("УРОВЕНЬ 2: Управление скоростью моторов (PID контроллер)")
print("=" * 70)
# Задаём одинаковую скорость обоим моторам
speed_value = 100 # условные единицы (0-255)
print(f"\n1. Устанавливаем скорость = {speed_value}")
print(" Что происходит под капотом:")
print(" → PID контроллер КАЖДЫЕ 100мс читает энкодеры")
print(" → Сравнивает скорость левого и правого мотора")
print(" → Если левый медленнее - увеличивает его PWM")
print(" → Если правый медленнее - увеличивает его PWM")
print(" → В результате оба мотора синхронизируются")
mirte.setSpeed('left', speed_value)
mirte.setSpeed('right', speed_value)
print(f"\n2. Едим 5 секунд (с автоматической синхронизацией)...")
time.sleep(5)
print("3. Останавливаем")
mirte.setSpeed('left', 0)
mirte.setSpeed('right', 0)
print("\n" + "+" * 70)
print("РЕЗУЛЬТАТ: Робот ездит РОВНО (не криво)!")
print("+" * 70)
print("\nЧТО УЛУЧШИЛОСЬ по сравнению с уровнем 1:")
print(" ✅ Робот ездит прямо (оба мотора синхронизированы)")
print(" ✅ Предсказуемое поведение")
print(" ✅ Даже если один мотор немного слабее - система скомпенсирует")
print("\nЧТО ВСЕ ЕЩЁ НЕ РЕШЕНО:")
print(" ❌ Точность всё ещё примерно ± 20 см")
print(" ❌ Мы НЕ ЗНАЕМ, где робот на самом деле")
print(" ❌ Если батарея разрядилась - робот будет медленнее, но скорость 100 останется 100")
print(" ❌ Мы всё ещё гадаем по времени: 'ехать 5 секунд' - это как далеко?")
def level_2_smooth_acceleration():
"""
Дополнительный пример: плавный разгон через PID.
PID контроллер делает разгон мягким и предсказуемым,
а не рывком.
"""
mirte = robot.createRobot()
print("\n" + "=" * 70)
print("УРОВЕНЬ 2: Плавный разгон с PID")
print("=" * 70)
max_speed = 150
print("\nФаза 1: Разгон от 0% до 100% мощности")
for speed in range(0, max_speed, 15):
progress = (speed / max_speed) * 100
print(f" → Скорость {speed:3d} ({progress:5.1f}%)", end='\r')
mirte.setSpeed('left', speed)
mirte.setSpeed('right', speed)
time.sleep(0.1)
print(f"\nФаза 2: Едим с максимальной скоростью...")
mirte.setSpeed('left', max_speed)
mirte.setSpeed('right', max_speed)
time.sleep(2)
print("Фаза 3: Плавное торможение от 100% до 0%")
for speed in range(max_speed, 0, -15):
progress = (speed / max_speed) * 100
print(f" → Скорость {speed:3d} ({progress:5.1f}%)", end='\r')
mirte.setSpeed('left', speed)
mirte.setSpeed('right', speed)
time.sleep(0.1)
mirte.setSpeed('left', 0)
mirte.setSpeed('right', 0)
print("\n✓ Разгон/торможение завершены")
if __name__ == '__main__':
level_2_move_forward_with_pid()
time.sleep(1)
level_2_smooth_acceleration()
Архитектура: как PID контроллер работает
mirte.setSpeed('left', 100)
↓
Mirte OS: КАЖДЫЕ 100 мс
↓
┌─────────────────────────────────┐
│ 1. Читаем энкодеры │
│ current_speed_left = 95 │
│ current_speed_right = 100 │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ 2. Вычисляем ошибку │
│ error_left = 100 - 95 = 5 │
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ 3. PID алгоритм │
│ correction = P*5 + I*∫5 + D*5'│
└─────────────────────────────────┘
↓
┌─────────────────────────────────┐
│ 4. Корректируем PWM │
│ new_pwm_left = 150 + 1 = 151 │
│ new_pwm_right = 150 (как было)
└─────────────────────────────────┘
↓
Оба мотора крутятся синхронно ✓
Плюсы этого уровня
✅ Ученик видит PID контроллер — один из самых важных инструментов в инженерии
✅ Введение в концепцию обратной связи — система сама себя корректирует
✅ Робот ездит прямо — ровное, предсказуемое движение
✅ Всё ещё просто — 2 строки кода, но под ними скрывается серьёзная инженерия
Минусы этого уровня
❌ Точность всё ещё ± 20 см
❌ Не знаем точно, где робот находится
❌ Управление по времени, а не по расстоянию
Когда его использовать
? Возраст 10-12 лет — когда ученик спрашивает "почему криво?"
? Для первых проектов с движением — робот должен ездить прямо
? Для понимания инженерных решений — как инженеры решают проблемы
Ключевой вопрос ученика на этом уровне:
"Отлично, робот ездит ровно. Но как я узнаю, что он проехал ровно 1 метр? Как мне рассчитать время? Что если батарея разрядилась?"
Этот вопрос ведёт к следующему уровню.
Уровень 3: высокоуровневые функции (простая ROS абстракция)
Код
from mirte_robot import robot
import time
def level_3_move_forward_high_level():
"""
Уровень 3: используем высокоуровневые функции Mirte.
Вместо управления пинами или даже скоростями, мы просто говорим:
"проехать вперёд на 1 метр" - и система сама разбирается,
как это сделать.
За кулисами:
1. Функция публикует Twist сообщение (ROS интерфейс скорости)
2. Робот считает пройденное расстояние через одометрию
3. Робот автоматически останавливается, когда достиг цели
Это ИНТЕЛЛЕКТУАЛЬНОЕ управление!
"""
mirte = robot.createRobot()
print("=" * 70)
print("УРОВЕНЬ 3: Высокоуровневые функции Mirte")
print("=" * 70)
# Самый простой способ: просто вызвать функцию!
print("\n1. Вызываем: mirte.move_forward(duration=1.0, speed=50)")
print(" (робот ездит 1 секунду со скоростью 50)")
mirte.move_forward(duration=1.0, speed=50)
print("\n2. Робот двигается с автоматическим контролем расстояния")
print(" Под капотом происходит:")
print(" → Публикуется Twist сообщение с нужной скоростью")
print(" → PID контроллер синхронизирует моторы")
print(" → Энкодеры считают расстояние")
print(" → Одометрия обновляет позицию робота (X, Y, угол)")
print(" → Функция move_forward() читает одометрию")
print(" → Когда пройденное расстояние >= нужного - функция останавливает робота")
print("\n" + "+" * 70)
print("РЕЗУЛЬТАТ: Робот проехал примерно нужное расстояние!")
print("+" * 70)
print("\nЧТО УЛУЧШИЛОСЬ:")
print(" ✅ Точность: ± 5 см (реальная обратная связь от одометрии!)")
print(" ✅ Простой интерфейс - одна функция вместо 10 строк кода")
print(" ✅ Робот сам знает, когда остановиться")
print(" ✅ Введение в ROS парадигму (топики, одометрия)")
print("\nЧТО СКРЫТО ПОД КАПОТОМ:")
print(" → Стандартная ROS архитектура")
print(" → Одометрия (позиция робота)")
print(" → Управление через Twist топик")
def level_3_turn_example():
"""
Пример: повернуться на 90 градусов.
"""
mirte = robot.createRobot()
print("\n" + "=" * 70)
print("УРОВЕНЬ 3: Пример - повернуться на месте")
print("=" * 70)
print("\nВызываем: mirte.turn_right(angle=90)")
mirte.turn_right(angle=90)
print("✓ Робот повернулся на 90 градусов (с точностью ± 5 градусов)")
def level_3_complex_example():
"""
Пример посложнее: нарисовать квадрат через высокоуровневые функции.
"""
mirte = robot.createRobot()
print("\n" + "=" * 70)
print("УРОВЕНЬ 3: Проект - нарисовать квадрат")
print("=" * 70)
print("\nПроект: нарисовать квадрат 1x1 метр")
print("\nКод:")
print(" for i in range(4):")
print(" mirte.move_forward(distance=1.0, speed=0.2)")
print(" mirte.turn_right(angle=90)")
for i in range(4):
print(f"\nСторона {i+1}: едим 1 метр вперёд")
mirte.move_forward(distance=1.0, speed=0.2)
if i < 3:
print(f"Поворот {i+1}: вращаемся на 90 градусов")
mirte.turn_right(angle=90)
print(f"\n✓ Квадрат готов!")
if __name__ == '__main__':
level_3_move_forward_high_level()
time.sleep(0.5)
level_3_turn_example()
# level_3_complex_example() # раскомментируй, чтобы нарисовать квадрат
Интерфейс Mirte уровня 3
# Основные высокоуровневые функции:
mirte.move_forward(distance=1.0, speed=0.2)
# → Проехать 1 метр вперёд со скоростью 0.2 м/с
mirte.move_backward(distance=1.0, speed=0.2)
# → Проехать 1 метр назад
mirte.turn_right(angle=90)
# → Повернуться на 90 градусов вправо
mirte.turn_left(angle=90)
# → Повернуться на 90 градусов влево
x, y, theta = mirte.get_odometry()
# → Получить текущую позицию и ориентацию робота
Плюсы этого уровня
✅ Точность ± 5 см — реальная обратная связь от одометрии
✅ Простой API — одна функция вместо множества строк кода
✅ Введение в ROS архитектуру — под капотом работает стандартная ROS парадигма
✅ Переносимый код — похожие функции есть на других ROS роботах
✅ Видна интеграция системы — команды → датчики → решения
Минусы этого уровня
❌ Скрыта сложность — ученик не видит, что происходит под капотом
❌ Сложнее отлаживать — если что-то не работает, нужно лезть в ROS
❌ Нельзя реализовать сложную логику — функции ограничены
Когда его использовать
? Возраст 12-14 лет — когда нужна точность и простота
? Для проектов, требующих точности — навигация, рисование фигур
? Для введения в ROS без "шока сложности" — ученик видит результат, а не архитектуру
? Когда нужна масштабируемость — добавляем датчики, логика работает
Ключевой вопрос ученика на этом уровне:
"Эти функции хорошо работают, но что если мне нужна более сложная логика? Что если робот должен принимать решение на основе датчика расстояния? Как я это напишу?"
Этот вопрос ведёт к следующему, финальному уровню.
Уровень 4: полноценная ROS нода (профессиональная архитектура)
Код
#!/usr/bin/env python3
"""
Уровень 4: Полноценная ROS нода.
Это уже ПРОФЕССИОНАЛЬНЫЙ подход к разработке на робототехнике.
Вместо использования готовых функций, мы:
1. Подписываемся на ROS топики (одометрия, датчики)
2. Публикуем команды (скорость)
3. Реализуем нашу собственную логику управления
Это позволяет создавать произвольно сложные системы управления.
"""
import rospy
from geometry_msgs.msg import Twist
from nav_msgs.msg import Odometry
from sensor_msgs.msg import Range
from tf_transformations import euler_from_quaternion
import math
class MirteNavigationNode:
"""
ROS нода для управления Mirte.
Подписывается на топики, публикует команды, реализует логику.
"""
def __init__(self):
# Инициализируем ROS узел
rospy.init_node('mirte_navigation_node', anonymous=False)
# Издатель для команд скорости
self.cmd_vel_pub = rospy.Publisher(
'/cmd_vel',
Twist,
queue_size=10
)
# Подписчик на одометрию
self.odom_sub = rospy.Subscriber(
'/odom',
Odometry,
self.on_odometry_received
)
# Подписчик на датчик расстояния (если есть)
self.distance_sub = rospy.Subscriber(
'/mirte/distance_sensor',
Range,
self.on_distance_received
)
# Переменные состояния
self.current_x = 0.0
self.current_y = 0.0
self.current_yaw = 0.0
self.distance_to_obstacle = float('inf')
rospy.loginfo("MirteNavigationNode инициализирована")
def on_odometry_received(self, msg):
"""
Callback: вызывается когда приходит новое сообщение одометрии.
Одометрия - это информация о позиции робота:
- X, Y: координаты в глобальной системе
- Yaw: ориентация (угол)
"""
self.current_x = msg.pose.pose.position.x
self.current_y = msg.pose.pose.position.y
q = msg.pose.pose.orientation
(_, _, self.current_yaw) = euler_from_quaternion(
[q.x, q.y, q.z, q.w]
)
def on_distance_received(self, msg):
"""
Callback: вызывается когда приходит данные с датчика расстояния.
Это может быть ультразвуковой датчик, LIDAR и т.д.
"""
self.distance_to_obstacle = msg.range
def publish_velocity(self, linear_x, angular_z):
"""
Публикует команду скорости в ROS.
linear_x: скорость вперёд (м/с)
angular_z: угловая скорость (рад/с)
"""
twist = Twist()
twist.linear.x = linear_x
twist.angular.z = angular_z
self.cmd_vel_pub.publish(twist)
def move_forward_with_obstacle_avoidance(self, target_distance):
"""
Проехать вперёд, но если впереди препятствие - остановиться.
Это пример того, как на уровне ROS ноды можно реализовать
сложную логику, объединяя информацию из нескольких датчиков.
"""
start_x = self.current_x
start_y = self.current_y
rospy.loginfo(f"Едим вперёд на {target_distance} м (с проверкой препятствий)")
rate = rospy.Rate(10) # 10 Hz
while not rospy.is_shutdown():
# Вычисляем пройденное расстояние
distance_traveled = math.sqrt(
(self.current_x - start_x)**2 +
(self.current_y - start_y)**2
)
# Проверяем препятствия
if self.distance_to_obstacle < 0.2: # менее 20 см впереди
rospy.logwarn("⚠️ Препятствие впереди! Останавливаемся!")
self.publish_velocity(0.0, 0.0)
break
# Проверяем, достигли ли цели
if distance_traveled >= target_distance:
rospy.loginfo(f"✓ Достигли цели ({distance_traveled:.2f} м)")
self.publish_velocity(0.0, 0.0)
break
# Иначе продолжаем ехать
progress = (distance_traveled / target_distance) * 100
rospy.loginfo(f"Прогресс: {progress:.1f}%")
self.publish_velocity(0.2, 0.0) # 0.2 м/с вперёд
rate.sleep()
def move_in_square_with_sensing(self, side_length):
"""
Нарисовать квадрат, но если впереди препятствие - остановиться.
Пример сложной логики с использованием датчиков.
"""
rospy.loginfo(f"Рисуем квадрат {side_length}x{side_length} м")
for side in range(4):
rospy.loginfo(f"Сторона {side + 1}/4")
# Пытаемся проехать
self.move_forward_with_obstacle_avoidance(side_length)
# Если упёрлись в препятствие - выходим
if self.distance_to_obstacle < 0.2:
rospy.logwarn("Не смогли завершить маршрут - препятствие!")
break
# Если не последняя сторона - поворачиваемся
if side < 3:
rospy.loginfo("Поворот на 90 градусов...")
self.turn_in_place(angle=math.radians(90))
rospy.loginfo("✓ Квадрат завершен (или прерван препятствием)")
def turn_in_place(self, angle):
"""
Повернуться на месте на нужный угол.
angle: в радианах
"""
start_yaw = self.current_yaw
rate = rospy.Rate(10)
while not rospy.is_shutdown():
angle_diff = self.current_yaw - start_yaw
# Нормализуем угол
while angle_diff > math.pi:
angle_diff -= 2 * math.pi
while angle_diff < -math.pi:
angle_diff += 2 * math.pi
# Если повернулись - выходим
if abs(angle_diff) >= abs(angle):
break
# Иначе продолжаем вращаться
self.publish_velocity(0.0, 0.3) # 0.3 рад/с
rate.sleep()
self.publish_velocity(0.0, 0.0) # стоп
def main():
"""Главная функция"""
try:
# Создаём ROS ноду
navigator = MirteNavigationNode()
# Даём время на инициализацию
rospy.sleep(1)
# Пример 1: просто ехать вперёд
# navigator.move_forward_with_obstacle_avoidance(target_distance=1.0)
# Пример 2: нарисовать квадрат с проверкой препятствий
navigator.move_in_square_with_sensing(side_length=1.0)
except rospy.ROSInterruptException:
pass
if __name__ == '__main__':
main()
Архитектура ROS ноды
ROS нода запущена
↓
Подписывается на топики:
├── /odom (одометрия - позиция робота)
└── /mirte/distance_sensor (датчик расстояния)
↓
Каждый раз когда приходит новое сообщение:
├── on_odometry_received() обновляет x, y, yaw
└── on_distance_received() обновляет distance_to_obstacle
↓
Главная логика: move_in_square_with_sensing()
├── Проверяет: достигли ли цели?
├── Проверяет: препятствие впереди?
├── Принимает решение: ехать, остановиться или повернуться
└── Публикует команду скорости в /cmd_vel
↓
PID контроллер + моторы + энкодеры
↓
Робот движется и отправляет новую одометрию
↓
Цикл повторяется 10 раз в секунду
Плюсы этого уровня
✅ Произвольная сложность — можем реализовать любую логику
✅ Многодатчиковая интеграция — объединяем данные из разных источников
✅ Модульность — каждый метод делает одно
✅ Переиспользуемость — эту ноду можно использовать в других проектах
✅ Стандарт индустрии — это архитектура реальных роботов
✅ Профессиональный код — готово к deployment в реальные системы
Минусы этого уровня
❌ Нужно понимать ROS архитектуру
❌ Нужно понимать callbacks и асинхронность
❌ Больше кода, сложнее отлаживать
Когда его использовать
? На курсах вузов — робототехника, автономные системы
? Для сложных проектов — уклонение препятствий, планирование пути
? Когда нужна модульность — интегрируем несколько датчиков и поведений
? Для подготовки к реальной индустрии — это реальный код робот-разработчиков
Сравнение: одна задача, четыре решения
Таблица
Параметр |
Уровень 1 |
Уровень 2 |
Уровень 3 |
Уровень 4 |
|---|---|---|---|---|
Что используем |
PWM пины |
setSpeed + PID |
Функции Mirte |
ROS нода |
Размер кода |
5 строк |
10 строк |
5 строк |
100+ строк |
Скорость разработки |
⚡⚡⚡ |
⚡⚡ |
⚡⚡ |
⏱️ медленнее |
Точность |
± 50 см |
± 20 см |
± 5 см |
± 5 см |
Обратная связь |
❌ нет |
✅ слабая |
✅ полная |
✅ полная |
Переносимость |
❌ Mirte only |
❌ Mirte only |
⚠️ похожие функции |
✅ ROS стандарт |
Сложность логики |
простая |
простая |
средняя |
произвольная |
Для кого |
8-10 лет |
10-12 лет |
12-14 лет |
14+ / профи |
Использование |
обучение |
обучение + проекты |
проекты |
реальные системы |
Образовательная ценность: почему все четыре уровня?
Для ученика: путь от новичка к инженеру
Уровень 1 (PWM) — понимание физики
Вопрос: "Почему робот перемещается?"
Ответ: Потому что я установил напряжение на мотор через PWM
Уровень 2 (PID) — понимание инженерного контроля
Вопрос: "Почему робот не ездит криво?"
Ответ: Потому что PID контроллер читает энкодеры и корректирует скорость
Уровень 3 (функции) — системное мышление
Вопрос: "Откуда робот знает, что проехал 1 метр?"
Ответ: Из одометрии - система интегрирует данные энкодеров в позицию
Уровень 4 (ROS нода) — архитектурное мышление
Вопрос: "Как реализовать сложное поведение с несколькими датчиками?"
Ответ: Разделить на методы, подписать на топики, объединить логику
Ключевое: знания НАКАПЛИВАЮТСЯ, не теряются
На уровне 3 ученик НЕ ЗАБЫВАЕТ про PWM и PID — он их видит под капотом.
На уровне 4 ученик НЕ ЗАБЫВАЕТ про Twist и одометрию — он их использует в своей ноде.
Для учителя: гибкость и долгосрочность
Разные ученики, разные уровни:
Ученик, который впервые кодирует → уровень 1-2
Ученик, который знает Python → уровень 2-3
Ученик, готовящийся к вузу → уровень 3-4
Ученик, готовящийся к работе → уровень 4 + реальные проекты
Один робот, одна платформа:
8 лет: Mirte уровень 1 (PWM, LED, простые движения)
10 лет: Mirte уровень 2 (ровное движение, PID)
12 лет: Mirte уровень 3 (точная навигация, одометрия)
14 лет: Mirte уровень 4 (ROS архитектура, сложные проекты)
Выпускник знает:
✅ Физику электроники (GPIO, PWM)
✅ Инженерные решения (PID контроллер)
✅ Системное архитектуру (ROS топики, одометрия)
✅ Профессиональное программирование (ROS ноды, callbacks, навигация, SLAM)
Почему это важно
Традиционный путь (неправильный):
8 класс: Lego WeDo (закрытый, визуальный)
↓ (забываем всё)
10 класс: Arduino + датчики (открытый, но не ROS)
↓ (забываем всё, переучиваемся)
ВУЗ: ROS + C++ (шок сложности!)
Путь Mirte (правильный):
8 класс: Mirte уровень 1 (PWM)
↓ (знания остаются, добавляются)
10 класс: Mirte уровень 2 (PID) - видим PWM под капотом
↓ (знания остаются, расширяются)
12 класс: Mirte уровень 3 (ROS) - видим PID и PWM в системе
↓ (знания остаются, углубляются)
14 класс: Mirte уровень 4 (ROS нода) - проектируем архитектуру
↓ (готовы к ВУЗ и работе)
Практический вывод
На Mirte ученик видит весь путь — от одного провода к архитектуре системы.
Каждый уровень закрывает вопрос предыдущего:
"Почему криво?" → Уровень 2 (PID)
"Как узнать расстояние?" → Уровень 3 (одометрия)
"Как реализовать сложное поведение?" → Уровень 4 (ROS нода)
"Как работает реальная робототехника?" → Уровень 4 показывает это
Это не просто четыре способа написать код. Это четыре парадигмы инженерного мышления.
И именно поэтому Mirte работает как долгосрочная образовательная платформа — от ребёнка в 8 лет, управляющего LED через PWM, до старшеклассника, проектирующего ROS архитектуру.
Обсудить статью можно в ROS чате.
Народный курс по ROS2 на степике.
Как понять, что образовательный подход и образовательный робот приносит пользу? Главный критерий готовит ли он кадры с необходимыми знаниями и опытом для бизнеса и государства, именно поэтому были разработаны ROS2 соревнования которые пройдут на ROS meetup 21-22 марта 2026 года. Задача соревнований максимально приближена к той которую решает мобильная манипуляция в сервисной и промышленной робототехнике. Победители соревнования могут претендовать на вавакансии в ведущих робототехнических компаниях. О этих соревнованиях вы можете прочитать подробную статью на Хабре.
Комментарии (17)

PerroSalchicha
26.01.2026 08:43Это не просто «ещё один робот», это тре́к обучения инженерии, который можно растянуть на годы.
А является ли это достоинством? Я пытаюсь это представить с позиции ребенка: сколько времени можно прикручивать функции к одному и тому же проекту, прежде чем он совершенно надоест? Мне кажется, наоборот, лучше использовать разные конструкторы на разных уровнях, чтобы сохранять чувство новизны.

AmigoRRR Автор
26.01.2026 08:43Вы не уловили мысль, сшить все в одном роботе, хочется новизны в конструкции вперед в соревнование ROS2 роботов, меняйте конструкцию как вам хочется, но всегда помните что чтобы победить нужно выбирать оптимальный путь, а не перебирать бесконечно конструкции, сейчас нужны умные роботы, а не разные.

PerroSalchicha
26.01.2026 08:43Вообще не понял, мы говорим о роботе для обучения робототехнике, или о роботе для соревнований?

DmitryKolosov
26.01.2026 08:43Mirte — это недорогая полностью open-source платформа учебного мобильного робота, где ученик проходит путь «от телеуправления и Blockly до Python, SSH и полноценного ROS», задуманная как единый «трек» обучения от начальной школы до университета, оставаясь на одном и том же роботе и в одной и той же среде. Идея Mirte в образовании — не прятать “настоящую” робототехнику за игрушечными абстракциями, а сделать к ней удобный, поэтапный вход.
Кто придумал переизобретать колесо?
Инженерная образовательная линейка Фишерпрайс перестпла удовлетворять?

ViacheslavMezentsev
26.01.2026 08:43Тут подумал "запустить VS Code" на Raspberri Pi Zero 2W и не смог этого сделать. Ресурсов платы не хватает для "прокручивания" сервера на борту (мало ОЗУ). Поэтому для этой платы пишу обычный код C/C++ в Visual Studio, т.к. он не нагружает плату в отличие от VS Code.
Мне интересно сколько будет стоить такой универсальный робот, я уже не говорю про поддержку ROS, на котором будет идти VS Code? И дальше больше. Этот VS Code требует расширений и постоянно обновляется. Не на каждом ПК даже он нормально работает в полной комплектации.
У меня на Orange Pi 5 с 4ГБ ОЗУ и то со скриптом VS Code работает (серверная часть). Я пишу ноды для ROS1 и делаю это на C/C++, т.к. python тормозной.
AmigoRRR Автор
26.01.2026 08:43Можно еще через remote ssh, возможно тогда серверная часть будет меньше

Swarg32
26.01.2026 08:43Ничего революционного нет совершенно.

DmitryKolosov
26.01.2026 08:43Так каждая заметка этого автора в стиле бородатого анекдота про импортозамещение:
Всемирно известный квартет ищет двух скрипачей и виолончелиста. Всё остальное вроде есть.

cahdro
26.01.2026 08:43У нас в некоторых школах учителей математики не хватает, а вы такое предлагаете. Идея хорошая но не для каждой школы. Я про то что народным это никогда не станет в РФ, максимум в крупных областеых городах, в некоторых школах.
MAXH0
Это реклама Mirte? ИМХО намного лучше чем LEGO, но пока федеральные и международные стандарты соревнований не подтянутся, все будет так, как есть...
AmigoRRR Автор
Не не реклама, просто как пример как можно сделать, что можно перенять из зарубежного образовательного опыта. Есть мысль перенсти это на народного ROS2 робота. Собственно мы и проводим уже такие соревнования