3. Magnetic Field Measurement Tests
这项测试是测试算法库校准水平的。Android 推荐在室外或至少是干净的磁场环境下进行测试。如果测试人员在自己办公桌上或周围有许多电子设备的环境里测试,即使测试失败也不能说明有什么问题。
地磁传感器(Magnetic Field Sensor)主要用途是来指示方向,最常见的应用就是指南针。它的原理就是测量出设备所在的环境的磁通量,可以模拟机械指南针的指向功能。但是由于地磁传感器是安装在PCB板上,既有周围金属的硬磁(Hard Iron)[1]干扰,又有器件线路上电后的软磁(Soft Iron)干扰。算法通过做规定的校准动作(8字校准,8-figure movement)来计算这些软硬磁干扰和offset,然后做相应的补偿,以求达到最接近环境磁场的值。但是算法的软件校准也是有限制的,如果地磁传感器被安装在非常差的位置,受周围器件干扰非常大;又或者地磁传感器所在的环境磁通量不稳定且变化幅度较大;这两种情况算法库都无法完成校准。(地球表面磁场的磁通量只有 60 uT 左右。打个比方,拿个磁铁靠近机械指南针,它肯定找不着北了。)
Android-CDD_6.0 Magnetometer [2]
我们来看测试项。
1) testNorm. 测试范数,范数是个数学概念没必要深究。这个测试的目的是检测校准后的Magnetic Field数据是否在规定范围之内。直接看代码:
/* Maximum magnetic field on Earth's surface */
float MAGNETIC_FIELD_EARTH_MAX = 60.0;
/* Minimum magnetic field on Earth's surface */
float MAGNETIC_FIELD_EARTH_MIN = 30.0
public String testNorm() throws Throwable {
getTestLogger().logMessage(R.string.snsr_mag_verify_norm);
TestSensorEnvironment environment = new TestSensorEnvironment(
getApplicationContext(),
Sensor.TYPE_MAGNETIC_FIELD,
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation verifyNorm =
TestSensorOperation.createOperation(environment, 100 /* event count */); /* 取100个sample */
/* 期望值 = (60 + 30)/ 2 = 45 */
float expectedMagneticFieldEarth =
(SensorManager.MAGNETIC_FIELD_EARTH_MAX + SensorManager.MAGNETIC_FIELD_EARTH_MIN) / 2;
/* 误差范围 = 45 - 30 = 15 */
float magneticFieldEarthThreshold =
expectedMagneticFieldEarth - SensorManager.MAGNETIC_FIELD_EARTH_MIN;
verifyNorm.addVerification(new MagnitudeVerification(
expectedMagneticFieldEarth,
magneticFieldEarthThreshold));
verifyNorm.execute(getCurrentTestNode());
return null;
}
由于设备所处的地理位置不确定,只要是在地球表面上,那么地磁传感器校准后的磁通量就应该在一定的范围内。如果不在该范围,则说明算法库校准失败,那么这个测试项也会失败。failure提示:
**Magnitude mean out of range: mean=%s (expected %s+/-%s**
2) testStandardDeviation.
测试地磁传感器三轴数据的标准差(Standard Deviation).
下面分析一下代码片断:
/* 设置 fasted odr (10Hz/20Hz/25ha/50Hz, 收集100个数据,设置三轴threshold:2uT) */
public String testStandardDeviation() throws Throwable {
getTestLogger().logMessage(R.string.snsr_mag_verify_std_dev);
TestSensorEnvironment environment = new TestSensorEnvironment(
getApplicationContext(),
Sensor.TYPE_MAGNETIC_FIELD,
SensorManager.SENSOR_DELAY_FASTEST);
TestSensorOperation verifyStdDev =
TestSensorOperation.createOperation(environment, 100 /* event count */);
verifyStdDev.addVerification(new StandardDeviationVerification(new float[]{2f, 2f, 2f} /* uT */));
verifyStdDev.execute(getCurrentTestNode());
return null;
}
...
/* 计算均值,平方值 */
for (int i = 0; i < event.values.length; i++) {
float delta = event.values[i] - mMeans[i];
mMeans[i] += delta / mCount;
mM2s[i] += delta * (event.values[i] - mMeans[i]);
}
...
/* 计算标准差 */
float[] stdDevs = new float[mM2s.length];
for (int i = 0; i < mM2s.length; i++) {
stdDevs[i] = (float) Math.sqrt(mM2s[i] / (mCount - 1));
}
/* 如果标准差超出threshold范围,则测试fail */
if (stdDevs[i] > mThreshold[i]) {
failed = true;
}
if (failed) {
Assert.fail(String.format("Standard deviation out of range: stddev=%s (expected %s)", stddevSb.toString(), expectedSb.toString()));
}
3) testCalibratedAndUncalibrated
与陀螺仪的测试项Calibrated and Uncalibrated相同,验证等式:
calibrated = uncalibrated - bias +- threshold
/* threshold 是3uT */
float THRESHOLD_CALIBRATED_UNCALIBRATED_UT = 3f;
以上三个测试用例,如果失败则说明磁场环境太差导致无法校准或者算法自身不完善。解决方法是,一 从硬件角度,更改地磁传感器在PCB上的位置,利用地磁传感器提供的一些功能:如滤波降低nosie level等。二,从软件角度,完善算法。
[1] Hard Iron and Soft Iron
[2] Android-CDD_6.0