Всем добрый день, сегодня я хотел бы поделиться своим опытом проектирования ракеты с управлением вектора тяги. Так получилось, что я долго сидел дома и решил купить 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/МаксимГеймдев
Да и в целом я написал эту статью для поиска единомышленников, если вы тоже увлекаетесь робототехникой или разработкой дронов, скидывайте свои проекты в комментарии либо пишите, что бы вы хотели увидеть в следующих постах.
Заранее большое спасибо за фидбэк и критику :)
Автор: Максим Геймдев