Плата управления квадрокоптером. Комплементарный фильтр.



В прошлой статье мы вплотную приблизились к построению простой БИНС на основе гироскопа, акселерометра и цифрового компаса. Давайте продолжим.



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

Сразу напрашивается вопрос: почему мы говори о цифровых фильтрах, ели мы строим БИНС? Просто, в данной реализации, для определения положения (углов), используется именно алгоритм фильтра. По мере углубления в материал все станет понятно.

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

Перейдем к делу, и рассмотрим сначала «одномерный» случай, а потом перейдем к трехмерному пространству.

Пока предположим, что наш ЛА неподвижен. У нас есть 2 значения одного и того же угла. Одно значение (Ag) мы получили интегрируя показания с гироскопа, второе (Aa) на основании показаний акселерометра. На всякий случай напомню, что в случае неподвижного ЛА, акселерометр нам даст вектор, направленный вертикально вверх, и этот вектор мы хотим использовать для коррекции накапливающейся погрешности.

Собственно говоря, для введения кориектировки мы будем после каждого цикла интегрирования «смешивать» показания с гироскопа (после интегрирования) и акселерометра в определенной «пропорции». Пропорция будет определяться «весами» w1 и w2 соответственно.

A = (w1 *Ag + w2 *Aa ) / (w1 + w2)

где:
A – значение скорректированного угла
Ag – значение угла «по гироскопу» (результат интегрирования)
Aa – значение угла «по акселерометру»
w1, w2 – «веса»

Вот, собственно, данное выражение и есть наш фильтр. Давайте попробуем «на пальцах» разобраться, как это работает. Для наглядности перейдем к частному случаю, приняв, что w1 = (1 – w2), а w2 обозначим как w, причем w лежит в диапазоне {0… 1}. Получим:

A = (1 – w) *Ag + w *Aa

В данном случае w – это единственный параметр фильтра, значение которого нам нужно будет подобрать/вычислить.

Чтобы наглядно продемонстрировать работу фильтра, давайте проделаем мысленный эксперимент. Предположим ЛА неподвижен, при этом Aa = 4 (что соответствует реальному значению угла) а Ag = 3 (отличается от реального значения из-за накопившейся погрешности при интегрировании). Примем значение параметра фильтра w=0.1 и посмотрим, как будет меняться значение скорректированного угла в каждой итерации цикла интегрирования (цикле опроса датчиков).


0.      (1 - 0.1) * 3.00 + 0.1 * 4.00 = 3.10
1.      (1 - 0.1) * 3.10 + 0.1 * 4.00 = 3.19
2.      (1 - 0.1) * 3.19 + 0.1 * 4.00 = 3.27
3.      (1 - 0.1) * 3.27 + 0.1 * 4.00 = 3.34
4.      (1 - 0.1) * 3.34 + 0.1 * 4.00 = 3.41
5.      (1 - 0.1) * 3.41 + 0.1 * 4.00 = 3.47
...
22.     (1 - 0.1) * 3.90 + 0.1 * 4.00 = 3.91
23.     (1 - 0.1) * 3.91 + 0.1 * 4.00 = 3.92
24.     (1 - 0.1) * 3.92 + 0.1 * 4.00 = 3.93
...
n.     (1 - 0.1) * 4.00 + 0.1 * 4.00 = 4.00


Я извиняюсь за такую излишне «разжеванную» подачу материала, просто хотелось все продемонстрировать «на пальцах».

Из такой «симуляции» видно, что с каждой итерацией цикла значение скорректированного угла (A) стремится к реальному значению угла (4).

Наш алгоритм корректировки, в принципе, работает. Чем больше будет коэффициент w – тем быстрее будет происходить корректировка.

Но пока мы «работали» с неподвижной моделью. Если ЛА начнет ускорятся, то наш «эталонный» угол (Aa), полученный с акселерометра, будет отклонятся. Что произойдет тогда?

Вот здесь, наш фильтр и проявляет себя как фильтр. Если посмотреть на правую часть выражения A = (1 – w) *Ag + w *Aa, то при малых значениях w произведение w *Aa работает как фильтр низких частот для Aa.

Другими словами, из-за малого значения коэффициента w существенное изменение Aa не приводит к резкому и существенному изменению значения скорректированного угла A. Если в процессе работы нашего цикла интегрирования значение Aa кратковременно (пусть даже значительно) отклонится – мы этого практически не заметим. Значение скорректированного угла А будет сремится к усредненному значению Aa. Чем меньше коэффициент w тем больше будет «усредняется» значение Aa.

Если вынуться к коптреам, то наш фильтр будет подавлять кратковременные отклонения «эталонного» вектора, вызванные собственным ускорением коптера. Конечно, если ускорение будет действовать достаточно долго (и направлено в одну сторону), то усредненное значение вектора существенно сместиться от вертикали. В этом случае, наш фильтр будет не корректировать, а, наоборот, вносить погрешность.

Но, на практике данный подход успешно работает для «среднестатистического» режима полета квадрокоптера. Плюс, не забавам, что есть пилот, который управляет полетом и может вмешаться. И не забываем, что это одна из самых простых реализаций БИНС. Дальше будут более «интеллектуальные» системы.

Теперь рассмотрим, как это все работает в реальной жизни (в трехмерном пространстве) на примере прошивки MultiWii v1.9. Данная прошивка реализует «абсолютную» стабилизацию коптера по углам крена и тангажа. Для определения углов используется гироскоп, для коррекции ошибки – акселерометр или цифрой компас.

Для начала, нужно перейти от одномерной системы к трехмерной. Есть несколько способов, большинство склоняются к использованию кватерионов. В данной прошивке оперируют векторами в декартовой системе координат и матрицами поворота, чем воспользуемся и мы.

Для описания гулов крена и тангажа воспользуемся вектором – нормалью к горизонтальной плоскости (R). При инициализации программы, когда ЛА стоит на земле, мы явно присваиваем значения проекциям данного вектора Rх = 0, Ry = 0, Rz = 1. Получаем вектор, который направлен вертикально вверх, и совпадает по направлению с вектором, получаемым с акселерометра (G).



Теперь рассмотрим основной цикл управления.

1. Получаем моментальные значения углов с гироскопа, умножаем их на значение времени между опросами (разница между текущим значением времени и временем предыдущего опроса гироскопа — t). Для каждого из углов получаем приращение угла (значение угловой скорости * t).

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

3. Получаем моментальное значение проекций вектора G с акселерометра.

4. Используя проекции вектора R и вектора G корректируем значение вектора R:

Rx = (1 — w) * Rх + w * Gx
Rу = (1 — w) * Rу + w * Gy
Rz = (1 — w) * Rz + w * Gz

5. Нормализируем вектор R (приводим значение вектора по модулю к 1).

6. Используем полученное значение вектора R для определения отклонения от горизонтального положения, отклонение подаем на ПИД регулятор.

7. Переходим к пункту 1.

Вот, приблизительно как-то так.

Есть несколько особенностей в реализации MultiWii, на которые хотелось бы обратить внимание.

1. Для матрицы поворота используются аппроксимация для малых углов. Считается, что приращение угла за один период цикла будет очень небольшим, и для таких углов считаем что sin(x) = x, cos(x) = 1

2. Корректировка угла (пункт 4) выполняется только в том случае, если значение вектора G по модулю приблизительно равно g.

Что почитать:

1. Обзорная статья (вернее стенограмма доклада)
2. Неплохая статья на английском.
3. Исходники MultiWii (код, честно говоря, написан плохо).

Заранее приношу извинения за возможные неточности. Исправления и уточнения приветствуются.
  • +6
  • 27 марта 2012, 21:13
  • e_mc2

Комментарии (167)

RSS свернуть / развернуть
2. Корректировка угла (пункт 5) выполняется только в том случае, если значение вектора G по модулю приблизительно равно g.
Быть может, все же «пункт 4»?

А вообще это обычный LERP между проинтегрированным вектором с гироскопа и вектором с акселерометра.
Кватернионы пожалуй вычислительно дешевле обошлись бы, и не сложнее при таком алгоритме, какой описан.

А что из себя аппаратно представляет MultiWii? Какой проц, набор датчиков, etc. И почему она так назвается?
0
  • avatar
  • Vga
  • 27 марта 2012, 21:36
Да, конечно же пункт 4, исправил.

MultiWii базируется на Arduino. Датчики – из «нунчака» от игровой приставки Wii (поддерживается несколько разных датчиков, например, гироскопы ITG3205, ITG3200 и т. д.). Выбор датчика осуществляется дефайнами в коде).
0
Судя по тому что я читал – дешевле купить «нунчак» от Wii и выковырять оттуда датчики чем покупать датчики по отдельности. Собственно из-за доступности датчиков проект и популярен.
0
Нунчак или все же вимоут?
Гироскоп кстати в моушенплюсе. Продается отдельно и стоит почти как моут с чаком вместе взятые (это если говорить про китайские реплики, если тырить детальки из оригинальных контроллеров коптер золотой будет).
0
Я, честно говоря, не очень разбираюсь в данной приставке. Судя по тому, что пишут у них на сайте гироскоп покупают отдельно (такой-же как и в Wii Motion Plus). А акселерометр достают из нунчака (он, вроде, недорогой).
0
Ох щи. Не, китайский M+ стоит жалких 10 баксов, и аксель там выведен прямо на коннектор (интерфейс расширения вимоута — ни что иное, как шина I2C, нинтендо ее как минимум со времен GBA любит).
Нунчак — не знаю, я брал комплект вимоут+нунчак, вроде около 15 баксов.
0
и аксель там выведен прямо на коннектор
Тьфу, гироскоп.
0
Упс, это я налажал, не вчитался.

Они наоборот приводят эту ссылку на сайте, для того чтобы показать, что отдельно гироскоп стоит дорого, а китайская копия Wii Motion стоит 10 — 15 баксов.
0
Кстати, насчет «выведен наружу» я, кажется, наврал. Тут еще какая-то микра-сопля стоит.
Впрочем, протокол вроде расковырян, так что все равно можно через интерфейс М+ работать.
0
значение эталонного угла Аа, полученного с гироскопа, изменится

Может, с акселерометра?
0
  • avatar
  • enq
  • 27 марта 2012, 21:57
Да, спасибо, исправил.
0
Большое спасибо за статьи! Начинаю понемногу понимать назначение 100500 настроек в программе управления пилотного контроллера Rabbit flight controller.
Без понимания принципов работы очень непросто подобрать оптимальные значения, т.к. приходится их тыкать наугад.
Для примера скриншот:
скриншот из программы управления
0
Чего-то я туплю… Почему поворот с помощью матрицы поворота в противоположную сторону является интегрированием? Мысль где-то на краю осознания вертится, но в голову никак идти не хочет… :(
0
На самом деле интегрирование производится в п.1, когда из угл.скорости (производной угла) получается угол. А в п.2 производится поворот приращений углов из связанной системы координат (ССК), к приращениям в инерциальной системе координат (ИСК), которая в нашем случае связана с поверхностью Земли (с горизонтом, если хотите).

Но на самом деле так делать можно только при небольших углах и то результат будет приближенный. Реально же необходимо интегрировать кинематические уравнения углового движения (например в направляющих косинусах). В результате интегрирования мы получаем угловое положение ЛА относительно ИСК, имея угловые скорости ЛА, в проекциях на ССК.
Нельзя просто проинтегрировать показания датчиков угловой скорости (которые часто называют гироскопами, что не совсем верно), закрепленных на корпусе ЛА. Полученные таким образом углы не будут отражать угловое положение ЛА в ИСК.
0
SosoMan все правильно написал. Интегрирование происходит на этапах 1, 2. На этапе 1 мы умножаем мгновенное значение угловой скорости на время, получаем приращение угла. На этапе 2 мы поворачиваем вектор R (который отражает текущие значения углов) на величину приращений.
0
И еще, можете картинку сделать чуть крупнее чтобы углы и остальные буквы читались лучше? При увеличении все размазывается. Догадаться конечно можно но не айс…
+1
Отличный цикл статей.
Надеюсь будет статья с описанием алгоритма стабилизации коптера?
+1
Исходники MultiWii (код, честно говоря, написан плохо)

если сказали «А», значит надо говорить и «Б». Т.е. если код имеет недостатки, то надо бы указать на них. Где? В алгоритмах? В стиле кодирования или еще где-то?
Мне просто интересно, т.к. сейчас вплотную подошел к раскопкам этого кода. До этого был фактически просто пользователем, но не кодером :)
0
В основном все претензии к стилю кода. Весь обмен данными между подсистемами происходит через глобальные переменные. В коде много абсолютно ненужных «телодвижений», например контекстно-зависимые определения (дефайны) которые только затрудняют чтения кода. Во многих местах в коде встречаются непонятные действия/константы, с комментарием типа «это было подобрано империческим путем». Это не «наезд» на автора, автор молодец, проделал большую работу. Но стиль его программы ужасный.

А по самой реализации алгоритма особо претензий нет. Не то, чтобы реализация идеальна, но явных багов я не встречал (правда, я изучал в основном только код связанный с БИНС).
0
это да. Как раз сейчас чищу код от этих лишних кусков с дефайнами. Зная на чем будешь летать и конкретно свой набор сенсоров, код уже уменьшился раза в 1.5. Конечно, это лишает его универсальности, но зато делает более пригодным для понимания :)
0
Насчет дефайнов, мне особенно запомнился следующий момент.
Код введения коррекции с акселерометра:


    for (axis = 0; axis < 3; axis++) {
        int16_t acc = ACC_VALUE;
        ...
    	EstG.A[axis] = (EstG.A[axis] * GYR_CMPF_FACTOR + acc) * INV_GYR_CMPF_FACTOR;
    }
 


Вроде все понятно, идем в цикле по трем проекциям и для каждой проекции вводим корректировку. Стоп! Получается, что мы все проекции корректируем одним и тем же значением «acc»! Как так может быть?

Оказывается

#define ACC_VALUE accSmooth[axis]


ACC_VALUE – это контекстно-зависимое определение. Вот зачем так делать? Чтобы запутать вероятного противника? :)
0
скорее всего, чтобы в случае нужды легким движением пальцев сменить это самое контекстное определение на другое, а не рыть код.
0
Зачем автор использовал дефайн – понятно. Непонятно зачем так использовать дефайн. Такой дефайн «скрывает» тот факт, что в цикле мы работаем с массивом, а не с константой. Кроме того, дефайн контекстно-зависим, требует, чтобы была определена переменная «axis». А если я захочу назвать итератор цикла по-другому – делать еще один дефайн?

Логичнее было бы сделать определение


#define ACC_VALUE accSmooth


А в цикле использовать его


int16_t acc = ACC_VALUE[axis];


Это обеспечивает гибкость, о которой Вы говорите, но, при этом, не уменьшает читабельность кода и не привязывает accSmooth к конкретному названию итератора.
0
В следующей строчке Ag диет до 4.00, но на самом деле оно бесконечно будет увеличиваться, то есть коптер не сможет просто висеть(лететь в одном положении) он перевернется… как мне кажется.
n. (1 — 0.1) * 4.00 + 0.1 * 4.00 = 4.00
0
Нет. Оно не будет бесконечно увеличиваться. Оно будет стремиться к 4.
Если значение скорректированного угла достигнет 4 – мы «зациклимся» на этом значении:
n. (1 — 0.1) * 4.00 + 0.1 * 4.00 = 4.00
n + 1. (1 — 0.1) * 4.00 + 0.1 * 4.00 = 4.00
n + 2. (1 — 0.1) * 4.00 + 0.1 * 4.00 = 4.00
0
Возможно я чего-то не понимаю, но если мы интегрируем значения гироскопа, то в следствии шумов (они то же интегрируются и складываются с значениями его) — наши значения получаемые = значение + шум -> если мы не двигаемся то мы получаем только интегрирование шума и как следствие получаемые значения постоянно ползут и ни к чему они не стремятся и не остановятся ни когда, наш горизонт по гироскопу все время крутиться, медленно но…
0
если мы не двигаемся то мы получаем только интегрирование шума

Совершенно верно. При интегрировании накапливается погрешность – в этом вся проблема. Именно по этому, мы и вводим коррекцию с акселерометра.

В случае неподвижного ЛА акселерометр дает нам проекцию вектора, который направлен вертикально вверх. Вот, собственно, этот вектор и позволяет нам скорректировать расчетные значения углов, которые мы получили при интегрировании показаний гироскопа. Это позволяет избавиться от накапливающейся погрешности интегрирования.

Комплементарный фильтр «подмешивает» (после каждого цикла интегрирования) в результат интегрирования (расчетные значения углов) показания акселерометра.
0
1) — Из этой фразы — «Совершенно верно. При интегрировании накапливается погрешность – в этом вся проблема.» следует что — Ag = проинтегрированный (шум + значение) -> Ag — всегда плывет и если мы будем подставлять в формулу A = (1 – w) *Ag + w *Aa то получим постоянное «вращение» А.

2) —

И вообще из вашего примера
0. (1 — 0.1) * 3.00 + 0.1 * 4.00 = 3.10
1. (1 — 0.1) * 3.10 + 0.1 * 4.00 = 3.19
2. (1 — 0.1) * 3.19 + 0.1 * 4.00 = 3.27
3. (1 — 0.1) * 3.27 + 0.1 * 4.00 = 3.34
4. (1 — 0.1) * 3.34 + 0.1 * 4.00 = 3.41
5. (1 — 0.1) * 3.41 + 0.1 * 4.00 = 3.47

22. (1 — 0.1) * 3.90 + 0.1 * 4.00 = 3.91
23. (1 — 0.1) * 3.91 + 0.1 * 4.00 = 3.92
24. (1 — 0.1) * 3.92 + 0.1 * 4.00 = 3.93

n. (1 — 0.1) * 4.00 + 0.1 * 4.00 = 4.00

следует, что вместо новх полученых значений интегрирования значений гироскопа ( которые как мы выяснили всегда

плывут в следствии интегрирования шума) в Ag мы подставляем значение A, а значение гироскопа мы в Ag подставляем

только на шаге «0»

0: Ag = 3.0 — проинтегрированное занчени (включая шум) -> A = 3.10

А вот далее каким-то магическим образом Ag становиться равным A с предыдущего шага, а не как сказано цитата «Предположим ЛА неподвижен, при этом Aa = 4 (что соответствует реальному значению угла) а Ag = 3 (отличается от реального значения из-за накопившейся погрешности при интегрировании).» — смотрим:

1: Ag = 3.10 -> A = 3.19 (А предыдущего шага равнялось 3.10)
2: Ag = 3.19 -> A = 3.27 (А предыдущего шага равнялось 3.19)
3: Ag = 3.27 -> A = 3.34 (А предыдущего шага равнялось 3.27)
4: Ag = 3.34 -> A = 3.41 (А предыдущего шага равнялось 3.34)
5: Ag = 3.41 -> A = 3.47 (А предыдущего шага равнялось 3.41)


22: Ag = 3.90 -> A = 3.91 (А предыдущего шага равнялось 3.47)
23: Ag = 3.91 -> A = 3.92 (А предыдущего шага равнялось 3.91)
24: Ag = 3.92 -> A = 3.93 (А предыдущего шага равнялось 3.92)


n: Ag = 4.00 -> A = 4.00 (А предыдущего шага равнялось 4.00)

В этом случаи зацикливание будет на 4.00, но тогда мы не используем значение гироскопа кроме как на шаге «0»
0
Для того, чтобы наглядно продемонстрировать работу фильтра я упростил систему и отбросил накапливаемую в цикле погрешность интегрирования (предполагаем, что в неподвижном состоянии гироскоп возвращает нулевые значения угловых скоростей, хотя в реальной жизни, конечно, будет погрешность измерения). Я просто хотел показать чистую математику работы фильтра, извиняюсь, если ввел Вас в заблуждение.

А вот далее каким-то магическим образом Ag становиться равным A с предыдущего шага

Это так, но магии здесь нет. После каждого цикла интегрирования мы вводим коррекцию, и на следующем цикле интегрирования мы прибавляем приращение (интернируем) к уже скорректированному (на предыдущей итерации) значению угла. Другими словами, после расчета скорректированного угла мы делаем присвоение Ag = A.
Обратите внимание, на шаг 4 алгоритма:
Rx = (1 — w) * Rх + w * Gx
Rу = (1 — w) * Rу + w * Gy
Rz = (1 — w) * Rz + w * Gz


В реальности, на каждом цикле интегрирования, из-за неточности гироскопа, будет добавляется погрешность. Для того чтобы система эффективно работала коэффициент w фильтра должен быт выбран таким, чтобы на каждой итерации цикла введенная коррекция перекрывала погрешность внесенную интегрированием.
0
Тогда надо было написать:
Ag = Ak-1 + приращение по гироскопу за период от k-1 до k
Ak-1 — скорректированное значение на предыдущем шаге.
Или что-то в этом духе.
0
3. Получаем моментальное значение проекций вектора G с гироскопа.
или с акселерометра?
0
Да, конечно, Вы правы. Исправил.
0
Всем здрасьте.
Я, вероятно, немного опоздал, но все же попробую поучаствоваь в обсуждении. Статьи понравились, однако есть вопросы:
— отчего не учитывается влияние линейных ускорений при расчёте угла наклона? На осях акселерометра при отклонении от горизонтали отображаются проекции ветора g. По сути, проекции g на оси и есть значения углов отклонения (например: X=g*sinA). Но они, даже при малых углах наклона, будут сравнимы со значениями ускорения вдоль осей. Как тогда отслеживать перемещения коптера?
Мне кажется, что использование комплементарного фильтра будет эффективно лишь при условии, что ЛА висит в точке и регуляторы компенсируют только лишь отклонение от гризонтали. Перемещения коптера будут вносить ошибку в работу фильтра.
И вот ещё: "… акселерометр дает нам проекцию вектора, который направлен вертикально вверх..." почему ветор силы тяжести направлен вверх?
0
— отчего не учитывается влияние линейных ускорений при расчёте угла наклона

А как выделить линейные ускорения? Акселерометр дает «смешанное» ускорение (g+линейное ускорение). Если бы был датчик, который бы фиксировал только линейное ускорение – можно было вносить коррекцию по его показаниям.

Перемещения коптера будут вносить ошибку в работу фильтра.

Будут но не так существенно (собственное ускорение нашего ЛА незначительное и непродолжительное). На практике, намного большую проблему создает вибрация от двигателей, которую регистрирует акселерометр.

"… акселерометр дает нам проекцию вектора, который направлен вертикально вверх..."

В данном случае акселерометр измеряет «кажущееся» ускорение, по сути это вектор реакции опоры/подвеса и он направлен в противоположенную сторону от вектора силы тяжести. Хотя, направление данного вектора (верх/низ) не принципиально, мы можем расположить систему координат так, что вектор будет направлен вниз.
0
А как выделить линейные ускорения? Акселерометр дает «смешанное» ускорение (g+линейное ускорение).
Например так: a=Ax-g*sinA, где а — линейное ускорение, Ах — значение снятое с соответствующей оси акселерометра, sinA — синс угла наклона ЛА измеренный гироскопом.
Я сейчас пытаюсь реализовать подобную систему.
Будут но не так существенно (собственное ускорение нашего ЛА незначительное и непродолжительное).
Ускорения ЛА существенны, поскольку, чтобы достичь скорости хотя бы 5-6км/ч, ЛА должен довольно продолжительное время (по крайней мере пару секунд)испытывать ускорение порядка 1,5м/с*с. За это время акселерометр подмешает к данным по углу, который он меряет порядка 15% ошибки (соотношение a/g).
Я попытался сделать макет платформы, которая должна была возвращаться в исходное положение после её перемещения по горизонтали на основании показаний акселерометра. Даже не смотря на коррекцию силы тяжести, которую я пытался вводить в программу, влияние силы тяжести при интегрировании вносило такую ошибку, что платформа просто не могла стоять на месте и всё время укатывалась. Данный макет работал удовлетворительно только в условиях установки платформы на качающуюся плоскость и отключении интегрирования показаний, т.е. только при отслеживании измениения проекции g на ось Х акселерометра.
Оттого я и пытаюсь реализовать сейчас систему выделяющую непосредственно линейное ускорение объекта. Может я заблуждаюсь, но пока не нахожу доводов опровергающих мои построения. На данном этапе моя проблема — сильный дрейф гироскопа L3G4200D фирмы ST. Tо ли мне такой экземпляр достался, то ли я обсчитываю неверно? Кто-нибудь имел опыт работы с этим прибором?
0
Я сейчас пытаюсь реализовать подобную систему.

О, я рад, что кто-то в сообществе занимается подобной тематикой. Будем обмениваться опытом. Если что, не стесняйтесь, обращайтесь в личку.

Теперь по делу.

a=Ax-g*sinA

Идея понятна. У нас, в данном случае, разные подходы.
А как Вы планируете водить, в этом случае, коррекцию расчетного угла с гироскопа. Если не вводить коррекцию, то sinA будет накапливать ошибку при интегрировании. Предположим, что коптер стоит, датчики откалиброваны и т. д. В начальный момент времени Ax = g*sinA, а = 0; Ок. Но далее, Ax не меняется (коптер стоит на месте) в sinA начинает накапливаться ошибка. Это приведет к тому, что появится «несуществующее» собственное ускорение, которое будет расти по мере накопления ошибки интегрирования.

На данном этапе моя проблема — сильный дрейф гироскопа L3G4200D фирмы ST

Я начинал свои эксперименты с LSM330DL от ST. Помимо сильного дрейфа нуля гироскопа, у меня еще очень сильно шумел канал Y (относительно других каналов). Я перешел на MPU6050 – дрейф меньше, шумит тоже меньше.

Еще одна проблема, о которой я уже говорил – вибрации. Я, «на столе», получаю идеальные результаты, стоит поставить плату на коптер и включить двигатели – углы начинают плавать в диапазоне 2-3 градуса.
0
Пока погрешность, вносимая собственным ускорением через фильтр, меня не беспокоит. Я ее буквально не вижу, на фоне вибрации. В будущем, я планировал определять собственное ускорение через положение коптреа в пространстве и двойное дифференцирование. Как определить положение копптера – вопрос. Как вариант – GPS либо видео камера + распознавание объектов.
0
Еще одна проблема, о которой я уже говорил – вибрации.
Вибрации можно отрезать ФНЧ, если они не совсем низкочастотные. Я думаю вибрации от моторов всё же выше 20-25Гц, а частоту среза ФНЧ вполне можно взять и 5Гц.
Есть ещё одна проблема с гироскопом — нулевой уровеь показаний, т.е. выдаваемое значение ускорения при фактическом отсутствии угловой скорости. Иными словами: ЛА неподвижен, а с гиры идут показания, что ЛА поворачивается с какой-то скоростью. Для моего датчика по даташиту эта мнимая угловая скорость довольно велика — при шкале в 500гр/сек она может лежать в пределах +-10гр/сек. Я пытался подбором корректировать эту ошибку вычитая её из показаний гироскопа, но на данный момент при интегрировании она всё равно накапливается довольно быстро.
Сталкивались ли Вы с этой проблемой?
0
Вибрации можно отрезать ФНЧ, если они не совсем низкочастотные.

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

Сталкивались ли Вы с этой проблемой?

Да, конечно. Это дрейф нуля. Он есть всегда, более того, он очень сильно зависит от температуры. Первое что можно сделать – это калибровка (по сути то, что Вы описали, но лучше не подбором а именно калибровать).

Каждый раз, перед запуском двигателей, пока коптер стоит на земле, делаем много замеров показаний гироскопа, вычисляем среднее арифметическое (по каждой оси) и принимаем этот результат за «нуль». В дальнейшем из показаний гироскопа вычитаем этот «нуль». Это уменьшаете дрейф, но он все равно есть. И при интегрировании быстро накапливается ошибка. Вот, что-бы от нее избавиться и приходиться вводить корректировку по акселерометру.
0
А как Вы планируете водить, в этом случае, коррекцию расчетного угла с гироскопа.
Честно сказать, ещё не обдумал детально этот вопрос. На вскидку, можно так же применить коррекцию угла с гироскопа при помощи показаний акселерометра, т.е. откорректировать угол применив тот же комплементарный фильтр. Основная идея — учёт силы тяжести.
0
угол применив тот же комплементарный фильтр

Более эффективно ИМХО, использовать ПИ-регулятор для корректировании (я вскользь описывал это здесь)

Ну, честно говоря, не знаю, что получится если использовать акселерометр одновременно и для коррекции расчетных углов и для определения собственного ускорения. Грубо говоря, можно попробовать вносить коррекцию из данных акселерометра пропущенных через ФНЧ, а для расчета собственного ускорения брать моментальное показание акселерометра, и, в свою очередь, учитывать это ускорение при вынесении коррекции. Нужно будет попробовать.
А что, если не секрет, Вы делаете? Тоже коптер или какой-то другой проект?
0
Более эффективно ИМХО, использовать ПИ-регулятор для корректировании (я вскользь описывал это здесь)
Вы сами писали в тексте по ссылке, что по сути ПИД-регулятор — тот же комплементарный фильтр. В данном случае так оно и есть, поскольку складываются дифференциальная составляющая с акселерометра и интегральная с гироскопа — две комплементарных(дополняющих) величины. Акселерометр отсекает постоянную составляющую(ФВЧ), а гироскоп переменную (ФНЧ).
не знаю, что получится если использовать акселерометр одновременно и для коррекции расчетных углов и для определения собственного ускорения.
Я пока тоже не знаю, но буду пробовать. Пока же я хочу добиться максимально чистых данных с гироскопа, чтобы весь матаппарат не работал только на очистку данных, а занимался именно отслеживанием движения ЛА.
Грубо говоря, можно попробовать вносить коррекцию из данных акселерометра пропущенных через ФНЧ,
Это будет уже скорость, а не ускорение и получить такой интеграл из данных с акселерометра не очистив их от проекции g не получится — будет шустро набегать неслабая погрешность. Я уже через это прошёл.
А что, если не секрет, Вы делаете? Тоже коптер или какой-то другой проект?
Мне коптер как ЛА неинтересен, я летаю на вертолётах…
Может стоит перенести наше обсуждение в личку? Вроде бы больше никто не интересуется.
0
Вы сами писали в тексте по ссылке, что по сути ПИД-регулятор — тот же комплементарный фильтр.

Они похожи, но не совсем. Дело в том, что комплементарный фильтр учитывает только текущую ошибку (рассогласование) между расчетным углом и углом, полученным с акселерометра. Он работает как пропорциональный регулятор, вносимая коррекция пропорциональна значению рассогласования. А вот ПИ-регулятор, учитывает интеграл ошибки (рассогласования). Вносимая коррекция пропорциональна значению текущей ошибки (П) и сумме предыдущих ошибок (И).

Может стоит перенести наше обсуждение в личку?

Ну, вроде, разговор по теме, может еще кому интересно будет.
0
Это будет уже скорость, а не ускорение и получить такой интеграл из данных с акселерометра не очистив их от проекции g не получится — будет шустро набегать неслабая погрешность.

Здесь я Вас не совсем понял. Пропустив данные с акселерометра через обычный ФНЧ, мы получим, скорее, «усредненное» значение кажущегося ускорения. Почему должна получится скорость, мы просто фильтруем данные с акселерометра, а не дифференцируем показания акселерометра?
0
Упс, вернее «мы просто фильтруем данные с акселерометра, а не интегрируем показания акселерометра»?
0
Вчера дети отобрали ноутбук и я не смог продолжить обсуждение, поэтому пишу только сейчас с работы.
мы просто фильтруем данные с акселерометра, а не интегрируем показания акселерометра
А «просто фильтруем» — это что за процедура? ФНЧ по сути интегратор, а в цифровом виде и подавно.
комплементарный фильтр учитывает только текущую ошибку (рассогласование) между расчетным углом и углом, полученным с акселерометра.
Я понимаю, что комплементарный фильтр корректирует мгновенное значение угла с акселерометра при помощи интегрального значения с гироскопа. В результате получается полосовой фильтр ограниченный снизу частотой среза ФНЧ гироскопа, а сверху ФВЧ акселерометра. Применительно к ПИД — это сумма дифференциальной и интегральной составляющей, а пропорциональная составляющая вносится опционально, если нужно увеличить скорость реакции.
По поводу zero rate level гироскопа что-нибудь посоветуете? Что у вас сыпется с выходов гироскопа в состоянии покоя?
0
Я понимаю, что комплементарный фильтр корректирует мгновенное значение угла с акселерометра при помощи интегрального значения с гироскопа.

В данном случае наоборот, интеграл с гироскопа (расчетный угол) корректируется данными с акселерометра.

По поводу zero rate level гироскопа что-нибудь посоветуете? Что у вас сыпется с выходов гироскопа в состоянии покоя?

Вот графики для LSM330DL, ось Х.
Желтый – сырые данные, град/с * 500
Зеленый – данные с учетом калибровки, град/с * 500
Красный – интеграл (угол), град * 100
Горизонтальный масштаб – одна клетка 5 сек.

Сразу после калибровки



Прошло около 3 мин, интеграл уполз приблизительно на 0.5 градуса



Самое веселое – нагрев (просто касаюсь пальцем корпуса микросхемы).



Что с этим можно сделать – ну, первое – калибровка, второе – ввод коррекции нуля от температуры (в моем случае не эффективно, я от этого отказался). Дрейф в любом случае остается (проявляется со временем). Полностью победить дрейф, ИМХО, невозможно. Единственный вариант корректировать интеграл по акселерометру.
0
На всякий случай уточню «град/с * 500» это «х500 градусов/сек.»

Гироскоп в MPU6050 шумит меньше, и дрейф нуля меньше (особенно тепловой дрейф). Если интересно – могу попозже снять с него графики.
0
На всякий случай уточню «град/с * 500» это «х500 градусов/сек.»
Млин, вернее так: 500 единиц на графике, это 1 градус/сек
0
Спасибо. Я думал все гораздо хуже. За 3 минуты земля поворачивается на 0.75 градуса :)
0
Ну, не все так радостно. Я привел тесты для идеальных условий. Плюс, у меня канал Y плывет значительно сильнее остальных (и на этом канале проскакиваю одиночные выбросы с амплитудой в 9 разрядов). Подозреваю, что это проблема конкретно моего экземляра чипа (т. к. он у меня единственный, статистику собрать не могу).

Вот график для канала Y при тех же условиях. За 30 сек интеграл уплыл на четверть градуса.



Еще пару слов о калибровке. Калибровать нужно не раньше чем 5 сек после ресета датчика. И калибровать нужно «тщательно». Я считаю среднее арифметическое для выборки из 500 значений с интервалом 0.1 сек. На выборке из 300 значений результат получается хуже. Все расчеты я, пока, провожу в float, время для оптимизации еще не настало :)
0
Упс, 500 значений с интервалом 0.01 сек. Это отнимает 5 сек перед каждым запуском двигателей :(
0
Извиняюсь, парни, я ввел вас в заблуждение. Решил все перепроверить, уж слишком красивые результаты получились как для интегрирования без внесения коррекции на данном датчике.

Посмотрел исходник программы визуализации, каналы телеметрии, которые я использовал для построения графиков при выводе, похоже, масштабируются в 8 раз:

gx = BitConverter.ToInt16(packet, o) / 8;


Поэтому, умножаем все результаты графиков на 8. Уход за 30 сек составляет 4 градуса. Завтра, на работе, перепроверю все на партактиве, возможно я смотрю не ту ветку в репозитории. Но 4 градуса больше похоже на правду.
0
Уход за 30 сек составляет 4 градуса.

Вернее уход за 3мин составляет 4 градуса для канала X
0
Плюс, у меня канал Y плывет значительно сильнее остальных
А как он расположен? Может, это связано с тем, что он физически расположен иначе, чем два остальных (скажем, два остальных лежат в плоскости кристалла, а этот — перпендикулярно)?
0
Каналы X и Y расположены в плоскости кристалла, канал Z, соответственно, перпендикулярен данной плоскости.



Согласен с Вами, было бы логично, если бы канал Z вел себя неадекватно по сравнению с осями, которые лежат в плоскости кристалла. Но глючит именно канал Y. Питание, земля, опорное напряжение и тактирование общее для всех каналов.
0
Может стоит перенести наше обсуждение в личку? Вроде бы больше никто не интересуется.

Не надо.
+2
Может стоит перенести наше обсуждение в личку? Вроде бы больше никто не интересуется.
Не путайте «не может ничего путного по теме сказать» и «не интересуется».
+1
Да, графики хороши! Вы как их строили? Мне до такого результата, похоже, ещё очень далеко.
Сегодня попробовал способ, который умники из ST описывают в своих апноутах: сначала усреднить Zero Rate Level, а потом урезать оставшиеся шумы с помощью установки порогового значения в регистре REFERENCE. Получилось не очень. Сначала усреднял по 32 значениям — практически то же, что и без усреднения, потом по 64 значениям — стало чуть получше, но всё равно ошибка набегает очень быстро. У меня индикация довольно убогая — угол пересчитывается в 10-битный ШИМ и светят два светодиода — красный минус, зелёный плюс, по яркости свечения определяю величину угла.
В итоге: в покое всё хорошо, стоит качнуть и… привет — сразу появляется непредсказуемая ошибка и один из светодиодов уверенно набирает яркость. Хуже всего, что ошибка непредсказуема.
0
Да, графики хороши! Вы как их строили?

Я для телеметрии повторил протокол телеметрии из MultiWii 2.0. Он очень прост в реализации и под него есть несколько программ для визуализации показаний телеметрии (изначально, я просто отбрасывал логи в UART, но по текстовым логам отлеживать динамические процессы тяжело, а писать свою программу для визуализации было лень). Я использую эту программу для визуализации.

Касательно калибровки, я описал алгоритм калибровки в комментарии выше. Выборка из 32 значений для усреднения очень мало, я использую 500.
0
Я для телеметрии повторил протокол телеметрии из MultiWii 2.0.
Честно сказать, я ленюсь разбираться с чужими программами. Нельзя ли в двух словах пояснить принцип?
изначально, я просто отбрасывал логи в UART
Я к этому тоже склоняюсь, а потом можно, к примеру, в Exel визулизировать.
Выборка из 32 значений для усреднения очень мало, я использую 500.
Да уж, я догадывался, что всё не очень хорошо, но чтобы настолько плохо! В апноуте ST говорится, что достаточно 50-100 замеров. Вертолётные модельные гироскопы инициализиуются меньше, чем за полминуты. При этом стабильность даже у самых дешёвых моделей весьма достойная. В чём фокус? Частота опроса больше или алгоритмы другие? Инициализировать пять минут — это невозможно долго!
0
Извиняюсь, я ошибся в частоте опроса, и уже исправился в комментарии выше.

Упс, 500 значений с интервалом 0.01 сек. Это отнимает 5 сек перед каждым запуском двигателей :(

Что-то я сегодня слишком много ошибаюсь, мне даже как-то неудобно.

Нельзя ли в двух словах пояснить принцип?

Протокол предельно прост (но в старших версиях они его усложнили).
Все параметры телеметрии передаются по запросу одним блоком. Программа шлет с определенной периодичностью запрос на получение телеметрии (это просто один байт, символ ‘M’), в ответ устройство отравляет ей блок данных (полную информацию по телеметрии), который можно описать следующей структурой:


#pragma pack(push, 1)

typedef struct {
    uint8_t MagicStart;
    uint8_t Version; //Version
    int16_t Acc[3]; //ACC
    int16_t Gyro[3]; //GYRO
    int16_t Mag[3]; //MAG
    uint16_t Altitude; //EstAlt
    int16_t Heading; //heading
    uint16_t Servo[8]; //servo
    uint16_t Motor[8]; //motor
    uint16_t RC[8]; //rc input
    uint8_t DeviceFlags; //Device ready flags
    uint8_t ModeFlags; //Mode flags
    uint16_t CycleTime;	//Cycle time
    uint16_t I2CErrorsCount; //i2c errors
    int16_t AngleP;//Angle
    int16_t AnfleR;//Angle
    uint8_t DeviceType; //Copter type
    uint8_t PidsState[8][3]; //PIDs
    uint8_t RCRate; //rcRate8
    uint8_t RCExpo; //rcExpo8
    uint8_t RollPitchRate; //rollPitchRate
    uint8_t YawRate; //yawRate
    uint8_t DynThrPID; //dynThrPID
    uint8_t Test[11][2]; // use highest bit to transport state in mwc
    uint16_t GPSDistanceToHome; //GPS_distanceToHome
    uint16_t GPSDirectionToHome; //GPS_directionToHome
    uint8_t GPSNumSat; //GPS_numSat
    uint8_t GPSFix; //GPS_fix
    uint8_t GPSUpdate; //GPS_update
    uint16_t PowerMeterSum; //intPowerMeterSum
    uint16_t PowerTrigger1; //intPowerTrigger1
    uint8_t Vbat; //vbat
    int16_t Debug1; // Debug 1
    int16_t Debug2; // Debug 2
    int16_t Debug3; // Debug 3
    int16_t Debug4; // Debug 4
    uint8_t MagicStop;
} DeviceInfo;
#pragma pack(pop)


Далее программа визуализации парсит и визуализирует данные. Это актуально для версии Mw-WinGUI-1.04, в более старших версиях протокол другой.
Ели нужно, могу расписать более детально протокол и назначение полей структуры.
0
MagicStart и MagicStop – это константы, признак начала и конца пакета, они равны ‘M’.
Version – это версия, в данном случае 20, DeviceType – схема коптера (2 = квадрокоптер по схеме +).

Info.MagicStart = 'M';
Info.MagicStop = 'M';
Info.Version = 20;
Info.DeviceType = 2;
Info.DeviceFlags = 3;

Остальные поля – собственно данные телеметрии.
0
Хочу уточнить (а то и так, из-за спешки, я наделал множество ошибок в своих комментариях)- разные каналы/поля структуры могут масштабироваться программой при визуализации. Например, AngleP и AnfleR – углы тангажа и крена нужно задавать в десятых градуса.

Я, для своих нужд, использовал Debug1 – Debug4. Они не масштабируются, но выводятся на графике одним цветом. При построении данных графиков, хотелось показать сразу несколько значений, и я решил воспользоваться «каналом» гироскопа (Gyro[3]). Как оказалось, при визуализации, полученные от девайса значения делятся на 8 :(
0
Спасибо за разъяснения по проге визуализации. Что за мутный язык в программе? Я окончательно определился в том, что ваш вариант визуализации использовать не стану. Склоняюсь к самому простому для меня варианту — увеличу частоту моего выходного ШИМ и банально проинтегрирую его. Сделаю к-т ШИМ функцией не от угла, а от угловой скорости и буду в реальном времени смотреть на осциллографе. Мне так проще, поскольку программист я начинающий и не шибко способный.
По поводу инициализации: Попробую по Вашему примеру взять побольше значений и посмотрю что будет на выходе.
0
Что за мутный язык в программе?
Если Вы об этом
gx = BitConverter.ToInt16(packet, o) / 8;

То это C#, остальной код, который я приводил – С

Сделаю к-т ШИМ функцией не от угла, а от угловой скорости и буду в реальном времени смотреть на осциллографе.

Тоже вариант. Но, ИМХО, рана или поздно потребуется многоканальная телеметрия, и, желательно, по радирканалу.

Вот, снял график с MPU6050. Масштаб я не исправлял, оставил как есть, чтобы можно было сравнить с прядущим чипом. На графике данные через 8 мин после калибровки. Как видно, амплитуда шума у данного чипа значительно меньше, и интеграл уполз за 8 мин чуть меньше чем на 4 градуса. У LSM330DL такая ошибка накапливалась уже за 3 мин.



Попробую по Вашему примеру взять побольше значений и посмотрю что будет на выходе.
Если не тяжело, отпишитесь плиз о результатах.
0
Опробовал увеличенную выборку усреднения сначала на 128, потом на 256 замеров. Разница с выборкой в 64 замера малозаметна. Увеличил частоту опроса до 200Гц — стало чуть лучше, но всё равно угол набегает очень шустро. Причём тенденция сохранилась — пока в покое всё нормально, качнёшь и угол уезжает в плюс.
Подпаял интегрирующую цепь на выход ШИМ и увеличил частоту ШИМ до 31,25кГц. Потыкал осциллографом — на выходе, оказывается присутствуют периодические (2-3Гц)выбросы в плюс амплитудой от 1 до 3 гр/сек, в минус шум более-менее однородный. Теперь стало понятно поведение интеграла: редкие, но большие положительные выбросы утягивают интеграл в плюс.
Пробовал сделать ФНЧ с минимально возможной частотой среза: картинка стала стабильнее, но, естественно, большие угловые скорости перестали отслеживаться. Увеличение частоты среза возвращает всю ситуацию и угол вновь уходит в плюс.
Честно сказать, я расстроен. Ни ожидал столь геморройного расклада. Мыслей пока больше нет, кроме как начать корректировать показания гироскопа акселерометром, но это уже вопиюще неправильно — это как бороться со стуками в подвеске машины путём умягчения сидений.
0
Разница с выборкой в 64 замера малозаметна.

Странно, у меня проявляется разница между выборкой в 300 и 500 значений. Очень не существенная, но разница есть. Я тоже пробовал фильтровать данные с гироскопа, но отказался о этой идеи.

Мыслей пока больше нет, кроме как начать корректировать показания гироскопа акселерометром

Ну, теоретически можно взять более точные гироскопы (например, от Analog Devices). Но платить $100 за одноосевой гироскоп ИМХО перебор.
0
Некоторые мысли, если кому будет интересно (все таки к реализации БИНС сам я ещё не приступал, могу ошибаться).

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

Но есть интересная особенность акселерометра, в его показаниях присутсвует постоянная составляющая. В общем случае из суммы двух сигналов нельзя получить ни первый ни второй. Но если каким то образом их разделить, то система будет частично наблюдаема по ориентации.

Самый простой способ исходит из предположения о том, что на длинных временных отрезках ускорение объекта в среднем равно нулю. Получается усреднятор (ФНЧ) который оценивает вектор g. На коротких отрезках времени оценка производится по дусам. Это метод описанный e_mc2 .

Следующее улучшение состоит в использовании априорной информации о движении объекта. Те сигналы, что подаются на контроллеры двигателей и скорости винтов (вместе со всем состоянием системы) определяют значительную часть ускорения. Все остальное принимается за случайные возмущения, которые в среднем опять же равны нулю, но уже на гораздо более коротких отрезках времени.

Но для этого нужна точная модель. А чем точнее модель тем меньше робастность. Хотя мне интересен именно этот вариант.

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

Наблюдаемости по линейному положению с помощью только дусов и акселерометров не получить. Хотя при хорошей точности можно определить широту, но это не для mems датчиков и не для полетов на десяток метров.

По поводу числовых данных. Мне кажется, достаточно стабильности +/- 1 градус за десяток секунд.

И ещё кое что. Оценку нулевого сигнала можно производить и во время работы системы. Когда производится коррекция (по акселерометру например, но источник не важен) мы имеем величину ошибки. Если ошибка чаще направлена влево чем вправо делаем вывод о том, что нулевой уровень надо смещать влево. Получается опять ФНЧ а затем препроекция на оси дусов.

Чтобы не возится с тем где и как поставить ФНЧ или ещё какой мелкий фильтр хочется использовать ФК. Давно уже обнаружил интересный его вариант, а именно unscented (не знаю как перевести). Хорош тем, что ему не требуется предоставлять систему в матричном виде. Достаточно написать функции f (переход к следующему состоянию) и h (формирование сигналов выхода), задать начальные неопределенности в матрице P, и шумы в Q и R. Фильтр работает с «облаком» точек прогоняя их через функции, чтобы выявить какая переменная на какую и как сильно влияет, вместо линейного проецирования ковариаций (P=FPF'+Q) в классическом варианте.

Ну и последнее. Посмотрел в маны по cortex-m*. Кажется нет смысла использовать fixed-point, если только не работать с 8/16 бит и dsp инструкциями. Даже для 16.16 получается хуже чем с float, да ещё и проблемы с переполнениями.
0
Те сигналы, что подаются на контроллеры двигателей и скорости винтов (вместе со всем состоянием системы) определяют значительную часть ускорения.

Согласен, но ИМХО, получится достаточно сложная модель, и эту модель нужно будет спороть под каждый конкретный ЛА, т.к нужно будет учитывать кучу физических параметров (масса, длина лучей, характеристики двигателей и пропеллеров и т. д.).

Я, планирую, попробовать вычислять ускорение через координаты. У меня есть идея – поставить камеру, которая смотрит вертикально вниз «в землю». Далее, берем 2 кадра, выделяем на них некоторые опорные точки (не важно как, можно попробовать по контрасту, можно взять более сложный алгоритм). Имея точки, сравниваем, куда произошло смещение точек между первым и вторым кадром и получаем изменение координат ЛА. Вообщем все то же что и в оптических мышках. На самом деле не все так просто, нужно будет учитывать высоту и наклон камеры. И работать это будет на ограниченной высоте, и для некоторых поверхностей тяжело будет выделить опорные точки. Но попробовать стоит. Я видел опыт применения подобного датчика (но там, на сколько я помню, брали датчик от мышки и с помощью линз меняли фокусное расстояние).

Есть еще один момент. Я уже несколько раз упоминал о вибрации. Проблема в том, что акселерометр не просто чувствует вибрацию. Датчик буквально «сходит с ума». Например, если выводить усредненное значение длинны вектора g, то при включении двигателей его длина уменьшается приблизительно в 2 раза :) Притом изменяется, в основном, проекция Z.

Чуть позже попробую продемонстрировать это все на графиках, дабы показать масштаб трагедии.
0
Вот оптический датчик, о котором я говорил.
0
Книга по теме.

eknigi.org/nauka_i_ucheba/141192-osnovy-navigacii-po-geofizicheskim-polyam.html

Про вибрации интересно постмотреть.
0
Некоторые результаты по влиянию вибрации.

Это синтетические тесты, снимать показания с каптера неудобно (и опасно), поэтому я наколхозил «вибростенд». Плата установлена на пластиковой подставке (стоит на столбиках из нескольких слоев двухстороннего скотча – типа виброразвязка). Рядом я кладу двигатель (сверлилу для плат) – это источник вибрации :) Условия немного не те (другие обороты двигателя и т. д.) но в целом показания на стенде соответствуют показаниям на коптрере.

Первый график модуль вектора с акселерометра. В начале графика модуль равен g, а потом я включаю двигатель.



Вот показания всех трех осей. В начале графика Z = g, X=Y=0.



Слегка шумит :) Странно, что на LSM330DL от вибрации вектор сильно проседал по оси Z, а на MPU6050 такого я не вижу.

Самое плохое, что в шуме есть постоянная составляющая, вот как выглядит шум пропущенный через ФНЧ (я для наглядности немного увеличил масштаб)



Напомню, что горизонтальный масштаб – одна клетка = 5 сек.
0
Интересно как это можно объяснить. От ориентации датчика зависимости нет? Происходит именно «удлиннение» вектора g?

Догадываюсь о нелинейности которая портит симметрию шума.
0
Происходит именно «удлиннение» вектора g?

Происходит увеличение модуля выходного вектора акселерометра (sqrt(X^2 + Y^2 + Z^2) ).
Изменять ориентацию платы я не пробовал она стоит штатно, ось Z смотрит вверх. Завтра попробую при другой ориентации осей.

Догадываюсь о нелинейности которая портит симметрию шума.

Поделитесь догадкой, я попробую ее проверить.
0
Происходит увеличение модуля выходного вектора акселерометра (sqrt(X^2 + Y^2 + Z^2) ).

Я просто уточняю, что удлиняется именно модуль выходного вектора (первый график) а не проекция g на ось Z. Проекция g на ось Z шумит (видно на втором графике) но относительно симметрично от базового значения (g).
0
Разная чувствительность для разных значений ускорения. Выше длины g ускорение «растягивается» на большее количество разрядов, чем ниже. Можно проверить делая интегрирование и совершая вертикальные движения с возвратом в начальную точку. Или с помощью поворотной платформы/центрифуги можно задавать ускорение и проверять ошибку.

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

В ДШ об этом молч, но есть подозрительная high-pass фильтрация.

Итого, хороших версий не имею.
0
но есть подозрительная high-pass фильтрация.
ФНЧ для разных целей используют, я ничего подозрительного в отрезании постоянной составляющей не вижу.
0
ФНЧ для разных целей используют
Прошу прощения, я имел в виду ФВЧ.
0
модуль выходного вектора (первый график)
Под модулем, если я правильно понял, понимается истинная длина суммарного вектора ускорений?
Думаю, что при условиях, в которых вы тестировали, присутствует дисбаланс ротора мотора. Он и дает подобное смещение. Проверить можно перевернув плату на 180гр. Если вектор сместится симметрично в другую сторону, то это точно дисбаланс ротора мотора.
0
Под модулем, если я правильно понял, понимается истинная длина суммарного вектора ускорений?

Да.

Думаю, что при условиях, в которых вы тестировали, присутствует дисбаланс ротора мотора.

Вы правы, дисбаланс присутствует (как и на реальном коптере). На втором графике видно, что самая высокая амплитуда шума у оси X (красный график). Поворачиваешь плату на 90 градусов – шум по X уменьшается, по Y – увеличивается. Но изменение не очень существенное, X все равно шумит больше чем Y.
0
Собственно говоря, то, что увеличивается длинна вектора – это логично. К вертикальной составляющей по Z (g) добавляется горизонтальная по X и Y (вибрация). Даже если шум горизонтальных составляющий симметричен, общая дина вектора sqrt(X^2 + Y^2 + Z^2) увеличивается.
0
Если принять это предположение как верное, то остаётся скомпенсировать паразитные вибрационные составляющие ускорений по трём осям и получится весьма близкая к реальности модель.
0
Если принять это предположение как верное, то остаётся скомпенсировать паразитные вибрационные составляющие ускорений по трём осям и получится весьма близкая к реальности модель.

Вы правы, но есть нюансы.

В частном случае (на стенде, где одни двигатель вращается на постоянной скорости) я запросто могу искусственно ввести коррекцию, и скомпенсировать постоянную составляющую вибрации.

Но, как я уже писал,

Частота вибрации зависит от оборотов. Плюс на коптере много моторов, частоты их вибраций могут быть близки и при наложении возникнут «биения». Плюс резонанс конструкции (рамы).

на реальном коптере все сложнее.
0
Кстати, коллеги, рекомендую посмотреть следующую ветку форума на rcdesign. Автор предоставляет мало информации (и порой, его посты похожи на тролинг) но результаты впечатляют.
0
Мне как-то ни разу не очевидно.

1. Как вибрационный шум может быть не симметричным? Это бы означало, что присутствует постоянная составляющая ускорения. Но вибро-стенд же не взлетел?

2. Если постоянная составляющая осталась на месте то почему должна изменится длина?
0
Если постоянная составляющая осталась на месте то почему должна изменится длина?

В формуле sqrt(X^2 + Y^2 + Z^2) проекции возводиться в квадрат, при этом теряется знак и длинна растет. Или я где-то торможу?
0
Если уреднять проекции, то g останется g при симметричном шуме.

Если усреднять длину, то да, наверно она станет больше. Но зачем усреднять длину?
0
Но зачем усреднять длину?

Я и не усредняю.

Мы с Вами где-то потеряли нить разговора и, видимо, я непонятно описал, что изображено на графиках.

Вернемся к изначальному комментарию с тремя графиками.

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

Второй график – три оси (красный – X, зеленый – Y, синий – Z). После включения двигателя все жутко шумит.

Третий график – те-же три оси, с шумом, пропущенные через ФНЧ. Здесь, по сравнению с предыдущим графиком я увеличил масштаб (я указал это в комментарии), чтобы было лучше видно постоянную составляющую по X и Y.
Проекция Z на третьем графике равна 1g.

Я так понимаю, Вас сбила с толку разница в масштабе между вторым и третьим графиком?

Если уреднять проекции, то g останется g при симметричном шуме.

Так оно и есть (3-тий график)
0
Ясно, спасибо. Почему-то думал, что на первом графике была проекция на Z.

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

Уже думал надо будет выбросить те LSM330DLC, что успел купить :)
0
Непонимаю только зачем было говорить о увеличении длины если это геометрический (или статистический) эффект

Да, честно говоря, особой смысловой нагрузки этот график не несет.

Я его привел, потому, как сам изначально не учел, что модуль вектора увеличится от вибрации.

У меня была идея – чтобы уменьшить влияние собственного ускорения, вносить коррекцию только тогда, когда модуль вектора с акселерометра приблизительно равен 9.8 м/с^2. Если модуль сильно отличается от этого значения – значит, явно присутствует линейное ускорение, и внесение коррекции в таком случае, только увеличит ошибку.

В коде написал проверку – вносим поправку в расчетный угол только тогда, когда модуль вектора с акселерометра лежит в диапазоне {9.7… 9.9}. Протестировал на столе, потряс плату – вроде все ок. Поставил на каптер – а коррекция вноситься как-то странно, погрешность быстро накапливается. Долго тупил и думал, пока не вывел аналогичный график и не понял причину происходящего.
Уже думал надо будет выбросить те LSM330DLC, что успел купить :)
Нет, выбрасывать не стоит. :)
0
Долго тупил и думал, пока не вывел аналогичный график и не понял причину происходящего.
И как Вы поступили после выяснения причины? Вы отказались от идеи:
вносить коррекцию только тогда, когда модуль вектора с акселерометра приблизительно равен 9.8 м/с^2.
0
Нет, от этой идеи я не отказался. Я отказался от жесткого условия (при таких-то условиях вносим поправку, при других не вносим вообще).

Я решил сделать коэффициент комплементарного фильтра не константой, а функцией от некоторого состояния системы (текущее значение модуля g, дифференциал ошибки и т. д.) Получается некое подобие адаптивного фильтра, чем более «идеальные» условия, тем «активнее» вноситься поправка, и наоборот.

Сейчас занимаюсь поиском этой самой функции.
0
Я решил сделать коэффициент комплементарного фильтра не константой, а функцией от некоторого состояния системы (текущее значение модуля g, дифференциал ошибки и т. д.)
Мне кажется, что функционирование самих ПИДов, на которые потом поступают обсчитанные значения с датчиков, будет осуществлять гибкое регулирование. Текущее значение модуля g — пропорциональная компонента, дифференциал — говорит сам за себя, ну и до кучи, скорость, как интегральная компонента.
Получается некое подобие адаптивного фильтра, чем более «идеальные» условия, тем «активнее» вноситься поправка, и наоборот.
Получается система с положительной обратной связью, а это (насколько я помню из теории регулирования) чревато автоколебаниями.
У меня сейчас вылезла другая фишка: при статичном положении гироскопа выходной сигнал также статичен. В динамике же, при возврате в исходное положение, возникает существенное отклонение от исходного положения. Мне сейчас очень наглядно видно, поскольку угол отклонения отображается у меня в абсолютном виде посредством отклонения качалки на сервомашинке.
0
Мне кажется, что функционирование самих ПИДов, на которые потом поступают обсчитанные значения с датчиков, будет осуществлять гибкое регулирование.

Не совсем понял, что Вы в данном случае имеете ввиду (о каком ПИД идет речь): ПИД регулятор для расчета управляющего воздействия на двигатели или ПИД регулятор для внесения коррекции в расчетный угол?

Получается система с положительной обратной связью, а это (насколько я помню из теории регулирования) чревато автоколебаниями.

Возможно, я непонятно высказался. Я не планирую вводить положительную обратную связь.

Если проводить аналогию с пропорциональным регулятором, то я предлагаю классический регулятор с отрицательной обратной связью, единственное, коэффициент регулятора я предлагаю сделать динамическим.

В динамике же, при возврате в исходное положение, возникает существенное отклонение от исходного положения

Вы говорите о сырых данных с гироскопа (угловой скорости) или о интеграле (значении угла)?
0
единственное, коэффициент регулятора я предлагаю сделать динамическим.
Возможно я ошибаюсь, но в таком случае при определенном сочетании параметров условия устойчивости могут нарушаться. Ловить такое врагу не пожелаешь. Разве что задемпфировать все по самое небалуйся, но тогда упадет скорость реакции на изменения. IMHO.
0
Возможно я ошибаюсь, но в таком случае при определенном сочетании параметров условия устойчивости могут нарушаться.

Да, просто так баловаться с коэффициентами опасно, но можно принудительно ограничить диапазон изменения коэффициента и т. д.

Попробую изложить свою идею подробнее. Давайте забудем о шумах акселерометра, собственных ускорениях, вибрации и т. д. Предположим (для начала) что акселерометр показывает «истинный вектор g», и углы, полученные с акселерометра соответствуют реальному положенную ЛА. И рассмотрим одномерный случай.

Предположим, что после интегрирования показаний гироскопа (в очередной итерации цикла), мы получили угол Ag (угол с гироскопа). Одновременно, мы имеем тот-же угол с акселерометра (Аа). В данном случае, как мы пока договорились, мы считаем, что угол с акселерометра Аа истинный, а в Ag присутствует ошибка (вызванная интегрированием).

Ок, вводи коррекцию через Пропорциональный регулятор

Рассогласование/ошибка (E) равна

E = Аа – Ag;

Соответственно, введение коррекции будет выглядеть как

Ag += Kp * E;

Kp – коэффициент нашего регулятора, он связывает значение ошибки и значение вводимой корректировки.

А вот, теперь, вспомним, что на акселерометр действует собственное ускорение, вибрация и т. д. Для нас это паразитические воздействия, они могут вместо внесения корректировки внести ошибку. Но мы эти паразитические воздействия (как-то, косвенно) можем оценить и представить как Aerror. Aerror — это наша оценка вероятности ошибки в показаниях акселерометра в данный момент, например, по шкале [0… 1].

Логично, что чем больше Aerror, тем с большей вероятностью мы вместо коррекции угла внесем ошибку. Но мы можем учесть это в формуле регулятора.

Ag += (Kp * (1 — Aerror ) ) * E;

Теперь коэффициент нашего пропорционального регулятора лежит в диапазоне [Kp… 0] и зависит от вероятности ошибки в показаниях акселерометра. Чем больше вероятность ошибки — тем меньше будет величина вводимой коррекции.
0
Уточню, я говорил о применении регулятора для внесения коррекции. Если говорить о ПИД для расчета управляющего воздействия на двигатели – то это классический ПИД, там нет акселерометров, вероятностей, и т. д. Есть толь отклонение от заданного угла (вычисленного с помощью БИНС), которое нужно скомпенсировать.
0
Попробую изложить свою идею подробнее.

И это всего лишь идея, рабочая гипотеза. Критика и комментарии приветствуется.
0
В скоординированном вираже акселерометр всегда показывает примерно то же, что и равномерном прямолинейном полете без крена и тангажа, поэтому такой подход сведет на нет все коррекции по акселерометру на НЕТ.
0
Т.е. вектор силы тяжести будет перпендикулярен плоскости ХУ аппарата (этоя я так, уточнил, вдруг непонятно выразился)
0
В скоординированном вираже акселерометр всегда показывает примерно то же, что и равномерном прямолинейном полете без крена и тангажа

ОК, но мы и вводим Aerror для того чтобы на таких виражах не вносилась ошибка. Мы можем «распознать», что мы находимся в вираже и вернуть Aerror близкое к 1, тогда коррекция (вернее, в данном случае, ошибка) в этот момент вноситься не будет. Как распознать «вираж» — у нас для этого есть множество внутренних параметров (текущее значение углов крена и тангажа, дифференциал ошибки, сигналы с пульта и т. д.). Мы можем учесть эти данные при расчете Aerror. Если совсем в лоб, то, например, возвращать Aerror = 1 если текущее значение крена и тангажа больше 10 градусов (это просто пример, на самом деле я планирую сделать функцию расчета Aerror намного более сложной и учитывать много параметров).
0
эти паразитические воздействия (как-то, косвенно) можем оценить и представить как Aerror.
Как именно можно оценить эти паразитные воздействия и как отличить их от не паразитных? Подбор или статистика?
0
Я попытаюсь сначала аналитически выделить те «переменные» внутреннего состояния, от которых потенциально зависит Aerror. Потом представить их в виде формулы (например, как сумма с некоторыми весовыми коэффициентами). А вот как подобрать потом значения этих весовых коэффициентов – вопрос. Либо мат. моделирование, либо тупо подбор по результатам экспериментов на коптере (но это плохой вариант, как я уже писал, тяжело субъективно оценить незначительные изменения в поведении коптера).
0
Грубо говоря, я предполагаю что коптрер имеет собственно линейное ускорение если
— Модуль вектора g отличается от 9.8
— Резко увеличивается дифференциал ошибки
— я отклоняю ручку крена/тангажа на пульте
— и т. д.
Ок, я могу записать это все как
Aerror = K1*abs(g – 9.8) + K2* abs(Eprev – E) + K3*abs(RCStikPos) + …

Это просто пример, функция не обязательно должна быть линейной и т.д.
0
Немного скорректировать и будет изложение сути фильтра Калмана простыми словами, а вы говорите непонятная магия :)
+1
Спасибо, значит я на верном пути. Но фильтр Калмана так и остается для меня магией. Я понимаю только отдельные моменты, общего понимания принципа работы данного фильтра у меня нет.
0
Скалярный случай. Имеем ошибку.

e = r — x

Имеем процедуру внесения поправки.

x' = x + K e

Вопрос, какое выбрать K? Ответ, которое минимизирует дисперсию x', то есть оценки. Записываем.

D[x'] = D[x + Ke]

Дисперсия суммы открывается следующим образом.

D[x + Ke] = Dx + K^2De + cov(x,Ke)

Множители выносятся с квадратом (легко показать расписав на бумажке). Ковариация это вот такое выражение.

cov(x,Ke) = M[(x)(Ke)]

Открываем ошибку.

M[(x)(Ke)] = M[(x)(K(r-x))] = M[Kxr-Kx^2] =
= KM[xr] — KM[x^2]

Первое слагаемое равно нулю, т.к. предполагается, что шум измерения и имеющаяся неточность оценки не коррелируют (ковариация равна нулю). Второе есть KDx по определению дисперсии D[x]=M[(x-Mx)^2] и того, что Mx=0 (для упрощения, можно расписать и для общего случая, но лень, лишние слагаемые все равно сократятся далее).

Возвращаемся к выражению.

D[x + Ke] = Dx + K^2De + cov(x,Ke)

Дисперсия e считается легко т.к. x и r не коррелируют.

De = Dr + Dx

Теперь введем обозначения.

Dx = P — дисперсия имеющейся оценки
Dr = R — дисперсия шума измерения

Переписываем выражение.

P' = P + K^2(P+R) — 2KP

Нам нужен минимум, берем производную по K.

dP'/dK = 2K(P+R) — 2P

Равняем к нулю, и находим K.

2K(P+R) — 2P = 0

K = P / (P+R)

Сравниваем с формулой ФК, видим, что получили тоже самое.

Для понимания нужно знать только базовый теорвер.
+1
fix: в формуле ковариации должно быть 2cov.
0
Я, если позволите, немного поспрашиваю, но попрошу не судить строго за уровень вопросов.
Имеем ошибку: e = r — x
Я правильно понял, что r-реальное значение параметра, а x-измеренное значение того же параметра? Тогда получается, что r=x+Re? Или х'-это скорректированное значение измеренного параметра, но ещё, как бы, не истинное?
0
x — оценка (выход фильтра)
r — измерение (вход фильтра)

R — дисперсия r
P — дисперсия x

Истинное получить нельзя, магии здесь нет, а погрешность всегда есть :)
0
Огромное спасибо! Наконец я понял, как работает данный фильтр. Все достаточно логично, нет никакой магии :)
0
Я процесса вывода конечной формулы, честно сказать, так и не понял, но сама конечная формула подкупает своей простотой. Получается, что к-т коррекции равен соотношению дисперсии входного параметра к общей дисперсии измерений. Эдакая «относительная дисперсия».
Остаётся понять как эти дисперсии счиаются? Это опять выборка? Или они просто подбираются?
0
Что-то у вас все перепутано. Попробуем так. Есть фильтр первого порядка, апериодическое звено.

x(n+1) = x(n) K1 + r(n) K2

Для фильтрации интересен случай когда K1+K2=1 и оба коэффициента положительные. Сделав переобозначения получаем.

K1 = 1 — K2
K2 = K

x(n+1) = x(n) + (r(n) — x(n)) K

Разделим равенство на несколько, хотя это может выглядеть неестественно и непонятно.

1. Модель системы, в данном случае предполагается неизменность x.

x'(n+1) = x(n)

2. Внесение поправки.

x(n) = x'(n) + (r(n) — x'(n)) K

x'(n) — это промежуточный результат, уже экстраполирован на новый n+1-йшаг но не поправлен.

Дальше для выбора K справедливо все то из предыдущего поста. Но ещё надо добавить корректировку дисперсии x.

На старте имеем начальную P, которая задается исходя из достоверности начального значения x. И для каждого шага нужно определится с дисперсиями щумов модели и измерения, они могут быть постоянными или разными на каждом шаге.

Во время экстраполяции мы находим предполагаемое значение оцениваемой величины на следующем шаге в среднем. Для описания непредсказуемых изменений величины предполагается стохастическая модель.

x'(n+1) = x(n) + q

Где q — нормально распределенная случайная величина с дисперсией Q и нулевым матожиданием. Дисперсия Q используется для определения дисперсии x(n+1).

D[x'(n+1)] = D[x(n) + q] = D[x(n)] + D[q] + 2cov(x(n)) = P + Q + 0

P'(n+1) = P(n) + Q

Следующий шаг, поправка.

P = P' + K^2(P'+R) — 2KP'

Сюда входит K которое выбирается вот так.

K = P' / (P'+R)

Подставляем.

P = P' + P'^2/(P'+R) — 2 P'^2/(P'+R)
P = P' — P'^2/(P'+R)
P = P' (1 — P'/(P'+R))

P = P' (1 — K)

Итого имеем следующую процедуру фильтрации.

Задаем начальное x, P, все Q и R если они не постоянные.

Делаем экстраполяцию значения и его дисперсии.

x'(n+1) = x(n)
P'(n+1) = P(n) + Q

Делаем поправку и находим дисперсию результата этой поправки.

K = P' / (P'+R)
x(n) = x'(n) + (r(n) — x'(n)) K
P = P' (1 — K)

Конец.

Q и R берутся исходя из предполагаемых знаний о системе, если этих знаний нет то можно оценить статистически. Есть каке-то схемы когда они оцениваются в процессе работы фильтра. Но для ФК это внешняя информация.

Если положить Q=0 и иметь только начальную неопределенность в P то получим рекурсивный МНК. P будет только убывать, а оценка x к чему-то сходится.
0
Для меня есть еще один непонятный момент.

Я смотрю на общее описание фильтра Калмана, на примеры реализации и я не понимаю, почему при экстраполяции /коррекции ковавариации ошибки (P) никак не учитывается текущее состояние системы, входы/выходы фильтра.

Мы экстраполируем вектор состояния, матрицу ковариации ошибки. Потом рассчитываем коэффициент усиления Кальмана, используя его, вносим коррекцию в вектор состояния и матрицу ковариации ошибки.

Но, по тому, что я вижу, предсказание ошибки никак не засвистит от входа/выхода фильтра.

В предсказании/корректировке учувствуют начальное значение ковариации ошибки, матрица перехода (F), ковариация шума процесса (Q), ковариация шума измерения (R), и т. д. Но ведь это все константы. Тоесть предсказание ошибки зависти только от этих констант и начальных условий?
0
Все правильно, ФК не занимается оценкой параметров шумов, а принимает готовые матрицы ковариаций.

Значения вектора состояния могут иметь влияние на выбор K если система не линейна или не стационарна. А для линейной стационарной системы и постоянных Q, R, K тоже будет сходится к постоянному значению.

Да и Q, R не обязаны быть постояннами, как и F, H. На вычислении линейных приближений F, H в текущей точке системы основан EKF.

Можно заставить EFK оценивать параметры цветного шума, если очень хочется. В Q будет какая-то постоянная дисперсия, а дальше фильтр с параметрами зависящими от x. Хотя я не пробовал.

Есть более общие методы, которые работают «поверх» ФК и оценивают Q, R. Но подробностей не как уже говорил не знаю/ не помню.
+1
Понятно, просто у меня были подозрения, что я что-то упустили из виду. Спасибо за ответ.
0
x'(n) — это промежуточный результат, уже экстраполирован на новый n+1-йшаг но не поправлен.
Тогда выходит x'(n+1) — это х+2?
1. Модель системы, в данном случае предполагается неизменность x.
x'(n+1) = x(n)
Может быть нужно как то по-другому сформулировать, поскольку из равенства выходит, что х не меняется со временем? Может так: x'(n+1) = f(x), т.е. следующий не скорректированный результат измерений зависит от предыдущего(cov(x(n);x'(n+1))?
Более логичным выглядит вот это выражение: x'(n+1) = x(n) + q. И для дисперсии утверждение P'(n+1) = P(n) + Q выглядит логичным.
Последняя фраза поста
Если положить Q=0 и иметь только начальную неопределенность в P то получим рекурсивный МНК.
вносит для меня путаницу, поскольку, если нет Q, то зачем фильтр?
0
Более логичным выглядит вот это выражение: x'(n+1) = x(n) + q

Мы не можем при экстраполяции учитывать q, т. к. мы не знаем, чему равно q на данном шаге, q для нас это случайная величина с нулевым мат. ожиданием. Поэтому, согласно нашей модели, мы считаем что x'(n+1) = x(n). А вот дисперсию q мы знаем, и учитываем ее при экстраполяции дисперсии ошибки.

Вообще, в примере автор показал упрошенную модель, в базовой теории это выглядит так

x'(n+1) = F x(n) + B u(n)

F – это матрица перехода (по сути это и есть f(x)), u – управляющее воздействие, B – матрица применения управляющего воздействия

если нет Q, то зачем фильтр?

Есть еще погрешность измерения с дисперсией R
0
Вообще, в примере автор показал упрошенную модель, в базовой теории это выглядит так

Вернее не модель а предсказание состояния
0
вносит для меня путаницу, поскольку, если нет Q, то зачем фильтр?

Есть еще погрешность измерения с дисперсией R

Я, наверно, не до конца понял Ваш вопрос и поспешил с ответом. Если Q = 0 и начальное значение Р = 0 то фильтр действительно не нужен, мы достоверно знаем состояние системы и оно не меняется. И измерять тоже ничего не нужно. Речь идет о случае, когда мы не знаем начальное значение x, или знаем приблизительно (с дисперсией P). Но мы можем измерить его значение (опять же с дисперсией R).
0
x'(n+1) = F x(n) + B u(n)
Вот это понятно. Тогда ещё конкретнее можно? Применительно к показаниям акселерометра и гироскопа.
По предложению amaora (кстати, очень любопытно имеет ли этот ник какой-то смысл?) задаём начальные значения х, Р, Q, R: если я правильно понимаю, хo=0 (объект неподвижен) и Рo=0, Q можно взять для начала произвольно, а R из основываясь на выборке полученной при калибровке датчика. Так?
1.Экстраполируем х: поскольку никаких других данных о системе, кроме предыдущего состояния нет, то думаю, что x'(n+1)=x(n) + q = 0+q = q;
Экстраполируем Р: P'(n+1) = P(n) + Q = P'(n+1) = Q + 0 = Q;
2.Считаем К: K = P' / (P'+R)= Q / (Q+R). Допустим мы приняли Q=0,1g; R=0,05g. Тогда К=0,1/0,15=0,67.
3. Считаем х: x(n)= x'(n)+(r(n) — x'(n))K = q+(r(n)-q))*0,67 для примера предположим, что q=0 (ведь это не исключено и весьма вероятно?), а тоже r=0 (почему нет?), тогда: x(n)=q+(r(n)-q))*0,67=0.
Пока всё сходится — прогноз для неподвижного объекта соответствует реалности.
Возмём другие значения q=0,1g; r=0,05g(вроде укладываются в дисперсии?). x(n)=q+(r(n)-q))*0,67=0,1+(0,05-0,1)*0,67= -0,1335g получается довольно много, но есть P = P' (1 — K)=Q(1-K)=0,33Q=0.033g,
которая на следующем шаге даст уменьшение К и соответствующее уменьшение изменения x(n)=x'(n)+(r(n)—x'(n))K. И вроде бы так должно происходить пока x(n) не приблизится к истинной величине.
Я смысл понял или опять накосячил?
0
Ну, конечно, накосячил. К ведь меньше нуля, соответственно: P = P'(1 — K)=Q(1-K)=1,1335Q=0,11335g
0
Я, честно говоря, не совсем понял логику Вашей симуляции. Вы оперируете q, но ведь мы не знаем значение q и не можем узнать. О том, что состояние системы изменилось, мы можем узнать только через измерение r. Но r не рвано x(n) + q, как-как есть ошибка измерения (R)

Ели хотите просимулировать работу скалярного фильтра, то вот в этой статье есть реализация (там правда С#, но реализация очень простая, по сути чистая математика, можно перевести на любой другой язык).
0
Вы оперируете q, но ведь мы не знаем значение q и не можем узнать.
А отчего по-простому не взять «от балды»? Величина ведь случайная. Просто, чтобы проверить как влияет я взял так.
О том, что состояние системы изменилось, мы можем узнать только через измерение r.
Но это только одна, хоть и основная, компонента влияющая на формирование управляющего воздействия.
За ссылку по Калману большое спасибо, но на данный момент я (прошу не судить строго) уже так свыкся с теми обозначениями и определениями, которые мы здесь обсуждаем, что просто не воспринимаю по-другому.
0
Да, только если дисперсия нормально распределенной сл. величины равна Q это не значит, что её реализации (значения) не могут превысить Q. И для представления о распределении удобнее пользоваться квадратным корнем из дисперсии, то есть среднеквадратичным отклонением. Но значения отклонения q от среднего могут превышать и sqrt(Q) с довольно большой вероятностью, они всего лишь в среднем равны sqrt(Q).

Если хотите сделать статистический тест, сформируйте большую реализацию значений x, r. Подайте в фильтр указав правильные P R, соответствующие реализациям. И посчитайте дисперсию выхода для разных K, чтобы понять где минимум и соответствует ли он P/(P+R).

Ник комбинация транслитированных букв настоящего имени которая плохо гуглилась на момент создания.
0
они всего лишь в среднем равны sqrt(Q)

Или даже это не верно? :)
0
М… Тогда, видимо, я чего-то не понял.

Предположим, на первой итерации цикла (фильтра) мы получили выход x = 0, на следующей итерации мы чего-то там намерили и получили r=0,05. Мы должны применить коррекцию к значению 0 (к экстраполированному значению х предыдущего цикла).

В данной симуляции работы фильтра — использование q это «читерство», мы ведь не знаем значения q :)
0
Просто коллега mpetrovich на второй итерации применяет коррекцию

x(n)=q+(r(n)-q))*0,67

Но фильтр не знает, что значения что значение x изменилось на величину q, и мы должны применять коррекцию к экстраполированному значению х с прошлой итерации, тобиш к 0?
0
Да, только если дисперсия нормально распределенной сл. величины равна Q это не значит, что её реализации (значения) не могут превысить Q.
А слово «Да» в начале поста означает согласие с моей попыткой симуляции или оно здесь выступает как междометие?
если дисперсия нормально распределенной сл. величины равна Q это не значит, что её реализации (значения) не могут превысить Q.
Ну, Вы мне совсем не доверяете! Я намедни освежил своё представление о тервере после 25 лет перерыва. Я взял такие конкретные значения Q и q чтобы было что подставить в приведёные Вами формулы.
Если хотите сделать статистический тест,
Я хочу не статистический тест, я хочу работу фильтра понять и реализовать. Вы, господа, мне, надеюсь, в этом поможете. Ведь Вы сами над тем же трудитесь.
Ник комбинация транслитированных букв настоящего имени
Таинственно, однако, получилось!
У меня так не выходит, мой ник по-моему весьма прозрачен.
0
Хочу ещё вот что сказать: мне кажется, что в нашем случае, когда относительные данные с гироскопа корректируются абсолютными данными с акселерометра, нужно фильтровать Калманом только показания акселерометра. Это, так сказать, минимально необходимая фильтрация. Если иметь достоверные данные абсолютной величины, то относительные величины связанные с этой абсолютной величиной могут быть откорректированы простой линейной функцией типа f(w)=k*f(a).
0
Я потерялся в этом полотенце комментов, пора куда-то переехать.

нужно фильтровать Калманом только показания акселерометра


В том виде о котором шла речь это будет ФНЧ с оптимальной постоянной времени для заданного шума. Скалярный случай это только для упрощения объяснения.

Применительно к коптеру, я уже наверно говорил, чтобы приблизится к пределу возможностей системы, надо использовать полную модель. Размеры вектора x будут достигать некрасивых значений, 3 переменных для линейного положения, 3 для скоростей, 4 для ориентации, 3 для угловой скорости, 4 для скоростей винтов. Для калибровки/адаптации можно добавить, 3*N масштабы/смещения датчиков, 1 масса, 3 моменты инерции, 1 момент инерции двигателя+винт, 2 давление/температура, 3 постоянная составляющая ветра,. Ещё нужна какая-то хотя бы упрощенная газодинамика винта, но и без этого уже три десятка переменных.

Здесь ФК будет работать больше не на учет шума а на учет зависимостей переменных (например коррекция каких-то коэффициентов зависимости тяги винта от давления на основе ошибки по ориентации).

Но никто похоже не хочет влезать так глубоко.
0
Согласен с Вами, ФК лучше применять именно для учета зависимостей переменных. ИМХО, просто как фильтр (скалярный) он не интересен.

Конечно, размерность х в предложенной вами модели впечатляет. Не ресурсоемкостью вычислений а тем, что придётся каким то образом для такой модели вычислять (подбирать ?) параметры фильтра (Q, R, H и т. д.).

Но я полностью поддерживаю Ваш подход, другое дело, что я его не осилю. Вы пишете

Но никто похоже не хочет влезать так глубоко.

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

Я потерялся в этом полотенце комментов, пора куда-то переехать.

Я, честно говоря, тоже. Но куда переезжать?
0
каким то образом для такой модели вычислять (подбирать ?) параметры фильтра (Q, R, H и т. д.).
Если вычислитель будет справлятся, то в модели не будет постоянных, все будет в векторе x. Q выбирать исходя из величины неучтенных возмущений. R из параметров датчиков.

дело не в том, что не хочет (я бы с удовольствием) а в том, что мало кто может влезть так глубоко. Я, увы, не могу, мне банально не хватает знаний.
Ещё ~год назад я лишь что-то смутно помнил о ФК, и линейных наблюдателях. И наверно отчасти поэтому, я все ещё ковыряюсь с сервой, а не делаю бинс и не даже bldc. Я тоже мог бы сказать, что не могу.

Но куда переезжать?
Отдельный пост о ФК?
0
Ещё ~год назад я лишь что-то смутно помнил о ФК

Понимаете, коллега, все относительно и индивидуально. Ваша базовая подготовка (базовые знания по данной тематике) для меня является «идеалом».

Ещё ~год назад я вообще не знал что такое БИНС и ФК. И задавал здесь, в сообществе, вопросы типа «зачем нужна интегральная составляющая в ПИД регуляторе?». Я не прибедняюсь, просто моя профессиональная деятельность лежит далеко от ЦОС и ТАУ.

Я не сдаюсь, не говорю, что «я не могу, и значит даже пытаться не стоит», я просто объективно оцениваю свои возможности на данный момент.

Отдельный пост о ФК?
Ну, Вы сами напросились на написание поста :)
0
Ну, Вы сами напросились на написание поста :)
Я ещё не настолько наигрался с ФК, чтобы рассказывать об этом :)
0
я все ещё ковыряюсь с сервой, а не делаю бинс и не даже bldc
Не понял о чём здесь? Имеется в виду способ управления тягой винтов или что-то другое?
0
Про серву можете посмотреть среди моих публикаций здесь. Серва более простая система, подходит для испытания неизведанных методов наблюдения и управления. Да и не нравится мне модельные сервы с их односторонним протоколом.

Следующий шаг контроллер bldc, хотя последнее время я работал только в сторону синусоидального управления или foc. С шестью шагами все как-то плохо с синхронизацией.

А до бинс совсем далеко, ничего ещё не начинал, только мысленно, и какие нибудь тесты-проверки_идеи в octave на 5 минут. Термех ещё почитал, все оказалось не так сложно как казалось.
0
В том виде о котором шла речь это будет ФНЧ с оптимальной постоянной времени для заданного шума. Скалярный случай это только для упрощения объяснения.
Я бы не прочь хоть так обкатать ФК на практике, только вот в голове пока не очень всё устаканилось для написания хоть чего-нибудь.
Ещё нужна какая-то хотя бы упрощенная газодинамика винта,
Вот уж не согласен я! Параметры двигателей, винтов, да и регулей тоже, нужно выбирать по принципу простой избыточности. Нет нужды обсчитывать работу каждого отдельного исполнительного узла. Достаточно оценочных характеристик. Иначе можно скатиться к учёту трения в подшипниках.
Другое дело, если бы нужно было бы работать в условиях когда узлы нагружены на грани возможностей. Тогда вышеупомянутый подход имел бы смысл. Однако, к счастью, нынешний уровень модельных комплектующих позволяет практически любые выкрутасы моделиста.
В своё время я спорил на тему замены вертолётного гироскопа (стабилизирующего ЛА относительно вертикальной оси) на контроллер обсчитывающий реактивный момент несущего ротора и компенсацию рулевого винта. Так вот мне сказали простую мысль, которая меня убедила: гироскоп — ИНТЕГРАЛЬНЫЙ датчик, который учитывает все (почти) возмущения положения ЛА относительно рабочей оси: изменение оборотов НВ, угла атаки лопасти, изменение циклического шага, порывы ветра, восходящие потоки и т.п. Так вот, я это к тому, что нужно просто правильно выбрать подобный ИНТЕГРАЛЬНЫЙ датчик(и) и работать в направлении максимальной достоверности его показаний. Остальное обсчитается как угодно в соответствии с фантазией моделиста.
ФК будет работать больше не на учет шума а на учет зависимостей переменных (например коррекция каких-то коэффициентов зависимости тяги винта от давления на основе ошибки по ориентации).
А разве это не общая постановка задачи, которую решает любая из систем управления — измерив отклонение от заданного параметра произвести управляющее воздействие, которое нивелирует это отклонение.
0
Вот уж не согласен я! Параметры двигателей, винтов, да и регулей тоже, нужно выбирать по принципу простой избыточности. Нет нужды обсчитывать работу каждого отдельного исполнительного узла.

amaora не предлагает выбирать комплектующие для ЛА исходя из модели. Выбор комплектующих остается за вами, от предлагает учитывать их характеристики в модели.

Потенциально, чем больше у нас будет вектор состояния системы, чем больше будет наблюдаемых параметров – тем точнее получится результат. Естественно, фанатизм не нужен, и учитывать трение в подшипниках тоже нет смысла. Но какая размерность вектора состояний является оптимальной? ИМХО, пока не попробуешь – не поймешь. То, описание вектора состояния которое предлагает автор (ИМХО) выглядит логичным (хотя кол-во параметров впечатляет). Более того, если я правильно понимаю, ФК позволяет получить оценку данных, которые мы не можем измерить напрямую, например, данные о ветре.

гироскоп — ИНТЕГРАЛЬНЫЙ датчик, который учитывает все (почти) возмущения положения ЛА

Да. Только но не точен. Более того, если мы говорим о MEMS ДУС-е, то там все вообще печально. Поэтому имея данные с гироскопа и данные о реактивном моменте, можно получить более точные данные о реальном положении чем просто считав данные с гироскопа.

Как говориться, «Добрым словом и револьвером можно добиться большего, чем одним только добрым словом.» :)
0
(о каком ПИД идет речь):
Об этом:
ПИД регулятор для расчета управляющего воздействия на двигатели
Вы говорите о сырых данных с гироскопа (угловой скорости) или о интеграле (значении угла)?
Я говорю об интеграле. Но по сути, конечно, наличиствует ошибка угловой скорости.
0
А какая ошибка угла у Вас получается в абсолютном значении? Например, плата лежит горизонтально, поворачиваем ее на 45 градусов а потом возвращаем в исходное положение. На сколько при этом уплывает значение угла (хочу сравнить со своими результатами)? И какие у вас настройки гироскопа (диапазон, частота опроса, используете ли внутренний фильтр)?
0
Гироскоп IMU-3000, FS = 500deg/s, полоса пропускания фильтра низких частот 5Гц(встроенный), частота выборки (опроса) 100Гц. Больше не фильтрую перед алгоритмом. За часа три гироскоп уплывает в зависимости от оси от 3-7 градусов. Использую не комплиментарный фильтр, а модифицированный Махоуни. Если в текущем состоянии при повороте платы на 45 и обратно у меня 0 градусов ошибки, но это с моими костылями и палками. Но есть одно но, у нас не коптер, а что-то близкое к самолету=)
0
За часа три гироскоп уплывает в зависимости от оси от 3-7 градусов.

На всякий случай уточню – мы говорим о интегрировании данных с гироскопа, без внесения коррекции? Для меня ваш результат выглядит недосягаемым, у меня ошибка в 3 градуса накапливается за ~8 минут (и это в идеальных условиях).

У меня, правда, больше диапазон (2000 deg/sec), но я пробовал уменьшать диапазон, результаты были лучше, но не настолько хороши как у Вас.

Завтра, для гарантии, повторно протестирую на 500 deg/sec.
0
без внесения коррекции?
Да, без коррекции.
Другой вопрос в том, что при произвольном вращении можно получить ошибку ~10 градусов, но это из за отсутствия коррекции=(
0
Другой вопрос в том, что при произвольном вращении можно получить ошибку ~10

Ну, с произвольным вращением понятно, там проявляется погрешность измерения, погрешность интегрирования и т. д.

В вот Ваши результаты «статического» теста впечатляют.
0
Попробовал изменить ориентацию осей.

Вот график (данные пропущены через ФНЧ), ось Y смотрит вверх.



В принципе, результаты похожи не предыдущие, но есть некоторые отличия

1. Проекция g на ось Y больше чем проекция g на Z в предыдущем тесте. Как это объяснить (корме как разная нелинейность по разным осям) я не знаю. На всякий случай перепроверил тестовый код – вроде я нигде не лажаю.

2. Ось Х шумит слабее и шум симметричнее, на оси Z шум больше и смещен в положительную область.

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

В тесте «Z направлена вверх» проекция g на Z составляет 3330 единиц. Переворачиваю плату (ось Y направлена вверх) – проекция g на Y составляет 4140 единиц. Странно. По даташиту, проекция должна быть равна 4096 единиц.
0
Да вроде все в норме, если аксель не откалиброван.=) Да и 4096 единиц при каком разрешении? Если привести к Ж то по идее должно получитьсяя чуть больше чем допустимое при данных пределах
0
Да и 4096 единиц при каком разрешении?

При диапазоне измерений +/- 8g

Да вроде все в норме, если аксель не откалиброван.=)

Ну, своей (программной) калибровкой я, конечно, это все исправляю. Просто странно что «заводская» калибровка так сильно отличается по разным осям.
0
При диапазоне измерений +/- 8g
Ну так вроде там 2mg на LSB, так что вроде 0.002*4000=8g
Просто странно что «заводская» калибровка так сильно отличается по разным осям
Во всех акселерометрах, что проходили через меня был такой косяк=) Причем у ST самый заметный…
Kionix чуть меньше, ну а IvenSense вроде как нормуль (хотя калибровать все равно пришлось)
0
Ну так вроде там 2mg на LSB, так что вроде 0.002*4000=8g

Нет, по даташиту на MPU-6050, чувствительность в данном режиме 4096 LSB/g. 1g = 4096 LSB.

Просто в LSM330DL заводская калибровка по всем осям была боле точной, а в MPU-6050 заводская калибровка по Z сильно ушла в минус. Хотя, это не критично, я все равно программно калибрую датчик, на заводскую калибровку можно забить.
0
Да уж, картинка удручающая.
А если полосовой фильтр попробовать? Частоту можно с мотора(ов) снять, к примеру.
И совсем уж дурная мысль: а может этот сигнал тоже проинтегрировать? Он периодический, симметричный (относительно). Вдруг прокатит?
0
Ну, почему, коллеги, все не так уж плохо (после ФНЧ). Постоянная составляющая в шуме акселерометра есть, но она не такая большая (в пересчете на градусы, получается около 2-3 градусов). И это абсолютная ошибка, в отличии от интегрирования показаний гироскопа она не накапливается. В случае моего коптера, такая ошибка приводит к линейному дрейфу коптера со скоростью около 5 см/сек (специально я не мерял, но «на глаз» где-то так). Жить с этим можно. Просто я хочу добиться «идеального зависания», насколько это возможно на этих датчиках. Да и есть еще магнитометр (он, конечно, жутко шумит), но думаю кое что из него выжать можно.

Частоту можно с мотора(ов) снять, к примеру.

Думаю не получится. Частота вибрации зависит от оборотов. Плюс на коптере много моторов, частоты их вибраций могут быть близки и при наложении возникнут «биения». Плюс резонанс конструкции (рамы).
0
дрейфу коптера со скоростью около 5 см/сек (специально я не мерял, но «на глаз» где-то так).

Наверное, дрейф больше что-то около 5-10 см/сек.
0
такая ошибка приводит к линейному дрейфу коптера со скоростью около 5 см/сек
Это как то многовато. Порядка 20км/ч получается, скорость хорошего велосипедиста.
0
0.18 км/ч, скорость беговой улитки.
0
Как уже заметил ACE , Вы где-то ошиблись в расчетах, 10 см/с = 0.36 км/ч. Но и это действительно много (я сравниваю с видео других моделистов, у которых коптер в помещении висит практически идеально). Мне до такого результата еще работать и работать (притом не только над БИНС). Пока я поставил локальную задачу – добиться мин влияния вибрации (не прибегая к вибро-развязке, чисто алгоритмически).

Вообще, с тестированием всего этого добра на коптере у меня есть проблемы – тяжело оценить «на глаз» результаты, тяжело добиться четкого повторения результатов. Поменял что-то в прошивке, залил на коптер. Один раз взлетаешь – вроде лучше чем на прошлой версии прошивки. Взлетаешь второй раз – а может и не лучше. Взлетаешь третий – а может и хуже. Изменения незначительные, и их тяжело оценить по субъективному восприятию. Мы занимаемся данной темой с приятелем, так вот часто бывает, что он говорит, что новая прошивка летает лучше, а я что хуже :) Нужно бы выработать какую-то методику для объективной оценки стабильности ЛА, но я не знаю, как это можно сделать.
0
Как уже заметил ACE, Вы где-то ошиблись в расчетах, 10 см/с = 0.36 км/ч.
Ну да, проглядел букву «с» и посчитал, что это метры в секунду. Невнимательность — моё давнее «счастье».
0
По поводу числовых данных. Мне кажется, достаточно стабильности +/- 1 градус за десяток секунд.
Ха-ха, это шутка?
Оценку нулевого сигнала можно производить и во время работы системы.
Это плавающее ил динамическое усреднение. Я тоже думал об этом, но тогда должна быть достаточно высокая скорость опроса датчиков — никак не 100Гц, а раз в 10-20 больше.
0
Ха-ха, это шутка?
Не думаю, что надо работать в сторону длительной автономной (без коррекции) инерциальной навигации. Это возможно, но дорого и массивно.

Это плавающее ил динамическое усреднение.
Здесь я не понял зачем повышать частоту. Цель — лишь убрать постоянную состовляющую ошибки, а не корректировать на каждом такте. Это похоже на интегральную составляющую в ПИ регуляторе. В результате ноль будет держаться не за счет ошибки а за счет интеграла. Как это все связано с частотой?
0
Не думаю, что надо работать в сторону длительной автономной (без коррекции) инерциальной навигации.

Полностью поддерживаю. Ели мы говорим о бюджетной системе на MEMS гироскопах, то я не вижу вариантов, кроме как корректировать накапливающуюся ошибку по другим датчикам.
0
Здесь я не понял зачем повышать частоту.
Я имел в виду интегрирование «пачек» усреднённых значений в течении промежутка времени. Не последовательное складывание величин приходящих сдатчика после каждого замера, а, скажем, по 4 значения и потом уже усреднять результат этих малых порций. Для этого и понадобится увеличение частоты опроса.
Я опробовал этот способ, но результат не порадовал. Может и стало чуть лучше, но глазом не видно.
Цель — лишь убрать постоянную состовляющую ошибки, а не корректировать на каждом такте. Это похоже на интегральную составляющую в ПИ регуляторе.
Интеграл (ФНЧ) как раз постоянную составляющую и выделяет. Убрать постоянную составляющую можно дифференцируя (ФВЧ), только зачем? Вопорс у меня в том, как убрать непериодическую помеху случайной амплитуды?
Один умник посоветовал корелляционный фильтр, но с чем кореллировать не сказал. В принципе, это универсальный способ, только как его применить в моём случае?
0
Вот теплится мысль, выложу её пока не угасла: можно попробовать способ дифференциального съёма показаний с двух симметрично и разнонаправлено расположеных датчиков. К примеру: один сверху платы, другой снизу. Нигде пока не виде подобного, но почему нет?
0
Нигде пока не виде подобного, но почему нет?

Почему, поход с избыточном количеством датчиков и мат. обработкой результатов достаточно распространенный, например вот.

А вот именно в любительских ЛА я действительно не встречал подобных решений.
0
А это всё применимо к OpenPilot?
А то я тут клон сделал akb77.com/g/stm32/cc3dx/
Но по части мат анализа не силен
0
  • avatar
  • x893
  • 16 декабря 2012, 01:35
А это всё применимо к OpenPilot?

Нет, в OpenPilot применяется намного боле сложный алгоритм на базе фильтра Калмана.
0
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.