1

私は音叉アプリを作成しています。このアプリでは、iPhone をもう一方の手の手のひらに、または柔らかい面に軽くたたき、音叉を設定します。

そこで、それぞれの「バンプ」に含まれるエネルギーを検出したいと思います

(編集:大量のガンプを削除)

誰かがこれをクラックするのを手伝ってくれますか?

4

3 に答える 3

4

freenode の #math チャンネル (Igor に感謝) のウィザードの 1 人のおかげで、私は非常に優れた実用的なソリューションを手に入れました。

標準メソッドを使用して、可能な最大周波数 (100Hz) でコールバックを起動します。これには、瞬間的な加速度 x、y、z 値が含まれます。

良いコードは常にそれ自体で語るべきです。

typedef 
struct {
    double x,y,z;
}
vec_d3;

#define RECENT_COUNT 10

#define SMOOTH_IP( x, x_new, fac )  x  =  fac * x  +  ( 1. - fac ) * x_new

- (void) accelerometer: (UIAccelerometer *) accelerometer 
          didAccelerate: (UIAcceleration *) acceleration 
{
    // smooth incoming acceleration values
    static vec_d3 smooth = { DOUBLE_EMPTY, 0, 0 };

    {
        if ( smooth.x == DOUBLE_EMPTY )
        {
            smooth.x = acceleration.x;
            smooth.y = acceleration.y;
            smooth.z = acceleration.z;

            return;
        }

        SMOOTH_IP( smooth.x, acceleration.x, 0.9 );
        SMOOTH_IP( smooth.y, acceleration.y, 0.9 );
        SMOOTH_IP( smooth.z, acceleration.z, 0.9 );
    }

    // keep track of last k smoothed acceleration values
    static vec_d3 recent[ RECENT_COUNT ];
    {
        static int ptr = 0;
        static BOOL gotEnoughData = NO;

        recent[ ptr ] = smooth;

        ptr++;
        if ( ptr == RECENT_COUNT )
        {
            ptr = 0;
            gotEnoughData = YES;
        }

        // return if array not filled yet
        if ( ! gotEnoughData )
            return;
    }

    // get the resultant variation in acceleration over the whole array
    double variation;
    {
        vec_d3 min = smooth, max = smooth;

        for ( int i=0; i < RECENT_COUNT; i++ )
        {
            min.x = MIN( min.x, recent[ i ].x );
            min.y = MIN( min.y, recent[ i ].y );
            min.z = MIN( min.z, recent[ i ].z );

            max.x = MAX( max.x, recent[ i ].x );
            max.y = MAX( max.y, recent[ i ].y );
            max.z = MAX( max.z, recent[ i ].z );
        }

        vec_d3 V = (vec_d3) 
        {
            .x = max.x - min.x,
            .y = max.y - min.y,
            .z = max.z - min.z
        };

        variation = sqrt(
                         V.x * V.x  +
                         V.y * V.y  +
                         V.z * V.z
                         );
    }

    // smooth it
    static double var_smoothed = DOUBLE_EMPTY;
    {
        if ( var_smoothed == DOUBLE_EMPTY )
        {
            var_smoothed = variation;
            return;
        }
        SMOOTH_IP( var_smoothed, variation, 0.9 );
    }


    // see if it's just passed a peak
    {
        static double varSmoothed_last = DOUBLE_EMPTY;
        if ( varSmoothed_last == DOUBLE_EMPTY )
        {
            varSmoothed_last = var_smoothed;
            return;
        }

        static double varSmoothed_preLast = DOUBLE_EMPTY;
        if ( varSmoothed_preLast == DOUBLE_EMPTY )
        {
            varSmoothed_preLast = varSmoothed_last;
            varSmoothed_last = var_smoothed;
            return;
        }

#define THRESHOLD_IMPULSE .15

        if ( varSmoothed_last > varSmoothed_preLast  
            &&  varSmoothed_last > var_smoothed  
            &&  varSmoothed_last > THRESHOLD_IMPULSE )
        {
            LOG ( @"PotPeak @ %f", varSmoothed_last );

            // hit a peak at imp_last
            [self peakedWithImpulse: varSmoothed_last ];
        }

        varSmoothed_preLast = varSmoothed_last;
        varSmoothed_last = var_smoothed;
    }
}
于 2011-07-10T15:55:00.873 に答える
3

まず、あなたが尋ねた質問:

A)キャリブレーションするだけです。立っている加速度は重力の安定した引っ張りであり、突然の偏差は何かにぶつかることによる加速度の追加です。また、ジャイロスコープによって報告された方向の変化を追跡する必要があります。これにより、重力による新しい方向への突然のシフトを無視できます。

B)加速度を積分して、速度の変化を取得します。電話の質量の2乗を2で割ったものが、(静止フレーム内の)エネルギーです。

C)これは基本的に解決できません。理論的には、ケースが柔軟な場合、衝撃による加速度は特徴的な形状のスパイク状の曲線として現れる傾向があるため、ピーク上にないポイントがいくつかある場合は、全体の形状を推定できます。 。しかし、デバイスが硬すぎて、サンプリングがまばらすぎるのではないかと思います。ハードウェアがあなたのために加速を統合しない限り、これについてあなたができることは何もありません、それは私が疑っています(私はiPhoneを知りません)。

しかし、とにかくエネルギーはおそらく使用するのに最適な手段ではありません。枕で叩くのと同じくらいのエネルギーをハンマーで叩くのと同じくらいのエネルギーを届けることができますが、音叉がそれほど大きく鳴るとは思わないでしょう。ピーク加速度の方が良いかもしれませんが、それでも加速度計からの良好なデータに依存しています。

マイクを使ってもらえますか?膝を叩いたときに聞こえる音を録音してみてください。通常の音にはない特徴を探してください。たとえば、大きな低周波振幅、広いスペクトル、おそらくは特徴的な共鳴などです。場合。それでも環境内の大きなノイズに少し反応するかもしれませんが、それは非常に現実的です。

于 2011-07-01T19:05:02.610 に答える
0

必要なのはカルマン フィルターです。そのフレーズをグーグルで検索してください。1 つについて書くことは、このようなインターネット フォーラムの範囲を超えています。カルマン フィルターに関する本や本、本があります。

問題の 1 つは、iPhone のインターフェイスが実際に必要なものに合わせて構築されていないことです。私の雇用主は、まさにこの問題のために、内部にアクセスしてマンジするために Apple と協力しなければなりませんでした。いいえ、彼らが何をしたか、またはプロジェクトが何であるかについて、私は多くを語ることはできません.

平らに保持したときの加速度計の読み取り値について: 1G を登録する必要があります。重力を感じる方法はありません。(ニュートンの視点: 重力シールドのようなものはありません。相対論的視点: 重力は架空の力です。) 加速度計は重力を感知していません。加速度計を押し上げている地球またはテーブルを感知しています。

于 2011-07-02T09:27:42.533 に答える