سؤال

كيف يمكنني تصفية الضوضاء من التسارع البيانات في أندرويد ؟ وأود أن إنشاء تمريرة عالية مرشح بلدي عينة البيانات بحيث لا يمكن القضاء على التردد المنخفض مكونات والتركيز على وتيرة عالية من المكونات.لقد قرأت أن مرشح كالمان قد يكون أفضل مرشح لهذا, ولكن كيف يمكنني دمج أو استخدام هذا الأسلوب في التطبيق والتي سوف وكتب معظمها في الروبوت جافا ؟ أو يمكن القيام به في المقام الأول ؟ أو من خلال Android NDK?هل هناك أي فرصة أن هذا يمكن القيام به في الوقت الحقيقي ؟

أي فكرة سوف تكون محل تقدير كبير.شكرا لك!

هل كانت مفيدة؟

المحلول

وعينات من SDK أبل فعلا تنفيذ التصفية بطريقة أبسط وهو باستخدام التعلية:

//ramp-speed - play with this value until satisfied
const float kFilteringFactor = 0.1f;

//last result storage - keep definition outside of this function, eg. in wrapping object
float accel[3]; 

//acceleration.x,.y,.z is the input from the sensor

//result.x,.y,.z is the filtered result

//high-pass filter to eliminate gravity
accel[0] = acceleration.x * kFilteringFactor + accel[0] * (1.0f - kFilteringFactor);
accel[1] = acceleration.y * kFilteringFactor + accel[1] * (1.0f - kFilteringFactor);
accel[2] = acceleration.z * kFilteringFactor + accel[2] * (1.0f - kFilteringFactor);
result.x = acceleration.x - accel[0];
result.y = acceleration.y - accel[1];
result.z = acceleration.z - accel[2];

نصائح أخرى

وهنا هو رمز لالروبوت، مقتبسة من التفاح على التكيف عالية تمرير مرشح سبيل المثال. مجرد سد هذا في وتنفيذ onFilteredAccelerometerChanged ()

private static final boolean ADAPTIVE_ACCEL_FILTER = true;
float lastAccel[] = new float[3];
float accelFilter[] = new float[3];

public void onAccelerometerChanged(float accelX, float accelY, float accelZ) {
    // high pass filter
    float updateFreq = 30; // match this to your update speed
    float cutOffFreq = 0.9f;
    float RC = 1.0f / cutOffFreq;
    float dt = 1.0f / updateFreq;
    float filterConstant = RC / (dt + RC);
    float alpha = filterConstant; 
    float kAccelerometerMinStep = 0.033f;
    float kAccelerometerNoiseAttenuation = 3.0f;

    if(ADAPTIVE_ACCEL_FILTER)
    {
        float d = clamp(Math.abs(norm(accelFilter[0], accelFilter[1], accelFilter[2]) - norm(accelX, accelY, accelZ)) / kAccelerometerMinStep - 1.0f, 0.0f, 1.0f);
        alpha = d * filterConstant / kAccelerometerNoiseAttenuation + (1.0f - d) * filterConstant;
    }

    accelFilter[0] = (float) (alpha * (accelFilter[0] + accelX - lastAccel[0]));
    accelFilter[1] = (float) (alpha * (accelFilter[1] + accelY - lastAccel[1]));
    accelFilter[2] = (float) (alpha * (accelFilter[2] + accelZ - lastAccel[2]));

    lastAccel[0] = accelX;
    lastAccel[1] = accelY;
    lastAccel[2] = accelZ;
    onFilteredAccelerometerChanged(accelFilter[0], accelFilter[1], accelFilter[2]);
}

لأولئك الذين يتساءلون ما المعيار () والمشبك () طرق القيام به في الجواب من rbgrn، يمكنك ان ترى لهم هنا: <الصورة> http://developer.apple.com/library /IOS/samplecode/AccelerometerGraph/Listings/AccelerometerGraph_AccelerometerFilter_m.html

double norm(double x, double y, double z)
{
    return Math.sqrt(x * x + y * y + z * z);
}

double clamp(double v, double min, double max)
{
    if(v > max)
        return max;
    else if(v < min)
        return min;
    else
        return v;
}

أتذكر أن يتم ذلك في أبل نموذج التعليمات البرمجية ل اي فون.دعونا نرى...

البحث عن AccelerometerFilter.ح / .م على جوجل (أو الاستيلاء أبل AccelerometerGraph عينة) و هذا الرابط: http://en.wikipedia.org/wiki/High-pass_filter (هذا ما أبل رمز على أساس).

هناك بعض الزائفة رمز في ويكي أيضا.ولكن الرياضيات بسيطة إلى حد ما ترجمة التعليمات البرمجية.

والمنظمة البحرية الدولية، وتصميم مرشح كالمان كما المحاولة الأولى هو الإفراط في تعقيد ما هو على الأرجح مشكلة بسيطة إلى حد ما. كنت أبدأ مع فلتر FIR بسيط، وفقط محاولة شيء أكثر تعقيدا عندما / إذا كنت قد اختبرت ذلك وجدت بدرجة معقولة من اليقين أنه لا يمكن أن توفر ما تريد. تخميني، ومع ذلك، هو أنها لن تكون قادرة على القيام بكل ما تحتاج إليه، ويفعل ذلك أكثر من ذلك بكثير بسهولة وكفاءة.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top