2012-06-17 31 views
16

Tôi sẽ phát triển ứng dụng Android cần phải đọc tọa độ x, y, z của điện thoại trên không gian 3D.Đọc tọa độ x y z của điện thoại android bằng gia tốc

Tôi muốn viết mã đơn giản và thử nghiệm trên thiết bị.

Tôi đang sử dụng bánh gừng trên cả thiết bị và trình mô phỏng.

+0

Bản sao có thể có của [Sử dụng gia tốc kế, con quay hồi chuyển và la bàn để tính toán chuyển động của thiết bị trong thế giới 3D] (http://stackoverflow.com/questions/8264518/using-accelerometer-gyroscope-and-compass-to-calculate-devices- chuyển động-in-3d) superset cũng yêu cầu trạng thái quay. –

Trả lời

16

Để nhận vị trí từ gia tốc, bạn cần tích hợp nó hai lần.

Tích hợp tăng tốc cho phép bạn vận tốc và tích hợp vận tốc cho bạn vị trí.

Hãy nhớ rằng tích hợp tiếng ồn tạo ra trôi dạt và tích hợp trôi tạo ra rất nhiều trôi dạt, các cảm biến android có xu hướng tạo ra khá nhiều tiếng ồn.

Trên Galaxy S3 của tôi, tôi đã có thể nhận được độ lệch ở vị trí xuống 0,02 m trong 5 giây bằng cảm biến tổng hợp Linear Accelerometer của Google.

Tôi không chắc liệu bạn có thể sử dụng cảm biến gia tốc tuyến tính trên bánh gừng hay không. Nếu bạn không thể, bạn sẽ phải loại bỏ trọng lực trước khi tích hợp.

Nếu bạn chưa sẵn sàng, đọc tất cả mọi thứ ở đây http://developer.android.com/guide/topics/sensors/sensors_motion.html

A nói chuyện tuyệt vời về các cảm biến chuyển động trong android

http://www.youtube.com/watch?v=C7JQ7Rpwn2k

Code:

static final float NS2S = 1.0f/1000000000.0f; 
float[] last_values = null; 
float[] velocity = null; 
float[] position = null; 
long last_timestamp = 0; 

@Override 
public void onSensorChanged(SensorEvent event) { 
    if(last_values != null){ 
     float dt = (event.timestamp - last_timestamp) * NS2S; 

     for(int index = 0; index < 3;++index){ 
      velocity[index] += (event.values[index] + last_values[index])/2 * dt; 
      position[index] += velocity[index] * dt; 
     } 
    } 
    else{ 
     last_values = new float[3]; 
     velocity = new float[3]; 
     position = new float[3]; 
     velocity[0] = velocity[1] = velocity[2] = 0f; 
     position[0] = position[1] = position[2] = 0f; 
    } 
    System.arraycopy(event.values, 0, last_values, 0, 3); 
    last_timestamp = event.timestamp; 
} 

Bây giờ bạn có vị trí trong không gian 3d, hãy ghi nhớ rằng nó giả định rằng điện thoại là văn phòng phẩm khi nó sta rts lấy mẫu.

Nếu bạn không loại bỏ trọng lực, nó sẽ sớm ở rất xa.

Điều này không lọc dữ liệu chút nào và sẽ tạo ra nhiều sự trôi dạt.

+1

Nó không chỉ là tiếng ồn cảm biến tạo ra sự trôi dạt. Giới hạn chính của phương pháp này là về cơ bản là không thể phát hiện một tốc độ không đổi với gia tốc kế.Vì vậy, tích hợp dường như có thể cho kết quả hợp lý khi bạn chỉ lắc điện thoại một chút, nhưng đối với các loại chuyển động khác, ví dụ như khi lái xe hoặc đi xe đạp, sự trôi dạt sẽ rất lớn. – Junuxx

+0

Bạn hoàn toàn đúng. Tôi đang sử dụng gia tốc kế để theo dõi một chiếc xe và cho rằng tôi đã thực hiện một bộ lọc kalman để tiếp tục giảm trôi. Tôi cũng tính toán độ chính xác của gia tốc kế bằng cách đo tiếng ồn khi nó dừng, sau đó nó được sử dụng để cân trọng lượng dữ liệu trong bộ lọc. Tôi nhận được kết quả khá tốt cho đến nay. – spontus

+0

Ở đây bạn cũng sẽ nhận được rất nhiều "trôi" như bạn đang gọi nó bởi vì bạn tính toán tất cả điều này với vật lý newton, đó là không chính xác. Làm Runge-kutta hoặc một số cách tính chính xác hơn để có được kết quả tốt hơn. – Automatico

7

Đọc this tutorial.

tóm tắt ngắn gọn về các hướng dẫn nêu trên ::

đầu tiên có được một thể hiện của SensorManagerSensor.
Bên onCreate() ::

mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); 

sau này, ghi đè onSensorChanged(SensorEvent event) và sử dụng event.values[] để có được tọa độ.

@Override 
public void onSensorChanged(SensorEvent event) { 
    float x = event.values[0]; 
    float y = event.values[1]; 
    float z = event.values[2]; 
}