2012-04-19 3 views
27

나는 당신이 당신과 같이 직면하고있는 방법을 보여줍니다 위치 화살표를 포함하여,지도 응용 프로그램을 만들고있어 : 방위각. 화면이 지평선 위를 가리키고 세로 방향으로 전화가 걸려 있으면 화살표가 정상적으로 작동합니다. 그러나 :인간의 방향과 일치하는 안드로이드 전화 방향을 얻는 방법? <p></p> <p><img src="https://i.stack.imgur.com/o9DYE.png" alt="Map with a blue arrow"></p> 내가 <code>SensorManager.getOrientation()</code>에서 직접 방향을 얻을 첫 번째 반환 값을 사용하여 :

  • 화면이 수평선 아래를 가리 키도록 휴대 전화를 잡고 있으면 화살표는 사용자가 향하고있는 방향에서 180도 떨어진 지점을 가리 킵니다.
  • 화면이 수평이되도록 전화를 잡았을 때 화살표는 가리키는 방향을 알 수 없습니다. 방위각은 의미있는 결과를 전혀 반환하지 않습니다.
  • 휴대 전화를 왼쪽이나 오른쪽으로 기울이거나 가로 방향으로 기울이면 화살표가 왼쪽이나 오른쪽으로 기울어집니다.

아래의 신중하게 제작되고 과학적인 이미지는 내가 의미하는 바를 나타냅니다 (파란색은 사용자의 얼굴, 빨간색은 화살표 방향, 화면은 대략 사용자의 얼굴을 향하고 있으며 Google지도는 원하는대로 정확하게 수행함).

Graph of what happens vs what I want

은 (자동 회전이 꺼져있는 경우, 성공적 목록에있는 마지막 두 작업을하지 않는 Google지도와 함께, 그 참고. 그러나 나는 아직, 심지어 단계에서 아니에요. 하나 한 번에 하나씩)

간단히 여기에 표시된 Y 축 방향을 사용하여 : http://developer.android.com/reference/android/hardware/SensorEvent.html, Z 축 방향 지시의 반대 방향, 대부분의 시간 및 Y가 전화기가 평평한 경우 사용하려고 할 때. 그러나 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

는 문제가 해결 되었습니까? lastAcceleration, lastMagneticField는 어떻게 얻었습니까? –

+0

Nope. 절대로 해결하지 못했습니다. 어쩌면 해결할 수 없었을 것입니다. 그리고 구글 맵스는 내가 생각한만큼 현명하지 못한 것 같습니다. 나는 오랫동안 같은 일을하는 대신에 같은 회사에서 일하지 않기 때문에 일을해야하는 일 목록에서 그것을 버렸다. 어쨌든 안드로이드는 요즘과는 완전히 다른 방식으로 작동합니다. – AlbeyAmakiir

답변

0

매우 까다 롭습니다. 나는 안드로이드에 대한 PNS를 개발하고 있는데, 나는 여전히 빛을 필요로하는 유사한 문제에 직면하고있다. How to get the rotation between accelerometer's axis and motion vector?

사실 어떤 방향으로 사용자가 향하고 있는지를 알 수 없다. 그가 움직이지 않으면 장치가 아닙니다.) 사람이 몸에 센서가 없으므로 장치가 절대 동일한 위치에 있지만 사용자가 90 ° 회전 한 경우 어떻게됩니까? 이걸 찾을 방법이 없어.

내가 제안 할 수있는 것은 (실제로 내 문제에 부합 함) 사용자의 동작을 사용하여 사용자의 방향을 결정할 수 있다는 것입니다. 설명하겠습니다. A. 사용자가 첫 번째 위치에 있다고 가정 해 보겠습니다. 사용자가 B로 이동합니다.그런 다음 AB 벡터를 작성하고 B에서 멈추었을 때 사용자의 표제를 가져올 수 있습니다. 그러면 대상에 도착할 때 향한 방향으로 코드를 제한해야합니다.

나는 이것이 Google지도가 얻는 것만 큼 좋지는 않지만 Google이 이것을 위해 무엇을 사용하는지 알고 있습니까? 내 생각에 그들은 accelero 및 mag.field 센서 만 사용합니까?

+0

나는 사용자가 그 앞에 장치를 들고 스크린을 향한 채로 있다는 가정을하고있다. 그 이상으로, 나는 분명히 더 이상 할 수 없습니다. 또한 사용자의 동의를 얻고 있습니다. 그것은 멈출 때 가속도계와 자기장이 이어져야한다는 것입니다. – AlbeyAmakiir

6

remapCoordinateSystem을 (를) 호출 했습니까? 그렇지 않으면 휴대 전화가 세로로 고정되어있을 때만 오른쪽 방향 값을 얻습니다. 케이스의 경우 화면이 수평을 향하게 전화기가 잡혀있을 때 사용자의 얼굴을 잡을 수있는 방법이 없습니다. 방향을 잡으려면 센서 좌표의 z 값을 좌표계에서 xy 평면으로 투영해야하며 장치를 수평으로 유지하면 영점입니다.

전화를 직면 시키려면 전화기가 수평에서 약 25도 기울어 져야하고 remapCoordinateSystem을 호출해야합니다. 다음 코드는 위의 마지막 두 그림에 대해 원하는 것을 제공합니다.
코드 getOrientation 당신에게 전화를 가정 올바른 값을 제공

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; 
} 

평면 누워있다. 따라서 휴대 전화가 세로로 놓여 있으면 평면 좌표를 얻기 위해 좌표를 다시 매핑해야합니다. 기하학적으로, 여러분은 phone -z 축을 world xy 평면으로 투영 한 다음이 투영 벡터와 world y 축 사이의 각도를 계산합니다.

+0

나는 잘 모르겠다. 아니면 그렇지 않을 수도 있습니다. 화면이 수평 일 때 방향을 잡는 것은 불가능하지 않습니다. 왜냐하면 그것이 Google이하는 일이고 내가 지금 가지고있는 일이기 때문입니다. 전화가 수직 일 때 나는 얼굴을보아야합니다. 그리고, 아니. 나는'remapCoordinateSystem'을 호출하지 않았다. 문서는 그것을 사용하는 방법에 대해 완전히 명확하지 않습니다. – AlbeyAmakiir

+0

휴대 전화를 들고 있으면 나침반의 방향은 알 수 있지만 휴대 전화의 방향은 알 수 없으므로 화면의 방향이 수평과 수평이됩니다. 그것이 전화가 땅을 향하고 있기 때문에 북쪽, 남쪽 등등에 대해 말하는 것이 의미가 없습니다 ... "나침반 방향"을 얻을 수 있지만이 방향은 전화기의 방향에 달려 있습니다. 즉, 휴대 전화가 세로 모드로 평평하게 놓여 있고 나침반이 0도를 가리킨 경우 가로로 회전하면 나침반이 회전 한 방향에 따라 나침반이 90 또는 270dergrees로 표시됩니다. –

0

은 사용자가 수직으로 전화를 들고 베어링을 얻을 수있는 적절한 방법이 같은 것을 사용하는 것 같다 : 당신은 (수직 평면) 두 가지를 처리하려면

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

을하면됩니다 아마 그것을 감지하고 수직 일 때만이 재 매핑을 수행 할 필요가 있습니다.

here API 문서를 참조하십시오.

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); 

꽤 잘 해결되었습니다. 누구든지 개선안을 제안 할 수 있는지 알려 주시기 바랍니다. 감사.