2012-04-19 11 views
27

मैं एक नक्शा एप्लिकेशन बना रही हूँ, स्थान तीर है कि आप का सामना करना पड़ जो रास्ता रहे हैं, ताकि तरह से पता चलता सहित:एंड्रॉइड फोन अभिविन्यास मानव अभिविन्यास से मेल खाता कैसे प्राप्त करें?

Map with a blue arrow

मैं SensorManager.getOrientation() से सीधे उन्मुखीकरण मिलता है, पहले दिए गए मान का उपयोग कर: दिगंश। जब फोन आयोजित किया जाता है ताकि स्क्रीन क्षितिज से ऊपर इंगित हो, और चित्र में, तीर ठीक काम करता है। हालांकि:

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

ध्यान से निर्मित और वैज्ञानिक छवि नीचे दिखाती है कि मेरा क्या मतलब है (जहां नीला उपयोगकर्ता का सामना कर रहा है, लाल तीर दिशा है, स्क्रीन लगभग उपयोगकर्ता के चेहरे का सामना कर रही है, और Google मानचित्र बिल्कुल वही करता है जो मैं चाहता हूं):

Graph of what happens vs what I want

(ध्यान दें कि, गूगल मैप्स के साथ, इसे सफलतापूर्वक सूची पर पिछले दो कार्यों ऐसा नहीं करता है, तो स्वत: घुमाने बंद है। लेकिन मैं भी इस स्तर पर अभी तक नहीं कर रहा हूँ। एक एक समय में बात।)

ऐसा प्रतीत होता है कि यह है बस वाई अक्ष पॉइंटिंग दिशा का उपयोग करके यहां दिखाया गया है: http://developer.android.com/reference/android/hardware/SensorEvent.html, जब मैं इसे ज़ेड अक्ष पॉइंटिंग दिशा के विपरीत, अधिकतर समय, और वाई जब फोन सपाट हो, तो इसका उपयोग करना चाहता हूं। हालांकि, getOrientation() रिटर्न के मान दिए गए हैं, मुझे कुछ मुद्दों को ठीक करने के लिए जटिल मामलों को लिखना होगा, और फोन-फेस-क्षितिज उपयोग केस असफल है। मुझे यकीन है कि एक आसान तरीका है।

float[] rotationMatrix = new float[9]; 
if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){ 
    float[] orientMatrix = new float[3]; 
    SensorManager.getOrientation(rotationMatrix, orientMatrix); 

    orientation = orientMat[0]*180/(float)Math.PI; 
} 

क्या मैं गलत कर रहा हूँ:

यहाँ मेरी कोड (कहाँ lastAcceleration और lastMagneticField दोनों आंतरिक सेंसर से आया है) है? क्या इसे करने का कोई आसान रास्ता है?

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

+16

वैज्ञानिक छवि के लिए +1 –

+0

आपकी समस्या हल हो गई है? आखिरी एक्सेलेरेशन, आखिरी मैग्नेटिकफाल्ड कैसे मिला? –

+0

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

उत्तर

0

यह बहुत मुश्किल लग रहा है। मैं एंड्रॉइड के लिए एक पीएनएस विकसित कर रहा हूं और मुझे किसी भी तरह की समस्या का सामना करना पड़ रहा है जिसके लिए मुझे अभी भी प्रकाश की आवश्यकता है: How to get the rotation between accelerometer's axis and motion vector?

बात यह है कि मुझे यह पता लगाना बिल्कुल असंभव लगता है कि उपयोगकर्ता किस दिशा में सामना कर रहा है (डिवाइस नहीं) अगर वह हिल नहीं रहा है। उस मनुष्य के शरीर पर कोई सेंसर नहीं है, तो क्या होगा यदि डिवाइस पूरी स्थिति में रहे लेकिन उपयोगकर्ता 90 डिग्री से घिरा हुआ हो? मुझे यह खोजने का कोई तरीका नहीं दिख रहा है।

मैं क्या सुझाव दे सकता हूं (और यह वास्तव में मेरी समस्या के लिए फिट बैठता है) यह है कि आप (मुझे नहीं पता कि आप वास्तव में अपने कोड में क्या करते हैं) उपयोगकर्ता की गति का निर्धारण करने के लिए उपयोगकर्ता की गति का उपयोग करें। मुझे समझाने दो। मान लें कि आपके पास पहली स्थिति है। उपयोगकर्ता बी पर जाता है।फिर आप एबी वेक्टर बना सकते हैं और जब वह बी पर रुक जाता है तो उपयोगकर्ता का शीर्षक प्राप्त कर लेता है। फिर आपको गंतव्य पर पहुंचने पर उस दिशा में अपने कोड को सीमित करना होगा।

मुझे पता है कि यह Google मानचित्र के जितना अच्छा नहीं है, लेकिन क्या आप जानते हैं कि Google इसके लिए क्या उपयोग करता है? मेरा मतलब है कि वे केवल accelero और mag.field सेंसर का उपयोग करते हैं?

+0

मैं इस धारणा को बना रहा हूं कि उपयोगकर्ता उनके सामने डिवाइस रख रहा है, स्क्रीन की ओर इशारा करते हुए। इसके अलावा, मैं स्पष्ट रूप से और नहीं कर सकता। इसके अलावा, मैं उपयोगकर्ता की गति ले रहा हूं। यह बस इतना है कि, जब वे रुकते हैं, एक्सेलेरोमीटर और चुंबकीय क्षेत्र को लेना चाहिए। – AlbeyAmakiir

6

क्या आपने रीमैप कोऑर्डिनेट सिस्टम कहा था? अन्यथा, जब फोन लंबवत हो तो आपको केवल सही मूल्य का मूल्य मिल जाएगा। मामले के लिए जब फोन आयोजित किया जाता है तो स्क्रीन का सामना क्षितिज के साथ स्तर होता है, तो उपयोगकर्ता का सामना करने का कोई तरीका नहीं है। चूंकि सामना करने के लिए आपको विश्व समन्वय में एक्सई प्लेन में पढ़ने वाले सेंसर के जेड वैल्यू को प्रोजेक्ट करना होगा और डिवाइस क्षैतिज रूप से आयोजित होने पर शून्य हो जाएगा।

अधिक सटीक होने के लिए, यदि आप फोन का सामना करना चाहते हैं तो फोन को क्षैतिज से कम से कम 25 डिग्री झुकाव होना चाहिए और आपको रीमेप कोऑर्डिनेट सिस्टम को कॉल करना होगा। निम्नलिखित कोड आपको उपरोक्त अंतिम 2 चित्रों के लिए जो चाहिए, वह आपको देगा।
कोड

float[] rotationMatrix = new float[9]; 

if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){ 
    float[] orientMatrix = new float[3]; 
    float remapMatrix = new float[9]; 
    SensorManager.remapCoordinateSystem(rotationMatrix, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapMatrix); 
    SensorManager.getOrientation(remapMatrix, orientMatrix); 

    orientation = orientMat[0]*180/(float)Math.PI; 
} 

getOrientation आप फोन संभालने सही मान देता फ्लैट बिछाने है। इस प्रकार, अगर फोन लंबवत रखा जाता है, तो आपको फ्लैट स्थिति प्राप्त करने के लिए समन्वय को रीमेप करना होगा। ज्यामितीय रूप से, आप फोन xz अक्ष को दुनिया xy विमान में नीचे प्रोजेक्ट करते हैं और फिर इस प्रक्षेपण वेक्टर और विश्व वाई-अक्ष के बीच कोण की गणना करते हैं।

+0

मुझे यकीन नहीं है कि मैं अनुसरण करता हूं। या शायद आप नहीं करते हैं। स्क्रीन क्षैतिज होने पर अभिविन्यास प्राप्त करना असंभव नहीं है, क्योंकि यह वही है जो Google करता है, और मेरे पास अभी क्या है। फोन लंबवत होने पर सामना करने के लिए मैं _want_। और नहीं। मैंने 'रीमैप कोऑर्डिनेट सिस्टम 'नहीं कहा है। दस्तावेजों का उपयोग करने के तरीके पर पूरी तरह से स्पष्ट नहीं हैं। – AlbeyAmakiir

+0

आप कंपास दिशा प्राप्त कर सकते हैं लेकिन अगर फोन आयोजित किया जाता है तो फ़ोन का सामना नहीं किया जाता है, इसलिए स्क्रीन का सामना क्षितिज के साथ स्तर होता है। वह फोन जमीन का सामना कर रहा है, इसलिए उत्तर, दक्षिण आदि के बारे में बात करना समझ में नहीं आता है ... आप "कंपास दिशा" प्राप्त कर सकते हैं लेकिन यह दिशा फोन के अभिविन्यास पर निर्भर करती है। यही कारण है कि फोन आपके सामने पोर्ट्रेट मोड में फ्लैट रखता है और कंपास 0 डिग्री दिखाता है, फिर जब आप परिदृश्य में घुमाते हैं, तो कंपास आपके द्वारा घूमने वाली दिशा के आधार पर 90 या 270 डर्गी दिखाएगा। –

0

ऐसा लगता है कि असर जब उपयोगकर्ता फ़ोन को सीधा कर रहा है प्राप्त करने के लिए उचित तरीके से कुछ इस तरह उपयोग करने के लिए है: आप दोनों तरीकों (ऊर्ध्वाधर और फ्लैट) को संभालने के लिए चाहते हैं

// after calling getRotationMatrix pass the rotationMatix below: 
SensorManager.remapCoordinateSystem(inR, AXIS_X, AXIS_Z, outR); 

आप होगा शायद इसे पहचानने की आवश्यकता है और फिर लंबवत होने पर ही यह रीमेप करें।

एपीआई दस्तावेज़ीकरण here देखें।

0

आपको पिच लेना चाहिए और यह निर्धारित करना चाहिए कि उपयोगकर्ता लंबवत फोन को पकड़ने के करीब है या नहीं।

मैंने चुना कि मेज पर फ्लैट से 45 डिग्री पिच ऊपर या नीचे के बाद, समन्वय प्रणाली को दोबारा हटाया जाना चाहिए।

if (Math.round(Math.toDegrees(-orientation[1])) < 45 && Math.round(Math.toDegrees(-orientation[1])) > -45) { 
//do something while the phone is horizontal 
}else{ 
//R below is the original rotation matrix 
float remapOut[] = new float[9]; 
SensorManager.remapCoordinateSystem(R, SensorManager.AXIS_X, SensorManager.AXIS_Z, remapOut); 
//get the orientation with remapOut 
float remapOrientation[] = new float[3]; 
SensorManager.getOrientation(remapOut, remapOrientation); 

यह बहुत अच्छी तरह से काम किया है। मुझे बताएं कि क्या कोई इस पर सुधार का सुझाव दे सकता है। धन्यवाद।

संबंधित मुद्दे