通过NativeActivity的NDK接入(快轮询)加速度计加速度计、NativeActivity、NDK、快轮询

由网友(深海的鱼)分享简介:我搜索教程/轮询加速计的回答更快NDK,但没有找到求解呢。刚刚发现一个androiddevelopers文档这里。I've searched for a tutorial/an answer on polling accelerometer faster with NDK but didnt find solver...

我搜索教程/轮询加速计的回答更快NDK,但没有找到求解呢。刚刚发现一个androiddevelopers文档这里。

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.

我需要的是轮询加速大约每秒100个样本(100Hz的),默认情况下,我的设备(姜饼2.3.5三星Galaxy SL i9003的)与默认SENSOR_DELAY_FASTEST只能得到大约60个样品persecond(60赫兹)。 因此,我试图通过NativeActivity的通过生成.c文件,我尽量让基于sensor.h和looper.h访问传感器NDK:

what i need is polling acceleration about 100 samples per second (100Hz), by default my device (Samsung Galaxy SL i9003 with gingerbread 2.3.5) with default SENSOR_DELAY_FASTEST can only get about 60 samples persecond (60Hz). Therefore i tried to access sensor via NativeActivity with NDK by generating .c files that i try to make based on sensor.h and looper.h:

#include <jni.h>
#include <string.h>

#include <android/sensor.h>
#include <android/log.h>
#include <android/looper.h>

#define TAG "accelerondk"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)

#define LOOPER_ID 1
#define SAMP_PER_SEC 100 //i've changed to 120, even 10, but nothing happen

void Java_azka_web_ndk_AcceleroNDKActivity_startMonitoring(JNIEnv* env, jclass clazz) {
    ASensorManager* sensorManager = ASensorManager_getInstance();

    ALooper* looper = ALooper_forThread();
    if(looper == NULL)
        looper = ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS);

    ASensorRef accelerometerSensor = ASensorManager_getDefaultSensor(sensorManager,ASENSOR_TYPE_ACCELEROMETER);
    LOGI("accelerometerSensor: %s, vendor: %s", ASensor_getName(accelerometerSensor), ASensor_getVendor(accelerometerSensor));

    ASensorEventQueue* queue = ASensorManager_createEventQueue(sensorManager, looper, LOOPER_ID, NULL, NULL);

    ASensorEventQueue_enableSensor(queue, accelerometerSensor);
    ASensorEventQueue_setEventRate(queue, accelerometerSensor, (1000L/SAMP_PER_SEC)*1000); 

    int ident;//identifier 
    int events;
    while (1) {
        while ((ident=ALooper_pollAll(-1, NULL, &events, NULL) >= 0)) {
            // If a sensor has data, process it now.
            if (ident == LOOPER_ID) {
                ASensorEvent event;
                while (ASensorEventQueue_getEvents(queue, &event, 1) > 0) {
                    LOGI("aaaaaaa accelerometer X = %f y = %f z=%f ", event.acceleration.x, event.acceleration.y, event.acceleration.z);
                }
            }
        }
    }

}

到目前为止,我已经能够访问加速度计NativeActivity的,但有一些样品没有变化采取。甚至当我改变ASensorEventQueue_setEventRate足够大或足够小的加速度记录的静止约每秒60样本(每15 milisec 1个样本)

so far, i've been able to access accelerometer with NativeActivity, but there is no change with number sample had taken. even when i change ASensorEventQueue_setEventRate big enough or small enough the acceleration recorded still about 60 samples per second (1 samples per 15 milisec)

有没有在我的code任何错误?什么的,我忘了呢?

is there any mistakes in my code? or something that i forget with?

在此先感谢

推荐答案

我也尝试了一些事情传感器的采样率。我使用的是Galaxy Nexus的。 如果我只用了加速感应频率非常低(约40Hz的),但如果我使用加速感应加磁场和陀螺传感器的采样率每个传感器100Hz左右。 我也没有解释为什么会这样。另一个观察是,传递给ASensorEventQueue_setEventRate的值没有任何效果。取样速率始终是相同的。 该行为是完全一样SDK- code。

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.

下面是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;
}
阅读全文

相关推荐

最新文章