access (faster polling) accelerometer via NativeActivity NDK

前端 未结 4 1841
故里飘歌
故里飘歌 2020-12-28 20:13

I\'ve searched for a tutorial/an answer on polling accelerometer faster with NDK but didnt find solver yet. just found an androiddevelopers documentation here.

what

相关标签:
4条回答
  • 2020-12-28 20:59

    You are probably limited by the speed of the accelerometer hardware in your device. However, you could use interpolation to get some extra data points.

    0 讨论(0)
  • 2020-12-28 21:01

    This is an old question but given the lack of documentation and articles out there, I thought I'd share my experience. I did all my tests on a Nexus 5X. Your device might be different.

    The original code looks right. What isn't obvious from the documentation is that you can only set the event rate after enabling the sensor, and that...

    If you re-enable the sensor (say, after onPause() and onResume()), you need to set the event rate again. If you had a "double enable" like I did in my code (enable()/setEventRate() in init(), but only enable() in onResume()), you will get the default polling rate.

    0 讨论(0)
  • 2020-12-28 21:04

    Question is a bit old but maybe these two articles will help out a bit for anyone else that stumbles on this question and wonders why bother, or how to optimize the example in the NDK a bit.

    These two short articles layout the issues and potential solutions (but no complete source solution)

    Java interfaced sensor performance

    Native Sampling Improvement

    0 讨论(0)
  • 2020-12-28 21:17

    I also tried a few things with the sample rate of sensors. I use a Galaxy Nexus. If I use only the Acc-Sensor the frequency is very low (about 40Hz), but if I use the Acc-Sensor plus the magnetic- and the gyro-sensor the sample rate for each sensor is about 100Hz. I have no explanation why this happens. Another observation is that the values passed to ASensorEventQueue_setEventRate have no effect. The sample-rate is always the same. The behaviour is exactly the same for SDK-Code.

    Here is the code I used for benchmarking:

    #include <string.h>
    #include <jni.h>
    #include <android/sensor.h>
    #include <android/looper.h>
    #include <android/log.h>
    #include <time.h>
    #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "TestJNIActivity", __VA_ARGS__))
    #define LOOPER_ID 1
    #define SAMP_PER_SEC 100
    
    ASensorEventQueue* sensorEventQueue;
    
    int accCounter = 0;
    int64_t lastAccTime = 0;
    
    int gyroCounter = 0;
    int64_t lastGyroTime = 0;
    
    int magCounter = 0;
    int64_t lastMagTime = 0;
    
    /* This is a trivial JNI example where we use a native method
     * to return a new VM String. See the corresponding Java source
     * file located at:
     *
     *   apps/samples/hello-jni/project/src/com/example/HelloJni/HelloJni.java
     */
    
    static int get_sensor_events(int fd, int events, void* data);
    
    struct tm* start;
    struct tm* finish;
    
    
    jstring
    Java_de_tum_ndktest_TestJNIActivity_stringFromJNI( JNIEnv* env, jobject thiz )
    {
        LOGI("stringFromJNI");
        return (*env)->NewStringUTF(env,"Hello from JNI !");
    }
    
    void
    Java_de_tum_ndktest_TestJNIActivity_sensorValue( JNIEnv* env, jobject thiz ) {
    
        ASensorEvent event;
        int events, ident;
        ASensorManager* sensorManager;
        const ASensor* accSensor;
        const ASensor* gyroSensor;
        const ASensor* magSensor;
        void* sensor_data = malloc(1000);
    
        LOGI("sensorValue() - ALooper_forThread()");
    
        ALooper* looper = ALooper_forThread();
    
        if(looper == NULL)
        {
            looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);
        }
    
        sensorManager = ASensorManager_getInstance();
    
        accSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
        gyroSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_GYROSCOPE);
        magSensor = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_MAGNETIC_FIELD);
    
    
    
        sensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper, 3, get_sensor_events, sensor_data);
    
        ASensorEventQueue_enableSensor(sensorEventQueue, accSensor);
        ASensorEventQueue_enableSensor(sensorEventQueue, gyroSensor);
        ASensorEventQueue_enableSensor(sensorEventQueue, magSensor);
    
        //Sampling rate: 100Hz
        int a = ASensor_getMinDelay(accSensor);
        int b = ASensor_getMinDelay(gyroSensor);
        int c = ASensor_getMinDelay(magSensor);
        LOGI("min-delay: %d, %d, %d",a,b,c);
        ASensorEventQueue_setEventRate(sensorEventQueue, accSensor, 100000);
        ASensorEventQueue_setEventRate(sensorEventQueue, gyroSensor, 100000);
        ASensorEventQueue_setEventRate(sensorEventQueue, magSensor, 100000);
    
        LOGI("sensorValue() - START");
    }
    
    
    
    static int get_sensor_events(int fd, int events, void* data) {
      ASensorEvent event;
      //ASensorEventQueue* sensorEventQueue;
      while (ASensorEventQueue_getEvents(sensorEventQueue, &event, 1) > 0) {
            if(event.type == ASENSOR_TYPE_ACCELEROMETER) {
                    //LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
                    if(accCounter == 0 || accCounter == 1000)
                        {
                         LOGI("Acc-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastAccTime))/1000000000.0);
                         lastAccTime = event.timestamp;
                         accCounter = 0;
                        }
    
                    accCounter++;
            }
            else if(event.type == ASENSOR_TYPE_GYROSCOPE) {
                    //LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
                    if(gyroCounter == 0 || gyroCounter == 1000)
                        {
    
                         LOGI("Gyro-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastGyroTime))/1000000000.0);
                         lastGyroTime = event.timestamp;
                         gyroCounter = 0;
                        }
    
                    gyroCounter++;
            }
            else if(event.type == ASENSOR_TYPE_MAGNETIC_FIELD) {
                    //LOGI("accl(x,y,z,t): %f %f %f %lld", event.acceleration.x, event.acceleration.y, event.acceleration.z, event.timestamp);
                    if(magCounter == 0 || magCounter == 1000)
                        {
                         LOGI("Mag-Time: %lld (%f)", event.timestamp,((double)(event.timestamp-lastMagTime))/1000000000.0);
                         lastMagTime = event.timestamp;
                         magCounter = 0;
                        }
    
                    magCounter++;
            }
    
      }
      //should return 1 to continue receiving callbacks, or 0 to unregister
      return 1;
    }
    
    0 讨论(0)
提交回复
热议问题