Android:通过使用 NDK 和轮询提高传感器采样率
我想编写一个应用程序,从不同的传感器(GPS、Acc、陀螺仪、指南针)读取尽可能多的传感器值(每次)。所以我必须调查一下使用NDK是否有优势。
我的问题如下:
a) 从传感器读取传感器值时的瓶颈是什么?是senosr本身还是Java?我可以通过使用 NDK 来提高速率吗? (我认为对于 GPS 来说,瓶颈是传感器本身,但我读到,例如陀螺仪传感器速度相当快) 我发现这个线程,看来瓶颈是传感器。有人可以证实这一点吗?
b) 使用轮询代替使用 EventListener 是否会提高速率?快速读取传感器值的最佳方法是什么?
c) 使用NDK对应用程序的功耗有影响吗?我没有找到任何关于此的信息。
d) 我是 Android 新手。使用 NDK 是否比普通 Java 更经济? 根据这个示例代码,与它进行交互似乎很简单使用事件队列的传感器,但是编译代码并从应用程序中使用它需要多少钱?
提前致谢。
I want to write an application that reads as many sensor vaulues (per time) as possible from different sensors (GPS, Acc, Gyro, Compass). So I have to investigate if there is an advantage in using NDK.
Here are my questions:
a) What is the bottleneck when reading sensor values from a sensor? Is it the senosr itself or Java? Can I increase the rate by using NDK? (I think for GPS the bottleneck is the sensor itself, but I've read that e.g. the Gyro-Sensor is quite fast)
I found this thread and it seems the bottleneck is the sensor. Can someone confirm this?
b) Does polling instead of using EventListener increase the rate? What's the best way to read sensor values fast?
c) Has the use of NDK any influence on the power consumption of the application? I didn't find anything about this.
d) I'm new to Android. Is it much more afford to use NDK instead of normal Java?
According to this sample-code it seems to be straightforward to interact with the sensors using an event-queue, but how much afford is it to compile the code and to use it from the application?
Thanks in advance.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
a) 从传感器读取传感器值时的瓶颈是什么?
(注意:这只是我的印象和推理。除了我开发应用程序“phyphox”的经验之外,我没有其他来源。 ”,它记录了物理实验中使用的传感器数据。)
我不确定这是否应该被称为“瓶颈”,但似乎
SENSOR_DELAY_FASTEST
的速率是制造商的设计选择。SENSOR_DELAY_FASTEST
通常会产生 100Hz 左右的速率,但某些设备(Nexus/Pixel、某些 Smasung 旗舰产品)在相同设置下可提供高达 500Hz 的速率。如果您读出传感器的制造商和型号,您通常可以找到实际设备的数据表,并且您会注意到,它们通常可以驱动得更快。我认为该速率是快速速率和合理噪声之间的权衡。此外,(也许更重要)如果制造商为
SENSOR_DELAY_FASTEST
设置较高的速率,这可能会影响电池寿命。手机不仅必须读出每个值(如果手机有专门的处理器来执行此操作,则该处理器需要具有必要的带宽),许多应用程序都无需太多考虑就使用SENSOR_DELAY_FASTEST
设置。每个值都会调用新值的回调函数,因此频率为 500 Hz 的手机必须以相同的速率调用此函数,并且可能会在应用程序中表现出错误的编码例程,而该例程似乎在设备上运行得很好提供 100 Hz 的频率。b) 使用轮询代替使用 EventListener 是否会提高速率?快速读取传感器值的最佳方法是什么?
我不知道直接轮询传感器的方法。在您链接的线程中,术语“轮询”用于“轮询”传感器已填充的数据队列。如果有人可以通过展示直接在 Android 上轮询传感器的方法来纠正我,我会很高兴...
c) NDK 的使用对应用程序的功耗有影响吗?我没有找到任何关于此的信息。
如果您可以通过更高效的本机例程来减少计算负载,那么显然是有的。如果您可以优化一些繁重的计算,我预计只会产生显着的影响。
d) 我是 Android 新手。使用 NDK 是否比普通 Java 更经济?根据此示例代码,使用事件队列与传感器交互似乎很简单,但是编译代码并从应用程序中使用它需要多少钱?
这是相当主观的,但是设置和学习如何使用 NDK 及其接口花了我一段时间。一旦运行,扩展代码和重新编译就可以在 Android Studio 中顺利进行。
--
我不太清楚您打算如何处理传感器数据,但您应该考虑到 Java 可以轻松处理音频数据,这些数据通常以 48 kHz 录制。诚然,音频样本是写入缓冲区的 16 位值,而不是传递给回调的 SensorEvent 对象,但您仍然可以使用 Java 实时迭代每个样本,因此除非您计划进行一些奇特的分析,否则 Java 的速度不应该成为一个问题。传感器的问题。
您应该注意的另一件事是
SensorDirectChannel
在 API 级别 26 中引入。我还没有尝试过,但是文档提到了RATE_VERY_FAST
提供 440 Hz 至 1760 Hz 。如果你的手机支持这个...a) What is the bottleneck when reading sensor values from a sensor?
(Careful: This is only my impression and my reasoning. I do not have a source for this except my experience in developing the app "phyphox", which records sensor data to be used in physics experiments.)
I am not sure if this should be called a "bottleneck", but it seems like the rate for
SENSOR_DELAY_FASTEST
is a design choice by the manufacturer.SENSOR_DELAY_FASTEST
often results in rates around 100Hz, but some devices (Nexus/Pixel, some Smasung flagships) offer rates up to 500Hz with the same setting. If you read out the manufacturer and the model of the sensor, you can often find the datasheet of the actual device and you will notice, that they usually could be driven much faster. I think that the rate is a trade-off between a fast rate and reasonable noise.Also, (and maybe even more important) if the manufacturer sets a high rate for
SENSOR_DELAY_FASTEST
, this may have an impact on battery life. Not only does the phone have to read out each value (and if the phone has a dedicated processor for this, this processor needs to have the necessary bandwidth), many apps use theSENSOR_DELAY_FASTEST
setting without much consideration. Each value will call the callback function for a new value, so a phone with a rate of 500 Hz will have to call this function at the same rate and might exhibit a badly coded routine in an app that seems to work just smoothly on a device that offers 100 Hz.b) Does polling instead of using EventListener increase the rate? What's the best way to read sensor values fast?
I do not know of a method to poll the sensor directly. In the threads you linked, the term "polling" is used to "poll" the data queue which has been filled by the sensor. I would be happy if someone could correct me here by showing a method to poll a sensor directly on Android...
c) Has the use of NDK any influence on the power consumption of the application? I didn't find anything about this.
It obviously has if you can reduce computational load by a more efficient native routine. I would only expect a noticable impact if you can optimize some otherwise heavy computation.
d) I'm new to Android. Is it much more afford to use NDK instead of normal Java? According to this sample-code it seems to be straightforward to interact with the sensors using an event-queue, but how much afford is it to compile the code and to use it from the application?
This is rather subjective, but setting up and learning how to use NDK and its interfaces took me a while. Once you have it running, extending your code and recompiling works seemlessly in Android Studio.
--
I do not exactly know what you plan to do with the sensor data, but you should consider that Java can easily handle audio data, which is typically recorded at 48 kHz. Granted, audio samples are 16 bit values written into a buffer instead of SensorEvent objects handed to a callback, but you can still iterate over each sample in realtime using Java, so unless you plan some fancy analysis, the speed of Java should not be an issue for the sensors.
Another thing you should be aware of is
SensorDirectChannel
introduced with API level 26. I have not tried it yet, but the documentation mentionsRATE_VERY_FAST
offering 440 Hz to 1760 Hz. If your phone supports this...注册传感器监听器时,您需要将
SensorManager.SENSOR_DELAY_FASTEST
传递给registerListener()
。请参阅 http://developer.android.com/reference/android/hardware/SensorManager .html 了解更多详细信息。
When you register your sensor listener you need to pass
SensorManager.SENSOR_DELAY_FASTEST
toregisterListener()
.Refer to http://developer.android.com/reference/android/hardware/SensorManager.html for more details.
根据经验,我至少可以回答您的第一个问题:
a) 使用基础 Java 的速度足以处理多个传感器。在我的一个应用程序中,我使用 SENSOR_DELAY_FASTEST 同时读取加速度计、陀螺仪、磁力计、游戏旋转矢量和未校准磁力计。
除此之外,我还进行了一系列数据过滤和存储,以及一些四元数数学来跟踪旋转。查看原始数据(我也将其保存到 .txt 文件中),似乎没有任何丢失数据或延迟(时间戳之间的平均差异与运行单个传感器而不进行计算相同)。
因此,就我而言,传感器尽可能快地工作,而 Java 也保持良好状态。
...
也就是说,如果您正在进行大量计算,那么使用 NDK 可能值得尝试。
From experience, I can at least answer the first of your questions:
a) Using base Java is fast enough for handling multiple sensors. In one of my applications, I read Accelerometer, Gyroscope, Magnetometer, Game Rotation Vector and Uncalibrated Magnetometer all at once with SENSOR_DELAY_FASTEST.
On top of this I also did a bunch of filtering and storing of data, as well as some quaternion maths to keep track of rotation. Looking at the raw data (which I also saved to a .txt file), there didn't seem to be any missing data or delays (average difference between time stamps was the same as running a single sensor with no calculations).
So in my case, the sensors were working as fast as they could and Java was keeping up fine.
...
That said, if you're doing very large amounts of computations, using NDK might be worth trying.