1.15. 陀螺仪

作为飞行器的重要惯性测量装置,陀螺仪甚至于比加速度计更重要。前一节我们已经使用过加速度传感器, 通过加速度传感器获取BlueFi的姿态,非常准确方便,但是细心一点你会发现,如果BlueFi不是绕水平轴旋转来改变姿态, 而是平躺在水平面上绕竖直方向旋转,加速度传感器的数据几乎不变!换句话说,加速度传感器并不能告诉我们,BlueFi 的金手指朝向那个方向。我们知道客机从中国飞到美国,无论选择两极或飞跃太平洋的那条航线,实际航线的方向几乎完全 不同,飞机如何确定自己的飞行方向呢?必须借助于陀螺仪。如下图,我们使用加速度传感器能够确定飞机起降时的俯仰角, 以及绕航线翻滚时的翻滚角,但不能确定飞机的航向角。

../../_static/images/bluefi_basics/airplane_att.png

玩手游的朋友大概对手机的陀螺仪不陌生,有些玩家甚至于时常分享如何巧妙使用手机陀螺仪辅助让自己成为吃鸡高手。 也有使用手机陀螺仪来控制3D游戏的视图旋转,使用鼠标和键盘都太麻烦,体感交互更方便。那么,陀螺仪到底是什么呢?

../../_static/images/bluefi_basics/gyro_principle.jpeg

我们玩指尖陀螺的体验是,一旦让陀螺旋转起来,无论你的手势如何变化,陀螺的旋转轴向保持不变。人们在19世纪末就发现 了陀螺轴向不变的现象,今天我们知道这是向心力的作用。陀螺仪正式利用这一特性,能够测量出当物体的姿态或运动发生 变化时的角速度。我们首先来了解陀螺仪测量的角速度数据特征。


1.15.1. 陀螺仪的角速度数据

将下面的示例程序保存到BlueFi的/CIRCUITPY/code.py文件中,在BlueFi执行示例程序期间,用手慢或快速地改变 BlueFi的姿态,并保持该姿态,观察并记录传感器的数据变化规律。示例代码如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
  import time
  from hiibot_bluefi.sensors import Sensors
  from hiibot_bluefi.screen import Screen
  screen = Screen()
  sensors = Sensors()
  gyro = sensors.gyro
  show_data = screen.simple_text_display(title="BlueFi Gyroscope", title_scale=1, text_scale=2)
  while True:
      gyro = sensors.gyro
      show_data[2].text = "X: {:.2f}".format(gyro[0])
      show_data[2].color = screen.RED
      show_data[3].text = "Y: {:.2f}".format(gyro[1])
      show_data[3].color = screen.GREEN
      show_data[4].text = "Z: {:.2f}".format(gyro[2])
      show_data[4].color = screen.BLUE
      show_data.show()
      time.sleep(0.1)

本示例程序与加速度传感器的第一个应用示例非常相似,我们将陀螺仪传感器的三个分量以多行文本形式显示在不同行,颜色也各部相同,很容易 分辨每一个分量值的变化。

示例代码分析:

  • 第1行,导入一个Python内建的模块“time”
  • 第2行,从“/CIRCUITPY/lib/hiibot_bluefi/sensors.py”模块中导入一个名叫“Sensors”的类
  • 第3行,从“/CIRCUITPY/lib/hiibot_bluefi/screen.py”模块中导入一个名叫“Screen”的类
  • 第4行,将导入的“Screen”类实例化为一个实体对象,名叫“screen”
  • 第5行,将导入的“Sensors”类实例化为一个实体对象,名叫“ensors”
  • 第6行,定义一个名叫“gyro”的Sensors类gyro型变量,并赋初值为sensors.gyro
  • 第7行,定义一个名叫“show_data”的Screen类的多行文本显示子类,设置文本显示的标题为“BlueFi Gyroscope”,标题字体放大1倍,文本字体放大2倍
  • 第8行,一个无穷循环的程序块
  • 第9行(无穷循环程序块的第1行),用sensors.gyro更新变量gyro
  • 第10行(无穷循环程序块的第2行),设置多行文本显示子类的第2行的文本内容为gyro0]的值
  • 第11行(无穷循环程序块的第3行),设置多行文本显示子类的第2行的文本颜色为红色
  • 第12行(无穷循环程序块的第4行),设置多行文本显示子类的第3行的文本内容为gyro[1]的值
  • 第13行(无穷循环程序块的第5行),设置多行文本显示子类的第3行的文本颜色为绿色
  • 第14行(无穷循环程序块的第6行),设置多行文本显示子类的第4行的文本内容为gyro[2]的值
  • 第15行(无穷循环程序块的第7行),设置多行文本显示子类的第4行的文本颜色为蓝色
  • 第16行(无穷循环程序块的第8行),更新多行文本显示
  • 第17行(无穷循环程序块的第9行),执行time的sleep方法,参数为0.1秒

你从自己记录的数据中发现什么规律了吗?譬如,将BlueFi平放在桌面上,绕着竖直方向且贴着桌面瞬时针方向旋转BlueFi,你会明显地观察到仅有蓝色 (z方向分量)数值变大,另外两个数值几乎保持不变;同样地,但逆时针旋转BlueFi时,明显看到只有z方向分量数值为负数且变大。无论你怎么改变,只要 停止旋转,保持BlueFi稳定不动,三个分量的数值几乎都回到0.0,并在0.0附近波动。

静止的物体,速度为零。

1.15.2. 从角速度得到角度: 姿态估算

陀螺仪只能感知姿态改变或运动发生变化时的角速度,这个结论你只需要继续前一个示例的试验就可以知道。譬如把BlueFi平放在桌面上,用手推着他快速 地贴着桌面平移,无论是沿x-或y-方向陀螺仪给出的数值都不变化,我们知道这个期间沿x-或y-方向的线速度一定有剧烈变化(如果你根加速度分量对比呢)。 如果我们拿着BlueFi绕着x-或y-方向旋转,你会发现其中一个分量值明显变大,符号只是代表旋转的方向(逆时针或顺时针)。

陀螺仪只能给出角速度。

根据数学知识,已知初始值(当前静止状态的角度)、角速度和运动时间,我们通过对这段运动时间内的角速度积分将会得到这段运动时间之后的角度。基于这一 数学依据,我们很容易计算出物体的角度。

利用加速度计、陀螺仪和地磁计共9个自由度的数据连续估算物体的空间姿态和朝向的算法,俗称姿态估算算法。我们将在后续的教程中继续介绍,你还会发现 姿态估算算法种类还很多。


总结:

  • 陀螺和轴向不变
  • 陀螺仪
  • 角速度
  • 从角速度如何得到角度
  • 姿态估算
  • 多行文本显示的数据结构
  • 文本字体的缩放
  • 本节中,你总计完成了17行代码的编写工作

重要

Sensors类的陀螺仪传感器接口

  • gyro (属性, 元组类型, 只读, 每个分量的有效值: -10.24~+10.24), BlueFi的Sensors类gyro属性, 陀螺仪角速度的三个分量值
    • gyro[0]: x方向分量
    • gyro[1]: y方向分量
    • gyro[2]: z方向分量
  • GyroRange (属性, 可读可写, 有效值: 0~5), BlueFi的Sensors类陀螺仪量程属性, 0:125dps, 1:250dps, .., 5:4000dps
  • GyroRate (属性, 可读可写, 有效值: 0~11), BlueFi的Sensors类陀螺仪传感器数据更新率属性, 0:SD, 1:1.6Hz, 2:12.5Hz, 3:26Hz, .., 10:3.33Khz, 11:6.66KHz