Строим мультикоптер, часть вторая
Часть 1 | Часть 2 | Часть 3 | Часть 4
Итак, мы полны энтузиазма и готовы тратить деньги-силы-время на эту прекрасную идею.
Для того, чтобы определить углы наклона/поворота мультикоптера по трем осям (а это жизненно важная задача для стабилизации аппарата в воздухе), можно использовать разные сенсоры: оптические (обработка видео, поступающего с камеры), пирометрические (немного урезанный вариант оптического, по сигналам от четырех таких датчиков можно отслеживать линию горизонта), магнитные и инерционные. Идеальным вариантом было бы использование всех вместе, но мы располагаем крайне скудными вычислительными способностями микроконтроллера, так что остановимся на традиционных для воздушной навигации гироскопах.
Современные достижения микроэлектроники позволили собрать механический (точнее MEMS) гироскоп в корпусе 5х5 мм. Компании ST и Analog Devices предоставляют целую линейку микроскопических гироскопов и акселерометров на любой вкус и чувствительность.
Теоретически, для определения углов можно было бы использовать только гироскопы, но есть ряд проблем. Гироскопы показывают угловую скорость вращения (некоторым уровнем напряжения, пропорциональным этой скорости), однако у них есть такое явление, как дрейф: смещение нулевого значения в случайную сторону (в моих руках это проявлялось как остаточное «головокружение» сенсора после того, как я его переставал вращать). Быстрое накопление ошибок не позволит обойтись без других сенсоров.
Еще есть акселерометры, которые аналогичным образом предоставляют информацию о приложенном к ним ускорении. Важный момент: акселерометры показывают разницу фактически приложенного ускорения и привычного нам g, а поэтому, путем нехитрых вычислений, из сигналов от трех акселерометров, направленных вдоль разных осей, можно получить углы поворота системы остчёта нашего аппарата относительно системы остчёта земли (может я криво выразился, в оригинале это frame of reference). Но как только наш аппарат получит какое-нибудь ускорение, полученные значения углов будут неточными (а если ускорение большое — совсем неверными).
Для того, чтобы связать значения, полученные от обоих типов датчиков, традиционно используется фильтр Калмана, в котором долго разбираться, но он дает прекрасный результат, а примеров его реализаций полно в интернете.
В принципе, можно было сразу купить один из готовых модулей инерциальной навигации с уже написанным софтом, но это не спортивно, правда? Поэтому мы закупили пару цифровых (а зачем нам аналоговые? I2C рулит!) MEMS-деталек и принялись читать их спецификации, дабы спаять для них плату.
Однако, довольно быстро выяснилось, что разводить плату под неизвестное устройство (даже футпринты — шаблоны для пайки — рисовать надо с нуля) очень скучно и долго. Лучше уж попробовать реализовать готовый модуль сенсоров, для него уже и разводка есть, только бери и печатай (Купить? Неееет, зачем платить 70$ и ждать, пока его привезут!). Заодно освоим метод лазерного утюга, пригодится.
Печатаем шаблоны (не один раз, так как постоянно забываем отзеркалить)
Утюжим десяток раз, пока не добьемся четких дорожек без разрывов
Травим и оттираем тонер. Убеждаемся, что что-то не протравилось, повторяем вышеописанные шаги.
Параллельно напрягаем обленившиеся извилины тригонометрией и «изобретаем» алгоритм управления. Подключаем (хух, на этот раз хоть купленные) контроллеры двигателей к ардуине. Блок питания от компьютера не мог запитать один ненагруженный мотор на средней скорости. Сила.
Надо заметить, делалось это не день, и не неделю. Пока за детальками съездишь на рынок четыре раза (вечно что-то забудешь, или нет в наличии), пока привезут из Америки тот акселерометр, которого не было в наличии…
А потом внезапно пришло осознание того, что металлизацию отверстий в плате дома сделать не получится, потому как отверстия находятся прямо под брюхом гироскопов и акселерометров в QFN-корпусе, который прилегает прямо к плате. Мягко говоря, мы ощутили огорчение. Пришлось заказывать плату на производстве, что обошлось в 17$ за два десятка штук (минимальный заказ). Еще одно препятствие ждало нас при попытке припаять детальки в этих самых корпусах без ножек, так как паяльной станции у нас не оказалось. Впрочем, за символическую плату нам с этим помогли те, у кого она оказалась. Даже умолчу о том, что долго не мог заставить работать эту схему, потому что надо внимательнее читать спецификацию.
Похоже, правда?
Итак, у нас, наконец, есть готовая плата с акселерометрами и гироскопами, можно начинать писать софт. А еще в головы начинает закрадываться мысль, что электронику делать с непривычки — занятие довольно неблагодарное. Но только начинает.
Для отладки собираем некоторое подобие arduino-shield с простеньким АЦП
Можно даже приделать это все к тестовой площадке, вращающей потенциометр, предполагая, что потенциометр нам покажет «честный» угол. Для справки, это не так.
Обладая поверхностными навыками программирования на всем, что компилируется, интерпретируется, или преобразуется в байт-код, набрасываем что-то вроде программы для получения значений от датчиков, складирования их в CSV-файл для обработки экселем, а также отображения 3д-модели и вывода графиков в реальном времени.
Первым делом получаем значения датчиков, лежащих неподвижно:
При попытке подвигать датчики, шум увеличивается. Страшно подумать, какой шум будет от 6 моторов.
Поворачиваем плату:
Естественно, полученные значения углов поворота у каждого датчика разнятся. Однако, на втором рисунке явно видно отклонение значений угла по версии акселерометра и по мнению потенциометра, а они должны быть более-менее одинаковыми.
Оказывается, сопротивление потенциометра в зависимости от угла поворота меняется нелинейно. Я бы даже сказал, хаотично.
Все, надоели графики. Выкидываем потенциометр, переписываем реализацию фильтра Калмана из С на C#, получаем более-менее адекватную реакцию на повороты.
(тут оба окна показывают одно и то же, но визуализация весьма недалека от реального положения датчиков в руке). Все работает.
UPD
SovGVD пишет:
мне кажется не стоит делить на мелкие заметки, такими темпами частей 20-30 еще будет + стоило бы упомянуть про Wii Motion Plus (пример работы того что с dx заказывал) и Wii Nunchack — гироскоп и акселерометр соответственно, на которых куча народу летает: multiwii.com и в разы проще всё собирается… точность не идеальная конечно, но зато цена копеечная, достать просто и платы травить не надо
Продолжение следует.
Надо заметить, тема с акселерометрами (и другими навигационными сенсорами) сейчас будет набирать популярность, как в контексте AR, так и для беспилотников. Да что говорить, даже в сигвеях используется та же самая инерциальная система. Кто дружит с матаном, может разработать более эффективные и надежные алгоритмы.
А начать можно с пары записей dihalta.
Итак, мы полны энтузиазма и готовы тратить деньги-силы-время на эту прекрасную идею.
Начнем с сенсоров
Для того, чтобы определить углы наклона/поворота мультикоптера по трем осям (а это жизненно важная задача для стабилизации аппарата в воздухе), можно использовать разные сенсоры: оптические (обработка видео, поступающего с камеры), пирометрические (немного урезанный вариант оптического, по сигналам от четырех таких датчиков можно отслеживать линию горизонта), магнитные и инерционные. Идеальным вариантом было бы использование всех вместе, но мы располагаем крайне скудными вычислительными способностями микроконтроллера, так что остановимся на традиционных для воздушной навигации гироскопах.
Современные достижения микроэлектроники позволили собрать механический (точнее MEMS) гироскоп в корпусе 5х5 мм. Компании ST и Analog Devices предоставляют целую линейку микроскопических гироскопов и акселерометров на любой вкус и чувствительность.
Теоретически, для определения углов можно было бы использовать только гироскопы, но есть ряд проблем. Гироскопы показывают угловую скорость вращения (некоторым уровнем напряжения, пропорциональным этой скорости), однако у них есть такое явление, как дрейф: смещение нулевого значения в случайную сторону (в моих руках это проявлялось как остаточное «головокружение» сенсора после того, как я его переставал вращать). Быстрое накопление ошибок не позволит обойтись без других сенсоров.
Еще есть акселерометры, которые аналогичным образом предоставляют информацию о приложенном к ним ускорении. Важный момент: акселерометры показывают разницу фактически приложенного ускорения и привычного нам g, а поэтому, путем нехитрых вычислений, из сигналов от трех акселерометров, направленных вдоль разных осей, можно получить углы поворота системы остчёта нашего аппарата относительно системы остчёта земли (может я криво выразился, в оригинале это frame of reference). Но как только наш аппарат получит какое-нибудь ускорение, полученные значения углов будут неточными (а если ускорение большое — совсем неверными).
Для того, чтобы связать значения, полученные от обоих типов датчиков, традиционно используется фильтр Калмана, в котором долго разбираться, но он дает прекрасный результат, а примеров его реализаций полно в интернете.
Изготовление платы для сенсоров
В принципе, можно было сразу купить один из готовых модулей инерциальной навигации с уже написанным софтом, но это не спортивно, правда? Поэтому мы закупили пару цифровых (а зачем нам аналоговые? I2C рулит!) MEMS-деталек и принялись читать их спецификации, дабы спаять для них плату.
Однако, довольно быстро выяснилось, что разводить плату под неизвестное устройство (даже футпринты — шаблоны для пайки — рисовать надо с нуля) очень скучно и долго. Лучше уж попробовать реализовать готовый модуль сенсоров, для него уже и разводка есть, только бери и печатай (Купить? Неееет, зачем платить 70$ и ждать, пока его привезут!). Заодно освоим метод лазерного утюга, пригодится.
Печатаем шаблоны (не один раз, так как постоянно забываем отзеркалить)
Утюжим десяток раз, пока не добьемся четких дорожек без разрывов
Травим и оттираем тонер. Убеждаемся, что что-то не протравилось, повторяем вышеописанные шаги.
Параллельно напрягаем обленившиеся извилины тригонометрией и «изобретаем» алгоритм управления. Подключаем (хух, на этот раз хоть купленные) контроллеры двигателей к ардуине. Блок питания от компьютера не мог запитать один ненагруженный мотор на средней скорости. Сила.
Надо заметить, делалось это не день, и не неделю. Пока за детальками съездишь на рынок четыре раза (вечно что-то забудешь, или нет в наличии), пока привезут из Америки тот акселерометр, которого не было в наличии…
А потом внезапно пришло осознание того, что металлизацию отверстий в плате дома сделать не получится, потому как отверстия находятся прямо под брюхом гироскопов и акселерометров в QFN-корпусе, который прилегает прямо к плате. Мягко говоря, мы ощутили огорчение. Пришлось заказывать плату на производстве, что обошлось в 17$ за два десятка штук (минимальный заказ). Еще одно препятствие ждало нас при попытке припаять детальки в этих самых корпусах без ножек, так как паяльной станции у нас не оказалось. Впрочем, за символическую плату нам с этим помогли те, у кого она оказалась. Даже умолчу о том, что долго не мог заставить работать эту схему, потому что надо внимательнее читать спецификацию.
Похоже, правда?
Итак, у нас, наконец, есть готовая плата с акселерометрами и гироскопами, можно начинать писать софт. А еще в головы начинает закрадываться мысль, что электронику делать с непривычки — занятие довольно неблагодарное. Но только начинает.
Получаем данные
Для отладки собираем некоторое подобие arduino-shield с простеньким АЦП
Можно даже приделать это все к тестовой площадке, вращающей потенциометр, предполагая, что потенциометр нам покажет «честный» угол. Для справки, это не так.
Обладая поверхностными навыками программирования на всем, что компилируется, интерпретируется, или преобразуется в байт-код, набрасываем что-то вроде программы для получения значений от датчиков, складирования их в CSV-файл для обработки экселем, а также отображения 3д-модели и вывода графиков в реальном времени.
Первым делом получаем значения датчиков, лежащих неподвижно:
При попытке подвигать датчики, шум увеличивается. Страшно подумать, какой шум будет от 6 моторов.
Поворачиваем плату:
Естественно, полученные значения углов поворота у каждого датчика разнятся. Однако, на втором рисунке явно видно отклонение значений угла по версии акселерометра и по мнению потенциометра, а они должны быть более-менее одинаковыми.
Оказывается, сопротивление потенциометра в зависимости от угла поворота меняется нелинейно. Я бы даже сказал, хаотично.
Все, надоели графики. Выкидываем потенциометр, переписываем реализацию фильтра Калмана из С на C#, получаем более-менее адекватную реакцию на повороты.
(тут оба окна показывают одно и то же, но визуализация весьма недалека от реального положения датчиков в руке). Все работает.
UPD
SovGVD пишет:
мне кажется не стоит делить на мелкие заметки, такими темпами частей 20-30 еще будет + стоило бы упомянуть про Wii Motion Plus (пример работы того что с dx заказывал) и Wii Nunchack — гироскоп и акселерометр соответственно, на которых куча народу летает: multiwii.com и в разы проще всё собирается… точность не идеальная конечно, но зато цена копеечная, достать просто и платы травить не надо
Продолжение следует.
Надо заметить, тема с акселерометрами (и другими навигационными сенсорами) сейчас будет набирать популярность, как в контексте AR, так и для беспилотников. Да что говорить, даже в сигвеях используется та же самая инерциальная система. Кто дружит с матаном, может разработать более эффективные и надежные алгоритмы.
А начать можно с пары записей dihalta.