重複の可能性:
Android加速度計の精度(慣性航法)
次のコードを使用して距離を計算しています。 tnew
とanew
はarraylists
で、タイムスタンプとが含まれていますそれぞれ加速度。
double distance=0;
double init_vel=0;
long time_prev=tnew.next();
while(anew.hasNext())
{
float temp_acc=anew.next();
long temp_time=tnew.next();
interval=(temp_time-time_prev)/1000f; //milliseconds to seconds
double fin_vel=init_vel+(temp_acc*interval);
distance+=(init_vel*interval)+0.5f*temp_acc*interval*interval;
init_vel=fin_vel;
time_prev=temp_time;
}
コードに論理的な間違いはありますか?実際の長さよりもはるかに小さい値を取得しているためです。LogCat
の出力:
--------- beginning of /dev/log/system
--------- beginning of /dev/log/main
V/PhonetapeActivity( 8842): Sensor Listener Registered
V/PhonetapeActivity( 8842): Sensor Unregistered
V/PhonetapeActivity( 8842): No. of Iterations : 49
V/PhonetapeActivity( 8842): Value of acceleration : 3.5762787E-7
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665585965
V/PhonetapeActivity( 8842): Value of acceleration : -0.15275347
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586017
V/PhonetapeActivity( 8842): Value of acceleration : 0.15585232
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586077
V/PhonetapeActivity( 8842): Value of acceleration : 1.075269
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586138
V/PhonetapeActivity( 8842): Value of acceleration : 3.6529458
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586199
V/PhonetapeActivity( 8842): Value of acceleration : 9.645137
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586257
V/PhonetapeActivity( 8842): Value of acceleration : 17.022213
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586316
V/PhonetapeActivity( 8842): Value of acceleration : 9.721476
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586376
V/PhonetapeActivity( 8842): Value of acceleration : -18.729362
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586437
V/PhonetapeActivity( 8842): Value of acceleration : -22.868385
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586497
V/PhonetapeActivity( 8842): Value of acceleration : -16.777517
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586557
V/PhonetapeActivity( 8842): Value of acceleration : -7.0492268
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586617
V/PhonetapeActivity( 8842): Value of acceleration : -3.860828
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586677
V/PhonetapeActivity( 8842): Value of acceleration : 1.7244682
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586737
V/PhonetapeActivity( 8842): Value of acceleration : 5.0734243
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586797
V/PhonetapeActivity( 8842): Value of acceleration : 6.4193974
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586857
V/PhonetapeActivity( 8842): Value of acceleration : 2.739545
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586917
V/PhonetapeActivity( 8842): Value of acceleration : 5.559997
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665586977
V/PhonetapeActivity( 8842): Value of acceleration : 4.2290807
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587037
V/PhonetapeActivity( 8842): Value of acceleration : 5.0012918
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587097
V/PhonetapeActivity( 8842): Value of acceleration : 5.9317436
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587157
V/PhonetapeActivity( 8842): Value of acceleration : 5.20226
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587217
V/PhonetapeActivity( 8842): Value of acceleration : 7.1381693
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587276
V/PhonetapeActivity( 8842): Value of acceleration : 7.6460614
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587337
V/PhonetapeActivity( 8842): Value of acceleration : 5.566694
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587396
V/PhonetapeActivity( 8842): Value of acceleration : 3.355657
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587457
V/PhonetapeActivity( 8842): Value of acceleration : 1.8876343
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587517
V/PhonetapeActivity( 8842): Value of acceleration : -0.8815446
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587577
V/PhonetapeActivity( 8842): Value of acceleration : -0.9595623
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587646
V/PhonetapeActivity( 8842): Value of acceleration : -4.233544
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587697
V/PhonetapeActivity( 8842): Value of acceleration : -1.9580669
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587765
V/PhonetapeActivity( 8842): Value of acceleration : -1.4569702
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587822
V/PhonetapeActivity( 8842): Value of acceleration : -0.6058636
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587876
V/PhonetapeActivity( 8842): Value of acceleration : -0.21207428
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587937
V/PhonetapeActivity( 8842): Value of acceleration : 0.5068469
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665587997
V/PhonetapeActivity( 8842): Value of acceleration : 5.614555
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588057
V/PhonetapeActivity( 8842): Value of acceleration : -4.5297813
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588122
V/PhonetapeActivity( 8842): Value of acceleration : -0.29250193
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588178
V/PhonetapeActivity( 8842): Value of acceleration : -2.4922757
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588237
V/PhonetapeActivity( 8842): Value of acceleration : -1.7652755
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588297
V/PhonetapeActivity( 8842): Value of acceleration : -2.3279366
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588357
V/PhonetapeActivity( 8842): Value of acceleration : -1.8127642
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588419
V/PhonetapeActivity( 8842): Value of acceleration : -1.956768
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588477
V/PhonetapeActivity( 8842): Value of acceleration : -0.8337221
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588537
V/PhonetapeActivity( 8842): Value of acceleration : -0.24841261
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588601
V/PhonetapeActivity( 8842): Value of acceleration : 0.23997736
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588657
V/PhonetapeActivity( 8842): Value of acceleration : 0.14441395
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588723
V/PhonetapeActivity( 8842): Value of acceleration : 0.23150349
V/PhonetapeActivity( 8842): Value of timestamp(milli) : 1350665588777
V/PhonetapeActivity( 8842): 1st while loop ended
V/PhonetapeActivity( 8842): 2nd while loop ended
V/PhonetapeActivity( 8842): Avg value : 0.4006781578063965
V/PhonetapeActivity( 8842): Max Value : 17.022213
V/PhonetapeActivity( 8842): Min Value : -22.868385
V/PhonetapeActivity( 8842): Standard Deviation : -0.0031174493
V/PhonetapeActivity( 8842): 3rd while loop started
V/PhonetapeActivity( 8842): startpos=3 endpos=8
V/PhonetapeActivity( 8842): acceleration=0.1558523178100586 interval=0.061000000685453415
V/PhonetapeActivity( 8842): distance=5.799264876044276E-4
V/PhonetapeActivity( 8842): next init velocity=0.009506991493243078
V/PhonetapeActivity( 8842): acceleration=1.0752689838409424 interval=0.061000000685453415
V/PhonetapeActivity( 8842): distance=0.005160928954000712
V/PhonetapeActivity( 8842): next init velocity=0.07509840024458736
V/PhonetapeActivity( 8842): acceleration=3.6529457569122314 interval=0.057999998331069946
V/PhonetapeActivity( 8842): distance=0.021805144861910285
V/PhonetapeActivity( 8842): next init velocity=0.2869692480489858
V/PhonetapeActivity( 8842): acceleration=9.645136833190918 interval=0.05900000035762787
V/PhonetapeActivity( 8842): distance=0.07231105232279186
V/PhonetapeActivity( 8842): next init velocity=0.8560323246566197
V/PhonetapeActivity( 8842): acceleration=17.022212982177734 interval=0.05999999865889549
V/PhonetapeActivity( 8842): distance=0.18495295465057213
V/PhonetapeActivity( 8842): next init velocity=1.8773650807587172
V/PhonetapeActivity( 8842): 3rd while loop ended
V/PhonetapeActivity( 8842): final distance=0.18495295465057213
V/PhonetapeActivity( 8842): values of acceleration, timestamp, distance, start_time and calibrating reset
logcatを観察する場合、最初に49の加速度の値とそれぞれのタイムスタンプをミリ秒単位で繰り返します。次に、平均、合計、最大、最小などがあります。
次に、startpos=3
とendpos=8
がある場合。これは反復回数の範囲です。距離の計算に使用しています。つまり、反復3から8までの加速度とタイムスタンプの値のみを使用しています。
これは、加速度の上昇からまでの距離計算の開始を検出したためです。反対方向への突然の変化。 3〜8の値がロジックに適合していることがわかります。 3からは加速度がかなり上昇し、8を過ぎると急激に減少します。
加速度計は非常に正確ですが推測航法が苦手です。ジャイロスコープはそれが得意ですが、時間の経過とともに「ドリフト」します。 「センサーフュージョン」は、アクセル/ジャイロデータを組み合わせて使用し、一方の欠陥を他方を使用して修正するプロセスです。 AFAIR、「センサーフュージョン」はGalaxyAceでは有効になっていません。 _LINEAR_ACCELERATION
_はACCELEROMETER
-重力成分に他なりません。ジャイロスコープのないデバイスでは、定義上、加速とジャイロが必要な融合は不可能です。
加速度計のデータには、9.8の重力成分が含まれています。これは、加速度計データの2つの連続するサンプル間の差を単純に決定することによって除外されます。これにより、_LINEAR_ACCELERATION
_データが得られます。
実際の内部コードについては、これを確認してください。
frameworks/base/services/sensorservice/LinearAccelerationSensor.cpp
関数LinearAccelerationSensor::process()
は上記のファイルで重要です。
また、上記のリンクやビデオで説明されているフィルタリング/平均化などの基本的な操作は、アプリで取得した加速度データに対して実行する必要があります。この方法で取得された処理値は、生の値よりも優れています(ただし、センサーフュージョンがデバイスに存在する場合に取得された値ほど良くはありません)。これらを使用して、速度と位置をより正確に計算できます。
とは言うものの、1秒間に16サンプル(@ poll-rate = 60ms)は、それ自体では比較的不正確です。 _SENSOR_DELAY_FASTEST
_を使用してsensorEventListner
を登録して、デバイスで取得できるサンプルの最大数を確認することをお勧めします。
また、電話の加速度計は特定の最大感度(通常は-/ + 2/4/8 G範囲)にクランプされていることに注意してください。通常のウォーキング/ランニングはこれらの範囲で動作する可能性がありますが、加速の突然の衝動(たとえば自転車)は確実にMAXに固定され、推測航法で同期が失われます。これは、-/ + MAXに非常に近いサンプルの数に注目することで確認できます。 -/ + MAXのサンプルが多いということは、実際の位置との同期が確実に失われていることを意味します。
私が最初にチェックするのはあなたの時間間隔です。正しく変換されているかどうかはわかりません。タイムスタンプは次のようにリストされます。
public long timestampイベントが発生したナノ秒単位の時間
したがって、ドキュメントでは、変換は1000ではなく10億で割ることによって行われることがわかります。
float dT = (event.timestamp - timestamp) / 1000000000.0f;
timestamp = event.timestamp;
とはいえ、変更すると値が縮小するだけだと思いますが、実際の距離を計算するには、ユニットを監視する必要があります。
次に、これらのことについて読むとき、人々は常に、実際の線形測定に関して意味をなすために、各読み取りの初期位置を知る必要がある方法について話します。完全な加速度ではなく、瞬間的な加速度または加速度の変化に基づいて、後続の各測定の積分を行う以前の加速度を追跡しているのがわかりません。
次のようなものを試してください。
final int X = 0;
double distance[];
double init_vel[];
double total_Accel[];
void dblIntegrate(SensorEvent event){
double data[] = new double[3];
for(int i = 0; i < event.lenght; i++){
data[i] = (double)event[i];
total_Accel[i] += data[i];
vel[i] = init_vel[i] + (total_Accel[i] * dt);
init_vel[i] = vel[i];
....rinse and repeate to get distance
(not using the accel data of course)
}
}
私はあなたがこれを理解していることを理解していますが、他の誰かがこれを読んでいる=> dblIntegrate()を呼び出すたびにカウント変数total_Accelまたはinit_velを再インスタンス化することはできないことを覚えておいてください。
正しく実行している場合は、デバイスを移動するたびに、total_Accelがゼロから最大値になり、その後ゼロに戻るはずです。これは、デバイスが任意の方向に移動するたびに、等しい部分の正と負の加速度を追加することを意味します。
これは、デバイスが静止状態から静止状態に移行するために、total_accelerationがゼロから最大pos/neg値に戻り、ゼロから反対の最大値に戻るため、正しく理解するのが最も難しい加速度の特性であると思います。ゼロに戻ります。
たとえば、電話をテーブルの上に仰向けに置いて、下を胸に向けて1メートル右に動かすと、次のようになります。
total_Accel = 0.0(0メートル)
total_Accel = 0.5
total_Accel = 1.0
total_Accel = 1.5(約0.25メートル)
total_Accel = 1.0
total_Accel = 0.5
total_Accel = 0.0(accelが完全に分散されている場合、.5メートル)
total_Accel = -0.5
total_Accel = -1.0
total_Accel = -1.5(約0.75メートル)
total_Accel = -1.0
total_Accel = -0.5
total_Accel = 0.0(1メートル)
この例では、加速度の変化を単純に2重積分しても、速度/変位の実際の変化が得られない理由がわかります。
とにかくそう願っています。これを書くのに思ったよりもずっと時間がかかったからです! :)
これはあなたの質問への答えです:
以前の加速度を追跡する必要がある理由。 onSensorChanged(MotionEvent event){}は、加速度に変化があったときに呼び出されます。これは、加速度の変化ではなく、新しい加速度を提供します。
簡単に言うと、初期条件(以前の加速度の合計)を含めずに読み取り値を積分すると、すべての情報が含まれていない値になってしまいます。さらに、あなたがより多くの情報を失うので、あなたが長く行くほど、あなたの価値は実際の価値からより遠くなります。
加速度、速度、変位の説明は必要ないと思います(そのための場所ではありません)ので、上記の例を拡張して説明できるかもしれません。
底を胸に向けてテーブルの上に仰向けになっている電話を右に任意の距離移動して停止します。データを見ると、次のようなものが得られます。もちろん、実際の数は大きく異なりますが、それらの符号は同じであり、比率は同じようなものですが、予想どおりにピークよりも小さくなります(壁などで銃から発射した場合を除く) 。:
時間...........加速度の読み取り...........総加速度........総速度
00ms .............. 0.0 ...................... 0.0 ..... .. ................. 0.000。。
10ms .............. 0.5 ...................... 0.5.........。 ............ 0.005 m/s ..
20ms .............. 0.5 ...................... 1.0.........。 ............ 0.015 m/s ..
30ms ............. 0.5 ...................... 1.5..........。 ........... 0.030 m/s ..
40ms ............. -0.5 ...................... 1.0.........。 ............ 0.040 m/s ..
50ms ............. -0.5 ...................... 0.5.........。 ............ 0.045 m/s ..
60ms ............. -0.5 ...................... 0.0.........。 ............ 0.045 m/s ..
70ms ............. -0.5 .....................- 0.5.........。 ............ 0.040 m/s ..
80ms ............. -0.5 .....................- 1.0.........。 ............ 0.030 m/s ..
90ms ............. -0.5 .....................- 1.5.........。 ............ 0.015 m/s ..
100ms ............. 0.5 ..........................- 1.0..........。 ........... 0.005 m/s ..
110ms ............. 0.5 ..........................- 0.5..........。 ........... 0.000 m/s ..
120ms ............. 0.5 ...................... 0.0..........。 ........... 0.000 m/s ..
総加速度を追跡しない場合、総速度は上記の総加速度とマークされた列になることがわかります。つまり、携帯電話は常にx軸の正の方向に移動しますが、移動の後半では速度が負(後方に移動)になります。
加速度や加速度計の背後にあるメカニズムを説明していなくても、これが私のケースを証明することを願っています。
加速度計がどのように機能するかを調べたい場合、それらはMEMSタイプのセンサーであり、加速度の力を測定するために加重端を備えた吊り下げられた片持ち梁を使用していると思います。