Android CTS Verifier Sensor Test Cases (3)
2016-09-04 00:08
801 查看
2. Gyroscope Measurement Test
前面一章提到加速度传感器适合描述设备静止的状态,而陀螺仪传感器则适合描述设备运动的状态,由于陀螺仪的特性,它能非常精确的反映设备绕某一轴旋转的角速度。设备静止时,由于白噪声等原因,陀螺仪会产生零飘。
Gyroscope Measurement Test 只有存在物力陀螺仪传感器时才有意义。ECompass(Acc+Mag, 6dof),或 M4G(Acc+Mag, Mag for Gyro)方案下,本测试项应该skip. 即使是M4G方案也不应该进行该测试。
该测试的目的是检测校准后的Gyrocope(即,Calibrated Gyroscope)数据质量,和与校准前的Uncalibrated Gyrosocpe sensor 数据相比是否满足Android 对这两种sensor类型的需求。
testCalibratedAndUncalibrated
这项测试要求在测试开始后不停的旋转设备,直到测试结束。测试时收集在Fasted 模式下每一时刻的Gyroscope Sensor 和 Uncalibrated Gyroscope Sensor 数据,验证是否符合等式:
同时CTS Verifier 定义了一个threshold允许Gyroscope 和Uncalibrated Gyroscope 数据的差值在bias之外的误差范围:
我们直接来看测试执行的代码:
该项测试的失败类型有两种:
1)没找到符合要求的一对Calibrated Gyroscope data 和 Uncalibrated Gyroscope data. Calibrated 和 Uncalibrated 数据都是由算法输出的Virtual Sensor 类型。他们都来源于物理sensor的原始数据。但是代码中Calibrated Gyroscope 和 Uncalibrated Gyroscope是先后打开的,收到的数据也是顺序收到的。重点来了,这段代码到HAL层的执行效率,可能会导致同是第n个数据,但是Calibrated Gyro 和 Uncalibrated Gyro并不属于同一个物理原始数据。还有一点,Android自己并不提供HAL层的代码,而是厂商自己写,里面会集成厂商自己的算法库。这个算法库的执行效率也会影响到 Calibrated 和 Uncalibrated data 是否来源于同一个原始数据 .
解决方法有:
a. 同时从算法库中获取Calibrated 和 Uncalibrated data,上层有enable就上报,没enable就不报。这样两个data的时间戳就相等;
b. 厂商检查自己HAL/Algorithm 库的逻辑,确保Calibrated Gyroscope 和 Uncalibrated Gyroscope data 上报频率保持一致;
c. 如果是厂商自己的 HAL/Algorithm 代码执行效率的限制,上报数据时再赋上时间戳;
2)不符合等式,即calibrated 不
b664
等于 Uncalibrated - bias +- threshold. 原因两种,一是 Calibrated Gyroscope 未校准成功,algorithm 没有产生bias 或者产生了错误bias; 二是虽然时间戳满足要求,但是这一对(pair)Calibrated 和 Uncalibrated 数据不是来源于同一个物理原始数据。
解决方法:
a. 如果是第一种原因,先确认一下算法返回的Calibrated Gyroscope accuracy status是否为3;若小于3,则说明未校准。Gyroscope sensor 的校准方式非常简单,enable Gyroscope sensor 后,静止1~2秒钟即可校准。如果没有校准,检查你的Algorithm的实现是否有异常。
b. 如果是第二个原因,参考1)的解决方法,或告诉测试人员在测试时,非常缓慢的方式旋转设备,陀螺仪非常灵敏,而且量程非常大(2000dps)。如果Calibrated 和 Uncalibrated 不是来源于同一个物理原始数据,则完全可能不符合等式。(Android并没有具体定义测试设备旋转的速度,缓慢旋转则可以保证原始数据不会突然变化的非常大);
testDeviceStatic
设备静止放置,开始测试收集一组10秒钟的数据,计算Gyroscope 三个轴的旋转角度。因为设备是静止不动的,所以三轴的理想值应该是0度,但是由于误差的存在,Android CTS Verifier 定义了一个静止时的Threshold, 只要是在这个范围内,就认为测试通过。
/* 10 senconds, 50 degrees, 不知道 Android 出于什么目的这个threshold定义的足够大,以至于很容易就能满足。静止状态10秒钟能漂50度以上的sensor还能用吗? */
private static final float THRESHOLD_AXIS_UNDER_NO_ROTATION_DEG =
50.0f;
这项测试失败原因也只能是10秒钟的静止数据漂了50度以上。解决方法换算法库或换sensor。
testRotateClockwise
开始测试时,设备正面朝上放置,沿设备Z轴顺时针旋转360度(只能而且必须旋转1周,转多了/少了都不符合测试要求),然后放置(依然正面朝上,参考动画演示)。
失败的情况就一个,测量值在[350, 370]区间之外。
具体原因:
a. Gyroscope 未校准,有offset时,可以引起测量值过小或过大。解决方法就是先校准到3,再测试;
b. Gyroscope Noise 太大,即使校准成功了,也可能因为noise的原因导致测量值不符合要求。解决方法是提高Gyroscope 的filter,比如average 4 or 其他设置(具体filter请查看gyroscope相应datasheet); c. Gyroscope 硬件本身的sensitivity (灵敏度)误差,导致设备旋转了360度,而数据通过积分只能现实小于350度或大于370度的值。器件自身问题,没有好的解决方法;
剩下的几个测试项testRotateCounterClockwise(逆时针), testRotateRightSide(右侧旋转),testRotateLeftSide(左侧旋转),testRotateTopSide(顶部旋转),testRotateBottomSide(底部旋转)测试内容都与testRotateClockwise一样,看演示动画操作即可。
本章节代码连接:
GyroscopeIntegrationVerfication.java
GyroscopeMeasurementTestActivity
前面一章提到加速度传感器适合描述设备静止的状态,而陀螺仪传感器则适合描述设备运动的状态,由于陀螺仪的特性,它能非常精确的反映设备绕某一轴旋转的角速度。设备静止时,由于白噪声等原因,陀螺仪会产生零飘。
Gyroscope Measurement Test 只有存在物力陀螺仪传感器时才有意义。ECompass(Acc+Mag, 6dof),或 M4G(Acc+Mag, Mag for Gyro)方案下,本测试项应该skip. 即使是M4G方案也不应该进行该测试。
该测试的目的是检测校准后的Gyrocope(即,Calibrated Gyroscope)数据质量,和与校准前的Uncalibrated Gyrosocpe sensor 数据相比是否满足Android 对这两种sensor类型的需求。
testCalibratedAndUncalibrated
这项测试要求在测试开始后不停的旋转设备,直到测试结束。测试时收集在Fasted 模式下每一时刻的Gyroscope Sensor 和 Uncalibrated Gyroscope Sensor 数据,验证是否符合等式:
calibrated = uncalibrated - bias
同时CTS Verifier 定义了一个threshold允许Gyroscope 和Uncalibrated Gyroscope 数据的差值在bias之外的误差范围:
private static final float THRESHOLD_CALIBRATED_UNCALIBRATED_RAD_SEC = 0.01f;
我们直接来看测试执行的代码:
/* 不停的旋转设备,收集10秒钟的数据,然后验证收集到的数据 */ /** * Executes the operation: it collects the data and run verifications on it. */ public void execute() throws Throwable { /* 先打开 Calibrated Gyroscope, 后打开 Uncalibrated Gyroscope */ mCalibratedSensorManager.registerListener(mCalibratedTestListener); mUncalibratedSensorManager.registerListener(mUncalibratedTestListener); Thread.sleep(TimeUnit.SECONDS.toMillis(10)); mCalibratedSensorManager.unregisterListener(); mUncalibratedSensorManager.unregisterListener(); /* 验证搜集到的数据 */ verifyMeasurements( mCalibratedTestListener.getCollectedEvents(), mUncalibratedTestListener.getCollectedEvents(), mThreshold); } /* Verification 的方法 */ private void verifyMeasurements( List<TestSensorEvent> calibratedEvents, List<TestSensorEvent> uncalibratedEvents, float threshold) { /* 获取Calibrated Gyroscope Sensor 的data rate. e.g. 200Hz = 5ms = 5000000ns */ long measuredSamplingPeriodNs = SensorCtsHelper.getSamplingPeriodNs(calibratedEvents); /* Data rate 除以2得到用来做同步的时间值。下面会用来判断Uncalibrated Gyroscope data 是否跟之前收到的Calibrated Gyroscope data 属于同一时间产生的数据 */ long synchronizationPeriodNs = measuredSamplingPeriodNs / 2; /* 有效事件的计数 */ int eventsValidated = 0; // TODO: this makes the algorithm O(n^2) when we could have it O(n), but it has little // impact on the overall test duration because the data collection is what takes the most // time for (TestSensorEvent calibratedEvent : calibratedEvents) { /* 当前Calibrated Gyroscope 数据自带的时间戳 */ long calibratedTimestampNs = calibratedEvent.timestamp; /* 加减前面的同步时间值得到期望的Uncalibrated Gyroscope 数据时间戳的范围 */ long lowerTimestampThresholdNs = calibratedTimestampNs - synchronizationPeriodNs; long upperTimestampThresholdNs = calibratedTimestampNs + synchronizationPeriodNs; for (TestSensorEvent uncalibratedEvent : uncalibratedEvents) { long uncalibratedTimestampNs = uncalibratedEvent.timestamp; /* Uncalibrated Gyroscope data自带的时间戳满足范围要求说明这两个数据来源于同一 gyroscope 物理原始数据 */ if (uncalibratedTimestampNs > lowerTimestampThresholdNs && uncalibratedTimestampNs < upperTimestampThresholdNs) { /* 验证等式 calibrated = Uncalibrated - bias +- threshold */ // perform validation verifyCalibratedUncalibratedPair( calibratedEvent, uncalibratedEvent, threshold); ++eventsValidated; } } } String eventsValidatedMessage = String.format( "Expected to find at least one Calibrated/Uncalibrated event pair for validation." + " Found=%d", eventsValidated); /* 根据时间戳范围限制,没找到符合要求的一对Calibrated Uncalbrated Gyro data, 则报错 */ Assert.assertTrue(eventsValidatedMessage, eventsValidated > 0); } private void verifyCalibratedUncalibratedPair( TestSensorEvent calibratedEvent, TestSensorEvent uncalibratedEvent, float threshold) { for (int i = 0; i < 3; ++i) { float calibrated = calibratedEvent.values[i]; float uncalibrated = uncalibratedEvent.values[i]; float bias = uncalibratedEvent.values[i + 3]; String message = String.format( "Calibrated (%s) and Uncalibrated (%s) sensor readings are expected to satisfy:" + " calibrated = uncalibrated - bias. Axis=%d, Calibrated=%s, " + "Uncalibrated=%s, Bias=%s, Threshold=%s", calibratedEvent.sensor.getName(), uncalibratedEvent.sensor.getName(), i, calibrated, uncalibrated, bias, threshold); /* 不符合等式要求,也报错 */ Assert.assertEquals(message, calibrated, uncalibrated - bias, threshold); } } }
该项测试的失败类型有两种:
1)没找到符合要求的一对Calibrated Gyroscope data 和 Uncalibrated Gyroscope data. Calibrated 和 Uncalibrated 数据都是由算法输出的Virtual Sensor 类型。他们都来源于物理sensor的原始数据。但是代码中Calibrated Gyroscope 和 Uncalibrated Gyroscope是先后打开的,收到的数据也是顺序收到的。重点来了,这段代码到HAL层的执行效率,可能会导致同是第n个数据,但是Calibrated Gyro 和 Uncalibrated Gyro并不属于同一个物理原始数据。还有一点,Android自己并不提供HAL层的代码,而是厂商自己写,里面会集成厂商自己的算法库。这个算法库的执行效率也会影响到 Calibrated 和 Uncalibrated data 是否来源于同一个原始数据 .
解决方法有:
a. 同时从算法库中获取Calibrated 和 Uncalibrated data,上层有enable就上报,没enable就不报。这样两个data的时间戳就相等;
b. 厂商检查自己HAL/Algorithm 库的逻辑,确保Calibrated Gyroscope 和 Uncalibrated Gyroscope data 上报频率保持一致;
c. 如果是厂商自己的 HAL/Algorithm 代码执行效率的限制,上报数据时再赋上时间戳;
2)不符合等式,即calibrated 不
b664
等于 Uncalibrated - bias +- threshold. 原因两种,一是 Calibrated Gyroscope 未校准成功,algorithm 没有产生bias 或者产生了错误bias; 二是虽然时间戳满足要求,但是这一对(pair)Calibrated 和 Uncalibrated 数据不是来源于同一个物理原始数据。
解决方法:
a. 如果是第一种原因,先确认一下算法返回的Calibrated Gyroscope accuracy status是否为3;若小于3,则说明未校准。Gyroscope sensor 的校准方式非常简单,enable Gyroscope sensor 后,静止1~2秒钟即可校准。如果没有校准,检查你的Algorithm的实现是否有异常。
b. 如果是第二个原因,参考1)的解决方法,或告诉测试人员在测试时,非常缓慢的方式旋转设备,陀螺仪非常灵敏,而且量程非常大(2000dps)。如果Calibrated 和 Uncalibrated 不是来源于同一个物理原始数据,则完全可能不符合等式。(Android并没有具体定义测试设备旋转的速度,缓慢旋转则可以保证原始数据不会突然变化的非常大);
testDeviceStatic
设备静止放置,开始测试收集一组10秒钟的数据,计算Gyroscope 三个轴的旋转角度。因为设备是静止不动的,所以三轴的理想值应该是0度,但是由于误差的存在,Android CTS Verifier 定义了一个静止时的Threshold, 只要是在这个范围内,就认为测试通过。
/* 10 senconds, 50 degrees, 不知道 Android 出于什么目的这个threshold定义的足够大,以至于很容易就能满足。静止状态10秒钟能漂50度以上的sensor还能用吗? */
private static final float THRESHOLD_AXIS_UNDER_NO_ROTATION_DEG =
50.0f;
这项测试失败原因也只能是10秒钟的静止数据漂了50度以上。解决方法换算法库或换sensor。
testRotateClockwise
开始测试时,设备正面朝上放置,沿设备Z轴顺时针旋转360度(只能而且必须旋转1周,转多了/少了都不符合测试要求),然后放置(依然正面朝上,参考动画演示)。
/* 沿Z轴旋转,不考虑X/Y轴数据变化,理想值应该是设备旋转了 -360度, Android 定义了旋转时的threshold (误差允许范围) 为正负10度以内 */ private static final float THRESHOLD_AXIS_UNDER_ROTATION_DEG = 10.0f; public String testRotateClockwise() throws Throwable { return verifyMeasurements(R.string.snsr_gyro_rotate_device, Z_AXIS, -ROTATE_360_DEG); }
失败的情况就一个,测量值在[350, 370]区间之外。
具体原因:
a. Gyroscope 未校准,有offset时,可以引起测量值过小或过大。解决方法就是先校准到3,再测试;
b. Gyroscope Noise 太大,即使校准成功了,也可能因为noise的原因导致测量值不符合要求。解决方法是提高Gyroscope 的filter,比如average 4 or 其他设置(具体filter请查看gyroscope相应datasheet); c. Gyroscope 硬件本身的sensitivity (灵敏度)误差,导致设备旋转了360度,而数据通过积分只能现实小于350度或大于370度的值。器件自身问题,没有好的解决方法;
剩下的几个测试项testRotateCounterClockwise(逆时针), testRotateRightSide(右侧旋转),testRotateLeftSide(左侧旋转),testRotateTopSide(顶部旋转),testRotateBottomSide(底部旋转)测试内容都与testRotateClockwise一样,看演示动画操作即可。
本章节代码连接:
GyroscopeIntegrationVerfication.java
GyroscopeMeasurementTestActivity
相关文章推荐
- Android CTS Verifier Sensor Test Cases (2)
- Android CTS Verifier Sensor Test Cases (5)
- Android CTS Verifier Sensor Test Cases (4)
- Android CTS Verifier Sensor Test Cases (7)
- CtsOsTestCasesTest android.os.cts.BuildVersionTest#testBuildFingerprint
- testBatchAndFlush(android.hardware.cts.SensorTest): WaitForFlush | sensor='PROXIMITY'
- CTS Verifier apk 测试失败Sensor Batching test failed(关于时间戳的问题)
- 【多线程问题】android8.1 cts测试原生bug多线程导致CtsJvmtiRedefineClassesHostTestCases中,testJvmti Fail
- android.media.cts.EncodeDecodeTest -- testVP8EncodeDecodeVideoFromPersistentSurfaceToSurfaceQCIF
- android.carrierapi.cts.CarrierApiTest#testHasCarrierPrivileges
- CTS: testSensorFeatures FAIL 的解决
- MT6735[CTS Verifier][Test Method]Widget Framework Test
- cts fail: com.android.cts.numberblocking.hostside.NumberBlockingTest#testNumberBlocking
- 如何通过Android CTS测试—testPackageSignatures
- How to add a test plan, package to Android CTS?
- How to add CTS test cases
- CTS Verifier - Car Dock Test is fail
- android官网译文《Using CTS Verifier》-CTS验证工具的使用
- mt6735 [CTS Verifier][Test Method]Camera FOV Calibration