Android CTS Verifier Sensor Test Cases (4)

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]

Android CTS Verifier Sensor Test Cases (4)_第1张图片

我们来看测试项。

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

你可能感兴趣的:(Android-CTS,Android,Sensor,magnetic)