Как реализовать компас с компенсацией наклона?

Поэтому я пытался реализовать компас с компенсацией наклона, используя HMC5883L и MPU6050. Проблема, с которой я сталкиваюсь, заключается в том, что существует 2 уравнения компенсации наклона

Компенсация наклона X: X,Y,Z-это выход компаса (необработанный выход).

new_X = X*cos(pitch) + Y*sin(roll)*sin(pitch) – Z*cos(roll)*sin(pitch)

Компенсация наклона Y:

новый Y = Y*cos(рулон) + Z*sin(рулон)

Заключительный заголовок : Азимут = atan2(Y, X) * RAD_TO_DEG

Углы, которые я получаю от mpu,-это углы с поправкой на дрейф гироскопа, которые проходят через фильтр Калмана. Эти углы подаются в вышеприведенные уравнения, и после atan2 я получаю направление с компенсацией наклона. Но проблема/наблюдение здесь заключается в том, что когда я поворачиваю тело(на котором находятся компас и mpu) вдоль оси Z (ось рыскания), заголовок не меняется(вроде как заблокирован), но меняется, когда я наклоняю тело в X/Y. Я искал подробные ссылки, но не смог найти ни одной!
Вот мой фрагмент кода (использует библиотеку compass part form adafruit):

double HEADING(double r, double p){
  sensors_event_t event; 
  mag.getEvent(&event);
  r = r * (PI/180);
  p = p * (PI/180);
  double x = (event.magnetic.x)*cos(p) + (event.magnetic.y)*sin(r)*sin(p) - (event.magnetic.z)*cos(r)*sin(p);
  double y = (event.magnetic.y)*cos(r) + (event.magnetic.z)*sin(r);
 
  float heading = atan2(y,x);
 
  float declinationAngle = 0.366667 * (PI/180);// (0°22')positve склонение
  heading += declinationAngle;
  
  if(heading < 0)
    heading += 2*PI;
    
  if(heading > 2*PI)
    heading -= 2*PI;
   
  heading = heading * 180/PI; 
  
  return heading;
}

Сбор данных HMC5883L я написал :

// мне просто нужна ссылка на направление, а не на фактический курс, просто чтобы сохранить свой беспилотник 
// устойчиво на оси рыскания относительно этого направления, но оно должно быть компенсировано наклоном.
#include<Wire.h>

#define MAG 0x1E

#define R 0
#define P 1
#define Y 2

float mag_raw[3],h;
float CMP_DEC = 0.36667 * (PI/180);



void setup(){
  Serial.begin(115200);
  Wire.begin();
  Wire.setClock(400000);
  
  Wire.beginTransmission(MAG);
  Wire.write(0x02);
  Wire.write(0x00);
  Wire.endTransmission(true);
  
}

void loop(){
  Wire.beginTransmission(MAG);
  Wire.write(0x03);
  Wire.endTransmission(false);
  Wire.requestFrom(MAG,6,true);

  mag_raw[R] = Wire.read() << 8 | Wire.read();
  mag_raw[P] = Wire.read() << 8 | Wire.read();
  mag_raw[Y] = Wire.read() << 8 | Wire.read();

  h = atan2(mag_raw[P],mag_raw[R]);

// h += CMP_DEC;

  if(h < 0) h+= (2*PI);
  if(h > (2*PI)) h -= (2*PI);
  h *= (180/PI);
  
// Serial.print("X : ");
// Serial.print(mag_raw[R]);
// Serial.print(" Y : ");
// Serial.print(mag_raw[P]);
// Serial.print(" Z : ");
// Serial.print(mag_raw[Y]);

  Serial.print(" H : ");
  Serial.println(h);
  
}

Некоторые рекомендации будут очень полезны!

, 👍3

Обсуждение

Вы пишете весь код? (Не используете библиотеки?) Я спрашиваю, поскольку вы не упомянули, как вы компенсируете выход магнитометра для ошибок твердого и мягкого железа. Создать наклонный компас достаточно сложно. Но я считаю, что лучше, если писать большую часть или весь код с нуля, создать обычный (использовать его плашмя на столе) компас 1st., @st2000

@st2000 Я попытался написать свой собственный код (общий подход для i2C Wire lib). Иногда я получал сплошной вывод (никаких изменений в данных, даже если я двигаюсь по другой оси), иногда данные приходили, но диапазон оставался почти около 170 для осей X , 65000 для осей Y и 56 для осей Z. Я не понимал, что происходит, поэтому начал использовать библиотеки :( можете ли вы дать мне несколько соответствующих ссылок ?, @Sajil

Малы ли углы тангажа и крена, когда тело лежит плашмя на столе? Изменяются ли необработанные значения компонентов магнитного поля при его вращении?, @Edgar Bonet

@EdgarBonet я отвечу в соответствии с тем, что я понял; Таким образом, углы R&P, исходящие от MPU, составляют 0±0.1°, когда они находятся на плоской поверхности. Теперь, когда я поворачиваю компас вдоль оси Z, значения не меняются(на самом деле они есть, но они изменились примерно на 3 точки, когда я повернул их на 90°!). Для осей X,Y значения сильно меняются !почти ±120 единиц. я просто добавлю свой *с нуля* написанный код в вопрос. Посмотрите на него, может быть, что-то не так видно..., @Sajil

@Sajil, начни с простого! Просто старайтесь заставить магнитометр работать. Забудьте об акселерометре. Тем не менее, я еще не видел, чтобы магнитометр выводил полезную информацию без компенсации диапазона (сложение или вычитание числа так, чтобы максимум и минимум данной оси были одинаковыми) и величины (умножение на число так, чтобы максимум и минимум всех 3 осей были одинаковыми). Пока вы этого не сделаете, выполнение математики на выходе магнитометра даст вам мусор., @st2000

@st2000 да, позвольте мне еще немного поработать над магнитометром. Не могли бы вы прислать мне несколько рекомендаций по этому поводу ? Возможно, не используя библиотеки (мне легко без библиотек )., @Sajil


1 ответ


1

Проверяя ваш код, вы не обнаруживаете, что компенсируете необработанные значения магнитометра для эффектов мягкого и твердого железа. Эти термины примерно относятся к регулировке диапазона и величины каждого из отдельных магнитометров (X, Y и Z). Некоторые производители магнитометров позволяют записывать эти значения компенсации в микросхему. Даже в этом случае разработчику и пользователю все равно придется выполнить некоторую калибровку, так как магнитометр не может предсказать, при каких условиях он будет использоваться. Вот еще одно объяснение с использованием матриц компенсации твердого и мягкого железа.

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

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

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

,