⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sensors_trout.c

📁 Android平台上Midware层源代码合集
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright 2008, The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * *     http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */#define LOG_TAG "Sensors"#include <hardware/sensors.h>#include <fcntl.h>#include <errno.h>#include <dirent.h>#include <math.h>#include <poll.h>#include <linux/input.h>#include <linux/akm8976.h>#include <cutils/log.h>#include <cutils/atomic.h>/*****************************************************************************/#define AKM_DEVICE_NAME             "/dev/akm8976_aot"#define SUPPORTED_SENSORS  (SENSORS_ORIENTATION  |  \                            SENSORS_ACCELERATION |  \                            SENSORS_MAGNETIC_FIELD | \                            SENSORS_ORIENTATION_RAW)// sensor IDs must be a power of two and// must match values in SensorManager.java#define EVENT_TYPE_ACCEL_X          ABS_X#define EVENT_TYPE_ACCEL_Y          ABS_Z#define EVENT_TYPE_ACCEL_Z          ABS_Y#define EVENT_TYPE_ACCEL_STATUS     ABS_WHEEL#define EVENT_TYPE_YAW              ABS_RX#define EVENT_TYPE_PITCH            ABS_RY#define EVENT_TYPE_ROLL             ABS_RZ#define EVENT_TYPE_ORIENT_STATUS    ABS_RUDDER#define EVENT_TYPE_MAGV_X           ABS_HAT0X#define EVENT_TYPE_MAGV_Y           ABS_HAT0Y#define EVENT_TYPE_MAGV_Z           ABS_BRAKE#define EVENT_TYPE_TEMPERATURE      ABS_THROTTLE#define EVENT_TYPE_STEP_COUNT       ABS_GAS// 720 LSG = 1G#define LSG                         (720.0f)// conversion of acceleration data to SI units (m/s^2)#define CONVERT_A                   (GRAVITY_EARTH / LSG)#define CONVERT_A_X                 (CONVERT_A)#define CONVERT_A_Y                 (-CONVERT_A)#define CONVERT_A_Z                 (CONVERT_A)// conversion of magnetic data to uT units#define CONVERT_M                   (1.0f/16.0f)#define CONVERT_M_X                 (CONVERT_M)#define CONVERT_M_Y                 (CONVERT_M)#define CONVERT_M_Z                 (CONVERT_M)#define SENSOR_STATE_MASK           (0x7FFF)/*****************************************************************************/static int sAkmFD = -1;static uint32_t sActiveSensors = 0;/*****************************************************************************//* * We use a Least Mean Squares filter to smooth out the output of the yaw * sensor. * * The goal is to estimate the output of the sensor based on previous acquired * samples. * * We approximate the input by a line with the equation: *      Z(t) = a * t + b * * We use the Least Mean Squares method to calculate a and b so that the * distance between the line and the measured COUNT inputs Z(t) is minimal. * * In practice we only need to compute b, which is the value we're looking for * (it's the estimated Z at t=0). However, to improve the latency a little bit, * we're going to discard a certain number of samples that are too far from * the estimated line and compute b again with the new (trimmed down) samples. * * notes: * 'a' is the slope of the line, and physicaly represent how fast the input * is changing. In our case, how fast the yaw is changing, that is, how fast the * user is spinning the device (in degre / nanosecond). This value should be * zero when the device is not moving. * * The minimum distance between the line and the samples (which we are not * explicitely computing here), is an indication of how bad the samples are * and gives an idea of the "quality" of the estimation (well, really of the * sensor values). * *//* sensor rate in me */#define SENSORS_RATE_MS     20/* timeout (constant value) in ms */#define SENSORS_TIMEOUT_MS  100/* # of samples to look at in the past for filtering */#define COUNT               24/* prediction ratio */#define PREDICTION_RATIO    (1.0f/3.0f)/* prediction time in seconds (>=0) */#define PREDICTION_TIME     ((SENSORS_RATE_MS*COUNT/1000.0f)*PREDICTION_RATIO)static float mV[COUNT*2];static float mT[COUNT*2];static int mIndex;static inlinefloat normalize(float x){    x *= (1.0f / 360.0f);    if (fabsf(x) >= 0.5f)        x = x - ceilf(x + 0.5f) + 1.0f;    if (x < 0)        x += 1.0f;    x *= 360.0f;    return x;}static void LMSInit(void){    memset(mV, 0, sizeof(mV));    memset(mT, 0, sizeof(mT));    mIndex = COUNT;}static float LMSFilter(int64_t time, int v){    const float ns = 1.0f / 1000000000.0f;    const float t = time*ns;    float v1 = mV[mIndex];    if ((v-v1) > 180) {        v -= 360;    } else if ((v1-v) > 180) {        v += 360;    }    /* Manage the circular buffer, we write the data twice spaced by COUNT     * values, so that we don't have to memcpy() the array when it's full */    mIndex++;    if (mIndex >= COUNT*2)        mIndex = COUNT;    mV[mIndex] = v;    mT[mIndex] = t;    mV[mIndex-COUNT] = v;    mT[mIndex-COUNT] = t;    float A, B, C, D, E;    float a, b;    int i;    A = B = C = D = E = 0;    for (i=0 ; i<COUNT-1 ; i++) {        const int j = mIndex - 1 - i;        const float Z = mV[j];        const float T = 0.5f*(mT[j] + mT[j+1]) - t;        float dT = mT[j] - mT[j+1];        dT *= dT;        A += Z*dT;        B += T*(T*dT);        C +=   (T*dT);        D += Z*(T*dT);        E += dT;    }    b = (A*B + C*D) / (E*B + C*C);    a = (E*b - A) / C;    float f = b + PREDICTION_TIME*a;    //LOGD("A=%f, B=%f, C=%f, D=%f, E=%f", A,B,C,D,E);    //LOGD("%lld  %d  %f  %f", time, v, f, a);    f = normalize(f);    return f;}/*****************************************************************************/static int open_input(){    /* scan all input drivers and look for "compass" */    int fd = -1;    const char *dirname = "/dev/input";    char devname[PATH_MAX];    char *filename;    DIR *dir;    struct dirent *de;    dir = opendir(dirname);    if(dir == NULL)        return -1;    strcpy(devname, dirname);    filename = devname + strlen(devname);    *filename++ = '/';    while((de = readdir(dir))) {        if(de->d_name[0] == '.' &&           (de->d_name[1] == '\0' ||            (de->d_name[1] == '.' && de->d_name[2] == '\0')))            continue;        strcpy(filename, de->d_name);        fd = open(devname, O_RDONLY);        if (fd>=0) {            char name[80];            if (ioctl(fd, EVIOCGNAME(sizeof(name) - 1), &name) < 1) {                name[0] = '\0';            }            if (!strcmp(name, "compass")) {                LOGD("using %s (name=%s)", devname, name);                break;            }            close(fd);            fd = -1;        }    }    closedir(dir);    if (fd < 0) {        LOGE("Couldn't find or open 'compass' driver (%s)", strerror(errno));    }    return fd;}static int open_akm(){    if (sAkmFD <= 0) {        sAkmFD = open(AKM_DEVICE_NAME, O_RDONLY);        LOGD("%s, fd=%d", __PRETTY_FUNCTION__, sAkmFD);        LOGE_IF(sAkmFD<0, "Couldn't open %s (%s)",                AKM_DEVICE_NAME, strerror(errno));        if (sAkmFD >= 0) {            sActiveSensors = 0;        }    }    return sAkmFD;}static void close_akm(){    if (sAkmFD > 0) {        LOGD("%s, fd=%d", __PRETTY_FUNCTION__, sAkmFD);        close(sAkmFD);        sAkmFD = -1;    }}static void enable_disable(int fd, uint32_t sensors, uint32_t mask){    if (fd<0) return;    short flags;        if (sensors & SENSORS_ORIENTATION_RAW) {        sensors |= SENSORS_ORIENTATION;        mask |= SENSORS_ORIENTATION;    } else if (mask & SENSORS_ORIENTATION_RAW) {        mask |= SENSORS_ORIENTATION;    }        if (mask & SENSORS_ORIENTATION) {        flags = (sensors & SENSORS_ORIENTATION) ? 1 : 0;        if (ioctl(fd, ECS_IOCTL_APP_SET_MFLAG, &flags) < 0) {            LOGE("ECS_IOCTL_APP_SET_MFLAG error (%s)", strerror(errno));        }    }    if (mask & SENSORS_ACCELERATION) {        flags = (sensors & SENSORS_ACCELERATION) ? 1 : 0;        if (ioctl(fd, ECS_IOCTL_APP_SET_AFLAG, &flags) < 0) {            LOGE("ECS_IOCTL_APP_SET_AFLAG error (%s)", strerror(errno));        }    }    if (mask & SENSORS_TEMPERATURE) {        flags = (sensors & SENSORS_TEMPERATURE) ? 1 : 0;        if (ioctl(fd, ECS_IOCTL_APP_SET_TFLAG, &flags) < 0) {            LOGE("ECS_IOCTL_APP_SET_TFLAG error (%s)", strerror(errno));        }    }#ifdef ECS_IOCTL_APP_SET_MVFLAG    if (mask & SENSORS_MAGNETIC_FIELD) {        flags = (sensors & SENSORS_MAGNETIC_FIELD) ? 1 : 0;        if (ioctl(fd, ECS_IOCTL_APP_SET_MVFLAG, &flags) < 0) {            LOGE("ECS_IOCTL_APP_SET_MVFLAG error (%s)", strerror(errno));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -