5

3軸加速度計から角度を計算していますが、コンパイラにatanまたはatan2関数がありません。予約済みのメモリスロットがありますが、どのファイルにも見つからない関数を呼び出します。

私のコンパイラは、ARMCCコンパイラを実行しているKeil µVision4です。コンパイルにはmath.hファイルがありますが、関数はexternであり、存在しません。

  extern _ARMABI double atan2(double /*y*/, double /*x*/);

関数arctanが実装されているlibまたは関数を含めることができますか?または、加速度計から角度を計算するための代替機能はありますか?角度の完全な3軸キャリブレーションが必要です。

編集:事前に計算された値でいっぱいのテーブルを避けたいと思っていました。

4

4 に答える 4

10

次のコードは、有理近似を使用して、[0 1)間隔に正規化されたアークタンジェントを取得します(結果にPi / 2を掛けて、実際のアークタンジェントを取得できます)。

normalized_atan(x)〜(bx + x ^ 2)/(1 + 2 bx + x ^ 2)

ここで、b = 0.596227

最大誤差は0.1620ºです

#include <stdint.h>
#include <math.h>

// Approximates atan(x) normalized to the [-1,1] range
// with a maximum error of 0.1620 degrees.

float normalized_atan( float x )
{
    static const uint32_t sign_mask = 0x80000000;
    static const float b = 0.596227f;

    // Extract the sign bit
    uint32_t ux_s  = sign_mask & (uint32_t &)x;

    // Calculate the arctangent in the first quadrant
    float bx_a = ::fabs( b * x );
    float num = bx_a + x * x;
    float atan_1q = num / ( 1.f + bx_a + num );

    // Restore the sign bit
    uint32_t atan_2q = ux_s | (uint32_t &)atan_1q;
    return (float &)atan_2q;
}

// Approximates atan2(y, x) normalized to the [0,4) range
// with a maximum error of 0.1620 degrees

float normalized_atan2( float y, float x )
{
    static const uint32_t sign_mask = 0x80000000;
    static const float b = 0.596227f;

    // Extract the sign bits
    uint32_t ux_s  = sign_mask & (uint32_t &)x;
    uint32_t uy_s  = sign_mask & (uint32_t &)y;

    // Determine the quadrant offset
    float q = (float)( ( ~ux_s & uy_s ) >> 29 | ux_s >> 30 ); 

    // Calculate the arctangent in the first quadrant
    float bxy_a = ::fabs( b * x * y );
    float num = bxy_a + y * y;
    float atan_1q =  num / ( x * x + bxy_a + num );

    // Translate it to the proper quadrant
    uint32_t uatan_2q = (ux_s ^ uy_s) | (uint32_t &)atan_1q;
    return q + (float &)uatan_2q;
} 

より高い精度が必要な場合は、3次の有理関数があります。

normalized_atan(x)〜(cx + x ^ 2 + x ^ 3)/(1 +(c + 1)x +(c + 1)x ^ 2 + x ^ 3)

ここで、c =(1 + sqrt(17))/ 8

0.00811ºの最大近似誤差があります

于 2012-12-31T11:29:18.540 に答える
8

独自の実装はそれほど難しくありませんarctan2この式を使用するように変換arctan2します。そして、この無限級数を使用して計算できます。この無限級数の十分な数の項を合計すると、ライブラリ関数の機能に非常に近くなります。arctanarctanarctan2

これは、参照として使用できる同様の実装の1つです。exp()

于 2012-08-13T08:51:03.590 に答える
4

ここにオープンソースのatan実装があります

于 2012-08-13T11:25:43.140 に答える
0

数学関数(または存在する場合はHWFPUへのスタブ)の実際の実装は、libmにある必要があります。GCCでは、これはコンパイラーに渡すことで示され-lmますが、特定のツールでどのように行われるかはわかりません。

于 2012-08-13T08:33:52.620 に答える