风筝
发表于: 2018-8-16 10:18:49 | 显示全部楼层

四轴飞行器、手机、核弹头和赛格威平衡车的共同点是什么?如果你猜可能是“摧毁世界的可能性”,答案很接近,但我所寻找的答案是“惯性测量单位”,简称IMU。虽然所有这些设备都带有不同准确度和精度的IMU,但它们中的每一个都使用某种形式的IMU来进行引导、导航和定向。惯性测量的一个非常常见的应用是形成姿态和航向指示系统,也称为AHRS)。例如,在飞机上,AHRS与“陀螺地平仪”屏幕集成在一起,以便飞行员可以确定他相对于直线和水平飞行的当前俯仰角、翻滚角和偏航角。

Horizon-feature.png


本篇文章主要是制作一个基本的AHRS,它使用WS2812 RGB LED灯带上的彩色灯来指示MPU-6050 IMU如何在三维空间中定向。


所需的材料

●    硬件部分

     ●    Arduino Uno开发板

     ●    WS2812可寻址RGB LED灯条

     ●    MPU-6050分线板(Breakout)

     ●    面包板和连接导线

●    软件部分

     ●    Arduino IDE

     ●    git

     ●    GitHub存储库


MPU,你好吗?

Invensense的MPU-6050包含一个三轴加速度计和三轴陀螺仪,分别测量三个正交轴的加速度和旋转速度。这会将系统中的总变量数(或“自由度”)增加到六个。可以使用额外的GPS、实时时钟、气压计、磁力计或其他空间/惯性传感设备添加更多度数。假设读取传感器的算法有效地利用数据,则每个额外的自由度增加了IMU的潜在准确性。 MPU-6050中的加速度计和陀螺仪均采用MEMS技术制造,这意味着它们依赖于由硅制成的微观结构的物理偏转。 MEMS陀螺仪美丽复杂的一个例子如下:

mems_gyroscope.jpg

来自www.geekmomprojects.com的MEMS陀螺仪图片


过滤算法!

一般来说,从IMU获取原始数据是相当微不足道的。真正的挑战(以及为什么他们支付指导和导航工程师的大笔费用)正在找出过滤和融合数据的方法,以便他们快速、准确地预测工艺的方向和/或“航位估算”位置或设备。在处理加速度和陀螺仪数据时,会出现两个主要问题。首先,加速度计本质上非常嘈杂,只能在一段时间内对许多样本进行平均后才能提供准确的加速度图像。另一方面,陀螺仪存在相反的问题:在大时间尺度下,测量容易“漂移”。存在导致该现象的一系列不同因素,但主要的一个因素是陀螺仪仅测量角速率(dθ/ dt)而不测量角位置(θ)。当您获取利率的不定积分来获得该位置时,它会产生一个流氓常数项。该常数产生偏差,并且由于偏差是随时间变化的,因此引起漂移。


那不仅仅是泡菜吗?怎么可能克服这个限制?过滤器!在该领域中使用了几种非常着名的算法,例如互补滤波器、卡尔曼滤波器/扩展卡尔曼滤波器(EKF),特别是在业余爱好者圈子中,Mahony / Madgwick滤波器。 OlliW在他的博客上对过滤器类型进行了很好的比较,而Mouser Electronics在他们的网站上有一个不错的解释。 Walter T. Higgins Jr.的补充和卡尔曼滤波的比较(PDF链接如下)也提供了对卡尔曼和互补滤波器以及它们如何不同的非常好的描述。

尽管如此,本篇文章不会深入过滤原始数据...这是你今晚的功课。然而,对于这个项目,MPU-6050为我们提供了一个非常方便的捷径。从数据表:

“内部数字运动处理™(DMP)引擎支持3D MotionProcessing和手势识别算法。MPU-60X0收集陀螺仪和加速度计数据,同时以用户定义的速率同步数据采样.MPU-60X0获得的总数据集包括3-轴陀螺仪数据,3轴加速度计数据和温度数据MPU计算出的系统处理器输出还可以包括来自数字3轴第三方磁力计的航向数据。


所有这些gobbledygook是什么意思?这意味着有人为我们付出了巨大代价来为我们付出辛勤劳动! DMP引擎将原始传感器数据(甚至来自外部磁力计的数据)过滤并组合成3D表示,并为播放数据提供了非常方便的界面。此外,Jeff Rowberg的I2Cdev设备库包括将融合和滤波后的DMP数据转换为有用量的算法,用于导航和定向,如欧拉角,四元数以及惯性参考系中的俯仰,滚转和偏航角度,是我们将利用的。由于该项目仅使用六个自由度,因此航向(偏航角)大多只是“估计”。你会发现它最终会更容易出现视频中的不准确和漂移。像MPU-9250这样的外部磁力计或9-DOF IMU可以大大减轻偏航误差。


硬件

硬件非常简单。 MPU-6050通过位于顶部标题行上的AREF和GND之外的SDA和SCL引脚连接到Arduino的I2C总线。一个较新的型号,SCL和SDA标记在引脚头本身的一侧。它还使用引脚2上的外部中断,以便在数据准备好进行处理时立即指定。 I2C网络的设置方式,它需要VCC和总线引脚之间的上拉电阻。我使用了10K电阻器,一切看起来都很笨拙。有趣的是,虽然技术上被指定为数据表中的3.3V器件,但MPU-6050非常乐意容忍5V信号和电源而不会爆炸(甚至损坏)。电源电压可处理VDD = -0.5V至+ 6V,逻辑电平为-0.5V至VDD + 0.5V。 RGB LED灯条只有一个控制LED链的引脚,在这种情况下连接到引脚4。


Fritzing图如下所示:

ahrseeyoulater.png

这是我的实际硬件设置。我只是将一些延长线焊接到我的灯条上,以便在我推挤我的面包板时更容易保持原位。

IMG_20151008_002801.jpg

库安装

在您的计算机上安装Git后,在某处以及终端或命令行类型中找到一个不错的项目目录:

  1. git clone --recursive https://github.com/swedishhat/yaaa
复制代码

为了在yaaa / mpu6050-led-ahrs /中编译sketch,您需要将以下目录复制到Arduino sketchbook目录中的“libraries”文件夹中。可以通过Arduino IDE选择File> Preferences来找到它。

●    yaaa/tools-and-resources/Adafruit_NeoPixel/

●    yaaa/tools-and-resources/i2cdevlib/Arduino/MPU6050/


一旦这一切都得到了解决,加载你的Arduino IDE,打开yaaa / mpu6050-led-ahrs / mpu6050-led-ahrs.ino,上传!


代码

以下代码是使用一维光带和各种颜色/强度的3D空间的快速和脏的可视化。这个项目的大部分代码都是从Jeff Rowberg的I2Cdevlib Arduino库的示例中包含的“MPU6050_DMP6 /”Teapot Demo中精心借用的。演示代码被剥夺了它的必需品并且习惯了偏航然后,我使用Adafruit的NeoPixel库为俯仰和滚动象限生成颜色和强度值。您可以在下图中将滚动,俯仰和偏航轴对应的图像来考虑它。 X,Y和Z轴分别为:

gradient_sphere.png

噢......有不同的颜色。 但这是什么意思!?


当IMU围绕偏航(Z)轴旋转时,白色指示器将指向当前航向。 在直线和水平操作(俯仰和滚转值近似为零)时,可以在球体的绿色赤道周围绘制“大圆”,与由偏航航向指示器描绘的线同心。 如果滚动(X)或俯仰(Y)值在各自的轴上变为负值,则对应于“鼻子”和端口(左)侧的LED将从绿色变为红色,而“尾部”和右舷(右)侧 LED将从绿色变为蓝色。 如果音高或滚动值为正,则会发生相反的情况。 然后可以将大圆圈可视化为围绕球体倾斜,并且圆圈接触的任何地方都是条带上LED的颜色。


完整代码可以在GitHub上的项目存储库中找到,但我的代码片段如下所示:

  1. // ================================================================
  2. // ===                NEOPIXEL AHRS ROUTINE                     ===
  3. // ================================================================

  4. // When we setup the NeoPixel library, we tell it how many pixels, and which pin to use to send signals.
  5. // Note that for older NeoPixel strips you might need to change the third parameter--see the strandtest
  6. // example in the lbrary folder for more information on possible values.
  7. Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIXELPIN, NEO_GRB + NEO_KHZ800);


  8. #include <Adafruit_NeoPixel.h>  // NeoPixel library from Adafruit
  9. #define PIXELPIN       4        // Arduino pin connected to strip
  10. #define NUMPIXELS      60       // Total number of RGB LEDs on strip

  11. void update_led_ahrs(float yaw, float pitch, float roll) {
  12.   // Note: the YPR values are in DEGREES! not radians
  13.   
  14.   // Clean slate.
  15.   pixels.clear();

  16.   // Determine the "nose" of the AHRS from yaw angle indication
  17.   int yaw_index = int(NUMPIXELS * (180.0 + yaw) / 360.0);

  18.   // Light intensity for pitch and roll quadrants
  19.   float roll_brightness = 255 * roll / 180.0;
  20.   float pitch_brightness = 255 * pitch / 180.0;

  21.   // Bread and butter: Counts through a quadrant's worth of NeoPixel indecies
  22.   // and determines the appropriate color for all four quadrants. The pitch and
  23.   // roll brightness values then scale how red, blue, or green each pixel. This
  24.   // emulates in admittedly simplistic fashion a Great Circle around an RGB
  25.   // sphere with red at the "South Pole", green at the "Equator", and blue at
  26.   // the "North Pole". Green values are inversely proportional to pitch and roll
  27.   int i;
  28.   for (i = 0; i < (NUMPIXELS / 4); i++){
  29.     if (pitch >= 0) {
  30.       pixels.setPixelColor((yaw_index - (NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(pitch_brightness, 255-2*pitch_brightness, 0));
  31.       pixels.setPixelColor((yaw_index + (3*NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(0, 255-2*pitch_brightness, pitch_brightness));
  32.     } else {
  33.       pixels.setPixelColor((yaw_index - (NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(0, 255 + 2*pitch_brightness, -1 * pitch_brightness));
  34.       pixels.setPixelColor((yaw_index + (3*NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(-1 * pitch_brightness, 255 + 2*pitch_brightness, 0));
  35.     }

  36.     if (roll >= 0) {
  37.       pixels.setPixelColor((yaw_index - (3*NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(roll_brightness, 255-roll_brightness, 0));
  38.       pixels.setPixelColor((yaw_index + (NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(0, 255-roll_brightness, roll_brightness));
  39.     } else {
  40.       pixels.setPixelColor((yaw_index - (3*NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(0, 255 + 2*roll_brightness, -1 * roll_brightness));
  41.       pixels.setPixelColor((yaw_index + (NUMPIXELS/8) + i) % NUMPIXELS, pixels.Color(-1 * roll_brightness, 255 + 2*roll_brightness, 0));
  42.     }      
  43.   }

  44.   // Set the "nose indicator" and turn the device on
  45.   pixels.setPixelColor(yaw_index, pixels.Color(255,255,255)); // White as can be
  46.   pixels.show();
  47. }
复制代码

总结

该项目不会因代码效率或实际AHRS设计而获得任何奖项,但希望它可以作为在您的项目中使用加速度计和陀螺仪的合理入门。这是实施四轴飞行器自动驾驶仪,运动计步器,自主火星探测器或其他需要以某种方式测量运动的其他任何东西的第一步。这些设备的价格每天都在下降,使用的障碍正随之而来。惯性控制系统的领域是巨大的,并且还有很多只是确定你在太空中的方向。例如,控制力矩陀螺仪和反作用轮可用于致动和移动。一个非常巧妙的应用是概念是来自苏黎世联邦理工学院动态系统和控制研究所的Cubli机器人。它使用一整套IMU和反作用轮来平衡,跳跃,移动和冷却。所以现在有了你新发现的IMU知识,轮到你做一些令人惊奇的事了。

跳转到指定楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题 700 | 回复: 1480



手机版|

GMT+8, 2024-4-19 14:39 , Processed in 0.141043 second(s), 6 queries , Gzip On, MemCache On. Powered by Discuz! X3.5

YiBoard一板网 © 2015-2022 地址:河北省石家庄市长安区高营大街 ( 冀ICP备18020117号 )

快速回复 返回顶部 返回列表