9

Tôi đang cố gắng xây dựng một Ứng dụng Augmented Reality đơn giản, vì vậy tôi bắt đầu làm việc với Dữ liệu cảm biến.Android: Các sự cố khi tính toán Định hướng Thiết bị

Theo chủ đề này (Android compass example) và ví dụ (http://www.codingforandroid.com/2011/01/using-orientation-sensors-simple.html), tính định hướng sử dụng Sensor.TYPE_ACCELEROMETERSensor.TYPE_MAGNETIC_FIELD không thực sự phù hợp.

Vì vậy, tôi không thể nhận được các giá trị "tốt". Các giá trị phương vị không có ý nghĩa gì cả, vì vậy nếu tôi chỉ di chuyển điện thoại ngược, giá trị thay đổi cực kỳ. Ngay cả khi tôi chỉ xoay điện thoại, các giá trị không đại diện cho hướng điện thoại.

Có ai có ý tưởng, ai để cải thiện chất lượng giá trị theo ví dụ đã cho không?

Trả lời

0

Bạn đã thử Sensor.TYPE_ROTATION_VECTOR kiểu kết hợp (sensor-fusion). Điều này có thể cho kết quả tốt hơn: Đi tới https://developer.android.com/reference/android/hardware/SensorEvent.html và tìm kiếm 'rotation_vector'.

+1

Ok, vậy có ví dụ nào về cách làm việc với cảm biến này không? Tôi nhận các giá trị cho x * sin (θ/2), y * sin (θ/2) và z * sin (θ/2). Nhưng làm thế nào để có được giá trị, tôi cần phải xây dựng la bàn của tôi. Tôi có nên sử dụng getRotationMatrix nữa không? Cảm ơn bạn đã giúp đỡ. –

+0

"X được định nghĩa là sản phẩm vectơ Y.Z (Nó tiếp tuyến với mặt đất tại vị trí hiện tại của thiết bị và gần điểm phía đông). Y tiếp tuyến với mặt đất tại vị trí hiện tại của thiết bị và hướng về phía bắc từ tính. Z chỉ về phía bầu trời và vuông góc với mặt đất. " Bụi ra khỏi sách lớp hình học của bạn, hoặc google nó :), và bạn sẽ có thể tìm ra nó. –

19

Bạn sử dụng ứng dụng mẫu này theo định hướng nào? Từ những gì được viết là mã này, hướng duy nhất được hỗ trợ là Chân dung hoặc căn hộ trên bàn, nó phụ thuộc vào thiết bị. Bạn có ý nghĩa gì bởi "tốt"?

Bình thường giá trị không phải là "tốt" khi xoay thiết bị, hệ tọa độ thiết bị được cho là hoạt động ở Chân dung hoặc không phẳng (Trục Y dọc dọc theo màn hình hướng lên, Z trục chỉ ra khỏi màn hình đến từ trung tâm của màn hình, trục X vuông góc với trục Y đi bên phải dọc theo màn hình). Có điều này, xoay thiết bị sẽ không xoay hệ tọa độ thiết bị, bạn sẽ phải remap nó.

Nhưng nếu bạn muốn tiêu đề của thiết bị theo hướng dọc, đây là một đoạn mã mà làm việc tốt cho tôi:

@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    // It is good practice to check that we received the proper sensor event 
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) 
    { 
     // Convert the rotation-vector to a 4x4 matrix. 
     SensorManager.getRotationMatrixFromVector(mRotationMatrix, 
       event.values); 
     SensorManager 
       .remapCoordinateSystem(mRotationMatrix, 
         SensorManager.AXIS_X, SensorManager.AXIS_Z, 
         mRotationMatrix); 
     SensorManager.getOrientation(mRotationMatrix, orientationVals); 

     // Optionally convert the result from radians to degrees 
     orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); 
     orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); 
     orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); 

     tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " 
       + orientationVals[1] + "\n Roll (not used): " 
       + orientationVals[2]); 

    } 
} 

Bạn sẽ nhận được tiêu đề (hoặc góc phương vị) trong:

orientationVals[0] 
+1

Để ghi lại, tôi đã thử mã này với một 3x3 Ma trận nhưng nó chỉ làm việc với 4x4 (aka float [16]) – MonoThreaded

+0

cho tôi cũng nó làm việc với 4 * 4 (aka float [16]) –

7

Có thể là muộn cho bữa tiệc. Dù sao đây là làm thế nào tôi có góc phương vị

private final int sensorType = Sensor.TYPE_ROTATION_VECTOR; 
float[] rotMat = new float[9]; 
float[] vals = new float[3]; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    sensorHasChanged = false; 
    if (event.sensor.getType() == sensorType){ 
     SensorManager.getRotationMatrixFromVector(rotMat, 
       event.values); 
     SensorManager 
       .remapCoordinateSystem(rotMat, 
         SensorManager.AXIS_X, SensorManager.AXIS_Y, 
         rotMat); 
     SensorManager.getOrientation(rotMat, vals); 
     azimuth = deg(vals[0]); // in degrees [-180, +180] 
     pitch = deg(vals[1]); 
     roll = deg(vals[2]); 
     sensorHasChanged = true; 
    } 
} 

Hy vọng nó giúp

+0

Cuộc gọi 'remapCoordinateSystem' chỉ là chuyển đổi nhận dạng, do đó, nó dư thừa. sử dụng 'rotMat' cho cả đầu vào và đầu ra, một cái gì đó tài liệu rõ ràng nói rằng bạn không nên làm – Thomas

+0

Cảm ơn bạn đã làm việc này – Bogdan

11

trả lời từ Tibo là tốt, nhưng nếu bạn đăng nhập giá trị cuộn, bạn sẽ mong đợi con số bất thường. (cuộn là quan trọng đối với AR trình duyệt)

Điều này là do

SensorManager.remapCoordinateSystem(mRotationMatrix, 
        SensorManager.AXIS_X, SensorManager.AXIS_Z, 
        mRotationMatrix); 

Bạn phải sử dụng ma trận khác nhau cho trong và ngoài remap. Mã sau đây hoạt động cho tôi với giá trị cuộn chính xác:

@Override 
public void onSensorChanged(SensorEvent event) 
{ 
    // It is good practice to check that we received the proper sensor event 
    if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) 
    { 
     // Convert the rotation-vector to a 4x4 matrix. 
     SensorManager.getRotationMatrixFromVector(mRotationMatrixFromVector, event.values); 
     SensorManager.remapCoordinateSystem(mRotationMatrixFromVector, 
        SensorManager.AXIS_X, SensorManager.AXIS_Z, 
        mRotationMatrix); 
     SensorManager.getOrientation(mRotationMatrix, orientationVals); 

     // Optionally convert the result from radians to degrees 
     orientationVals[0] = (float) Math.toDegrees(orientationVals[0]); 
     orientationVals[1] = (float) Math.toDegrees(orientationVals[1]); 
     orientationVals[2] = (float) Math.toDegrees(orientationVals[2]); 

     tv.setText(" Yaw: " + orientationVals[0] + "\n Pitch: " 
       + orientationVals[1] + "\n Roll (not used): " 
       + orientationVals[2]); 

    } 
} 
+0

Có, bạn có thể kiểm tra mã nguồn: public boolean remapCoordinateSystem (float [] inR, int X, int Y, float [] outR) * @param outR * ma trận xoay chuyển đổi. inR và outR không nên là cùng một mảng *. – codevscolor