Tôi gặp sự cố khi đọc chỉ số cảm biến định hướng tốt. Các chỉ số cảm biến dường như không đáng tin cậy, vì vậy tôi đã kiểm tra mã của mình dựa trên hai ứng dụng thử nghiệm cảm biến miễn phí (Sensor Tester (Dicotomica) và Sensor Monitoring (R's Software)). Tôi nhận thấy rằng trong khi các bài đọc của tôi thường đồng ý với các ứng dụng thử nghiệm cảm biến, đôi khi các giá trị cho góc phương vị/yaw và cuộn khác nhau lên đến 40 độ, mặc dù mức độ đọc phần lớn được đồng ý. Hai ứng dụng miễn phí dường như luôn đồng ý với nhau.Giá trị cảm biến định hướng không nhất quán trên Android cho góc phương vị/yaw và cuộn
Tôi đặt mã của mình vào một hoạt động Android nhỏ và có cùng sự mâu thuẫn. Mã như sau:
public class MainActivity extends Activity implements SensorEventListener {
private SensorManager mSensorManager;
private float[] AccelerometerValues;
private float[] MagneticFieldValues;
private float[] RotationMatrix;
private long nextRefreshTime; // used to ensure dump to LogCat occurs no more than 4 times a second
private DecimalFormat df; // used for dumping sensors to LogCat
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager)getSystemService(android.content.Context.SENSOR_SERVICE);
Sensor SensorAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, SensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
Sensor SensorMagField = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
mSensorManager.registerListener(this, SensorMagField, SensorManager.SENSOR_DELAY_UI);
AccelerometerValues = new float[3];
MagneticFieldValues = new float[3];
RotationMatrix = new float[9];
nextRefreshTime = 0;
df = new DecimalFormat("#.00");
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
System.arraycopy(event.values, 0, AccelerometerValues, 0, AccelerometerValues.length);
else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
System.arraycopy(event.values, 0, MagneticFieldValues, 0, MagneticFieldValues.length);
if (AccelerometerValues != null && MagneticFieldValues != null) {
if(SensorManager.getRotationMatrix(RotationMatrix, null, AccelerometerValues, MagneticFieldValues)) {
float[] OrientationValues = new float[3];
SensorManager.getOrientation(RotationMatrix, OrientationValues);
// chance conventions to match sample apps
if (OrientationValues[0] < 0) OrientationValues[0] += 2*(float)Math.PI;
OrientationValues[2] *= -1;
// dump to logcat 4 times a second
long currentTimeMillis = System.currentTimeMillis();
if (currentTimeMillis > nextRefreshTime) {
nextRefreshTime = currentTimeMillis+250;
Log.i("Sensors", // arrange output so that numbers line up in columns :-)
"(" + AngleToStr(OrientationValues[0]) + "," + AngleToStr(OrientationValues[1]) + "," + AngleToStr(OrientationValues[2])
+ ") ("+FloatToStr(AccelerometerValues[0]) + "," + FloatToStr(AccelerometerValues[1]) + "," + FloatToStr(AccelerometerValues[2])
+ ") ("+FloatToStr(MagneticFieldValues[0]) + "," + FloatToStr(MagneticFieldValues[1]) + "," + FloatToStr(MagneticFieldValues[2])+")");
}
}
}
}
private String AngleToStr(double AngleInRadians) {
String Str = " "+Integer.toString((int)Math.toDegrees(AngleInRadians));
return Str.substring(Str.length() - 3);
}
private String FloatToStr(float flt) {
String Str = " "+df.format(flt);
return Str.substring(Str.length() - 6);
}
@Override
protected void onDestroy() {
super.onDestroy();
mSensorManager.unregisterListener(this);
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) { }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
}
Tôi đang sử dụng Galaxy Note 2 chạy Jelly Bean 4.1.1. Bất cứ ai có thể cho tôi biết những gì tôi đang làm sai?
Cập nhật 24 tháng 3 năm 2013: Thông tin thêm. (1) Tôi đã vô hiệu hóa chuyển đổi giữa chân dung và phong cảnh trong tệp kê khai, do đó getWindowManager(). GetDefaultDisplay(). GetRotation() luôn bằng 0. Do đó tôi không nghĩ rằng remapCoordSystem sẽ giúp đỡ ở đây, bởi vì đó là để chuyển đổi trục, trong khi các lỗi mà tôi nhìn thấy không phải là lỗi lớn, chúng tinh tế hơn nhiều. (2) Tôi đã kiểm tra độ nhạy chính xác, và sự mâu thuẫn xảy ra khi cả hai cảm biến đều có độ chính xác cao.
Ví dụ về những mâu thuẫn mà tôi thấy, khi mã ở trên cho tôi (góc phương vị, độ dốc, cuộn) = (235, -52, -11) thì hai ứng dụng miễn phí hiển thị các giá trị tương tự. Nhưng khi tôi nhìn thấy (278, -58, -52) các ứng dụng hiển thị (256, -58, -26), sự khác biệt lớn như vậy trong cả Azimuth và cuộn, mặc dù sân có vẻ OK.
Nó chỉ cho Azimuth từ -90 đến 90 độ. Làm thế nào tôi có thể nhận được Azimuth trong khoảng 0 đến 359 độ khi di chuyển từ miền Bắc. – Master
@Hoosier câu hỏi tốt, bởi vì như bạn nói, ốp ngược nghịch đảo bình thường trả về số trong khu vực -90 đến 90 độ. Câu trả lời là sử dụng Atan2 (http://en.wikipedia.org/wiki/Atan2) có sẵn trong cả hai ngôn ngữ tôi sử dụng (cụ thể là C# và Java). – Stochastically
Cảm ơn. Tôi sẽ cố gắng sử dụng nó nếu nó hoạt động. – Master