Доступ к датчикам Android через NDK sensor.h - PullRequest
0 голосов
/ 26 мая 2020

Я использую NDK sensor.h для доступа к данным акселерометра и гироскопа. Я использую следующий код для чтения около 100 выборок в секунду:

bool ASensorController::imuStartUpdate() {
    // Get a reference to the sensor manager
    ASensorManager *sensorManager = ASensorManager_getInstance();
    if ( sensorManager == NULL ) {
        LOGI( "sensorManager == NULL" );
        return false;
    }

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

    // Creates a new sensor event queue and associate it with a looper
    aSensorEventQueue = ASensorManager_createEventQueue(sensorManager, looper,
                                                              LOOPER_ID_USER, ProcessASensorEventsCallback,
                                                              NULL);
    if ( aSensorEventQueue == NULL ) {
        LOGI( "aSensorEventQueue == NULL" );
        return false;
    }

    // Returns the default sensor for the given type
    const ASensor *accelerometer = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_ACCELEROMETER);
    if ( accelerometer == NULL ) {
        LOGI( "accelerometer == NULL" );
        return false;
    }

    const ASensor *gyroscope = ASensorManager_getDefaultSensor(sensorManager, ASENSOR_TYPE_GYROSCOPE);
    if ( gyroscope == NULL ) {
        LOGI( " gyroscope == NULL " );
        return false;
    }


    // Enable the selected sensor at default sampling rate
    auto status = ASensorEventQueue_enableSensor( aSensorEventQueue, accelerometer );
    if ( status < 0 ) {
        LOGI( "ASensorEventQueue_enableSensor failed, accelerometer" );
        return false;
    }

    status = ASensorEventQueue_enableSensor( aSensorEventQueue, gyroscope );
    if ( status < 0 ) {
        LOGI( "ASensorEventQueue_enableSensor failed, gyroscope" );
        return false;
    }


    // Sets the delivery rate of events in microseconds for the given sensor
    // This function has to be called after ASensorEventQueue_enableSensor
    status = ASensorEventQueue_setEventRate( aSensorEventQueue, accelerometer, SENSOR_REFRESH_PERIOD_US );
    if ( status < 0 ) {
        LOGI( "ASensorEventQueue_setEventRate failed, accelerometer" );
        return false;
    }

    status = ASensorEventQueue_setEventRate( aSensorEventQueue, gyroscope, SENSOR_REFRESH_PERIOD_US );
    if ( status < 0 ) {
        LOGI( "ASensorEventQueue_setEventRate failed, gyroscope" );
        return false;
    }

    return true;
}

int ASensorController::ProcessASensorEventsCallback(int fd, int events, void* data) {
    ASensorEvent aSensorEvent;

    // Retrieve pending events in sensor event queue
    // Retrieve next available events from the queue to a specified event array
    while ( ASensorEventQueue_getEvents(aSensorEventQueue, &aSensorEvent, 1) > 0 ) {
        if ( aSensorEvent.type == ASENSOR_TYPE_GYROSCOPE ) {
            SENSOR_MSG gyr_msg;

            gyr_msg.header = aSensorEvent.timestamp;
            // in iOS and in Android the unit is rad/s
            gyr_msg.x = aSensorEvent.uncalibrated_gyro.x_uncalib; // latestGyro.rotationRate.x
            gyr_msg.y = aSensorEvent.uncalibrated_gyro.y_uncalib; // latestGyro.rotationRate.y
            gyr_msg.z = aSensorEvent.uncalibrated_gyro.z_uncalib; // latestGyro.rotationRate.z

            gyr_buf.push( gyr_msg );
        }
        else if ( aSensorEvent.type == ASENSOR_TYPE_ACCELEROMETER ) {
            SENSOR_MSG acc_msg;

            acc_msg.header = aSensorEvent.timestamp;
            // in iOS and in Android the unit is rad/s
            acc_msg.x = aSensorEvent.acceleration.x; // latestAcceleration.x
            acc_msg.y = aSensorEvent.acceleration.y; // latestAcceleration.y
            acc_msg.z = aSensorEvent.acceleration.z; // latestAcceleration.z

            acc_buf.push( acc_msg );
        }
    }
    //should return 1 to continue receiving callbacks, or 0 to unregister
    return 1;
}

вот в чем проблема, когда я запускаю это приложение, оно быстро умирает. Но после того, как я запустил приложение, которое считывает образцы датчиков с помощью java sensormanager, я снова открываю приложение с помощью c ++ NDK, оно работает нормально. Но почему? Есть ли проблемы с моим кодом?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...