【问题标题】:Android: Improve sensor sampling rate by use of NDK and pollingAndroid:通过使用 NDK 和轮询提高传感器采样率
【发布时间】:2012-02-12 15:48:59
【问题描述】:

我想编写一个应用程序,从不同的传感器(GPS、Acc、陀螺仪、指南针)读取尽可能多的传感器值(每次)。所以我必须调查使用NDK是否有优势。

这是我的问题:

a) 从传感器读取传感器值时的瓶颈是什么?是传感器本身还是Java?我可以使用 NDK 提高速率吗? (我认为 GPS 的瓶颈是传感器本身,但我已经读过,例如陀螺传感器非常快) 我找到了this thread,似乎瓶颈是传感器。有人可以确认吗?

b) 轮询而不是使用 EventListener 会提高速率吗?快速读取传感器值的最佳方法是什么?

c) NDK 的使用对应用程序的功耗有影响吗?我没有找到任何关于此的信息。

d) 我是 Android 新手。使用 NDK 比使用普通 Java 更划算吗? 根据这个sample-code,使用事件队列与传感器进行交互似乎很简单,但是编译代码并从应用程序中使用它的成本是多少?

提前致谢。

【问题讨论】:

    标签: android performance android-ndk android-sensors


    【解决方案1】:

    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。如果你的手机支持这个...

    【讨论】:

      【解决方案2】:

      注册传感器侦听器时,您需要将SensorManager.SENSOR_DELAY_FASTEST 传递给registerListener()

      详情请参阅http://developer.android.com/reference/android/hardware/SensorManager.html

      【讨论】:

      • 感谢您的回答,但这不是我想要的。问题是使用 C++ (NDK) 而不是 Java (SDK) 是否有好处。
      • 我们正在使用 JNI 将 G-sensor 数据从 Java 传递到本机,并且没有发现任何问题。
      • 你的方法有什么好处吗?为什么不直接使用 NDK 的 Sensor-Interface 呢?对我来说,您的方法没有任何好处,因为我不对传感器数据进行任何计算,我只是将其转发到服务器。
      • 我们的应用程序必须在 Android 2.2 上运行,所以我们必须坚持使用 Java 代码。
      • 你能帮我解决这个question吗?
      【解决方案3】:

      根据经验,我至少可以回答您的第一个问题:

      a) 使用基本 Java 足以处理多个传感器。在我的一个应用程序中,我使用 SENSOR_DELAY_FASTEST 同时读取了加速度计、陀螺仪、磁力计、游戏旋转矢量和未校准的磁力计。

      除此之外,我还对数据进行了一系列过滤和存储,以及一些四元数数学来跟踪旋转。查看原始数据(我也将其保存到 .txt 文件中),似乎没有任何丢失的数据或延迟(时间戳之间的平均差异与运行单个传感器而不进行计算相同)。

      因此,就我而言,传感器的工作速度尽可能快,而 Java 则保持良好状态。

      ...

      也就是说,如果您要进行大量计算,那么使用 NDK 可能值得一试。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-05-11
        • 1970-01-01
        • 1970-01-01
        • 2012-10-05
        • 1970-01-01
        • 1970-01-01
        • 2019-03-06
        • 2021-06-13
        相关资源
        最近更新 更多