Выходной сигнал наклонного магнитометра - компенсация наклона по тангажу и крену - я потерялся

Я потратил 2 дня (и ночи) на эту конкретную проблему и полностью потерпел неудачу в компенсации наклона выходных данных моего магнитометра.
Я перепробовал все, что мог прочитать в Google и в примерах с открытым исходным кодом, ничто не помогло мне найти правильную компенсацию наклона для оба (крен и шаг). .

Настройка: я использую калиброванные значения, но не единичные значения.
У меня есть объединенный вектор силы тяжести, который работает правильно и точно.
Датчик представляет собой 9dof BMX055 (http://www.mouser)..com/ds/2/621/BST-BMX055-DS000-01-274824.pdf) Мин/макс магнитометра составляют +- 512 по каждой оси (с небольшими различиями, но все оси обнулены). Аппаратное обеспечение Sam3X8e (Cortex M3), все написано на C.
Вычисления с плавающей запятой и тригонометрия выполняются довольно быстро, так что это не проблема. Микросхема BMX055 выровнена таким образом, чтобы контакты 20, 19 и 18 были направлены вперед.
На страницах технического описания 159–161 указана ориентация. Высота тона увеличивается, когда я поднимаю переднюю часть.
Крен увеличивается, когда я поднимаю левую сторону.

Примеры значений:
Указание направления, которое мой алгоритм называет 305 градусов при выравнивании по горизонтали.

Pitch: 0  , Roll 0   : MAG cal:  x 132   y  93  z   -364  
Pitch: +24, Roll 0   : MAG cal:  x -109   y  93  z   -397  
Pitch: +46, Roll 0   : MAG cal:  x -303   y  89  z   -351  
Pitch: 0  , Roll -44 : MAG cal:  x 151   y  352  z   -235  
Pitch: 0  , Roll +36 : MAG cal:  x 130   y  -140  z   -328  
Pitch: 78 , Roll -2  : MAG cal:  x -503   y  93  z   -199  
Pitch: 7  , Roll -53 : MAG cal:  x 135   y  424  z   -180

Выравнивание всегда должно было быть около 305 градусов (насколько я мог это сделать), может быть +- 5 градусов.

Формула: (одна и та же, используемая везде)

uint16_t compass_tilt_compensation(float roll_radians, float pitch_radians,float mag_y, float mag_x, float mag_z) 
{

  float tilt_compensated_heading;
  float MAG_X;
  float MAG_Y;
  float cos_roll;
  float sin_roll;
  float cos_pitch;
  float sin_pitch;
  int16_t heading;
  //pitch_radians =roll_radians;
  //roll_radians *= -1;
  //mag_x *= -1;
  //roll_radians=0.0f;
  //pitch_radians=0;v
  //pitch_radians *=-1;

  cos_roll = cos(roll_radians);
  sin_roll = sin(roll_radians);
  cos_pitch = cos(pitch_radians);
  sin_pitch = sin(pitch_radians);


#if 0
  MAG_X = mag_x*cos_pitch+mag_y*sin_roll*sin_pitch+mag_z*cos_roll*sin_pitch;
  MAG_Y = mag_y*cos_roll-mag_z*sin_roll;
  tilt_compensated_heading = atan2f(-MAG_Y,MAG_X); 
#else
    MAG_X = mag_x * cos_pitch + mag_z * sin_pitch;
    MAG_Y = mag_x * sin_roll * sin_pitch + mag_y * cos_roll - mag_z * sin_roll * cos_pitch;
    tilt_compensated_heading = atan2f(-MAG_Y,MAG_X);
    //tilt_compensated_heading = atan2f(-mag_y,mag_x); // works fine when leveled
#endif

//convert to degree from 0-3599
    heading = tilt_compensated_heading * RAD_TO_DEG * 10;
     if ( heading < 0 ) 
     {
         heading += 3600;
     }

  return heading;
}

Я пробовал различные комбинации, я пытался зафиксировать только одну ось и всегда оставлять одну на 0, меняя местами X/Y шаг/рулон, *-1 на любом из входов.

Результаты всегда совершенно неверны. Иногда (в зависимости от того, где я пытаюсь инвертировать или не инвертировать значение методом проб/ошибок) значения кажутся почти линейными. Иногда одна ось компенсируется в положительных областях.
Однако качка всегда вызывает «случайные» прыжки и изменения курса.
Математика никогда не была моим фаворитом, теперь я жалею об этом.

Мое личное предположение, что формула в принципе правильная, маг в принципе работает (ведь я получаю надлежащие степени при прокачке), но я как-то не так кормлю. (Например, Y и X нужно поменять местами, z*-1, шаг должен быть *-1)

Может ли кто-нибудь, кто хорошо разбирается в этой теме, посмотреть и подсказать, как выбрать правильный заголовок?
Было бы здорово поспать несколько часов этой ночью, и вам больше не придется мечтать о неисправном алгоритме :)

Обновление: компенсация наклона здесь работает для отрицательного крена при наведении на курс 305 градусов. Он также используется здесь: http://www.emcu.it/MEMS/Compass/MEMS_Compass_A_RTM1v3.pdf


person John    schedule 08.07.2014    source источник


Ответы (2)


3 дня работы, наконец я нашел проблемы, которые у меня были, и компенсация наклона работает!
Я читал, что у многих людей были такие проблемы на разных форумах, поэтому вот что я сделал:

Я объясню, что я сделал и почему я сделал, шаг за шагом. Может кто с похожей проблемой найдет решение таким способом.

  1. Игра со значениями может помочь (может быть, нужно просто инвертировать тангаж или крен, нужно поменять местами X или Y).
    Однако существует довольно много значений, и количество комбинаций слишком велико, если ваша проблема больше, чем крошечный.

  2. Опубликованная формула работает нормально (та, что находится в активной ветке #if.
    Если у вас есть магнитометр и atan2(-y,x) дает правильный курс при горизонтальном уровне, то эта формула будет работать для вас слишком.

  3. Что я сделал, так это полностью проверил все свои датчики и векторы, начиная с двоичной логики I2C (и таблицы данных).
    В этом частном случае (BMX055) важно отметить, что страница ориентации страницы данных НЕВЕРНА!
    Есть несколько ошибок, связанных с ориентацией осей (x, y), а также с положительным или отрицательным вращением. Иногда применяется правило правой руки, иногда нет, и рисунки вводят в заблуждение (неправильные). Bosch плохо документировала этот чип (и предыдущий). Похоже, они не хотят, чтобы люди правильно это понимали, они несколько раз пишут о fusion API с оптимизированной арифметикой с фиксированной точкой и расширенной калибровкой, но он недоступен для общественности.

Что мне нужно было сделать, так это создать правильную систему отсчета тела. Решите сами, где находится X, а затем сделайте так, чтобы все ваши датчики правильно меняли ось X при наклоне/наклоне в одном и том же направлении (положительно/отрицательно). Сделайте это для тангажа, крена и силы тяжести/магнитного поля.

Как только все они хорошо сработались, я начал все сначала.
Формула курса все еще не работала, но теперь я впервые доверился векторам.
Я добавил матричную функцию вращения вектора и повернул магнитный вектор обратно с помощью вращения. и шаг и рыскание = 0. Сюрприз: магнитный вектор был скомпенсирован наклоном.

Теперь я знал, что это МОЖНО сделать :)

Я вернулся к исходной формуле, заменил X на Y (потому что я поменял их местами, чтобы они соответствовали системе отсчета тела (X и Y гироскопа/магнита).
Теперь компенсация наклона работала для шага но не для крена.
Итак, я инвертировал roll_radians, и неожиданно получилась идеальная компенсация наклона.

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

person John    schedule 09.07.2014

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

Вы используете магнитометр, а это очень чувствительные устройства. Первым делом я бы проверил, нет ли рядом с датчиком крупных металлических конструкций. Если у вас есть доступ к осциллографу, проверьте шины питания чипа и посмотрите, стабильно ли поступает на него питание. Добавление развязывающего колпачка 1 мкФ может решить проблемы с питанием. Я бы также предложил получить график с частотой дискретизации более 100 Гц и посмотреть, являются ли скачки периодическими. Если сигнал периодический с частотой 50 Гц, при условии, что датчик не перемещается, это может указывать на помехи от вашего источника питания. Выполнение БПФ-анализа данных не помешает. У нас были похожие проблемы, вызванные силовыми кабелями, проложенными под полом нашей лаборатории. Если датчик продолжает беспорядочно прыгать, вероятно, чип не работает. Использовали ли вы надлежащую защиту от электростатического разряда при обращении с ним?

Надеюсь это поможет.

person Evan    schedule 08.07.2014
comment
Если вы решите использовать осциллограф, будьте осторожны при подключении заземляющего зажима пробника. Это ссылка на заземление сети, и вы можете взорвать что-либо, если ваша цепь не плавает, и вы подключили зажим в любом другом месте, кроме земли вашей цепи. - person Evan; 09.07.2014
comment
Курс вычисляется правильно при выравнивании, разве это не указывает на то, что чип в порядке? Я также использую чип для гироскопа и ACC, эти значения очень хороши. Также я собрал значения во всех положениях ориентации, все они имеют расстояние около 1024 от минимального до максимального (именно так я сделал калибровку, чтобы обнулить их). - person John; 09.07.2014