Android Nexus 6P 上硬件传感器的采样率变化
Android sampling rates variation of hardware Sensors on Nexus 6P
我正在开发一个 Android 应用程序,用于研究,我正在读取多个传感器数据,如加速度计、陀螺仪、气压计等。
因此,我有 4 台 Nexus 6P 设备,所有设备都装有最新的 Factory Image,并且是全新设置的,除了预装的标准应用程序外,没有安装其他应用程序。
所以现在出现的问题是 phones 之一不断落后,所以例如我记录半小时的加速度计在 105 赫兹(所以加速度计的最大可能速率是 400Hz),只是确保我至少获得了我期望的 100Hz 样本量,结果如下:
在 100Hz 下采样半小时 -> 180000 个样本
在 105Hz 下采样半小时 -> 189000 个样本
(这现在只是加速度计的一个示例,但对于每台设备上的所有其他传感器都是相同的。因此设备 1、3、4 对其他传感器的效果大致相同,而设备 2 的效果相同所有其他传感器的结果)。
- 设备 1:180000 个样本
- 设备 2:177273 个样本 <- 落后的 phone
- 设备 3:181800 个样本
- 设备 4:179412 个样本
所以问题出在 2 号设备上,我丢失了将近 3000 个样本(我知道这是在高水平上哭泣),我猜这个问题可能与硬件有关。这可能是我可以排除的性能问题,因为无论我读取多少传感器以及以 400Hz 读取它们都可以按预期工作(如果需要,我也可以为此提供样本)。我还尝试将采样率设置为 400Hz,以便最快,然后根据导致相同结果的时间戳进行记录。
以防万一,我将提供如何注册传感器侦听器:
protected void onCreate(Bundle savedInstanceState){
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
unaccDataSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED);
}
....
private void Start(){
sensorManager.registerListener(unaccDataListener, unaccDataSensor, 10000);
}
所以我想要的是至少获得我应该期望的样本数量,所以高于这个数量是没有问题的,稍微低于这个数量也是可以接受的。
因此,如果有人知道我还能尝试什么或什么会导致问题,我将非常感激。
这是我的第一个 Post 所以如果有任何遗漏或者我解释的方式不正确,我很抱歉,我会尽力修复它。
我经常使用 Android 传感器,我可以告诉你硬件质量参差不齐。如果我需要结果在手机之间保持一致,我通常会使用过滤器:
// Filter to remove readings that come too often
if (TS < LAST_TS_ACC + 100) {
//Log.d(TAG, "onSensorChanged: skipping");
return;
}
然而,这意味着您只能将手机设置为匹配最低公分母。如果它有帮助,我发现对于大多数应用程序,即使是医疗应用程序,获得超过 25hz 的频率都是过大的。
它还可以帮助确保您正在执行的任何文件写入都是在线程外分批完成的,因为写入文件是一项昂贵的操作。
accelBuffer = new StringBuilder();
accelBuffer.append(LAST_TS_ACC + "," + event.values[0] + "," + event.values[1] + "," + event.values[2] + "\n");
if((accelBuffer.length() > 500000) && (writingAccelToFile == false) ){
writingAccelToFile = true;
AccelFile = new File(path2 +"/Acc/" + LAST_TS_ACC +"_Service.txt");
Log.d(TAG, "onSensorChanged: accelfile created at : " + AccelFile.getPath());
File parent = AccelFile.getParentFile();
if(!parent.exists() && !parent.mkdirs()){
throw new IllegalStateException("Couldn't create directory: " + parent);
}
//Try threading to take of UI thread
new Thread(new Runnable() {
@Override
public void run() {
//Log.d(TAG, "onSensorChanged: in accelbuffer");
// Log.d(TAG, "run: in runnable");
//writeToStream(accelBuffer);
writeStringBuilderToFile(AccelFile, accelBuffer);
accelBuffer.setLength(0);
writingAccelToFile = false;
}
}).start();
}
以上都做了,效果还算不错,但由于硬件的差异,永远不可能完美。
祝你好运!
我正在开发一个 Android 应用程序,用于研究,我正在读取多个传感器数据,如加速度计、陀螺仪、气压计等。 因此,我有 4 台 Nexus 6P 设备,所有设备都装有最新的 Factory Image,并且是全新设置的,除了预装的标准应用程序外,没有安装其他应用程序。 所以现在出现的问题是 phones 之一不断落后,所以例如我记录半小时的加速度计在 105 赫兹(所以加速度计的最大可能速率是 400Hz),只是确保我至少获得了我期望的 100Hz 样本量,结果如下:
在 100Hz 下采样半小时 -> 180000 个样本
在 105Hz 下采样半小时 -> 189000 个样本
(这现在只是加速度计的一个示例,但对于每台设备上的所有其他传感器都是相同的。因此设备 1、3、4 对其他传感器的效果大致相同,而设备 2 的效果相同所有其他传感器的结果)。
- 设备 1:180000 个样本
- 设备 2:177273 个样本 <- 落后的 phone
- 设备 3:181800 个样本
- 设备 4:179412 个样本
所以问题出在 2 号设备上,我丢失了将近 3000 个样本(我知道这是在高水平上哭泣),我猜这个问题可能与硬件有关。这可能是我可以排除的性能问题,因为无论我读取多少传感器以及以 400Hz 读取它们都可以按预期工作(如果需要,我也可以为此提供样本)。我还尝试将采样率设置为 400Hz,以便最快,然后根据导致相同结果的时间戳进行记录。
以防万一,我将提供如何注册传感器侦听器:
protected void onCreate(Bundle savedInstanceState){
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
unaccDataSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER_UNCALIBRATED);
}
....
private void Start(){
sensorManager.registerListener(unaccDataListener, unaccDataSensor, 10000);
}
所以我想要的是至少获得我应该期望的样本数量,所以高于这个数量是没有问题的,稍微低于这个数量也是可以接受的。 因此,如果有人知道我还能尝试什么或什么会导致问题,我将非常感激。
这是我的第一个 Post 所以如果有任何遗漏或者我解释的方式不正确,我很抱歉,我会尽力修复它。
我经常使用 Android 传感器,我可以告诉你硬件质量参差不齐。如果我需要结果在手机之间保持一致,我通常会使用过滤器:
// Filter to remove readings that come too often
if (TS < LAST_TS_ACC + 100) {
//Log.d(TAG, "onSensorChanged: skipping");
return;
}
然而,这意味着您只能将手机设置为匹配最低公分母。如果它有帮助,我发现对于大多数应用程序,即使是医疗应用程序,获得超过 25hz 的频率都是过大的。
它还可以帮助确保您正在执行的任何文件写入都是在线程外分批完成的,因为写入文件是一项昂贵的操作。
accelBuffer = new StringBuilder();
accelBuffer.append(LAST_TS_ACC + "," + event.values[0] + "," + event.values[1] + "," + event.values[2] + "\n");
if((accelBuffer.length() > 500000) && (writingAccelToFile == false) ){
writingAccelToFile = true;
AccelFile = new File(path2 +"/Acc/" + LAST_TS_ACC +"_Service.txt");
Log.d(TAG, "onSensorChanged: accelfile created at : " + AccelFile.getPath());
File parent = AccelFile.getParentFile();
if(!parent.exists() && !parent.mkdirs()){
throw new IllegalStateException("Couldn't create directory: " + parent);
}
//Try threading to take of UI thread
new Thread(new Runnable() {
@Override
public void run() {
//Log.d(TAG, "onSensorChanged: in accelbuffer");
// Log.d(TAG, "run: in runnable");
//writeToStream(accelBuffer);
writeStringBuilderToFile(AccelFile, accelBuffer);
accelBuffer.setLength(0);
writingAccelToFile = false;
}
}).start();
}
以上都做了,效果还算不错,但由于硬件的差异,永远不可能完美。
祝你好运!