7

以下のコードは正常に動作しているようです。

    // GPS Reader
    // Criteria
    Criteria criteria = new Criteria();
    //criteria.setAccuracy(Criteria.ACCURACY_COARSE); // Used when we can't get a GPS Fix
    criteria.setAccuracy(Criteria.ACCURACY_FINE); // Used when we can get a GPS Fix

    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setCostAllowed(true);
    criteria.setPowerRequirement(Criteria.POWER_LOW);

    LocationListener locationListener = new MyLocationListener();
    LocationManager lm = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 0, 0,
            locationListener);

ただし、Google マップで収集したデータをグラフ化すると、GPS 座標が非常に散らばっている場合や、見つけたばかりの歩いている道に沿って進んでいると、突然 1 マイル離れた地点に移動する場合があります。そして戻る。これを修正する方法はありますか?ある種の精度チェックだと思いますか?

更新

基本的に私の問題は例として次のようになります - GPS Jitter

更新 2 :

私はこれを報奨金にしないことを考えましたが、ここで何が起こっているのかを完全に理解し、私のアプローチが過剰ではないかどうかを確認したほうがよいと考えました. 3mの精度があるにもかかわらず、座標にジッターがあるという同じ問題がまだあります。これは、利用可能な衛星などに関係している可能性があります。わかりませんが、基本的には方法を理解しようとしていますこれらの他のすべてのアプリケーション、特に運動アプリは、同じ状況下でこれほどスムーズな読み取りを行うことができますか?

私は Quora を使用していて、これを見つけることができまし残念ながら、必要に応じてカルマンフィルターを使用できることを除いて、私の問題についてあまり洞察を得ることができませんでしたが、世の中のほとんどのアプリがこれを実装しているとは思えないため、複雑ではない手段が必要です。

とにかく、仲間の開発者が彼らが何をしているのかをいくつかの疑似コードで共有したいのであれば、それは大歓迎です. 私がカルマンにこだわっているなら、私はそうですが、アルゴリズムを実装するのがより簡単でなければならないと確信しており、それらとそれらを実装する方法を学びたいと思っています。

コンテキスト: これはモバイル歩行者アプリケーションです。

関連する SO の質問 から情報を収集しようとしまし た 一連の GPS 座標から滑らかな曲線を作成します 滑らか な gps データ: これは良いスタートでしたが、最小二乗法を適切に取得するためにどの擬似コードを実装する必要があるかわかりません適切に動作して、スプライン GPS データを取得し、それを Google マップなどで表示して、正しく実行したことを確認できます。問題は、これが私が扱っていた一般的な X および Y データであり、GEO 座標ではない場合、matlab テストで何かを書き込んで続行できることだと思います。

アップデート 3

受信しているめちゃくちゃな GPS データの画像 https://www.dropbox.com/s/ilsf8snao2no65e/gpsdata2.png

コード https://gist.github.com/4505688

4

4 に答える 4

6

GPS データ自体はエラーが発生しやすい傾向にあります。すべての LocationManager が正しく設定されていても (そして、正しく設定されているように見えますが)、場所にときどきジッターが見られることがあります。

正確さ

注意すべきことの 1 つは、GPS 精度は、受信した GPS 信号が与えられた場合の計算の精度を推定するだけであるということです。系統誤差は良好な精度数値 (<10m) を提供しますが、それでも大きな位置誤差を表します。これが、精度が非常に高くてもジッターが表示される理由です。精度測定は、非常に大きな誤差 (>100m) を取り除くのに適していますが、より低いレベルでは、計算が収束したことを示すだけです。

フィルタリング

フィルタリングは、多くのことと同様に、できる限り少ない場合に最適です。精度フィルターは大きなエラーを除去できるはずであり、最終的に適切なしきい値が得られれば、スムーズなデータを取得できる可能性があります。

実行中のアプリの位置の変化にしきい値を設定すると、利点が得られる場合もあります。たとえば、ランナーは時間の経過とともに特定の距離しかカバーできず、上限のしきい値 (Usain Bolt Cutoff) を設定することで、悪い点を取り除くことができるはずです。それに関する問題は、最初のポイントがエラーである場合、他のすべてのポイントを削除してしまうことです。

カルマン フィルター

カルマン フィルターは優れたソリューションであり、私が取り組んでいるナビゲーション アプリに実装しました。結果は非常に合理的であり、GPS が悪い場合や利用できない場合でも、推測航法を制限することができます. 残念ながら、ソース コードを共有することはできませんが、その方法を選択する場合は、簡単なガイダンスを提供できます。最良の結果は、加速度と速度を計算し、それを使用して位置を推定する 6 DoF フィルターから得られました。これは最も単純な解決策ではありませんが、良い結果が得られています。

最小二乗

カルマン フィルターは、位置をフィルター処理するためにリアルタイムで使用できるため、優れています。独自の状態を追跡するため、古い場所を保存する必要はありません。しかし一方で、ルートを後処理したい場合は、最小二乗法が最適な方法です。(カルマンは LSQ 式から導出されます)。後処理はあまりしませんが、古い教科書を掘り起こすことができると思います。ただし、理論は同じはずです。

ほとんどの GPS デバイスは非常に優れており、私が見たすべてのテストから、あなたの例で見られるようなジッターはあまり見られません。ただし、1 つの大きな利点であり、私がカルマン フィルターを実装した理由は、移動距離と速度の計算がはるかに正確であることです。

于 2013-01-16T18:59:50.650 に答える
4

あなたが得ているのは、あなたの基準が最高のプロバイダーを として識別しているためですNETWORK_PROVIDER。これはあなたの場所を特定するのではなく、その範囲があなたのデバイスをカバーする携帯電話基地局の場所を提供します.そのため、建物の外にいるときはGPS_PROVIDER、地理的位置の正確な精度を得るために使用することをお勧めします.なぜ散らばった座標を得るのですかデバイスが別のセルタワーの範囲に入るため、ロケーションジャンプが発生します. 直接使用することGPS_PROVIDERは、これまでで最高のソリューションです。

于 2013-01-10T08:12:12.860 に答える
2

Reto Meier のこの記事 (コード付き) を確認してください。考えるための多くの情報を提供してくれるはずです。少なくとも最小距離と時間パラメータを設定する必要があります。

lm.requestLocationUpdates(lm.getBestProvider(criteria, true), 5000, 20,
        locationListener);

また、複数のプロバイダーを組み合わせて、現時点で最適な座標を取得することもできます。幸運を!

于 2013-01-10T08:20:37.853 に答える
2

A simple approach is to throw away any old or inaccurate data and keep a running average of the longitude and latitude.

private static final long WILDLY_OUT = 15;
private static final long TOO_OLD = 30000;
private static final long NO_SAMPLES = 5;

double lastLocationTime;

double calclongitude(Location location, double oldLongitude) {
    double newLongitude = oldLongitude;

    if (location.getAccuracy() < WILDLY_OUT) {
        newLongitude = (NO_SAMPLES * oldLongitude + location
                .getLongitude()) / (NO_SAMPLES + 1);
        lastLocationTime = System.currentTimeMillis();
    }

    if (lastLocationTime > TOO_OLD) {
        newLongitude = location.getLongitude();
    }

    return newLongitude;
}

And do the same for latitude.

于 2013-01-17T01:21:10.660 に答える