जीपीएस डेटा को सुचारू करें


145

मैं जीपीएस डेटा के साथ काम कर रहा हूं, हर दूसरे मूल्य प्राप्त कर रहा हूं और नक्शे पर वर्तमान स्थिति प्रदर्शित कर रहा हूं। समस्या यह है कि कभी-कभी (विशेष रूप से सटीकता कम होने पर) मान बहुत भिन्न होते हैं, जिससे वर्तमान स्थिति मानचित्र में दूर के बिंदुओं के बीच "कूद" जाती है।

मैं इससे बचने के लिए कुछ आसान पर्याप्त विधि के बारे में सोच रहा था। पहले विचार के रूप में, मैंने कुछ सीमा से परे सटीकता के साथ मूल्यों को त्यागने के बारे में सोचा, लेकिन मुझे लगता है कि कुछ और बेहतर तरीके हैं। सामान्य तरीके प्रोग्राम क्या करते हैं?


मैं "जीपीएस शोर" के बुरे प्रभावों को महसूस करता हूं जब गति और ढलान जैसे संबद्ध (व्युत्पन्न) मूल्यों की गणना करने की कोशिश कर रहा है, जो विशेष रूप से उच्च नमूना दर ट्रैकलॉग के लिए बहुत ही बंद हैं (क्योंकि समय में पूर्णांक [एक सेकंड] संकल्प है)।
हेलटनबीकर

4
(यह भी, यदि आप मुख्य सड़कों के माध्यम से नेविगेट कर रहे हैं, तो आप "सड़कों पर स्नैप करें" एल्गोरिथ्म का उपयोग कर सकते हैं, बशर्ते कि आपके पास एक अच्छा [सही, सटीक] रोडमैप डेटासेट हो। बस एक विचार है)
हेलटनबीकर

मैं इस मुद्दे को सबसे अच्छी सटीकता के लिए भी सामना कर रहा हूं।
वीरुमैक्स

जवाबों:


80

यहाँ एक साधारण कलमन फ़िल्टर है जिसका उपयोग इस स्थिति के लिए किया जा सकता है। यह कुछ काम से आया था जो मैंने एंड्रॉइड डिवाइस पर किया था।

जनरल कलमन फ़िल्टर थ्योरी वैक्टर के लिए सभी अनुमानों के बारे में है, जो कि कोवरियन मैट्रिस द्वारा दर्शाए गए अनुमानों की सटीकता के साथ है। हालांकि, एंड्रॉइड डिवाइसों पर स्थान का अनुमान लगाने के लिए सामान्य सिद्धांत बहुत सरल मामले में कम हो जाता है। एंड्रॉइड लोकेशन प्रदाता एक सटीकता के साथ एक अक्षांश और देशांतर के रूप में स्थान देते हैं, जो मीटर में मापा जाने वाले एकल नंबर के रूप में निर्दिष्ट होता है। इसका मतलब यह है कि एक कोवरियन मैट्रिक्स के बजाय, कलमन फ़िल्टर में सटीकता को एक ही संख्या से मापा जा सकता है, भले ही कलमन फ़िल्टर में स्थान दो संख्याओं द्वारा मापा गया हो। इस तथ्य के बावजूद कि अक्षांश, देशांतर और मीटर प्रभावी रूप से सभी विभिन्न इकाइयों को नजरअंदाज किया जा सकता है, क्योंकि यदि आप कलिंग फिल्टर में स्केलिंग कारकों को उन सभी इकाइयों में बदलने के लिए डालते हैं,

कोड में सुधार किया जा सकता है, क्योंकि यह मानता है कि वर्तमान स्थान का सबसे अच्छा अनुमान अंतिम ज्ञात स्थान है, और यदि कोई व्यक्ति आगे बढ़ रहा है तो बेहतर अनुमान लगाने के लिए एंड्रॉइड के सेंसर का उपयोग करना संभव होना चाहिए। कोड में एक एकल मुक्त पैरामीटर क्यू है, जिसे प्रति सेकंड मीटर में व्यक्त किया गया है, जो बताता है कि किसी भी नए स्थान अनुमानों की अनुपस्थिति में सटीकता कितनी जल्दी घट जाती है। एक उच्च क्यू पैरामीटर का मतलब है कि सटीकता तेजी से कम हो जाती है। कलमन फिल्टर आम तौर पर बेहतर काम करते हैं जब सटीकता थोड़ी तेज हो सकती है जिसकी कोई उम्मीद कर सकता है, इसलिए एंड्रॉइड फोन के साथ घूमने के लिए मुझे लगता है कि क्यू = 3 मीटर प्रति सेकंड ठीक काम करता है, भले ही मैं आम तौर पर धीमी गति से चलता हूं। लेकिन अगर एक तेज़ कार में यात्रा करते हैं तो एक बड़ी संख्या स्पष्ट रूप से इस्तेमाल की जानी चाहिए।

public class KalmanLatLong {
    private final float MinAccuracy = 1;

    private float Q_metres_per_second;    
    private long TimeStamp_milliseconds;
    private double lat;
    private double lng;
    private float variance; // P matrix.  Negative means object uninitialised.  NB: units irrelevant, as long as same units used throughout

    public KalmanLatLong(float Q_metres_per_second) { this.Q_metres_per_second = Q_metres_per_second; variance = -1; }

    public long get_TimeStamp() { return TimeStamp_milliseconds; }
    public double get_lat() { return lat; }
    public double get_lng() { return lng; }
    public float get_accuracy() { return (float)Math.sqrt(variance); }

    public void SetState(double lat, double lng, float accuracy, long TimeStamp_milliseconds) {
        this.lat=lat; this.lng=lng; variance = accuracy * accuracy; this.TimeStamp_milliseconds=TimeStamp_milliseconds;
    }

    /// <summary>
    /// Kalman filter processing for lattitude and longitude
    /// </summary>
    /// <param name="lat_measurement_degrees">new measurement of lattidude</param>
    /// <param name="lng_measurement">new measurement of longitude</param>
    /// <param name="accuracy">measurement of 1 standard deviation error in metres</param>
    /// <param name="TimeStamp_milliseconds">time of measurement</param>
    /// <returns>new state</returns>
    public void Process(double lat_measurement, double lng_measurement, float accuracy, long TimeStamp_milliseconds) {
        if (accuracy < MinAccuracy) accuracy = MinAccuracy;
        if (variance < 0) {
            // if variance < 0, object is unitialised, so initialise with current values
            this.TimeStamp_milliseconds = TimeStamp_milliseconds;
            lat=lat_measurement; lng = lng_measurement; variance = accuracy*accuracy; 
        } else {
            // else apply Kalman filter methodology

            long TimeInc_milliseconds = TimeStamp_milliseconds - this.TimeStamp_milliseconds;
            if (TimeInc_milliseconds > 0) {
                // time has moved on, so the uncertainty in the current position increases
                variance += TimeInc_milliseconds * Q_metres_per_second * Q_metres_per_second / 1000;
                this.TimeStamp_milliseconds = TimeStamp_milliseconds;
                // TO DO: USE VELOCITY INFORMATION HERE TO GET A BETTER ESTIMATE OF CURRENT POSITION
            }

            // Kalman gain matrix K = Covarariance * Inverse(Covariance + MeasurementVariance)
            // NB: because K is dimensionless, it doesn't matter that variance has different units to lat and lng
            float K = variance / (variance + accuracy * accuracy);
            // apply K
            lat += K * (lat_measurement - lat);
            lng += K * (lng_measurement - lng);
            // new Covarariance  matrix is (IdentityMatrix - K) * Covarariance 
            variance = (1 - K) * variance;
        }
    }
}

1
विचरण गणना नहीं होना चाहिए: विचरण + = TimeInc_milliseconds * TimeInc_milliseconds * Q_metres_per_second * Q_metres_per_second / 1000000
होरासियो

4
@Horacio, मुझे पता है कि आप ऐसा क्यों सोचते हैं, लेकिन नहीं! गणितीय रूप से, यहां अनिश्चितता को एक वीनर प्रक्रिया द्वारा देखा जा रहा है (देखें en.wikipedia.org/wiki/Wiener_process ) और वीनर प्रक्रिया के साथ विचरण समय के साथ रैखिक रूप से बढ़ता है। चर उस विकिपीडिया लेख में अनुभाग "संबंधित प्रक्रियाओं" में चर से Q_metres_per_secondमेल खाती है sigmaQ_metres_per_secondएक मानक विचलन है और इसे मीटरों में मापा जाता है, इसलिए मीटर और मीटर / सेकंड इसकी इकाइयाँ नहीं हैं। यह 1 सेकंड बीत जाने के बाद वितरण के मानक विचलन से मेल खाती है।
स्टॉकेस्टली

3
मैंने इस दृष्टिकोण और कोड की कोशिश की, लेकिन इसने कुल दूरी को बहुत कम कर दिया। इसे बहुत बड़ा बना दिया।
एंड्रियास रुडोल्फ

1
@ user2999943 हाँ, निर्देश का उपयोग करने के लिए कोड का उपयोग करें जो आपको onLocationChanged () से मिलता है।
स्टोकेस्टली

2
@Koray यदि आपके पास सटीकता की जानकारी नहीं है तो आप एक कलमन फ़िल्टर का उपयोग नहीं कर सकते। यह पूरी तरह से मौलिक है कि कलमन फ़िल्टर क्या करने की कोशिश कर रहा है।
स्टोकेस्टली

75

आप जो खोज रहे हैं उसे कलमन फ़िल्टर कहा जाता है । इसका उपयोग अक्सर नेविगेशनल डेटा को सुचारू करने के लिए किया जाता है । यह आवश्यक रूप से तुच्छ नहीं है, और आपके द्वारा किए जाने वाले बहुत सारे ट्यूनिंग हैं, लेकिन यह एक बहुत ही मानक दृष्टिकोण है और अच्छी तरह से काम करता है। एक KFilter लाइब्रेरी उपलब्ध है जो C ++ कार्यान्वयन है।

मेरा अगला पतन कम से कम वर्गों में फिट होगा । एक कलमन फ़िल्टर खाते में वेग लेने वाले डेटा को सुचारू कर देगा, जबकि कम से कम चौकोर फिट दृष्टिकोण सिर्फ स्थिति संबंधी जानकारी का उपयोग करेगा। फिर भी, इसे लागू करना और समझना निश्चित रूप से सरल है। ऐसा लगता है कि GNU साइंटिफिक लाइब्रेरी का कार्यान्वयन हो सकता है


1
धन्यवाद क्रिस। हां, मैंने कुछ खोज करते हुए कलमैन के बारे में पढ़ा, लेकिन यह निश्चित रूप से मेरे गणित ज्ञान से थोड़ा परे है। क्या आप किसी भी नमूना कोड को पढ़ने (और समझने) के लिए आसान हैं, या बेहतर अभी तक, कुछ कार्यान्वयन उपलब्ध हैं? (C / C ++ / Java)
अल।

1
@Al दुर्भाग्य से कलमैन फिल्टर के साथ मेरा एकमात्र एक्सपोजर काम के माध्यम से है, इसलिए मेरे पास कुछ शानदार सुरुचिपूर्ण कोड हैं जो मैं आपको नहीं दिखा सकता।
क्रिस आर्गुइन जूल

कोई समस्या नहीं है :-) मैंने देखने की कोशिश की लेकिन किसी कारण से ऐसा लगता है कि यह कलमन की बात काला जादू है। सिद्धांत पृष्ठों के बहुत सारे लेकिन कोई भी कोड के लिए कम .. धन्यवाद, अन्य तरीकों की कोशिश करेंगे।
अल।

2
kalman.sourceforge.net/index.php यहाँ कलमन फ़िल्टर का C ++ कार्यान्वयन है।
रोस्टीस्लाव ड्रूज़ेन्को

1
@ChrisArguin आपका स्वागत है। अगर परिणाम अच्छा है तो कृपया मुझे बताएं।
रोस्टीस्लाव ड्रूज़ेन्को

11

इसमें थोड़ी देर हो सकती है ...

मैंने एंड्रॉइड के लिए यह KalmanLocationManager लिखा , जो दो सबसे आम स्थान प्रदाताओं, नेटवर्क और जीपीएस, कलामन-डेटा को लपेटता है, और एक LocationListener(दो 'वास्तविक' प्रदाताओं की तरह) अपडेट अपडेट करता है ।

मैं इसे ज्यादातर रीडिंग के बीच "इंटरपोलेट" करने के लिए उपयोग करता हूं - उदाहरण के लिए हर 100 मिली (अपडेट (एक सेकंड के अधिकतम अंतराल दर के बजाय)) प्राप्त करने के लिए, जो मुझे मेरी स्थिति को एनिमेट करते समय एक बेहतर फ्रेम दर देता है।

वास्तव में, यह प्रत्येक आयाम के लिए तीन कलमन फ़िल्टर का उपयोग करता है: अक्षांश, देशांतर और ऊंचाई। वे वैसे भी स्वतंत्र हैं।

यह मैट्रिक्स गणित को बहुत आसान बनाता है: एक 6x6 राज्य संक्रमण मैट्रिक्स का उपयोग करने के बजाय, मैं 3 अलग 2x2 मैट्रिक्स का उपयोग करता हूं। वास्तव में कोड में, मैं मेट्रिसेस का उपयोग बिल्कुल नहीं करता। सभी समीकरणों को हल किया और सभी मान आदिम (डबल) हैं।

स्रोत कोड काम कर रहा है, और एक डेमो गतिविधि है। कुछ स्थानों पर javadoc की कमी के लिए क्षमा करें, मैं पकड़ लूंगा।


1
मैंने आपके परिवाद कोड का उपयोग करने की कोशिश की, मुझे कुछ अवांछित परिणाम मिले, मुझे यकीन नहीं है कि मैं कुछ गलत कर रहा हूं ... (नीचे छवि url है, नीला फ़िल्टर किए गए स्थानों का पथ है, नारंगी कच्चे स्थान हैं) app.box। कॉम / एस / w3uvaz007glp2utvgznmh8vlggvaiifk
उमेश

जिस स्पाइक को आप मीन (ऑरेंज लाइन) से 'बढ़ते' देख रहे हैं, वह नेटवर्क प्रदाता अपडेट की तरह दिखता है। क्या आप कच्चे नेटवर्क और जीपीएस अपडेट दोनों की साजिश रच सकते हैं? शायद आप बिना नेटवर्क अपडेट के बेहतर होंगे, यह इस बात पर निर्भर करेगा कि आप क्या हासिल करना चाहते हैं। Btw, आप उन कच्चे नारंगी अपडेट कहाँ से प्राप्त कर रहे हैं?
विलेन

1
नारंगी अंक जीपीएस प्रदाता से हैं, और नीला कलमन से हैं, मैंने मानचित्र पर लॉग्स दिए हैं
उमेश

क्या आप मुझे कुछ पाठ प्रारूप में डेटा भेज सकते हैं? प्रत्येक स्थान अपडेट में Location.getProvider () फ़ील्ड सेट होता है। सभी Location.toString () के साथ बस एक फ़ाइल।
विलेन

9

आपको प्रति समय स्थिति परिवर्तन से गति की गणना नहीं करनी चाहिए। जीपीएस में गलत स्थिति हो सकती है, लेकिन इसकी सटीक गति (5 किमी / घंटा से ऊपर) है। इसलिए GPS लोकेशन स्टैम्प से स्पीड का उपयोग करें। और आगे आपको ऐसा नहीं करना चाहिए, हालांकि यह कई बार काम करता है।

जीपीएस पोजीशन, जैसा कि दिया गया है, पहले से ही कलमैन फिल्टर्ड हैं, आप शायद सुधार नहीं कर सकते, पोस्टप्रोसेसिंग में आमतौर पर आपके पास जीपीएस चिप जैसी सूचना नहीं होती है।

आप इसे सुचारू कर सकते हैं, लेकिन यह त्रुटियों का भी परिचय देता है।

बस यह सुनिश्चित करें कि डिवाइस के स्थिर होने पर आपकी स्थिति को हटा दें, इससे जंपिंग पोजीशन को हटा दिया जाता है, कि कुछ डिवाइस / कॉन्फ़िगरेशन हटा नहीं सकते हैं।


5
क्या आप कृपया इसके लिए कुछ संदर्भ प्रदान कर सकते हैं?
ivyleavedtoadflax

1
उस वाक्य में कई जानकारी और बहुत अधिक पेशेवर अनुभव है, कौन सा वाक्य वास्तव में आप के लिए एक संदर्भ चाहते हैं? गति के लिए: डॉपलर प्रभाव और जीपीएस की खोज करें। आंतरिक कलमन? यह बेसिक जीपीएस नॉलेज है, हर पेपर या किताब बताती है कि जीपीएस चिप इंटरनली कैसे काम करता है। smootig-त्रुटियाँ: कभी चौरसाई परिचय इरोस। अभी भी खड़े हो? कोशिश करके देखो।
एलेक्सजियन

2
"जब चारों ओर उछल" खड़ा हो, तब भी त्रुटि का एकमात्र स्रोत नहीं है। वहाँ भी संकेत प्रतिबिंब हैं (जैसे पहाड़ों से) जहां स्थिति चारों ओर कूदती है। मेरे जीपीएस चिप्स (उदाहरण के लिए गार्मिन डकोटा 20, एंबेड नियो) ने इसे फ़िल्टर नहीं किया है ... और जो वास्तव में एक चुटकुला है जो कि बैरोमीटर के दबाव के साथ संयुक्त नहीं होने पर जीपीएस सिग्नलों का उन्नयन मूल्य है। ये मान फ़िल्टर नहीं किए गए हैं या मैं अनफ़िल्टर्ड मान नहीं देखना चाहता।
होजेबेल

1
@AlexWien GPS एक समय में एक बिंदु से दूरी की गणना करता है जो आपको मोटाई के साथ गोलाकार देता है, जो एक उपग्रह के चारों ओर एक खोल होता है। आप इस शेल मात्रा में कहीं हैं। इन शेल संस्करणों में से तीन का चौराहा आपको एक पोजीशन वॉल्यूम देता है, जिसमें से सेंट्रोइड आपकी गणना की गई स्थिति है। यदि आपके पास रिपोर्ट की गई स्थितियों का एक सेट है और आप जानते हैं कि सेंसर आराम में है, तो केन्द्रक की गणना प्रभावी ढंग से एक बहुत अधिक गोले को काटती है, जिससे सटीकता में सुधार होता है। इस मामले में त्रुटि कम हुई है
पीटर फॉन

6
"जीपीएस पोजीशन, जैसा कि दिया गया है, पहले से ही कल्मन फ़िल्टर किए गए हैं, आप शायद सुधार नहीं कर सकते हैं"। यदि आप एक स्रोत की ओर इशारा कर सकते हैं जो आधुनिक स्मार्टफ़ोन (उदाहरण के लिए) के लिए इसकी पुष्टि करता है, तो यह बहुत उपयोगी होगा। मैं खुद इसका सबूत नहीं देख सकता। यहां तक ​​कि एक उपकरण के कच्चे स्थानों को छानने का सरल कलमन भी दृढ़ता से सुझाव देता है कि यह सच नहीं है। कच्चे स्थान अनिश्चित रूप से चारों ओर नृत्य करते हैं, जबकि फ़िल्टर्ड स्थान अक्सर वास्तविक (ज्ञात) स्थान के करीब होते हैं।
सोबरी

6

मैं आमतौर पर एक्सेलेरोमीटर का उपयोग करता हूं। थोड़े समय में स्थिति का अचानक परिवर्तन उच्च त्वरण का अर्थ है। यदि यह एक्सेलेरोमीटर टेलीमेट्री में परिलक्षित नहीं होता है, तो यह निश्चित रूप से स्थिति को गणना करने के लिए उपयोग किए जाने वाले "सर्वश्रेष्ठ तीन" उपग्रहों में परिवर्तन के कारण होता है (जिसे मैं जीपीएस टेलीपोर्टिंग के रूप में संदर्भित करता हूं)।

जब GPS टेलीपोर्टिंग के कारण कोई ऐसेट आराम में होता है और होपिंग करता है, अगर आप उत्तरोत्तर गणना करते हैं तो आप सटीक रूप से एक बड़े और बड़े सेट को खोलते हुए सटीक रूप से सुधार करते हुए प्रभावी ढंग से एक दूसरे को काटते हैं।

ऐसा करने के लिए जब परिसंपत्ति आराम पर न हो, तो आपको इसकी संभावना का अनुमान लगाना चाहिए कि गति, शीर्षक और रैखिक और घूर्णी (यदि आपके पास gyros है) त्वरण डेटा के आधार पर इसकी अगली स्थिति और अभिविन्यास है। यह कम या ज्यादा है जो प्रसिद्ध K फ़िल्टर करता है। आप एक एएचआरएस पर लगभग $ 150 के लिए हार्डवेयर में पूरी चीज प्राप्त कर सकते हैं, जिसमें जीपीएस मॉड्यूल, और एक जैक के साथ एक को जोड़ने के लिए सब कुछ है। बोर्ड पर इसका स्वयं का सीपीयू और कलमन फ़िल्टरिंग है; परिणाम स्थिर और काफी अच्छे हैं। जड़त्वीय मार्गदर्शन घबराहट के लिए अत्यधिक प्रतिरोधी है लेकिन समय के साथ बह जाता है। जीपीएस में घबराहट होती है, लेकिन समय के साथ बहाव नहीं होता है, वे व्यावहारिक रूप से एक दूसरे को क्षतिपूर्ति करने के लिए बनाए गए थे।


4

एक विधि जो कम गणित / सिद्धांत का उपयोग करती है, वह एक बार में 2, 5, 7 या 10 डेटा बिंदुओं का नमूना लेती है और यह निर्धारित करती है कि आउटलेयर कौन हैं। कलमन फ़िल्टर की तुलना में एक बाहरी रूप से कम सटीक माप का उपयोग निम्न एल्गोरिदम का उपयोग करने के लिए बिंदुओं के बीच सभी जोड़ी वार दूरी लेने के लिए किया जाता है और जो दूसरों से दूर होता है उसे फेंक देते हैं। आमतौर पर उन मानों को बदले गए मूल्य के निकटतम मूल्य से बदल दिया जाता है जिन्हें आप प्रतिस्थापित कर रहे हैं

उदाहरण के लिए

पांच नमूने बिंदुओं ए, बी, सी, डी, ई पर चौरसाई

ATOTAL = SUM की दूरी AB AC AD AE

BTOTAL = SUM की दूरी AB BC BD BE

CTOTAL = SUM की दूरी AC BC CD CE

DTOTAL = SUM की दूरियाँ DA DB DC DE

ETOTAL = SUM की दूरी ईए EB EC DE

यदि BTOTAL सबसे बड़ा है तो आप B के साथ बिंदु B को बदल देंगे अगर BD = min {AB, BC, BD, BE}

यह चौरसाई आउटलेर को निर्धारित करती है और स्थितीय रेखा को सुचारू करने के लिए बिंदु D के बजाय BD के मध्य बिंदु का उपयोग करके संवर्धित किया जा सकता है। आपका माइलेज अलग-अलग हो सकता है और गणितीय रूप से कठोर समाधान मौजूद हैं।


धन्यवाद, मैं इसे एक शॉट भी दूँगा। ध्यान दें कि मैं वर्तमान स्थिति को सुचारू बनाना चाहता हूं, क्योंकि यह प्रदर्शित किया जा रहा है और कुछ डेटा को पुनर्प्राप्त करने के लिए उपयोग किया जाता है। मुझे पिछले अंकों में कोई दिलचस्पी नहीं है। मेरा मूल विचार भारित साधनों का उपयोग कर रहा था, लेकिन मुझे अभी भी देखना है कि सबसे अच्छा क्या है।
अल।

1
अल, यह भारित साधनों का एक रूप प्रतीत होता है। यदि आप कोई सुचारू करना चाहते हैं, तो आपको "पिछले" बिंदुओं का उपयोग करने की आवश्यकता होगी, क्योंकि सिस्टम को वर्तमान स्थिति से अधिक होने की आवश्यकता है ताकि यह पता चल सके कि कहां भी चिकनी करना है। अगर आपका GPS प्रति सेकंड एक बार डेटा पॉइंट ले रहा है और आपका उपयोगकर्ता पांच सेकंड में एक बार स्क्रीन पर दिखता है, तो आप उसके बिना 5 डेटा पॉइंट का उपयोग कर सकते हैं! एक चलती औसत केवल एक डीपी द्वारा विलंबित होगी।
कार्ल

4

कम से कम चौकों के लिए फिट होने के लिए, यहाँ कुछ अन्य चीजें हैं:

  1. सिर्फ इसलिए कि यह कम से कम वर्ग फिट है इसका मतलब यह नहीं है कि इसे रैखिक होना चाहिए। आप डेटा को कम से कम वर्गों में एक द्विघात वक्र फिट कर सकते हैं, फिर यह एक ऐसे परिदृश्य में फिट होगा जिसमें उपयोगकर्ता तेजी ला रहा है। (ध्यान दें कि कम से कम वर्ग फिट का मतलब है कि मैं स्वतंत्र चर के रूप में निर्भर चर और समय के रूप में निर्देशांक का उपयोग कर रहा हूं।)

  2. आप रिपोर्ट किए गए सटीकता के आधार पर डेटा बिंदुओं को भारित करने का भी प्रयास कर सकते हैं। जब सटीकता कम होती है तो वे डेटा कम होते हैं।

  3. एक और बात जो आप आजमाना चाहते हैं, वह यह है कि एक बिंदु को प्रदर्शित करने के बजाय, यदि सटीकता कम है, तो एक वृत्त या ऐसा कुछ प्रदर्शित होता है, जो उस सीमा को इंगित करता है जिसमें उपयोगकर्ता रिपोर्ट की गई सटीकता के आधार पर हो सकता है। (यह वही है जो iPhone के अंतर्निहित Google मानचित्र एप्लिकेशन करता है।)


3

तुम भी एक तख़्ता उपयोग कर सकते हैं। आपके पास मौजूद मानों में फ़ीड करें और अपने ज्ञात बिंदुओं के बीच बिंदुओं को प्रक्षेपित करें। इसे कम से कम वर्ग के फिट के साथ जोड़ना, चलती औसत या कलमन फ़िल्टर (जैसा कि अन्य उत्तरों में उल्लेख किया गया है) आपको अपने "ज्ञात" बिंदुओं की गणना करने की क्षमता देता है।

अपने ज्ञात के बीच के मूल्यों को प्रक्षेपित करने में सक्षम होने के कारण आपको एक अच्छा चिकनी संक्रमण और / यदि आप एक उच्च निष्ठा रखते हैं तो क्या डेटा मौजूद होगा, इसका उचित / अनुमान लगाया जा सकता है। http://en.wikipedia.org/wiki/Spline_interpolation

अलग-अलग स्प्लिन की अलग-अलग विशेषताएं हैं। मैंने जो सबसे ज्यादा इस्तेमाल किया है वह अकीमा और क्यूबिक स्प्लिन हैं।

रामर-डगलस-पुकर लाइन सरलीकरण एल्गोरिथ्म पर विचार करने के लिए एक और एल्गोरिथ्म है, यह जीपीएस डेटा के सरलीकरण में आमतौर पर उपयोग किया जाता है। ( http://en.wikipedia.org/wiki/Ramer-Douglas-Peucker_algorithm )


3

कलमन फ़िल्टर पर वापस जा रहा हूं ... मुझे यहां जीपीएस डेटा के लिए एक कलमन फ़िल्टर के लिए एक सी कार्यान्वयन मिला: http://github.com/lacker/ikalman मैंने अभी तक इसे आज़माया नहीं है, लेकिन यह आशाजनक लगता है।


0

अगर किसी को दिलचस्पी है तो CoffeeScript के लिए मैप किया गया। ** संपादित करें -> बैकबोन का उपयोग करके क्षमा करें, लेकिन आपको यह विचार मिलता है।

Attribs के साथ एक बीकन को स्वीकार करने के लिए थोड़ा संशोधित

{अक्षांश: आइटम। लैट, देशांतर: आइटम। एलएनजी, तिथि: नई तिथि (आइटम। प्रभावी), सटीकता: आइटम। जीपीएस_सुरक्षा}

MIN_ACCURACY = 1

# mapped from http://stackoverflow.com/questions/1134579/smooth-gps-data

class v.Map.BeaconFilter

  constructor: ->
    _.extend(this, Backbone.Events)

  process: (decay,beacon) ->

    accuracy     = Math.max beacon.accuracy, MIN_ACCURACY

    unless @variance?
      # if variance nil, inititalise some values
      @variance     = accuracy * accuracy
      @timestamp_ms = beacon.date.getTime();
      @lat          = beacon.latitude
      @lng          = beacon.longitude

    else

      @timestamp_ms = beacon.date.getTime() - @timestamp_ms

      if @timestamp_ms > 0
        # time has moved on, so the uncertainty in the current position increases
        @variance += @timestamp_ms * decay * decay / 1000;
        @timestamp_ms = beacon.date.getTime();

      # Kalman gain matrix K = Covarariance * Inverse(Covariance + MeasurementVariance)
      # NB: because K is dimensionless, it doesn't matter that variance has different units to lat and lng
      _k  = @variance / (@variance + accuracy * accuracy)
      @lat = _k * (beacon.latitude  - @lat)
      @lng = _k * (beacon.longitude - @lng)

      @variance = (1 - _k) * @variance

    [@lat,@lng]

इसे संपादित करने की कोशिश की गई, लेकिन अंतिम लाइनों में एक टाइपो है जहां @latऔर @lngसेट हैं। इसके +=बजाय होना चाहिए=
jdixon04

0

मैंने @Stochastically से Kotlin में जावा कोड को बदल दिया है

class KalmanLatLong
{
    private val MinAccuracy: Float = 1f

    private var Q_metres_per_second: Float = 0f
    private var TimeStamp_milliseconds: Long = 0
    private var lat: Double = 0.toDouble()
    private var lng: Double = 0.toDouble()
    private var variance: Float =
        0.toFloat() // P matrix.  Negative means object uninitialised.  NB: units irrelevant, as long as same units used throughout

    fun KalmanLatLong(Q_metres_per_second: Float)
    {
        this.Q_metres_per_second = Q_metres_per_second
        variance = -1f
    }

    fun get_TimeStamp(): Long { return TimeStamp_milliseconds }
    fun get_lat(): Double { return lat }
    fun get_lng(): Double { return lng }
    fun get_accuracy(): Float { return Math.sqrt(variance.toDouble()).toFloat() }

    fun SetState(lat: Double, lng: Double, accuracy: Float, TimeStamp_milliseconds: Long)
    {
        this.lat = lat
        this.lng = lng
        variance = accuracy * accuracy
        this.TimeStamp_milliseconds = TimeStamp_milliseconds
    }

    /// <summary>
    /// Kalman filter processing for lattitude and longitude
    /// /programming/1134579/smooth-gps-data/15657798#15657798
    /// </summary>
    /// <param name="lat_measurement_degrees">new measurement of lattidude</param>
    /// <param name="lng_measurement">new measurement of longitude</param>
    /// <param name="accuracy">measurement of 1 standard deviation error in metres</param>
    /// <param name="TimeStamp_milliseconds">time of measurement</param>
    /// <returns>new state</returns>
    fun Process(lat_measurement: Double, lng_measurement: Double, accuracy: Float, TimeStamp_milliseconds: Long)
    {
        var accuracy = accuracy
        if (accuracy < MinAccuracy) accuracy = MinAccuracy

        if (variance < 0)
        {
            // if variance < 0, object is unitialised, so initialise with current values
            this.TimeStamp_milliseconds = TimeStamp_milliseconds
            lat = lat_measurement
            lng = lng_measurement
            variance = accuracy * accuracy
        }
        else
        {
            // else apply Kalman filter methodology

            val TimeInc_milliseconds = TimeStamp_milliseconds - this.TimeStamp_milliseconds

            if (TimeInc_milliseconds > 0)
            {
                // time has moved on, so the uncertainty in the current position increases
                variance += TimeInc_milliseconds.toFloat() * Q_metres_per_second * Q_metres_per_second / 1000
                this.TimeStamp_milliseconds = TimeStamp_milliseconds
                // TO DO: USE VELOCITY INFORMATION HERE TO GET A BETTER ESTIMATE OF CURRENT POSITION
            }

            // Kalman gain matrix K = Covarariance * Inverse(Covariance + MeasurementVariance)
            // NB: because K is dimensionless, it doesn't matter that variance has different units to lat and lng
            val K = variance / (variance + accuracy * accuracy)
            // apply K
            lat += K * (lat_measurement - lat)
            lng += K * (lng_measurement - lng)
            // new Covarariance  matrix is (IdentityMatrix - K) * Covarariance
            variance = (1 - K) * variance
        }
    }
}

0

यहाँ एक जावास्क्रिप्ट का कार्यान्वयन है @ Stochastically के जावा कार्यान्वयन के लिए किसी को भी इसकी आवश्यकता है:

class GPSKalmanFilter {
  constructor (decay = 3) {
    this.decay = decay
    this.variance = -1
    this.minAccuracy = 1
  }

  process (lat, lng, accuracy, timestampInMs) {
    if (accuracy < this.minAccuracy) accuracy = this.minAccuracy

    if (this.variance < 0) {
      this.timestampInMs = timestampInMs
      this.lat = lat
      this.lng = lng
      this.variance = accuracy * accuracy
    } else {
      const timeIncMs = timestampInMs - this.timestampInMs

      if (timeIncMs > 0) {
        this.variance += (timeIncMs * this.decay * this.decay) / 1000
        this.timestampInMs = timestampInMs
      }

      const _k = this.variance / (this.variance + (accuracy * accuracy))
      this.lat += _k * (lat - this.lat)
      this.lng += _k * (lng - this.lng)

      this.variance = (1 - _k) * this.variance
    }

    return [this.lng, this.lat]
  }
}

उपयोग उदाहरण:

   const kalmanFilter = new GPSKalmanFilter()
   const updatedCoords = []

    for (let index = 0; index < coords.length; index++) {
      const { lat, lng, accuracy, timestampInMs } = coords[index]
      updatedCoords[index] = kalmanFilter.process(lat, lng, accuracy, timestampInMs)
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.