陀螺仪、加速计、磁力计等传感器汇总


陀螺仪就是内部有一个陀螺,它的轴由于陀螺效应始终与初始方向平行,这样就可以通过与初始方向的偏差计算出实际方向。手机里陀螺仪实际上是一个结构非常精密的芯片,内部包含超微小的陀螺。
加速计是用来检测手机受到的加速度的大小和方向的,而手机静置的时候是只受到重力加速度(这个高中学过)的.所以很多人把加速计功能又叫做重力感应功能。
磁力计是测试磁场强度和方向的。


陀螺仪测量是参考标准是内部中间在与地面垂直的方向上进行转动的陀螺。通过设备与陀螺的夹角得到结果。
加速计是以内部测量组件在各个方向上的受力情况来得到结果。
磁力计的原理就是中学物理中涉及到的那个最简单的指南针了(那记得那根被磁化的钢针么)。


它们分别有自己的强项:
陀螺仪的强项在于测量设备自身的旋转运动。对设备自身运动更擅长。但不能确定设备的方位。
加速计的强项在于测量设备的受力情况。对设备相对外部参考物(比如,地面)的运动更擅长。但用来测量设备相对于地面的摆放姿势,则精确度不高。
磁力计的强项在于定位设备的方位。可以测量出当前设备与东南西北四个方向上的夹角。


举几个例子:
陀螺仪对设备旋转角度的检测是瞬时的而且是非常精确的,能满足一些需要高分辨率和快速反应的应用比如FPS游戏的瞄准。而且陀螺仪配合加速计可以在没有卫星和网络的情况下进行导航,这是陀螺仪的经典应用。加速度计可用于有固定的重力参考坐标系、存在线性或倾斜运动但旋转运动被限制在一定范围内的应用。同时处理直线运动和旋转运动时,就需要把加速度和陀螺仪计结合起来使用。如果还想设备在运动时不至于迷失方向,就再加上磁力计。


对于一个发射出去的导弹来说,要想精确追踪并调整导弹的轨道的话,下面几组数据必不可少:
GPS定位它的位置
加速计测量当前加速度
磁力计确定导弹头的方向(只能知道东南西北四个方向上的夹角),陀螺仪知道导弹的角速度。这两个仪器结合才能确定导弹的准确的立体运动方向。


加速计得到的结果就是XYZ三个值,分别代表三个方向的加速度。关于XYZ三值的介绍,可以看这里:
android 重力感应和屏幕旋转关系
http://blog.csdn.net/lzx_bupt/archive/2010/04/20/5507165.aspx


用加速计和磁力计可以计算出orientation(方位计),orientation涉及到了三个概念:
Roll:左右倾斜角度,也叫滚转角 http://baike.baidu.com/view/1769672.htm
Pitch:前后倾斜,也叫俯仰角 http://baike.baidu.com/view/3832041.htm
Yaw:左右摇摆,也叫偏航角 http://baike.baidu.com/view/1769448.htm


下面代码是Android2.3中/development/samples/Compass的源码,演示了如何使用加速计和磁力计来确定手机的摆放姿势和方位。因为手机运动的加速度不高,精确度也没有太大的要求,用加速计替代陀螺仪也可以。但如果做一些精度比较高的游戏的话,最好还是有陀螺仪。


[java]view plain copy

  1. //打开加速计和磁力计两个传感器。Sensor gsensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); Sensor msensor = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD); mSensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME); mSensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME); //加速计数据。private float[] mGData = https://www.it610.com/article/new float[3]; //磁力计数据。private float[] mMData = new float[3]; //旋转矩阵(rotation matrix),用于计算手机自身相对于地面坐标系的旋转角度。比如手机现在是横着还是竖着的。反映的是手机的立体摆放位置。这个数据最好用陀螺仪来测量,没有陀螺仪的话,借助于加速计和重力加速度也可以,只是精度不够强罢了。private float[] mR = new float[16]; //倾斜矩阵(inclination matrix),用于计算手机方位。比如手机的头部现在朝南还是朝北。是针对一个平面上的东南西北四个方向而言的。private float[] mI = new float[16]; //存放最终的旋转角度数据private float[] mOrientation = new float[3]; public void onSensorChanged(SensorEvent event) {int type = event.sensor.getType(); float[] data; if (type == Sensor.TYPE_ACCELEROMETER) {data = mGData; } else if (type == Sensor.TYPE_MAGNETIC_FIELD) {data = mMData; } else {// we should not be here.return; }for (int i = 0; i < 3; i++)data[i] = event.values[i]; //这一步的目的是获取mR和mI两个矩阵。SensorManager.getRotationMatrix(mR, mI, mGData, mMData); //用矩阵mR获取手机的旋转角度。SensorManager.getOrientation(mR, mOrientation); //用矩阵mI获取手机在东南西北四个方向上的夹角。float incl = SensorManager.getInclination(mI); final float rad2deg = (float)(180.0f / Math.PI); Log.d("Compass", "yaw: " + (int)(mOrientation[0] * rad2deg) + "pitch: " + (int)(mOrientation[1] * rad2deg) + "roll: " + (int)(mOrientation[2] * rad2deg) + "incl: " + (int)(incl * rad2deg)); }

补充于2011.7.14
gsensor的较正比较容易完成,一般是让机器以某个固定角度(比如水平)放置,然后连续取N个值(比如20个)进行一系列计算。Android和iphone中,屏幕会随着设备的旋转方向变化而改变,其实应用的只是gsensor。
msensor的较正分为水平较正和倾斜补偿。水平较正有平面较正、8字较正、十面较正等几种方法。经过水平较正后,msensor在水平放置时已经可以使用了,但设备与水平面有一定的倾斜角时,这个倾斜角会对msensor的精度造成影响。因此,还需要进行倾斜角补偿较正。先通过较正好的gsensor得出倾斜角,然后使用倾斜角(pitch,roll)进行补偿较正计算。
orientation sensor可以由一个单独芯片来实现,也可以由gsensor和msensor共同计算出来的(我看android2.3的Sample中的Compass就已经这样干了)。orientation sensor输出三个值:roll,pitch,yaw。其中,roll和pitch分别代表手机的X轴和Y轴与水平面的夹角,所以这两个值可以由gsensor计算出来。yaw代表手机y轴水平面上的投影与正北方向的夹角,由msensor计算出来。
陀螺仪可以捕捉很微小的运动轨迹变化,因此可以做高分辨率和快速反应的旋转检测。但不能像msensor或orientation sensor那样测量当前的运行方向。飞机当中就用它记录运动角度改变,从而形成运动轨迹。缺点就是随着时间增长会有误差积累,

补充于2011.7.19
陀螺仪的XYZ分别代表设备围绕XYZ三个轴旋转的角速度:radians/second。至于XYZ使用的坐标系与gsensor相同。逆时针方向旋转时,XYZ的值是正的。下面是使用陀螺仪进行开发时的演示代码:


[java]view plain copy
  1. private static final float NS2S = 1.0f / 1000000000.0f;
  2. private float timestamp;
  3. public void onSensorChanged(SensorEvent event)
  4. {
  5. if (timestamp != 0) {
  6. final float dT = (event.timestamp - timestamp) * NS2S;
  7. angle[0] += event.data[0] * dT;
  8. angle[1] += event.data[1] * dT;
  9. angle[2] += event.data[2] * dT;
  10. }
  11. timestamp = event.timestamp;
  12. }
另外,陀螺仪运转一段时间以后,noise和offset会导致数据偏差,需要借助其它传感器进行较正。


补充于2011.7.20


利用加速计(gsensor),磁力计(msensor)模拟出方位传感器(orientation)来

Android最近的新版本已经不建议我们在开发的时候像下面这样直接用方位传感器了:
Sensor ori = mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
mSensorManager.registerListener(this, ori, SensorManager.SENSOR_DELAY_GAME);
而是建议使用SensorManager.getOrientation(mR, mOrientation)这个API自己在应用程序的onSensorChanged中计算出方位传感器。但我们在做HAL层时,却不得不考虑一些APK还是像上面代码那样直接使用方位传感器的情况,所以,我们必须在sensor.c中模拟出一个方位传感器来:
激活方位传感器时,同时激活加速计和磁力计,关闭方位传感器时也要同时关闭加速计和磁力计,同时还要考虑如果用户注册了加速计或磁力计,并且正在使用的情况。



[cpp]view plain copy
  1. //默认状态,0代表关闭。
  2. static int accStatus = 0;
  3. static int magStatus = 0;
  4. static int switchSensor(int fd, int handle, int enabled) {
  5. int status = 0;
  6. switch (handle) {
  7. case ID_ACCELERATION:
  8. if (enabled) {
  9. if (!accStatus) {//=0说明当前状态是关闭时,执行打开操作。否则,说明已经打开过。
  10. status = ioctl(fd, ACC_FLAG, 1);
  11. LOGW("open gsensor");
  12. }
  13. accStatus++;
  14. } else {
  15. if (accStatus > 0) {//>0说明当前状态是打开,这个时候才会尝试关闭gsensor。
  16. accStatus--;
  17. if (!accStatus) {//减1后如果==0,说明orientation没有使用gsensor,可以关闭gsensor了
  18. status = ioctl(fd, ACC_FLAG, 0);
  19. LOGW("close gsensor");
  20. }
  21. }
  22. }
  23. break;
  24. case ID_MAGNETIC:
  25. if (enabled) {
  26. if (!magStatus) {
  27. status = ioctl(fd, MAG_FLAG, 1);
  28. LOGW("open msensor");
  29. }
  30. magStatus++;
  31. } else {
  32. if (magStatus > 0) {
  33. magStatus--;
  34. if (!magStatus) {
  35. status = ioctl(fd, MAG_MFLAG, 0);
  36. LOGW("close msensor");
  37. }
  38. }
  39. }
  40. break;
  41. case ID_ORIENTATION:
  42. if (enabled) {
  43. if (!accStatus) {//=0说明gsensor没有打开过,直接打开。
  44. status = ioctl(fd, ACC_AFLAG, 1);
  45. LOGW("open msensor");
  46. }
  47. if (!magStatus) {
  48. status = ioctl(fd, MAG_FLAG, 1);
  49. LOGW("open msensor");
  50. }
  51. accStatus++;
  52. magStatus++;
  53. } else {
  54. if (accStatus > 0) {//>0说明被打开过,尝试关闭gsensor。
  55. accStatus--;
  56. if (!accStatus) {//减1后=0说明用户没有直接使用gsensor,只是使用了orientation,可以关闭gsensor了。
  57. status = ioctl(fd, ACC_AFLAG, 0);
  58. LOGW("close gsensor");
  59. }
  60. }
  61. if (magStatus > 0) {
  62. magStatus--;
  63. if (!magStatus) {
  64. status = ioctl(fd, MAG_FLAG, 0);
  65. LOGW("close msensor");
  66. }
  67. }
  68. }
  69. break;
  70. default:
  71. LOGW("unsupported sensor type");
  72. }
  73. return status;
  74. }


【陀螺仪、加速计、磁力计等传感器汇总】
参考文章:
加速度计和陀螺仪的区别

http://www.cnblogs.com/liuq0s/archive/2010/09/02/1816394.html

三轴陀螺仪与加速度计如何辅助Iphone定位的
http://www.weizhiquan.com/archives/1072
ST集成传感器方案实现电子罗盘功能
http://www.eeworld.com.cn/gykz/2011/0408/article_5352.html
Android设备中实现陀螺仪(Orientation Sensor)

http://blog.csdn.net/beeboobeeboo/article/details/6536941

简单易懂的文字 带你认识iPhone 4陀螺仪

http://mobile.zol.com.cn/187/1876651.html

Android操作系统11种传感器介绍

http://hi.baidu.com/aokikyon/blog/item/f9a539d74a4f5fc4a044df40.html

From: http://blog.csdn.net/a345017062/article/details/6459643


-----------------------------------------------------------------------------------------------------------------------------------



加速度计和陀螺仪的区别
这是一篇 diydrones.com 网站上的文章,介绍为什么在无人机自主导航中需要用到加速度计、陀螺仪、磁罗盘计和GPS等传感器(原文地址)。http://www.diydrones.com是个开源的讨论UAV(无人机自主飞行导航器)的社区网站。
An accelerometer measures acceleration. A 3-axis accelerometer will tell you the orientation of a stationary platform relative to earth’s surface, once that platform starts moving, however, things get more complicated. If the platform is in free-fall, it will show zero acceleration. If it is accelerating in a particular direction, that acceleration will simply be added to whatever acceleration is being provided by gravity, and you will not be able to distinguish. A 3-axis accelerometer in an aircraft in a properly coordinated turn with a 60 degree angle of bank, for instance, will show 2 G “vertical” acceleration in the aircraft, despite the fact that the aircraft is tilted 60 degrees relative to the horizon. So, accelerometers alone can’t be used to keep in an aircraft in a particular orientation.
译文:加速度计用于测量加速度。借助一个三轴加速度计可以测得一个固定平台相对地球表面的运动方向,但是一旦平台运动起来,情况就会变得复杂的多。如果平台做自由落体,加速度计测得的加速度值为零。如果平台朝某个方向做加速度运动,各个轴向加速度值会含有重力产生的加速度值,使得无法获得真正的加速度值。 例如,安装在60度横滚角飞机上的三轴加速度计会测得2G的垂直加速度值,而事实上飞机相对地区表面是60度的倾角。因此,单独使用加速度计无法使飞机保 持一个固定的航向。
陀螺仪、加速计、磁力计等传感器汇总
文章图片

飞机的横滚角
A gyro measures rate of rotation around a particular axis. If a gyro is used to measure the rate of rotation around the aircraft roll axis, it will measure a non-zero value as long as the aircraft is rolling, but measure zero if the roll stops. So, a roll gyro in an aircraft in a coordinated turn with a 60 degree bank will be measure a rate of zero, same as an aircraft flying straight and level. You can approximate the current roll angle by integrating the roll rate over time, but you can’t do so without some error creeping in. Just to make life more interesting, gyros drift with time, so additional error will accumulate over a period of minutes or even seconds, and eventually, you’ll have a totally inaccurate idea of your current roll angle relative to the horizon. So, gyros alone can’t be used to keep in an aircraft in a particular orientation.
译文:陀螺仪测量机体围绕某个轴向的旋转角速率值。使用陀螺仪测量飞机机体轴向的旋转角速率时,如果飞机在旋转,测得的值为非零值,飞机不旋转时,测量的值为零。因此,在60度横滚角的飞机上的陀螺仪测得的横滚角速率值为零,同样在飞机做水平直线飞行时,角速率值为零。可以通过角速率值的时间积分来估计当前的横滚角度,前提是没有误差的累积。陀螺仪测量的值会随时间漂移,经过几分钟甚至几秒钟定会累积出额外的误差来,而最终会导致对飞机当前相对水平 面横滚角度完全错误的认知。因此,单独使用陀螺仪也无法保持飞机的特定航向。
陀螺仪、加速计、磁力计等传感器汇总
文章图片

飞机的俯仰角
陀螺仪、加速计、磁力计等传感器汇总
文章图片

飞机横滚角
陀螺仪、加速计、磁力计等传感器汇总
文章图片

飞机偏航角
So, in a nutshell: Accelerometers are right in the long term but wrong (noisy) in the short term. Gyros are right in the short term but wrong (drifiting) in the long term. You need both–each to calibrate the other–to be right all the time.
译文:一言以蔽之,加速度计在较长时间的测量值(确定飞机航向)是正确的,而在较短时间内由于信号噪声的存在,而有误差。陀螺仪在较短时间内则比较准确而较长时间则会有与漂移而存有误差。因此,需要两者(相互调整)来确保航向的正确。
But even that only works in for pitch and roll. For yaw, which is orthogonal to gravity, the accelerometers can’t help you, so you need something else to correct your drifting yaw gyro. That’s either magnetometers (electronic compasses, which are vulnerable to magnetic interference and intertial forces) or GPS.
译文:即使使用了两者,也只可以用于测得飞机的俯仰和横滚角度。对于偏航角度,由于偏航角和重力方向正交,无法用加速度计测量得到,因此还需要采用其他设备来校准测量偏航角度的陀螺仪的漂移值。校准的设备可以使用磁罗盘计(电子磁罗盘,对磁场变化和惯性力敏感)或者GPS。
GPS has a relatively slow update rate (1 to 10 Hz) and is subject to short term errors. It is possible to use GPS alone to keep a very stable and slow flying airframe on a particular ground track on a calm day.
译文:GPS数据更新较慢(1Hz到10Hz),并且短时间内存在误差。可以只用GPS就可在地磁平稳的时间内,在地面跟踪较为稳定和慢速的飞行 器。
An inertial measurement unit (IMU) combines (fuses) information from two or more sensors, such as gyros, accelerometers, magnetometer, and/or GPS, to determine orientation and velocity vector relative to the earth. The computations are fairly complex, and special filtering is often required to eliminate the measurement noise these silicon devices are subject to, so a “low cost” off-the-shelf IMU with decent specs can easily cost $1000 to $5000 US.
译文:惯性导航单元(IMU)组合(融合)来自两个或以上的传感器(例如陀螺仪、加速度计、磁场计和/或GPS)信息用于飞机相对地球的航向矢量和 速度矢量。这种融合算法相当复杂,同时还需要对这些电子器件固有的测量噪声进行特殊滤波,因此市场上具有还算过得去的参数,“廉价”的IMU的价格也要 1000至5000美元。
Infra-red horizon sensing “copilots” are inexpensive and work fairly well as long as they have a clear view of the horizon. Unfortunately, mountains, clouds, haze, buildings, etc., will confuse them. [Chris here: I think IR stabalization is more effective than people give it credit for, and is actually rarely confused in standard usage. Both Paparazzi and AttoPilot are built on it, and they work great. See this interview for more.]
译文:红外水平感应辅助导航仪价格便宜,只要有水平清晰的视觉,它工作良好。不幸的是,山峰、云层、烟雾和建筑等会影响其水平视觉。【Chris: 我认为红外导航仪的稳定性比人们认为的要稳定的多,并且在按标准情况下使用时很少会收到影响。Paparazzi和AttoPilot都使用了它,并工作 良好。可以参考this interview获取更多资料。】
In the end, the techniques used to stabilize a UAV will be very much dependent on the intended use, budget, and how comfortable one might be working with sensor fusion, Kalman filters, etc.
最后,用于UAV的导航器的设计技巧(设计方案)依赖于使用目的、经费预算和传感器数据融合计算、卡尔曼滤波的便利性等方面。

此日志的引用通告 URL 是: http://cid-fc7d91d51e30b93b.spaces.live.com/blog/cns!FC7D91D51E30B93B!169.trak




    推荐阅读