कम्पास सहित Android फोन अभिविन्यास अवलोकन


107

मैं थोड़ी देर के लिए एंड्रॉइड ओरिएंटेशन सेंसर के आसपास अपना सिर पाने की कोशिश कर रहा हूं। मुझे लगा कि मैं इसे समझ गया हूं। तब मुझे एहसास हुआ कि मैंने नहीं किया। अब मुझे लगता है (आशा है) मुझे फिर से इसके लिए बेहतर एहसास है लेकिन मैं अभी भी 100% नहीं हूं। मैं इसके बारे में मेरी समझ को समझने की कोशिश करूंगा और उम्मीद करूंगा कि अगर मैं भागों में गलत हूं या किसी रिक्त स्थान को भर दूं तो लोग मुझे सही कर पाएंगे।

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

अब फोन पर सेंसर आपको इस स्थिति में डिवाइस के ओरिएंटेशन (स्थान नहीं) को बाहर करने की अनुमति देते हैं। इस हिस्से ने मुझे हमेशा भ्रमित किया है, शायद इसलिए मैं यह समझना चाहता था कि मेरे काम करने से पहले कुछ काम कैसे किया गया था, यह सिर्फ काम किया। ऐसा लगता है कि फोन दो अलग-अलग तकनीकों के संयोजन का उपयोग करके अपने अभिविन्यास का काम करता है।

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

अब कल्पना करें कि कोई व्यक्ति अब आपको 90 डिग्री पर चक्कर लगाता है ताकि आप अब पूर्व की ओर मुंह कर सकें। आपको Y अक्ष के चारों ओर घुमाया जा रहा है। यह अक्ष भिन्न है क्योंकि हम इसे जैविक रूप से नहीं पहचान सकते हैं। हम जानते हैं कि हम एक निश्चित राशि से नाराज हैं, लेकिन हम ग्रह के चुंबकीय उत्तरी ध्रुव के संबंध में दिशा नहीं जानते हैं। इसके बजाय हमें एक बाहरी उपकरण ... एक चुंबकीय कम्पास का उपयोग करने की आवश्यकता है। यह हमें यह पता लगाने की अनुमति देता है कि हम किस दिशा में सामना कर रहे हैं। हमारे फोन के साथ भी यही सच है।

अब फोन में 3-एक्सिस एक्सेलेरोमीटर भी है। मेरे पास NO हैविचार करें कि वे वास्तव में कैसे काम करते हैं, लेकिन जिस तरह से मैं कल्पना करता हूं वह गुरुत्वाकर्षण को आकाश से गिरने और एक समान 'बारिश' के रूप में कल्पना करना है और ट्यूबों के रूप में ऊपर की आकृति में कुल्हाड़ियों की कल्पना करना है जो बारिश की मात्रा का पता लगा सकते हैं। जब फोन पूरी तरह से सीधा होगा तो बारिश 'Y' ट्यूब से होकर गुजरेगी। यदि फोन को धीरे-धीरे घुमाया जाता है, तो इसकी स्क्रीन आकाश से सामना करती है, Y के माध्यम से बहने वाली बारिश की मात्रा शून्य हो जाएगी, जबकि Z के माध्यम से वॉल्यूम लगातार बढ़ेगा जब तक कि अधिकतम मात्रा में बारिश नहीं होती है। इसी तरह अगर हम अब फोन को अपनी तरफ से टिप करते हैं तो एक्स ट्यूब अंततः बारिश की अधिकतम मात्रा को इकट्ठा करेगा। इसलिए 3 ट्यूबों के माध्यम से बहने वाली बारिश की मात्रा को मापकर फोन के उन्मुखीकरण के आधार पर आप अभिविन्यास की गणना कर सकते हैं।

फोन में एक इलेक्ट्रॉनिक कम्पास भी है जो एक सामान्य कम्पास की तरह व्यवहार करता है - इसकी "वर्चुअल सुई" चुंबकीय उत्तर की ओर इशारा करती है। एंड्रॉयड मर्ज के इन दो सेंसरों से जानकारी तो जब भी एक है कि SensorEventके TYPE_ORIENTATIONउत्पन्न होता है values[3]सरणी
मूल्यों [0]: दिगंश - (चुंबकीय उत्तर की कम्पास असर पूर्व)
मूल्यों [1]: पिच, चारों ओर x- अक्ष रोटेशन (फोन है आगे या पीछे झुकना)
मान [2]: रोल, y- अक्ष के चारों ओर घूमता है (फोन इसके बाएं या दाएं तरफ झुक रहा है)

इसलिए मुझे लगता है (यानी मुझे नहीं पता) कारण यह है कि एंड्रॉइड तीसरे एक्सेलेरोमीटर के पढ़ने के बजाय अजिमुथ (कम्पास बेयरिंग) देता है, यह है कि कम्पास असर सिर्फ अधिक उपयोगी है। मुझे यकीन नहीं है कि उन्होंने इस प्रकार के सेंसर को अपदस्थ क्यों किया क्योंकि अब ऐसा लगता है कि आपको SensorEventटाइप के लिए सिस्टम के साथ श्रोता को पंजीकृत करने की आवश्यकता है TYPE_MAGNETIC_FIELD। इवेंट के value[]ऐरे को SensorManger.getRotationMatrix(..)रोटेशन मैट्रिक्स (नीचे देखें) प्राप्त करने के लिए विधि में बाईपास करने की आवश्यकता होती है, जिसे तब SensorManager.getOrientation(..)विधि में पास किया जाता है। क्या किसी को पता है कि एंड्रॉइड टीम को क्यों निकाला गया Sensor.TYPE_ORIENTATION? क्या यह एक दक्षता की बात है? यह वही है जो टिप्पणियों में एक समान प्रश्न के लिए निहित है, लेकिन आपको अभी भी एक अलग प्रकार के श्रोता को पंजीकृत करने की आवश्यकता हैविकास / नमूने / कम्पास / src / com / उदाहरण / Android / कम्पास / CompassActivity.java उदाहरण।

अब मैं रोटेशन मैट्रिक्स के बारे में बात करना चाहता हूँ। (यह वह जगह है जहां मैं सबसे अनिश्चित हूं) इसलिए ऊपर एंड्रॉइड प्रलेखन से तीन आंकड़े हैं, हम उन्हें ए, बी और सी कहेंगे।

A = SensorManger.getRotationMatrix (..) विधि आंकड़ा और दुनिया की समन्वय प्रणाली का प्रतिनिधित्व करती है

B = कोऑर्डिनेट सिस्टम SensorEvent API द्वारा उपयोग किया जाता है।

C = SensorManager.getOrientation (..) विधि आकृति

तो मेरी समझ यह है कि A "विश्व की समन्वय प्रणाली" का प्रतिनिधित्व करता है, जिसे मैं मानता हूं कि ग्रह पर जिस तरह से स्थान हैं, वे एक वैकल्पिक (ऊंचाई) के साथ एक (अक्षांश, देशांतर) जोड़े के रूप में दिए गए हैं। X "ईस्टिंगिंग" को-ऑर्डिनेट है, Y "नॉर्थिंग" को-ऑर्डिनेट है। Z आकाश की ओर इशारा करता है और ऊंचाई का प्रतिनिधित्व करता है।

फोन को-ऑर्डिनेट सिस्टम को दिखाया गया है जो आंकड़ा B में तय किया गया है। इसका Y अक्ष हमेशा ऊपर की ओर इंगित करता है। रोटेशन मैट्रिक्स की गणना लगातार फोन द्वारा की जा रही है और दोनों के बीच मैपिंग की अनुमति देता है। तो क्या मैं यह सोचने में सही हूं कि रोटेशन मैट्रिक्स B से C की समन्वय प्रणाली को बदल देता है? इसलिए जब आप SensorManager.getOrientation(..)विधि को कॉल करते हैं, तो आप उन values[]मानों के साथ सरणी का उपयोग करते हैं जो आकृति सी के अनुरूप हैं। जब फोन आकाश की ओर इशारा किया जाता है तो रोटेशन मैट्रिक्स पहचान मैट्रिक्स (मैट्रिक्स गणितीय 1 के बराबर) है जिसका अर्थ है कि डिवाइस संरेखित करने के लिए कोई मैपिंग आवश्यक नहीं है। दुनिया की समन्वय प्रणाली के साथ।

ठीक। मुझे लगता है कि मैं अब बेहतर हूं। जैसे मैंने कहा कि इससे पहले कि मुझे उम्मीद है कि लोग मुझे बताएंगे कि मैंने कहां गड़बड़ की है या लोगों की मदद की है (या लोगों को और भी भ्रमित कर दिया है!)


25
मुझे वास्तव में यह सवाल पसंद है। मैं इसका जवाब नहीं दे सकता लेकिन मुझे यह पसंद है।
ऑक्टेवियन ए। डामियन

4
टिम, क्या आपको कभी जवाब मिला? मैं उसी समय अपना सिर खुजला रहा हूं। यह मेरे द्वारा देखे गए सबसे खराब दस्तावेज एपीआई में से एक है।
पियरे-ल्यूक पाऊर

सच में मुझे डर नहीं है। मुझे आगे बढ़ना था। किसी दिन मैं इस मुद्दे पर लौटूंगा।
टिम

1
यहाँ मेरा एक ही सवाल है, लगभग? और प्रतिक्रिया, समाधान भी। मेड सार्वजनिक मेरी कोड Github पर।

यही बात मैं सोच रहा हूं, मैंने एक एंड्रॉइड डिवाइस पर कम्पास लागू किया है और ठीक से काम कर रहा है अगर मैंने इंटरनेट से इसके ठीक काम में मदद ली, लेकिन भ्रमित करने वाली बात यह है ... मान लीजिए कि मेरा डिवाइस जमीनी चेहरे पर है मेरी ओर और इसके उत्तर की ओर इशारा करते हुए अब मैं अपना मोबाइल उठाता हूं और इसे बिना सिर के ऊपर खड़ा करता हूं और चेहरा अभी भी मेरी ओर है। सबसे पहले सुई को अपनी दिशा बदलनी चाहिए और क्यों। जैसा कि मैं सोच रहा हूं कि ऐसा नहीं होना चाहिए क्योंकि मैंने अपनी दिशा नहीं बदली है, लेकिन यह मेरे ऐप में बदल रहा है और अन्य सभी ऐप जो मैंने डाउनलोड किए हैं। क्या कोई समझा सकता है क्यों?
सैयद रज़ा मेहदी

जवाबों:


26

आप बाहर की जाँच करना चाहते हो सकता है वन स्क्रीन टर्न प्रोटेक्टेड अन्य लेख देखें। यह बताता है कि आपको रोटेशन मैट्रिक्स की आवश्यकता क्यों है।

संक्षेप में, फोन के सेंसर हमेशा एक ही समन्वय प्रणाली का उपयोग करते हैं, तब भी जब डिवाइस को घुमाया जाता है।

उन अनुप्रयोगों में, जो एकल अभिविन्यास में बंद नहीं होते हैं, जब आप डिवाइस को घुमाते हैं तो स्क्रीन समन्वय प्रणाली बदल जाती है। इस प्रकार, जब डिवाइस को अपने डिफ़ॉल्ट दृश्य मोड से घुमाया जाता है, तो सेंसर समन्वय प्रणाली अब स्क्रीन समन्वय प्रणाली के समान नहीं होती है। इस मामले में रोटेशन मैट्रिक्स का उपयोग ए को सी में बदलने के लिए किया जाता है (बी हमेशा निश्चित रहता है)।

यहां एक कोड स्निपेट है जो आपको दिखाता है कि इसका उपयोग कैसे किया जा सकता है।

SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);

// Register this class as a listener for the accelerometer sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                    SensorManager.SENSOR_DELAY_NORMAL);
// ...and the orientation sensor
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD),
                    SensorManager.SENSOR_DELAY_NORMAL);

//...
// The following code inside a class implementing a SensorEventListener
// ...

float[] inR = new float[16];
float[] I = new float[16];
float[] gravity = new float[3];
float[] geomag = new float[3];
float[] orientVals = new float[3];

double azimuth = 0;
double pitch = 0;
double roll = 0;

public void onSensorChanged(SensorEvent sensorEvent) {
    // If the sensor data is unreliable return
    if (sensorEvent.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE)
        return;

    // Gets the value of the sensor that has been changed
    switch (sensorEvent.sensor.getType()) {  
        case Sensor.TYPE_ACCELEROMETER:
            gravity = sensorEvent.values.clone();
            break;
        case Sensor.TYPE_MAGNETIC_FIELD:
            geomag = sensorEvent.values.clone();
            break;
    }

    // If gravity and geomag have values then find rotation matrix
    if (gravity != null && geomag != null) {

        // checks that the rotation matrix is found
        boolean success = SensorManager.getRotationMatrix(inR, I,
                                                          gravity, geomag);
        if (success) {
            SensorManager.getOrientation(inR, orientVals);
            azimuth = Math.toDegrees(orientVals[0]);
            pitch = Math.toDegrees(orientVals[1]);
            roll = Math.toDegrees(orientVals[2]);
        }
    }
}

4
बस उल्लेख है कि azimuth, पिच और रोल, पदावनत OrientationSensor से बाहर आने के समान नहीं हैं। orientation[0] = orientation[0] >= 0 ? orientation[0]: orientation[0] + 360;अज़ीमुथ if (orientation[1] <= -90) { orientation[1] += (-2*(90+orientation[1])); } else if(orientation[1] >= 90){ orientation[1] += (2*(90 - orientation[1])); }को सामान्य करेगा और पिच को सामान्य करेगा
राफेल टी

@ राफेलटी और रोल को सामान्य करने के लिए? या कि कोई मतलब नहीं है?
मथायस

@ राफेल्ट: अज़ीमुथ का आपका सामान्यीकरण प्रभावित करता है: मूल्य [-180,180] से [0, 360] तक जाते हैं। लेकिन मुझे मिलने वाला पिच वैल्यू पहले से ही [-90,90] में है, इसलिए आपके द्वारा प्रस्तावित सामान्यीकरण का कोई प्रभाव नहीं पड़ता है।
मथियास

जाँच करने के बाद (गुरुत्वाकर्षण! = Null && geomag! = Null) होने पर इसका क्या अर्थ है, जियोमैग का मान हमेशा 0 होता है, इससे कोई फर्क नहीं पड़ता कि मैं टैबलेट को कैसे स्थानांतरित करूं? जियोमैग सेंसर के बिना एक टैबलेट हो सकता है?
उन्नत

3

रोल गुरुत्वाकर्षण का एक कार्य है, एक 90 डिग्री का रोल गुरुत्वाकर्षण के सभी को एक्स रजिस्टर में डालता है।

पिच समान है, एक 90 डिग्री की पिच गुरुत्वाकर्षण के घटक के सभी को y रजिस्टर में डालती है।

Yaw / Heading / azimuth का गुरुत्वाकर्षण पर कोई प्रभाव नहीं पड़ता है, यह हमेशा गुरुत्वाकर्षण के लिए सही कोण पर होता है, इसलिए इससे कोई फर्क नहीं पड़ता कि आप गुरुत्वाकर्षण का सामना किस तरह से कर रहे हैं।

यही कारण है कि आपको आकलन करने के लिए कम्पास की आवश्यकता होती है, शायद यह समझ में आता है?


0

इस पर एक नज़र: Stackoverflow.com: Q.5202147

आप 3 आरेख, B, C तक अधिकतर सही प्रतीत होते हैं। उसके बाद आप खुद को भ्रमित कर चुके हैं।


0

मुझे यह समस्या आ रही थी इसलिए मैंने अलग-अलग दिशाओं में क्या होता है, इसकी मैपिंग की। यदि डिवाइस को लैंडस्केप फैशन में रखा गया है, उदाहरण के लिए कार में कम्पास से 'डिग्री' को माउंट करें तो 269 (पश्चिम और उत्तर के बीच) के ऊपर 0-275 (दक्षिणावर्त जा रहा है) से चलने लगता है, यह -90 से 0 से पीछे की ओर गिना जाता है, तब आगे 0 से 269 तक। 270 बन जाता है -90

फिर भी लैंडस्केप में लेकिन इसके बैक पर लगे डिवाइस के साथ मेरा सेंसर 0-360 देता है। और पोर्ट्रेट मोड में, यह 0-360 पर चलता है, दोनों इसकी पीठ पर झूठ बोलते हैं और पोर्ट्रेट में खड़े होते हैं।

आशा है कि किसी की मदद करता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.