Всем добрый день, сегодня я хотел бы поделиться своим опытом проектирования ракеты с управлением вектора тяги. Так получилось, что я долго сидел дома и решил купить 3D принтер, ну и конечно первое же, что я решил распечатать - модель ракеты типа «Батут-М», которую можно приземлять и беспроводной меч-огнемет.
Занимался ли я созданием ракет раньше? Никогда!!! Ну правда в одной моей iOS игре на самописном Objective-C движке «Minimal Man» - можно из ракетомета стрелять ракетами, например ограбить магазин, выпустив ракету по продавцу. В игре все ракеты взрываются.
Я выбрал 3D-принтер «Creality Ender-5», но сейчас уже доступна версия «Creality Ender-5 Pro» с тихими драйверами. Мои же драйвера шаговых моторов пищали при печати, но я купил обновленную плату с Aliexpress и прокачал принтер до «Pro» версии вручную. Теперь он работает бесшумно.
Ох, первое что я печатаю в жизни - и уже ракета, которую я хочу приземлить!!! Ну так запускаем программу SketchUP и проектируем 3Д модель.
По моему замыслу, все детали ракеты должны быть напечатаны на 3Д принтере, включая рычаги сервомоторов, собираться отверткой, без использования клея, проволок и прочих деталей, как обычный конструктор. Для каркаса я купил пачку алюминиевых трубок диаметром 6мм, но конечно в дальнейшем их хочу заменить на более легкий пластик из ЧПУ станка.
Как видно на 3Д модели нижней части ракеты - для отклонения вектора тяги я использую самые дешевые сервомоторы SG90 с Aliexpress, которые конечно же желательно заменить на более элитные. Я заказал дорогие аналоги данных сервомоторов с сайта HobbyKing - но к сожалению мне их так и не доставили, вернули деньги. Сейчас я все еще ищу качественные сервомоторы, если можете что-нибудь посоветовать, отпишите в комментариях, буду очень рад совету.
Пробуем распечатать 3Д модель нижней части ракеты, которую я называю «Система трех колец» или «Нагибатор двигателя»
Естественно, я сделал мобильное приложение «Ракета» для управления ракетой через iPad, iPhone, с джойстика от PlayStaton или с любой другой bluetooth кнопки, подключил сервомоторы и все оттестировал. Несмотря на то, что я печатаю в первый раз, распечатать все получилось очень легко, и буквально за несколько минут мне удалось собрать тестовую модель отверткой. Очень советую аккумуляторную отвертку от Xiaomi, с ней собирать делали очень даже приятно, детали собираются просто, как конструктор.
Я сразу же распечатал переходники для разных типов двигателей, включая твердотельные.
Затем я подключил соосные моторы к системе отклонения «трех колец» через дешевые китайские регуляторы бесколлекторных моторов на 30А и протестировал тягу с iPad и с джойстика и убедился, что тяга есть.
Собираем нашу модель отверткой, прикручиваем держатели для Arduino Nano и аккумулятора.
Почему же я решил делать все на итальянском микроконтроллере Arduino, да и еще на версии Arduino Nano? Все дело в том, что многие разработчики дронов и коптеров из России во всех своих статьях пишут, что не нужно разрабатывать полетный контроллер самому, нужно покупать готовые. Напомню, что полетный контроллер - это так называемые «мозги» устройства, то есть другими словами все советуют покупать готовые «мозги» (зарубежного производства).
Так-так-так, то есть все считают, что разработать свой полетный контроллер «с нуля» - это очень сложно. Из аргументов - «там сложно реализовать PID контроллер». Вообщем для того, чтобы выяснить в чем сложность, я решил начать с платы Arduino, все-таки это хобби у меня такое - ракету собирать, почему бы и не попробовать на Arduino. Если ее мощности не будет хватать, я смогу заменить ее на более мощную плату. Если вы знаете, на какую плату ее можно заменить, пожалуйста посоветуйте что-нибудь подходящее в комментариях.
Что же такое PID регулятор и почему его так боятся? Пропорционально-интегрально-дифференцирующий (ПИД) регулятор, согласно Википедии, имеет единственное предназначение - в поддержании заданного значения r некоторой величины y с помощью изменения другой величины u.
Посмотрим формулу:
Так, ну да, видимо интеграл в формуле выглядит довольно пугающе, сразу вспоминаются флешбеки с лекций по математическому анализу, когда ты на скорость переписываешь закорючки с доски, поначалу вникая, но в какой-то момент просто отпускаешь все мысли и перерисовываешь все с доски, как иероглифы, в надежде, что разберешься позже.
Но дело в том, что в интернете много готовых реализаций классов PID контроллера, которые выглядят просто как готовая функция, которой передаешь отклонение ракеты и она просто возвращает угол, на который нужно повернуть ракету! Всего-то!
Итак, определим два параметра нашей ракеты, числа «input_x» и «input_y»:
«input_x» - отклонение ракеты влево-вправо от вертикального положения
«input_y» - отклонение ракеты взад-вперед от вертикального положения
Если «input_x» больше нуля, значит ракета наклонилась вправо на «input_x» градусов, если меньше нуля - значит ракету отклонили влево. Тоже самое и для «input_y». Значит при нулевом «input_x» и «input_y» - ракета стоит вертикально.
Данные значения получаем от IMU сенсора с помощью функции IMU.readAcceleration, который уже встроен в мою версию Arduino Nano (так же в моей Arduino Nano уже есть встроенный барометр, для определения высоты, датчик температуры, bluetooth модуль, микрофон и другие датчики. И все это - на крохотной плате):
IMU.readAcceleration(input_z, input_x, input_y);
Теперь у нас есть значения отклонения ракеты, можно инициализировать PID контроллер:
double P = 1.0, I = 0.05, D = 0.03;
double refresh_time = 10;
PID xPID(P, I, D, refresh_time);
PID yPID(P, I, D, refresh_time);
xPID.setpoint = 0; // Ноль - для вертикальной стабилизации по оси X
yPID.setpoint = 0; // Ноль - для вертикальной стабилизации по оси Y
При создании PID регулятора нужны три числа:
P - Пропорциональная составляющая
I - Интегрирующая составляющая
D - Дифференцирующая составляющая
refresh_time - интервал, с которым мы будем опрашивать наш PID контроллер и получать значение для сервомотора, например раз в 10 миллисекунд.
Данные коэффициенты подбираются вручную либо при помощи специальной библиотеки PIDtuner на стенде, попробую немного объяснить, на что влияют эти коэффициенты:
P - Пропорциональная составляющая для получения выходного сигнала, противодействующему отклонению регулируемой величины от заданного значения (в нашем случае нуля), наблюдаемому в данный момент времени. Допустим мы установим коэффициент P=1, тогда при отклонении ракеты вправо на 15 градусов, сервомотор отклонит мотор в противоположную сторону на 15 градусов для того, чтобы ракета смогла восстановить вертикальное положение. Если бы коэффициент мы установили в значение P=2, то при отклонении ракеты на 15 градусов, сервомотор отклонил бы вектор тяги на 30 градусов в противоположном направлении.
I - Интегрирующая составляющая, коэффициент, благодаря которому ракету меньше «колбасит влево-вправо», пока она пытается стабилизироваться в вертикальном положении. Коэффициент, который пытается загасить волну отклонений «влево-вправо» как можно быстрее.
D - Дифференцирующая составляющая, коэффициент, который предсказывает, что пока ракету колбасит «влево-вправо» её может заносить по инерции, то есть этот коэффициент позволяет затормозить ракету заранее перед тем, как она приняла вертикальное положение, то есть избежать попадания ракеты в дрифт. Дрифт коэффициент, я его называю именно так.
Естественно, данные описания этих коэффициентов я привел в своей упрощенной интерпретации, подробнее можете сами почитать на википедии. В реальном проекте конечно есть много нюансов, например из-за значения «I» внутри функции PID-контроллера накапливается интегральная ошибка, которую нужно обнулять перед запуском, либо хранить ошибку в массиве чисел и удалять старые значения методом FIFO (англ. first in, first out — «первым пришёл — первым ушёл»), но это все экспериментальные функции, для общего понимания можете про это пока не думать.
С коэффициентами разобрались, это просто три числа, которые мы пытаемся подобрать, ничего сложного.
Теперь раз в 10 миллисекунд нам нужно получить значение для отклонения сервомоторов «output_x» и «output_y»:
// Получение значений отклонения для сервомоторов из PID-регулятора:
xPID.input = input_x;
yPID.input = input_y;
output_x = xPID.getResultTimer();
output_y = yPID.getResultTimer();
На данном этапе у нас есть значения «output_x» и «output_y» - поворачиваем наши сервомоторы на это значение.
Все!!! Так легко, просто кайф!!! Ну конечно же в реальном проекте я еще фильтровал значения с акселерометра через фильтр Калмана, для того, чтобы исключить шум на графике, но даже без фильтров с современных акселерометров приходят довольно точные значения отклонения, а некоторые IMU сенсоры уже содержат встроенный фильтр Калмана.
Для того, чтобы получить значения P, I, D коэффициентов автоматически, я распечатал тестовый стенд, на котором ракета может свободно вращаться, затем подключил библиотеку PIDtuner, запустил, ракета немного покачалась туда-сюда и на выходе PIDtuner я получил в логе коэффициенты:
double P = 0.55, I = 0.05, D = 0.03;
Теперь вписываем эти коэффициенты в мобильное приложение и пробуем запустить ракету
Первый запуск показал, что тяга действительно есть, ракета способна летать, но я все-таки запускал ракету в комнате, поэтому очень не хотел ее разбить, на гашетку я давил не в полную силу. Также видимо нужно более тщательно подобрать PID коэффициенты, просмотрев видео с запуском, можно заметить, что ракета все таки немного заваливается.
Сборку ракеты я записал на видео (ссылка ниже), на видео видно, что ракету в полете немного закручивает по часовой стрелке, все дело в китайских регуляторах моторов, которые раскручивают один мотор немного быстрее, чем другой. Но ничего, в следующих обновлениях я попробую заменить регуляторы или добавить еще один ПИД-регулятор на «повороты» - и если ракету начнет закручивать, можно попробовать использовать значение из ПИД-регулятора для понижения скорости мотора, который крутится быстрее другого.
В теории - к данной ракете можно прикрепить крыло - и попробовать приземлить ракету горизонтально. Либо прикрепить шар с водородом - и получится дирижабль с управлением вектора тяги. Ну либо можно попробовать вместо электромоторов попробовать сконструировать ракету на турбореактивной тяге (в продаже есть неплохие двигатели для моделей реактивных самолетов), правда придется переместиться в гараж.
Полное видео сборки можете посмотреть по ссылке:
Так же я по быстрому записал видео про сборку «беспроводного меча-огнемета», это видео вы так же можете найти на YouTube канале:
https://www.youtube.com/c/МаксимГеймдев
Да и в целом я написал эту статью для поиска единомышленников, если вы тоже увлекаетесь робототехникой или разработкой дронов, скидывайте свои проекты в комментарии либо пишите, что бы вы хотели увидеть в следующих постах.
Заранее большое спасибо за фидбэк и критику :)
Комментарии (38)
maxwolf
17.10.2021 04:10+7Когда-то давно я почти начал идти по этому пути, но потом внезапно купил дачу, и тема отложилась в долгий ящик…
Несколько лирических замечаний: у копеечных акселерометров маленькая точность, узкие диапазоны и большое время реакции, а нормальные стоят космических денег (какой-нибудь ADIS16445BMLZ стоит более $500, при цене наны со всеми датчиками в $30); при ракетных скоростях и ускорениях 10мс интервал — очень долго, но и в него много математики не всунуть; за энтузиастами управляемой ракетной техники внимательно наблюдают и бородатые люди в свободных одеждах, и гладко выбритые люди в строгих костюмах (это так, на уровне слухов, но IMHO, тоже стоит иметь в виду...)maxim-gamedev Автор
17.10.2021 16:13+210мс интервал - очень долго, да, нужно в 100 раз быстрее (1000 раз в секунду), придется другую плату поискать, я слышал есть маленькие и мощные, но забыл название :)
FGV
17.10.2021 20:48+21000 раз в секунду
а сервомашинка переварит 1мс? если память не изменяет там шим, 1.2мс +/-0.6мс.
maxim-gamedev Автор
18.10.2021 17:44+1Ой, опечатался, в 10 раз быстрее нужно, не в 100))) Ну и с учетом вашего комментария, даже не в 10, а в 5! Чтобы выжать максимум из китайских SG90 и SG90S - я написал свою библиотеку SportServo, пробовал много разных вариантов, даже с нелинейной скоростью и торможением, но все равно максимум выжать после фильтра Калмана удалось - обновление раз 10мс. Но ниже в комментариях советуют coreless крутые серво - там частота 560Hz
Пока выбрал на замену плату Teensy 4.0:
Teensy 4.0 - 600 МГц, 1 МБ оперативной памяти и 2 МБ энергонезависимой Flash-памяти
Arduino Nano 33 BLE Sense - 64 МГц, 1 МБ флеш-памяти и 256 КБ оперативной памяти
FGV
18.10.2021 18:22+2...комментариях советуют coreless крутые серво - там частота 560Hz...
Нафига такая скорость? Думаю 5-10 мс вполне хватит, у вас довольно стабильно изделие себя ведет. Плюсом фильтрация показаний датчиков вносит задержку, так что сначала надо бы определить целесообразность увеличения быстродействия дорогими сервами.
но все равно максимум выжать после фильтра Калмана удалось - обновление раз 10мс.
Фильтр Калмана? А параметры у него какие? Чую что для "фильтрации" датчиков он в конечном итоге превращается в обычный ФНЧ первого порядка -> легко заменяется на целочисленную арифметику, что та же АВРина вполне переварит на 1-2кГц.
maxim-gamedev Автор
22.10.2021 13:24+1Ну тут дело в SG90, без фильтра Калмана на высокой частоте они дребезжат)) Поэтому пришлось раз в 10мс вызывать Калмана и еще почему-то в коде я округляю показания, видимо только с такой конфигурацией удалось избежать дребезжание. Но я все же хочу попробовать дорогие серво, параметры так что будут другие
FGV
22.10.2021 14:34+2… SG90, без фильтра Калмана на высокой частоте они дребезжат…
…и еще почему-то в коде я округляю показания, видимо только с такой конфигурацией удалось избежать дребезжание.
Просто на выходе регулятора был шум вот сервы и дребезжали.
Грубо говоря приходит на серву импульс 1.1мс, через 10мс - 1.2мс, потом опять 1.1мс итд, серва эту мелочевку начинает отрабатывать отсюда и дребезг.
Введение фильтра (то что на скриншоте на Калмана не очень похоже) шум уменьшило, округление еще сильнее уменьшило и соответственно ушел дребезг. Вобще вместо непонятного фильтра можно воткнуть обычный фнч:
x_angle=x_angle+K*(sensor_x-x_angle);
где K - коэффициент фильтра > 0 и <1.
Но я все же хочу попробовать дорогие серво…
Без фильтра будет тоже самое дребезжание.
iAmGeorge
17.10.2021 04:47+5maxim-gamedev Автор
17.10.2021 16:16+2Класс!!! Я тоже думал сделать что-то похожее, думал даже аналог лампы из Pixar сделать
DonAgosto
17.10.2021 09:56+4при ракетных скоростях и ускорениях 10мс интервал — очень долго
Ну для быстродействия стабилизатора важнее наверно не скорости и ускорения, а моменты инерции. Но дело по большей части не в этом.
У самодельных запусков есть такая проблема: С одной стороны, желательно ускорение на старте делать как можно меньше — для уменьшения нагрузки на узлы ракеты и для зрелищности, чтобы неподготовленный зритель просто успевал понять что это вобще было. С другой — на малых скоростях парировать возмущения нечем, тк аэродинамические стабилизаторы не работают. Вот всем и приходится пользовать двигатели с такими кривыми давления, чтобы как можно быстрее набрать нужную для аэродинамики скорость.
И вот тут как раз вполне может помочь даже самая простая стабилизация. Берем двигатель, обеспечивающий минимальное ускорение — в начале подъема скорости имеем небольшие, реакции простого автомата вполне хватает. Дальше на основном участке полета активную стабилизацию просто отключаем, тк уже работает аэродинамика.
Retifff
17.10.2021 10:47+2Сейчас я все еще ищу качественные сервомоторы, если можете что-нибудь посоветовать, отпишите в комментариях, буду очень рад совету.
Если стоимость не смущает, посмотрите KST, подходящие по характеристикам.
maxim-gamedev Автор
17.10.2021 16:25+2KST X08H V5.0 - вроде подходит, 8.4г вес (SG90 - 13г) + усилие 3.1 кг/см (против 1.98 кг/см у SG90)
Retifff
17.10.2021 21:31+2Это где вы усилие 3.1 нашли? Там 2.8 кг/см и то при напряжении 8.4 V. Это высоковольтные машинки, в отличие от SG90, и максимальное усилие у них только при 8.4 V. Хотя у вас там не видно каких-то особенных усилий, вроде.
Dark_Purple
17.10.2021 11:26+4В комнате так чисто)) и да, умеете, магёте!
iShrimp
17.10.2021 19:18+2Тут либо ящик с деталями убран с виду, либо это отдельная комната для съёмки, а мастерская рядом :)
sappience
17.10.2021 22:27+2Сейчас я все еще ищу качественные сервомоторы, если можете что-нибудь посоветовать, отпишите в комментариях, буду очень рад совету.
Советую вертолетные сервы посмотреть, на автомат перекоса для радиоупрявляемых вертолетов специально делают быстрые, точные и весьма сильные моторы (на управление шагом хвостового винта еще более быстрые, но менее мощные). Как правило они цифровые, имеют zero dead-band и часто поддерживают частоту управляющих импульсов выше стандартных 50Hz (до 330Hz бывает). Модели подороже сделаны на brushless (без щеток надежнее) coreless (ротор без сердечника имеет меньшую массу и меньшую инерцию) движках. Например:
https://www.helidirect.com/collections/heli-servosmaxim-gamedev Автор
18.10.2021 17:49+2Большое спасибо, теперь я понял, почему они такие дорогие)) Без щеток и ротор без сердечника, круто) Буду погружаться в мир дорогих «вертолетных серво», благодарю)))
propell-ant
18.10.2021 11:03+2Ну русский язык-то нужно подтянуть:
"управление вектора тяги" означает что в векторе тяги есть устройство управления и сам вектор чем-то управляет. То есть чепуха полная.
Устоявшееся название - "с управляемым вектором тяги".
Winny63
18.10.2021 21:06+2Надо теперь "боковые" акселерометры задействовать для компенсации поперечного сноса
maxim-gamedev Автор
18.10.2021 22:01+2Ну да, в итоге имеем такой список на цикл:
ПИД регуляторы для компенсации отклонения: 2шт
ПИД регуляторы для компенсации поперечного сноса: 2шт
ПИД регулятор для поворотов вокруг вертикальной оси: 1шт
ПИД регулятор на удержание высоты: 1шт
Функции Калмана для фильтрации значений наклона: 2шт
b582q9
21.10.2021 23:30+2Очень интересно узнать подробнее что за система с соосными винтами? Что за двигатель или двигатели?
mrospax
Это ты молодец! Если сможешь поставь симетрично на корпусе ракеты ниже головного обтикателя стабилизаторы чтобы не вертело ее. А вообще прикольно было бы объединить огнемет с ракетой и вместо простого ротора под винтами сделать сопло испускающее огонь как у ракеты, но если вдруг не получится можно наверно вместо двух винтов сделать квадракоптер)))
GennPen
Чтобы не вращало нужно скорости вращения двигателей менять.
Стабилизаторы у головного обтекателя ракеты не стоит делать. Парусность верхней части увеличится, а это очень плохо для устойчивого полета ракеты.
tormozedison
«сделать сопло испускающее огонь как у ракеты»
У меня давно была идея сделать девайс, распыляющий воду и одновременно подсвечивающий получающееся облако, чтобы выглядело как огонь.