Идея постройки автопилота появилась примерно 2 года назад. Хотелось создать полностью автономный аппарат способный добраться из точки А в точку Б с возможностью ухода от столкновений и облёта преград, способного преодолевать зоны глушения или отсутствия спутникового сигнала. Также хотелось иметь удобное и простое управление с помощью мышки как это реализовано в играх (стратегии) управляя движением ЛА с помощью точек. Начинать всё пришлось с нуля, как и эту статью поэтому если есть ошибки напишите об этом в комментариях. Начну по порядку.
Аппаратное обеспечение
Изначально я не знал какое железо лучше использовать для этого проекта, но в итоге пришёл к выводу, что оптимальным вариантом будет связка микроконтроллер (МК) + одноплатный компьютер. Где МК решает задачу стабилизации летательного аппарата (ЛА), его движению по заданному курсу и высоте, а одноплатный компьютер решает задачу навигации и движения по маршруту. Поскольку в планах был уход от столкновений компьютер должен был быть достаточно мощным чтобы обрабатывать информацию от датчиков обнаружения препятствий, компактным и не слишком дорогим на том момент под это описание наиболее подходил TinkerBoard, Raspbery тогда это была 3B+ и сильно уступала по характеристикам. В качестве МК хотелось иметь arduino совместимый контроллер т.к. на arduino имелась огромная база готовых скетчей и поэтому выбор пал на DUE 84 МГц, 32bit ARM Cortex-M3 т.к. он был наиболее мощным и должен был компенсировать прямоту моих рук)).
В качестве датчиков ориентации изначально я планировал использовать MPU 9250 с фильтром Маджевика, результаты его работы были отличными. Главным преимуществом этого варианта было то, что все расчёты, включая калибровки датчиков (акселерометра, гироскопа и магнитометра), находились на МК. Но возникла проблема, фильтр плохо компенсировал линейное ускорение, которое постоянно возникает при толчках или резкой смене курса. Выражается это в показаниях тангажа и крена, в момент ускорения они начинают уплывать, а проходя через пропорционально дифференциальный (ПД) регулятор и особенно дифференциальную часть, уплывание создавало проблемы. Поэтому пришлось использовать датчик с уже реализованным фильтром BNO 055.
BNO в отличии MPU 9250 имеет на борту встроенный МК Cortex M0 который сразу рассчитывает ориентацию в углах Эйлера, кватернине абсолютной ориентации и рассчитывает линейное ускорение хотя этот датчик тоже имеет ряд недостатков. Основной проблемой данного датчика является автокалибровка а точнее то что её нельзя выключить это такая «фитча» этого датчика и есть у этой калибровки неприятное свойство пропадать, иногда абсолютно внезапно даже просто находясь на одном месте без движения. Отражается это в основном на рысканье которое в данном датчике привязано к магнитометру и должно показывать направление на магнитный северный полюс (курс) но иногда оно показывает на 100 градусов в строну, а потом ещё покалибровавшись может вернутся обратно))). В прочем проблему курса ещё можно решить с помощью синхронизации с GPS. В остальном датчик работает отлично, тангаж и крен он всегда определяет правильно, и линейные ускорения не сильно сказываются на его работе, если, конечно, ускорение не превышает 2G, т.к. этот порог используется для измерения вектора гравитации и компенсации дрейфа гироскопов.
Остальной набор железа выглядит следующим образом: GPS Ublox Neo M8N с USB выходом,
барометр BMP 280, сонар HSCR 04 для получении данных о наличии земли и более точной вертикальной скорости, EEPROM 24c16 для хранения данных калибровки и настроек ПИД, GSM модуль Neoway M509E для отправки сообщений о координатах ЛА на случай аварии.
Функциональная схема показана на рисунке 1:
Рисунок 1 — Функциональная схема Автопилота.
Программное обеспечение
Для разработки ПО я использую QT вместе с IDE QT Creator т.к. он наиболее мне знаком, а также благодаря кроссплатформенности я могу запускать свои программы как на одноплатном ПК с Debian так, и десктопе с Windows, что очень удобно. Для разработки ПО микроконтроллера используется Arduino IDE. Для наглядности постараюсь представить все разделы на рисунке 2.
Рисунок 2. — Архитектура АП (BNO 080 добавлен на будущее).
1) Графический интерфейс управления — представляет из-себя спутниковую карту с помощью которой осуществляется управление ЛА. Сама программа отображения спутниковых снимков не моя, она была украдена мной тут (её автор тоже пытался сделать что-то подобное).
Управлять ЛА можно с помощью точек (маркеров) либо кнопок WADS. Для управления по точкам, необходимо проложить маршрут полёта зелёными маркерами они ставятся мышью (ПКМ), и нажать загрузить маршрут, либо использовать (красный) маркер мгновенного перемещения (ЛКМ) и тогда ЛА с текущей позиции полетит к этой точке, для его работы необходимо установить галку в чекбокс «Ручное» от случайных нажатий.
Все параметры маркеров вводятся в соответствующие поля на форме, удалить маркеры можно двойным щелчком средней кнопки мыши, при этом они по-прежнему останутся в памяти ЛА, для удаления из памяти необходимо использовать кнопку удалить маршрут. По достижению точки, как и в стратегиях ЛА, будет вокруг неё вращаться. Управление кнопками WADS напрямую управляет рулями с помощью ПД регуляторов. При нажатии каждой кнопки на вход регулятора поступает значение, например, при нажатии S тангаж 30 а при отпускании 0. При нажатии W -30 и т.д. Включается WADS с помощью чекбоксов: «ручное», «кнопки». Данный режим помогает проверить работоспособность всех рулей пред стартом. Работает графический интерфейс на ноутбуке, команды управления от графического интерфейса с помощью TCP соккета предаются в ядро. Графический интерфейс управления представлен на рисунке 3:
Рисунок 3 — Графический интерфейс управления.
2) Ядро автопилота эта та часть ПО которая вычисляется на одноплатном компьютере TinkerBoard. Ядро отвечает за навигацию и движение по маршруту. Для этого к компьютеру подключен датчик GPS. С его помощью можно получить текущее положение ЛА (широту и долготу) и сравнить это положение с тем, что имеется в маршруте полёта. В результате этой операции получается азимут на цель, который отправляется на микроконтроллер вместе с остальными параметрами полёта. В дальнейшем ядро можно оснастить своим IMU датчиком, чтобы реализовать ИНС. Например, можно использовать BNO 080 проинтегрировать, ускорение и получить скорость, а проинтегрировав скорость получить расстояние. Расстояние, полученное от ИНС, необходимо будет перевести в систему координат GPS (широту и долготу) для её использования в расчёте азимута.
Такую ИНС можно использовать в связке с GPS датчиком на случай временной потери связи со спутником, чтобы ЛА не пропустил «поворот» на точку. В момент работы от GPS ИНС будет постоянно корректироваться его показаниями и заполнять промежутки между периодами обновления GPS датчика. Таким же образом должен вносить поправки алгоритм машинного зрения или SLAM изменяя высоту точки и создавая смещения рассчитанного азимута. После окончания расчёта маршрута ядро отправляет по UART данные: азимут, высоту, угол атаки, тип точки, а также необходимо ли выполнять вращение вокруг этой точки.
3) Команды ядра выполняет микроконтроллер, основная задача МК следовать по заданному курсу на заданной высоте. Для этого на МК установлен IMU датчик BNO 055, барометр bmp 280 и сонар. Для движения по курсу используется азимут полученный от ядра он, сравнивается с текущим курсом и полученное рассогласование передаётся в ПД регуляторы управления рысканьем и креном. Управление тангажом осуществляется 2мя ПД регуляторами: 1-й определяет рассогласование текущей и заданной высоты, которое поступает на вход 2-го регулятора, при этом выход регулятора высоты ограничен текущим углом атаки, чтобы контролировать её набор. В случае, если в графическом интерфейсе тип точки выбран взлёт или посадка, для определения высоты используется сонар. Его показания комплексируются с данными барометра, чтобы наиболее точно определить расстояние до земли и вертикальную скорость. Помимо основных функций МК также собирает телеметрию о работе IMU датчиков, текущем направлении и высоте, передаёт их в ядро, где эти данные дополняются данными от GPS и поступают в графический интерфейс.
Заключение
На данный момент автопилот ещё находится на стадии полётных испытаний и полностью не настроен. Впрочем я провёл только два запуска и пока не подобрал коэффициенты для регуляторов.
Вообще ПД регуляторы мне кажутся не стабильными и хочется заменить их чем-то более надёжным, тем более они уже устарели. Также необходимо заменить расчёты с углами Эйлера на расчёты в кватернионах, т.к. последние более стабильно себя ведут при развороте ЛА на углы больше 120 градусов и полётах во время ветра.
Ссылка на исходники ЯД (с библиотеками) Github тут только исходники
rPman
Как препятствия то обнаруживать собираетесь?
Userpc0101 Автор
Вероятнее всего с помощью стерео камеры. Как вариант использую для этого Stereo Pi с модулем CM4 когда он выйдет. Средствами Open CV карту глубины можно превратить в облако точек, эти точки по UTP отправятся на Tinker Board. Далее средствами OpenGL ES создам графическое приложение где эти точки будут отрисовываться в виде кубов относительно объекта который будет считаться самолётом в виртуальном пространстве, объект будет напрямую связан с ИНС и повторять все движения самолёта. Кубы как уже стало понятно и есть препятствия измеряя расстояние от кубов до объекта в этой программе можно будет уходить от препятствий и вероятно даже огибать ландшафт если измерения от камеры будут достаточно точными. Но это пока только планы возможно на этот год.
Jacksonn
В текущей реализации (на одноплатнике TinkerBoard) вариант со стереокамерами вряд ли себя оправдает. Дело в том, что алгоритмы построения карты глубин весьма сложны в вычислительном плане.
Для работы в режиме реального времени годятся только т.н. локальные алгоритмы поиска соответствий, такие как Block Mathing и Semi-Global Block Matching, которые имеют свою реализацию в библиотеках OpenCV.
Но при этом Block Matching весьма неточен. И хотя он даст довольно высокий FPS (порядка 25-35 кадров в секунду при разрешении 480x320 точек), на карте глубин будет очень много артефактов, которые неизбежно станут приводить к ложным срабатываниям при определении препятствий. Плюс добавить к этому тряску от ветра и вибрацию от мотора при полёте, которые будут смазывать изображение.
Semi-Global Block Matching даст результаты получше в плане качества. Но при этом он гораздо сложнее по вычислениям. При аналогичном разрешении входных изображений (480x320 точек), частота кадров едва ли будет больше 5-6 FPS.
При статичных испытаниях этого, возможно, покажется достаточно, но при реальном полёте на скорости 40-50 км/ч такой частоты кадров будет очень мало. FPS можно, конечно, увеличить, занизив разрешение входной стереопары, но опять же, это сильно ударит и по качеству карты глубин.
Userpc0101 Автор
Мне кажется шансы есть нужны эксперименты.
Быстродействие:
ИМХО сейчас Stereo Pi с 4х ядерным процессором А53 1.2ГГц и памятью DDR2 может строить карту глубины 640х240 точек со скоростью 17 фпс. Я полагаю что модуль CM4 с DDR4 и более мощным А72 процессором 1.5ГГц даст прирост в 2раза в основном за счёт новой динамической памяти. При этом карта глубины стандартно загружает 2а ядра надеюсь остальных 2х ядер должно хватить для построения карты в облако точек.
Алгоритмы:
Касательно работы StereoBM тут вы правы всё что перечисли имеет место быть, но DJI как-то поставили стереозрение на фантом и мавик значит можно. Skydio 2 американский на Nvidia Xarier обрабатывает в SLAM информацию одновременно с 12ти камер, SLAM обновляет 1 миллион точек в секунду, говорят даже в лесу может летать, тоже получается можно.
Артефакты можно попробовать убрать медианным фильтром. Кстати я нарыл (украл) исходники других интересны алгоритмов для карты глубины уже расправленных и более стабильных и продуктивных (алгоритмы тут а тут статья) судя по описанию они даже шустрее чем обычное вычисление блоков.
Итог:
Задача сложная и нужны эксперименты. Варианты такие: TOF камеры на улице вообще не работают, лидары не работают на скорости да и на улице тоже плохо, радары страдают от механической развёртки или АФАР но это-же не истребитель. Что остаётся? Пока только стереокамера.
Jacksonn
Шансы есть, конечно, но повозиться придётся основательно.
Насчёт Mavic'a — мне как-то попадалась инфа, что стереозрение реализовано у него на основе FPGA-микросхем. Тот же Semi-Global Block Matching вполне позволяет пернести вычисление карты глубин на FPGA и это даст просто колоссальный прирост производительности. Но это уже другой класс устройств и нужно, конечно, уметь с ними работать.
Ну а Nvidia Xarier специально оптимизирован под обработку больших массивов данных в реалтайме. Там один GPU с его 512 ядрами чего стоит, на которых можно распараллелить расчёт диспаратностей для карты глубин, если алгоритм позволяет это сделать.
Поэтому, если решите экспериментировать со стереозрением, мне кажется, стоит сразу искать алгоритмы, которые дадут приемлемое соотношение между качеством и производительностью.
Userpc0101 Автор
Да возможно что и FPGA иначе бы они батарейку быстрее кушали. В общем тут не паханное поле работы и экспериментов но есть результаты других компаний значит шансы тоже есть. Может в будущем китайцы продадут готовый FPGA уже с алгоритмами))).
trapwalker
У вас же самолёт. О каких препятствиях речь?
Наверно это могут быть:
Мне кажется с той стерео-базой, которую вы можете достичь на своём ЛА (скажем, расставив камеры на концах крыльев), вы не добьётесь приемлемого качества распознавания глубины на расстояниях, достаточных для реагирования.
Userpc0101 Автор
Главные препятствия это высотные здания, башни, рельеф местности и то что вы описали.
Касательно стерео пары на крыльях, я тоже об этом думал но крылья изменяют свою геометрию во время полёта калибровка нарушится. Лучше закрепить стерео пару на корпусе в 2х составном телескопическом корпусе тогда внутренний прочный корпус не будет подвержен внешним воздействиям и к нему можно закрепить камеры смотреться это будет не очень как акула молот но зато калибровка не сбросится))). Ну и камеры конечно с объективами без искажений и с дальним фокусом. Пока это всё планы может окажется что стерео-камера вообще не сможет работать на ЛА например из-за вибраций т.к. они будут размывать картинку.
trapwalker
Просто камеры, как мне кажется, и сложность обработки изображения с них выводит ваш проект далеко за уровень PET-проекта. Вы, кажется, не сказали для каких целей планируете использовать дрон. Возможно максимально простым решением было бы просто задрать крейсерскую высоту до уровня заведомо превышающего ожидаемые препятствия.
Вообще, меня пугает задача даже с помощью стереопары облетать здания или деревья или какие-нибудь скальные уступы. да что угодно. Нужно слишком много про них понимать, чтобы, хотя бы, выбрать с какой стороны облетать препятствие. даи какой сысл вообще облетать, если в нештатном случае эффективнее просто задрать высоту до заведомо безопасной, а в штатных просто поточнее лететь по чекпоинтам. Можно нарисованный маршрут анализирвоать на бэкенде выдавая алерты в случае наличия ЛЭП, рельефа и прочего в зоне полёта на малых высотах. Сейчас поверхность земли довольно точно картографирована, а высоты зданий детектируются даже со спутника за счёт перспективного сдвига крыши относительно стен до основания.
Userpc0101 Автор
В основном ради академического интереса. Можно просто поставить дальномер вниз для измерения земли на ToF лидар 180м и пытаться предсказывать повышение уровня земли по его показанием тем более вы верно сказали показания уровня земли есть. Можно даже взять и купить готовую систему и вообще не мучится. У это всего есть минусы это не так интересно и эффективно а так будет повод научится делать SLAM.
trapwalker
А какие ТТХ сейчас и какие планируются у вашего дрона?
Дальность автономного полёта, грузоподъёмность, практический потолок, оптимальная высота полёта.
Была у меня как-то идея для мультикоптерных дронов разработать захват, который позволил бы дрону как птичке садиться на провод и заряжаться от него снимая ЭДС индуктивной петлёй в лапах.
Userpc0101 Автор
Ну пока у меня нет конкретных ТТХ, 30 мин полёта, на низкой высоте (50-100м лучше меньше) с препятствиями. Кстати о ЛЭП я тоже раньше думал (в мечтах) пролетел так 2-3 км в доль линии зарядил батарею полетел дальше))). Так можно наверно камчатку улететь))).
trapwalker
Не, просто так налету индуктивно не снять и миллиампера. Надо садиться, цепляться…
Пол часа, конечно, маловато для такой автономности. Вон коптеры и по часу летают, а у вас крыло, оно заведомо эффективнее.
А не думали медленный но дальнобойный и автономный от сотовой связи радиоканал вроде LoRa прикрутить?
Userpc0101 Автор
На TinkerBoard можно подключить любой Ethernet совместимый модуль, думал, когда ЛА планировался по больше хотел ставить ubiquiti Rocket M2 (кстати удивился когда узнал что её ставят на наши боевые роботы Нерехта) но сюда она не поместится нужно что-то другое. И после испытаний когда летать будет нормально.
trapwalker
Да какой ethernet? О Чем вы? spi интерфейс на gpio и все.
Userpc0101 Автор
Spi а как потом TCP к нему прикрутить? И на ноутбук тоже SPI ставить получается? Тогда и свой протокол обмена писать по радио с контролем суммы. Мне кажется Ethernet будет проще только если выигрыш большой в дальности тогда SPI, но LORA это вроде 30 км ubiquiti Rocket M2 50км как-бы его пока нет.
trapwalker
Зачем TCP? Зачем WIFI?!
Ваш этот рокет — из пушки по воробьям. Вам для вашего дрона достаточно канала в считанные десятки байт в секунду, чтобы передать ему обновлённую цепочку координат и принять телеметрию. Благодаря низкой скорости можно сделать транспондер очень энергоэффективным, пробивным (за счет более длинноволновых диапазонов) и помехозащищенным.
На ноуте USB-Uart + направленная антенна.
Плюс за счет дешевизны и энергоэффективности устройств можно наделать скрытых ретрансляторов на местности.
Данные можно слать AT-командами через какой-нибудь Telnet.
Userpc0101 Автор
А кстати я не говорил Rocket был нужен чтобы водить данные VNS, видеть как работает SLAM, что он там рисует.
А если только маршрут можно но тогда протокол придётся писать самому, TCP ведь гарантирует доставку. В прочем это не дальнолёт Wi fi пока хватает, на 1км ловит. В приоритете замена регуляторов вот тут мне бы понадобилась помощь.
trapwalker
=))))
А мужики-то не знают!
TCP гарантирует целостность пакета, если долетели все его куски. В тяжелых условиях, вроде работы на беспилотнике, лучше принять битый пакет, но быстро, чем целый, но не пойми когда и медленно. К тому же пакеты будут компактные бинарные с большой избыточностью для коррекции ошибок.
Так-то понятно, что WIFI и TCP проще юзать. Но если от этого зависит целостность недешевой железки, нужно иметь запасной план и на TCP с WIFI я бы совсем не полагался. Не для того они.
Userpc0101 Автор
Что сказать согласен, но пока Wi-fi меня устраивает а улучшать можно что-то бесконечно и сделать потом истребитель))). Со временем доберусь и до сети, может вообще поставлю 4G модем будет везде ловить))).
whoim
Лора и сотовая связь — все таки разные вещи. Автору может подойти готовый проект ultimate lrs, его несложно построить. Я использую проект qczek, но он рассчитан только на прямое РУ управление и обратную одностороннюю телеметрию.
И ещё, мне думается, в этом проекте было бы разумнее использовать готовый автопилот на базе полетника на F4/F7 под ардупилотом/ардукоптером и направлять его по мавлинк, он это умеет.
Userpc0101 Автор
Можно было-бы управлять любым АП с помощью ШИМ сигнала т.к. все они подключаются к радио аппаратуре. Можно даже взять железо из квадрокоптера уже со стереокамерой и научится им управлять, но стоит ли?
whoim
В этой индустрии есть уже давно прижившиеся протоколы, методы, на которые все ориентируются. Тот же мавлинк.
Зачем изобретать велосипед, если ваша задача — стереовидение и автопилот по нему?
Это отдельный блок, модуль, как хотите назовите. А так вы погрязнете, повторяя работу по "механике", которую десятки лет пилят десятки людей в открытом доступе.
И вторая команда пилит inav, к нему ваша управлялка по протоколу msp может цепляться и творить с ним что угодно.
Полетник стоят копейки, сотни задач решены, очень много разных железок поддерживается. В общем, вам бы в пару хоббиста, который на этом скушал много собак… вы бы пару лет сэкономили )
whoim
Говорю как человек, который полгода планировал пилить простенький автопилот для крыла, а потом увидел inav.
Userpc0101 Автор
Не теперь я не могу вот так взять и всё бросить. Ну и мне кажется вы не правы вот делают DJI свой фантом и думают а давайте туда Pixawk воткнём он-же уже всё умеет поставим туда только стереозрение получится норм квадрик))).
Нужно-ли говорить что причины здесь не только коммерческие но и технические. Если-бы мне был нужен ЛА для конкретной задачи тогда вы были-бы правы, что например INAV всё решено он дешевле и лучше для этого подходит, но задача в том и состоит сделать не типичный автопилот. К тому-же стереозрение тоже может быть связанно с датчиками автопилота и если АП не даст к ним прямой доступ придётся эти элементы дублировать. Тоже самое законы управления коммерческий АП может летать только на том что решает производитель и только так как хочет производитель с тем набором датчиков который предусмотрел производитель и т.д.
whoim
dji работает десятки лет десятками специалистов на зарплате, врядле вы такое выдюжите. Все данные с датчиков доступны по мавлинк, включая обработанные, отфильтрованные и при этом по проверенным всем миром алгоритмам.
Бросите вы все равно, не разорветесь же. И в итоге ни там ни там толку не будет, а очень жаль. Автопилот по стереовиденью — этого нет. А очень хочется)
Надумаете идти как я предложил — пишите, помогу чем смогу. Врядле много чем, я с трудом понимаю как работает тот же пид регулятор, но есть и опыт кое какой с протоколами (парсинг и вытаскивание данных), и с железками. И выход на наиболее опытную верхушку сообщества, которая ради такого дела вам поможет всем, чем возможно, и тестинг тоже. Сейчас цифровой линк сообща пилится в ней, смежная тема.
Userpc0101 Автор
Хорошо, буду иметь в виду.
akaAzazello
>>Stereo PI с модулем CM4
Последния версия Jetson Nano(от февраля 2020) поддерживает 2 CSI MIPI входа(но только с RPi cam V2) — там и производительность CPU близка к RPi4/TinkerBoard(ядра медленнее, но память быстрее) + GPU есть с очень немалой производительностью (но программировать лучше через CUDA модули OpenCV(они в extras находятся), а то OpenCL(для core OpenCV) родного там нет, а только через pocl и медленнее).
За чуть большую цену/вес и потребление(до 9Вт проти 6.5Вт) получите раз в 10 больше вычислительной мощи — и для карты глубины, для чего-нибудь ещё.
PS: пример использования Jetson для дрона: news.developer.nvidia.com/skydio-2-jetson-tx2-drone
Userpc0101 Автор
Хорошая новость, Open CV есть вариант использовать SteroBM вместе с CUDA вот только плата эта не влезет в текущий планер но как вариант на будущее. Ну и я полагаю GPU будет сильно загружен картой поэтому всё равно лучше передать на TinkerBoard и там засунуть в Open GL всё таки там тоже 80 Гфлопс (у Nvidia вроде 500 Гфлопс).
З.Ы. Я полагал там 1 csi и второй порт для экрана.
З.Ы.Ы. Хороший дрон я тоже рассказывал про него в верху.
akaAzazello
Ставить Jetson в пару к TinkerBoard врядли целесообразно — это скорее информация для версии 2.0 вашего самолёта :) Может, к тому времени и I/O платы поменьше физически (ближе по размеру к StereoPi) появятся для Jetson Nano Compute Module.
500GFlop у Jetson Nano — это для int для CNN — для float32 меньше. Впрочем, как и 90 для Tinker Board;) Но разница в производительности в 5-10 раз между платами обычно остаётся.
PS: оставлю для других читающих — новая версия jetson nano с 2мя CSI MIPI входами — B01 (старая с 1м — A02)
trapwalker
А вот такого рода штуку если заюзать?
https://software.intel.com/ru-ru/articles/intel-movidius-neural-compute-stick
akaAzazello
Это классная вещь она для CNN(нейронных сетей) и классификации/распознования объектов, но в процессе построения карты глубины со стерео-камер она не учавствует.
Т.е. может сильно разгрузить обычную систему со стерео-камерами или помогать в работе с камерой ToF, лидаром или же интеловскими стерео-камерами ( www.intelrealsense.com/compare-depth-cameras — в них карта глубины считается внутри камеры )