Arduino IMU 尝试:错误、滞后、漂移

Posted

技术标签:

【中文标题】Arduino IMU 尝试:错误、滞后、漂移【英文标题】:Arduino IMU attempt : errors, lagging, drifting 【发布时间】:2021-03-07 22:19:50 【问题描述】:

我正在尝试使用带有屏幕的 Arduino Nano 33 BLE 来为飞机姿态指示器和方向陀螺仪创建一些东西。为此,我需要有精确的欧拉角。我发现 Nano 带有 9DOF 传感器,我尝试使用 Madgwick 库将传感器数据转换为有用的角度。

然而,看起来沿着偏航轴漂移正在发生,而且当沿着俯仰和偏航轴移动板时,过滤器需要很长时间才能赶上,有时甚至几秒钟才能得到结果。

另一种解决方案是尝试使用声称直接提供欧拉角的 Adafruit BNO055。但是,我认为更优雅的解决方案是调整我的代码,使其与 Nano 上已经提供的传感器一起工作。

想法?谢谢

#include "Arduino_LSM6DS3.h"
#include "MadgwickAHRS.h"
#include "Arduino_LSM9DS1.h"

// initialize a Madgwick filter:
Madgwick filter;
// sensor's sample rate is fixed at 104 Hz:
const float sensorRate = 104.00;

float sax, say, saz, sgx, sgy, sgz;

void setup() 
  Serial.begin(9600);
  // attempt to start the IMU:
  if (!IMU.begin()) 
    Serial.println("Failed to initialize IMU");
    // stop here if you can't access the IMU:
    while (true);
  
  // start the filter to run at the sample rate:
  filter.begin(sensorRate);


long lastPrint = 0;
long nz = 0;
float x = 0, y = 0, z = 0;

void loop() 
  // values for acceleration and rotation:
  float xAcc, yAcc, zAcc;
  float xGyro, yGyro, zGyro;

  // values for orientation:
  float roll, pitch, heading;
  // check if the IMU is ready to read:
  if (IMU.accelerationAvailable() &&
      IMU.gyroscopeAvailable()) 
    // read accelerometer &and gyrometer:
    IMU.readAcceleration(xAcc, yAcc, zAcc);
    IMU.readGyroscope(xGyro, yGyro, zGyro);
    nz++;
    if (nz < 500)   //hold the board still until nz is 500 for calibration
    
      sgz += zGyro;
      sgx += xGyro;
      sgy += yGyro;
      x = sgx / nz;
      y = sgy / nz;
      z = sgz / nz;
    

    // update the filter, which computes orientation:
    filter.updateIMU(xGyro - x, yGyro - y, zGyro - z, xAcc, yAcc, zAcc);

    // print the heading, pitch and roll
    roll = filter.getRoll();
    pitch = filter.getPitch();
    heading = filter.getYaw();
    long a = millis();
    if (lastPrint + 333 < millis())
    
      lastPrint = a;
      Serial.print(nz);
      Serial.print(" Acc ");
      Serial.print(xAcc);
      Serial.print(" ");
      Serial.print(yAcc);
      Serial.print(" ");
      Serial.print(zAcc);
      Serial.print(" ");

      Serial.print("Gyr ");
      Serial.print(xGyro);
      Serial.print(" ");
      Serial.print(yGyro);
      Serial.print(" ");
      Serial.print(zGyro);
      Serial.print(" avg ");

      Serial.print(" ~~Orientation: ");
      Serial.print(heading);
      Serial.print(" ");
      Serial.print(pitch);
      Serial.print(" ");
      Serial.println(roll);
    
  

【问题讨论】:

【参考方案1】:

您看到的偏航漂移可能仅仅是因为您没有读取 LSM9DS1 的磁力计并将其信息输入过滤器。

您无法用加速度计补偿陀螺仪的偏航漂移;加速度计看不到偏航;这就是磁力计的用武之地。磁力计就像指南针;它可以看到方向和偏航的变化。加速度计不能,因此,要校正偏航漂移,您需要一个磁力计。

所有陀螺仪都会漂移,您必须对此进行补偿。这不仅仅是减去平均漂移的问题;过滤器(互补、Madgwick、Kalman 等)用于组合陀螺仪、加速度计和磁力计数据,以计算不显示漂移的平滑 3D 方向数据。无人机制造商所说的“陀螺仪”实际上是陀螺仪、加速度计、磁力计和数学的组合。

您的设置中可能还有其他问题,我没有检查过,但这是基本问题:您将 9DoF 传感器视为 6DoF 传感器,没有任何东西可以补偿偏航漂移。

Madgwick 库确实有一个函数update(),它将从所有 3 个传感器获取信息; updateIMU()只能用2个。

另外,还有一些我没有仔细研究过的东西:您包含两个用于两个不同 IMU 的库;读数回路本身似乎对陀螺仪进行了校准;您可能更新过滤器过于频繁或不够频繁。

【讨论】:

我的错,Arduino_LSM6DS3 包含在我的代码中被注释掉了,但是注释符号没有以某种方式粘贴。现在我知道使用 9 个参数的 update() 但我没有使用它,因为我不太了解如何校准磁力计以及目的是什么。使用加速度计和陀螺仪,我得到了它......你几乎可以看到静止时的平均漂移是多少,然后你从读数中减去它。但是磁力计? 我正在考虑购买 30 美元的迷你无人机。它不偏航,不知何故使用仍然便宜的陀螺仪,并且没有校准程序。只需打开它就可以了。 查看编辑后的答案。如果您愿意,请不要忘记投票或接受它。 我决定测试其他硬件,发现 adafruit BNO055 工作得更好,所以我改用那个 它并没有“更好”地工作,它只是传感器融合本身,所以你不必考虑或理解它。

以上是关于Arduino IMU 尝试:错误、滞后、漂移的主要内容,如果未能解决你的问题,请参考以下文章

AR(2) 仅考虑第二个滞后

LOAM中关于坐标转换与IMU融合

利用GPS与IMU怎样在摄影瞬间直接获得方位元素?

使用 pyserial 将数据发送到串行 - 在 Razor 9DOF IMU 上工作

QNX Hypervisor 2.2 用户手册1.9 时间

当我尝试编写 dql 查询时,出现滞后和过度错误(beberlei/DoctrineExtensions)