Flix: разработка полетного контроллера с нуля
1.78K subscribers
28 photos
20 videos
2 files
53 links
По всем вопросам @okalachev
Чат обсуждения: @opensourcequadcopterchat
GitHub: https://github.com/okalachev/flix
Учебник: https://quadcopter.dev
Download Telegram
Пока мы обсуждали печатные платы, пользователи собрали четыре успешно полетевших Flix'а! Ничего себе. Значит, что-то в моем проекте есть, раз люди готовы потратить столько сил, чтобы его повторить. А это ведь сделать намного сложнее, чем собрать дрон из готовых компонентов.

🚀 @peter_ukhov собрал уже второй дрон. Очень аккуратное проектирование и сборка. Используется кастомная модель рамы и кастомный держатель ESP32: микроконтроллер не приклеен, а вставлен в специальные пазы. Транзисторы расположены снизу лучей и закреплены в специальных держателях. А еще это первый Flix на IMU ICM-20948 (используется плата GY-ICM20948V2).

🚀 Первый Flix от иностранного подписчика! Пользователь @yi_lun с Тайваня смог собрать дрон в рамках школьного проекта, и он успешно полетел! Здорово, что мой проект нашел отклик и в других странах.

🚀 Сборка от пользователя @p_kabakov. Первый Flix на МК, отличном от классического ESP32. А конкретно — на ESP32-C3. Этот микроконтроллер имеет совершенно иную архитектуру (RISC-V), но благодаря поддержке Arduino, код фактически не пришлось менять, и он просто заработал!

🚀 И еще один полетевший дрон, собранный в близком к эталонному виде, но с четырехлопастными пропеллерами. Автор: @fisheyeu.

Как обычно, я добавил все проекты в свой реестр успешно собранных дронов. Там же находятся ссылки на все материалы от авторов, включая кастомные 3D-модели. #user
🔥45👏11👍102
Реализовал MAVLink Console — доступ до интерфейса командной строки Flix через QGroundControl (коммит).

Команды пользователя и ответ на них запаковываются в специальное MAVLink-сообщение SERIAL_CONTROL, которое содержит, собственно, текстовые данные для пересылки через виртуальную консоль и некоторые служебные флаги. Для вывода строк вместо Serial.printf введена глобальная функция print, которая выводит строку и в Serial, и в MAVLink.

Теперь можно выполнять все функции командной строки прямо с телефона или компьютера по Wi-Fi, включая калибровку датчиков, отображение логов, проверку моторов и прочее.

Сделал возможность запуска прошивки на голой плате ESP32, без подключенной IMU (коммит в Flix, коммит в FlixPeriph). Теперь прошивка не будет останавливаться с ошибкой. Это позволит легко протестировать прошивку без сборки дрона — при запуске появится точка доступа Wi-Fi и будут доступны все основные функции: командная строка, подключение к QGroundControl, просмотр параметров.

Если у вас есть ESP32, можете попробовать залить на нее прошивку: все базовые функции должны заработать! Это упрощает использование прошивки в качестве основы для других проектов на ESP32.
🔥31👍13❤‍🔥3💘1
Интересные видео еще одной, я уже сбился какой по счету, сборки дрона на моей прошивке. Автор: @jeka_chex.

У этого дрона самодельная стеклотекстолитовая плата с драйверами моторов (транзисторы AON7410 + конденсаторы), а также установлена камера для FPV-полетов! В комментариях больше фоток.

На первом видео полет с комбинации телефон + аппаратура, соединение по Wi-Fi, можно видеть телеметрию и отправлять команды. На втором видео короткий FPV-полет. Я, конечно, не подразумевал свой дрон для FPV-полетов, и он, как видно, не так уж и легко управляется, но эксперимент интересный!

На официальной странице с проектами пользователей добавлены все ссылки на материалы проекта. #user
👍22🔥121
flix2-draft.pdf
327.6 KB
Драфт принципиальной схемы моей будущей платы. Что есть в схеме:

⚡️ Микроконтроллер — ESP32-S3, а точнее, модуль ESP32-S3-WROOM-1-N16R8 с 16 Мб флеша. Еще в этом модуле 8 Мб PSRAM-памяти — это дополнительная оперативная память, которая может быть полезна для приложений с компьютерным зрением и нейросетями.

⚡️ Питание: повышающе-понижающий стабилизатор напряжения TPS63021 на 3.3 В. Повышающий, потому что в полете Li-Po может просаживаться и ниже 3.3 В, что может привести (и приводит) к перезагрузкам ESP32.

⚡️ Инерциальный модуль: ICM-42688-P (без магнитометра). На текущий момент эта IMU является рекомендуемой InvenSense моделью для новых проектов. Также установлен барометр — более свежий BMP388 (вместо устаревшего BMP280), хотя в его необходимости я все еще не уверен.

⚡️ Для управления моторами я выбрал транзистор IRLML6344 (совет ChatGPT) с очень низким напряжением открытия. Есть вся необходимая обвязка: подтягивающий резистор и защитный диод. Я рассматривал вариант применения драйвера мотора DRV8833, но с ним как будто схема получается еще сложнее, поэтому пока остановился на транзисторе.

⚡️ Разъем для подключения камеры по интерфейсу DVP (камеры OV2640, OV3660 и другие). Этот интерфейс занимает кучу пинов МК, но я все же хочу попробовать позапускать какие-либо алгоритмы компьютерного зрения на МК параллельно с полетным кодом. Любопытно посмотреть, что из этого получится.

⚡️ Есть «гребенка», на нее выведены интерфейсы I²C, SPI, UART и несколько GPIO-пинов. Правда полноценный GPIO-пин остался только один, остальные параллельно используются для камеры. Камеру вроде бы можно подключить и по SPI, где гораздо меньше занимаемых пинов, но с этим я пока не доразобрался.

Еще в схеме есть RGB-светодиод, ридер SD-карт и цепь для измерения напряжения аккумулятора. Жду ваших комментариев! #pcb
👍31🔥18👏52🤝1
Очень простой метод калибровки гироскопа

Я уже описывал принцип калибровки гироскопа в дроне — при запуске он усредняет данные с гироскопа в течение 1 секунды, чтобы получить значения смещений (bias). Однако, у такого подхода есть минусы: требуется неподвижность дрона во время запуска (не всегда обеспечивается); со временем bias может изменяться, и это не учтено.

Поэтому я внедрил очень простой и минималистичный метод динамической калибровки гироскопа. Калибровка происходит в фоне все время, что дрон находится на земле и неподвижен (переменная landed). Фактически, вся калибровка это простой low-pass-фильтр, который обновляет значения bias, когда дрон не летит:


static LowPassFilter<Vector> gyroCalibrationFilter(0.001);
gyroBias = gyroCalibrationFilter.update(gyro);


Коэффициент сглаживания α подобран экспериментально, чтобы bias достаточно быстро сходился, но и чтобы он не был слишком шумным. Для значения в 0.001, time constant (время, за которое фильтр сойдется на ⅔) составляет 1 секунду.

Перед активацией калибровки предусмотрена задержка в 2 секунды, чтобы не ловить шумы и пики, когда дрон только приземлился.

Полетные тесты показали, что с этим методом калибровки дрон очень хорошо держит yaw, а также ориентацию в целом. К энтузиастам, собравшим дрон: просьба накатить новую версию и сообщить о ваших результатах!
👍21🔥91
Наконец-то доделал новое демо-видео: https://youtu.be/hT46CZ1CgC4.
Использовал съемки полетов в Гимназии Примакова, множество пользовательских видео. Теперь это — официальное демо-видео для Flix версии 1.
🔥33👍15👏3🥴1
Использование прерываний

Главный цикл моей прошивки работает с той же частотой, что и IMU, при помощи вызова блокирующего метода waitForData. Изначально этот метод использовал поллинг: то есть беспрерывно опрашивал IMU, пока не появлялись новые данные. Но это не оптимальный вариант — он бессмысленно «ест» процессорное время. Лучше использовать INT-пин IMU. Этот пин меняет состояние, когда в IMU появляются новые данные, а обработчик прерывания от пина должен разблокировать главный цикл.

Но как реализовать такой паттерн, но при этом сохранить простой дизайн в Arduino-стиле с главным циклом и функцией loop?

Для этого используются механизмы синхронизации, доступные в FreeRTOS, а конкретнее — нотификация или семафор. Нотификация может послать сигнал для разблокировки конкретной задаче. Семафор универсальнее (хотя чуть медленнее) — он может разблокировать любую задачу, которая ждет на данном семафоре.

Для использования семафора в функцию waitForData добавляется код для ожидания поднятия семафора:

xSemaphoreTake(semaphore, portMAX_DELAY);


А в функции-обработчике прерывания должен быть код, который поднимает семафор:

xSemaphoreGiveFromISR(semaphore, &xHigherPriorityTaskWoken);


Именно так я и поменял способ работы функции waitForData в библиотеке FlixPeriph. Теперь она не использует процессор, а просто ждет прерывания.

Правда, все собранные на данный момент Flix (включая мой) не имеют подключенного INT-пина к какому-либо GPIO-пину МК. Поэтому для совместимости я сделал так, чтобы это прерывание могло также работать по обычному таймеру ESP32. Таймер конфигурируется на установленную частоту работы IMU.

Конечно, таймер ESP32 может немного рассинхронизироваться с таймером IMU, но как показала практика, на полет это не влияет. На видео выше дрон летает уже с этим изменением и видимых проблем не возникло.

Кроме того, я добавил в прошивку команду sys, которая выводит список задач FreeRTOS и процент использования CPU для каждой задачи. С помощью этой команды я увидел, что потребление CPU главным циклом (loopTask) сократилось со 100% до приблизительно 30%. В числе прочего, это может уменьшить энергопотребление и нагрев МК, а, возможно, и улучшить работу Wi-Fi.
👍31👏1🦄1
Написал новую главу учебника. Начал с основ: подробно расписал про геометрические объекты, используемые в прошивке, — вектора и кватернионы. Причем с акцентом именно на практическом применении:

📖 quadcopter.dev/geometry.html.

В главе есть интерактивная 3D-визуализация, которая показывает, как работают различные представления ориентации в пространстве. Визуализация сделана на three.js и рендерится в SVG. В процессе ее создания получилось что-то вроде микро-фреймворка для создания векторных 3D-визуализаций.

Кстати, в мой учебник пришел первый донат. Спасибо! Обещаю потратить его на какие-нибудь детали для новых сборок.
🔥60👍313🙏21
Media is too big
VIEW IN TELEGRAM
За последнее время еще несколько дронов с моей прошивкой от читателей со всего мира увидели свет.

Подписчик @chkroko представил подробную статью о своей версии: https://telegra.ph/Flix-dron-06-13.

В статье не только подробно описана сборка и сделанные модификации, но и приведены ссылки на компоненты в маркетплейсах, которые многие просили (правда, не на все).

@chkroko добавил барометр BMP580 и мониторинг напряжения батареи и тока (с отображением в QGC!). Но, самое главное, он сделал управление дроном через Bluetooth ESP32 с использованием геймпада Flydigi Vader 3.

Именно для таких экспериментов я и проектировал прошивку: по его патчу можно увидеть, что добавление нового способа управления выглядит довольно прямолинейно и просто! #user
🔥30👍152❤‍🔥1🏆1🍾1
Добавил поддержку классического инерциального датчика MPU-6050.

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

Поэтому решил добавить ее поддержку в проект. За основу взял Arduino-библиотеку от ElectronicCats. Поддержка реализуется в библиотеке периферии для моего дрона — FlixPeriph (ее, кстати, можно использовать и отдельно).

Надо отметить, что MPU-6050 поддерживает только подключение по интерфейсу I2C, так что это не самый оптимальный вариант для использования (I2C медленный). Тем не менее, многие дроны используют этот интерфейс, так что летать должно. В полете я не тестировал, но алгоритм оценки ориентации Flix с ней работает нормально, частота 1000 Гц.

Кстати, это делает мою прошивку совместимой (в теории) с микро-дронами от Espressif — ESP-Drone, где стоит именно этот датчик. Про них тоже многие спрашивали.
👍24🔥9🏆2
Полноценная калибровка RC 🎮

Переработал подсистему для работы с пультом управления и реализовал полноценную калибровку. Задача калибровки RC — определить диапазоны значений каналов (это было) и их маппинг (это добавилось).

1. Диапазоны. RC-приемник передает до 16 значений каналов управления. В цифровом протоколе SBUS используется 11 бит на канал (0..2047), что навеяно традиционным аналоговым протоколом PPM, где каналы кодировались в импульсах от 1000 до 2000 мкс. На практике обычно используется диапазон от 172 до 1811, но у более дешевых пультов он может быть каким угодно.

2. Маппинг. Стандартный порядок каналов для пультов самолетного типа — AETR, что означает: Aileron (крен), Elevator (тангаж), Throttle (газ) и Rudder (рыскание). На практике, опять-таки, порядок может отличаться. Часто он оказывается другим при подключении пульта по USB для симуляции. Иногда в пульте это можно настроить, иногда — нет.

Как видно, обе калибровки нужны. Я реализовал очень простой метод калибровки, который одновременно определяет и то, и другое (процесс калибровки на скриншоте).

▶️ Сначала прошивка просит установить все стики в «нулевые» позиции. Значения каналов запоминаются.

▶️ Затем требуется поочередно переместить стик каждого нужного нам канала в положение максимума —  вверх или вправо. Для каждой такой итерации функция калибровки calibrateRCChannel ищет канал, значение которого изменилось больше всего (минимум 10). Именно этот канал и сохраняется в маппинг. Диапазон берется из запомненной нулевой позиции и найденной максимальной.
Если канал не найден, в маппинг записывается NAN. Так, можно не задавать каналы для арминга и переключения режимов — они опциональны.

Диапазоны каналов сохраняются в параметры RC_ZERO_X и RC_MAX_X, маппинг — в параметры RC_ROLL, RC_PITCH, ...

В итоге код подсистемы для пульта все еще остался достаточно простым, хотя и намного более функциональным. Результат можно посмотреть по ссылке — rc.ino.

Он по прежнему работает и в симуляторе, и в реальности. Также там есть некоторые архитектурные изменения, например, я убрал массив control и заменил его переменными controlRoll, controlPitch, ..., чтобы логически отделить команды пилота от массива каналов (при управлении со смартфона каналов нет). В общем дизайн стал чище и логичнее.
👍19🔥42🏆1🍾1
This media is not supported in your browser
VIEW IN TELEGRAM
Это — самый первый летающий Flix на бесколлекторных моторах!

Пользователь @chkroko проявляет впечатляющую активность и теперь успешно собрал дрон на бесколлекторниках. Используется ESC SpeedyBee Mini V2 4-в-1, причем он подключен по интерфейсу DShot (не PWM). DShot — это цифровой интерфейс, который, в отличие от PWM, не требует калибровки, поддерживает реверс и телеметрию.

Как я и предполагал, алгоритм управления не потребовал никакой модификации для работы с BLDC — многие об этом спрашивали. Сам патч для поддержки DShot можно увидеть здесь. Используется библиотека DShotRMT (с правками).

Как всегда, сборка добавлена в «официальный» реестр сборок, там указаны все подробности и дан полный список компонентов. #user
🔥49👍1632🏆1🍾1
🐍 pyflix — Python-библиотека для Flix

Это большое нововведение в проекте! Теперь возможно получать доступ к Flix из Python-скрипта (по Wi-Fi): читать телеметрию, выполнять команды, управлять полетом (эта часть в разработке).

Как обычно, дизайн библиотеки построен по принципу простоты и минимализма. Вся работа происходит через объект класса Flix:


from pyflix import Flix
flix = Flix() # создаем объект и ждем подключения


Телеметрия читается через поля объекта, причем их имена соответствуют именам глобальных переменных в коде прошивки:


flix.mode # текущий режим
flix.armed # заармлен ли дрон
flix.landed # на земле ли дрон
flix.attitude # текущая ориентация
flix.rates # угловые скорости
flix.channels # каналы с RC
flix.motors # выходы на моторы
flix.acc # данные акселерометра
flix.gyro # данные гироскопа


Библиотека построена вокруг паттерна Observable — предусмотрена возможность реакции на события:


flix.on('connected', lambda: print('Есть подключение'))
flix.on('disconnected', lambda: print('Подключение потеряно'))
flix.on('print', lambda text: print(f'Flix: {text}')) # вывод консоли дрона


Кроме того, можно ждать наступления событий, в том числе с условием:


gyro = flix.wait('gyro') # ждем новых данных гироскопа
attitude = flix.wait('attitude') # ждем обновления ориентации
flix.wait('armed', value=True, timeout=10) # ждем арминга
flix.wait('motors', value=lambda motors: not any(motors)) # ждем, когда все моторы остановятся


Доступна работа с параметрами и CLI:


pitch_p = flix.get_param('PITCH_P') # прочитать параметр
flix.set_param('PITCH_P', 5) # установить параметр
imu = flix.cli('imu') # выполнить команду
flix.cli('reboot') # перезапустить дрон


Запланировано автоматические управление полетом (пока не работает):


flix.set_position() # управление позицией
flix.set_attitude() # управление ориентацией
flix.set_rates() # управление угловыми скоростями
flix.set_motors() # управление моторами
flix.set_controls() # управление "стиками" (уже работает)


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

Библиотека уже доступна в pip (pip install pyflix) и работает как с реальным дроном, так и с симулятором. Ее можно попробовать прямо сейчас. Что думаете? Что добавить или изменить в API?
🔥41👍9🏆21
⚡️Первое настоящее испытание Flix «в полях».

Мой проект будет использован в качестве платформы в проектной смене «Роболагерь» в лагере «Пионер» под Питером. В течение этой и следующей недели 9 школьников будут собирать дроны Flix и пытаться заставить их полететь, причем желательно автономно (если повезет!).

Компоненты закуплены, в том числе много дополнительных — всевозможные варианты ESP32, ESP32-CAM, IMU, дальномеры, барометры и другие датчики.

Я тоже туда приеду через пару дней — обязательно напишу, как все пройдет и что у ребят получится.

Пишите — какие проекты можно попробовать реализовать в рамках такой смены?
🔥60👍197🎉3🤯1🏆1
Добрался до Роболагеря. За эти несколько дней все участники уже собрали свои квадрокоптеры, и больше половины из них уже успешно полетели! 🎉

Дети самостоятельно спроектировали и изготовили рамы для дронов (по мотивам моей). Используется как 3D-печать, так и лазерная резка по дереву — оба типа рамы успешно летают. Летаем с пульта BetaFPV через Wi-Fi.

Из модификаций: собственно, кастомные рамы, buck-boost-конвертеры для питания, многие поставили на дроны ИК-дальномеры. На один из дронов будет установлен датчик PMW3901 (optical flow). Еще один участник заводит дрон на плате ESP32-CAM. На этой плате не хватает пинов для моторов, и поэтому команды управления моторами будут передаваться на вспомогательный AVR, который будет генерировать PWM-сигналы.

В качестве основных задач смены пока думаем про: удержание высоты по дальномеру (реально), obstacle avoidance (реально), удержание позиции по optical flow-датчику (посложнее), автономный полет.
🔥36👍162🎉1