2012-05-07 27 views
14

Tôi đang phát triển một ứng dụng Android và tôi muốn biết liệu có thể phát hiện hướng di chuyển với một trục cố định không. Ví dụ, tôi muốn đặt điện thoại của tôi trên bàn và phát hiện hướng khi tôi di chuyển nó (trái, phải, lên và xuống). Khoảng cách là không cần thiết, tôi chỉ muốn biết hướng chính xác.Làm thế nào tôi có thể nhận được hướng chuyển động bằng cách sử dụng gia tốc kế?

Cảm ơn!

+0

Một số bài đăng về gia tốc kế: http://www.anddev.org/advanced-tutorials-f21/accessing-the-accelerometer-t499.html#p1987 http://developer.android.com/reference/android/hardware /SensorEvent.html#values ​​ – Niko

Trả lời

23

Có.

Sử dụng SensorEventListener.onSensorChanged(SensorEvent event) bạn có thể xác định giá trị được cung cấp dọc theo trục X & Y. Bạn sẽ cần phải ghi lại các giá trị này và sau đó so sánh chúng với bất kỳ giá trị mới nào mà bạn nhận được trên các cuộc gọi tiếp theo theo phương thức onSensorChanged để nhận giá trị delta. Nếu giá trị delta trên một trục là dương thì thiết bị đang di chuyển một chiều, nếu giá trị âm của nó di chuyển ngược lại.

Có thể bạn sẽ cần tinh chỉnh cả tốc độ mà tại đó bạn nhận được sự kiện gia tốc và ngưỡng mà bạn xem xét giá trị delta để biểu thị sự thay đổi hướng.

Dưới đây là một ví dụ mã nhanh chóng về những gì tôi đang nói về:.

public class AccelerometerExample extends Activity implements SensorEventListener { 
    TextView textView; 
    StringBuilder builder = new StringBuilder(); 

    float [] history = new float[2]; 
    String [] direction = {"NONE","NONE"}; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     textView = new TextView(this); 
     setContentView(textView); 

     SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 
     Sensor accelerometer = manager.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0); 
     manager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME); 
    } 

    @Override 
    public void onSensorChanged(SensorEvent event) { 

     float xChange = history[0] - event.values[0]; 
     float yChange = history[1] - event.values[1]; 

     history[0] = event.values[0]; 
     history[1] = event.values[1]; 

     if (xChange > 2){ 
      direction[0] = "LEFT"; 
     } 
     else if (xChange < -2){ 
      direction[0] = "RIGHT"; 
     } 

     if (yChange > 2){ 
      direction[1] = "DOWN"; 
     } 
     else if (yChange < -2){ 
      direction[1] = "UP"; 
     } 

     builder.setLength(0); 
     builder.append("x: "); 
     builder.append(direction[0]); 
     builder.append(" y: "); 
     builder.append(direction[1]); 

     textView.setText(builder.toString()); 
    } 

    @Override 
    public void onAccuracyChanged(Sensor sensor, int accuracy) { 
     // nothing to do here 
    } 
} 

Mã này sẽ chỉ cung cấp cho bạn các hướng chung trên trục X và Y là điện thoại đã di chuyển trong Để cung cấp một xác định hướng tốt hơn (ví dụ như cố gắng bắt chước chuyển động của chuột máy tính), bạn có thể thấy rằng gia tốc của điện thoại không phù hợp với mục đích. Để thử điều này, trước tiên tôi sẽ đặt độ trễ của cảm biến thành SensorManager.SENSOR_DELAY_FAST và tạo danh sách nhiều sự kiện lịch sử để tôi có thể phát hiện chuyển động theo thời gian và không bị ảnh hưởng bởi chuyển động nhỏ theo hướng ngược lại thường xảy ra khi dùng gia tốc kế phép đo ở mức phạt tiền như vậy. Bạn cũng sẽ cần phải đo lượng thời gian đã trôi qua để giúp tính toán số đo chính xác của chuyển động như được đề xuất trong nhận xét của bạn.

+0

Xin chào Louth! Cảm ơn vì đã trả lời. Tôi đã thử nghiệm một mã tương tự, vấn đề là những thay đổi khi điện thoại đang di chuyển. Khi tôi cần độ chính xác, tôi làm việc với một "xChange" khoảng 0,3. Ngay cả chuyển động là "liên tục" từ trái sang phải, giá trị thay đổi nhiều lần. Phân tích các giá trị gia tốc, tôi đã nhận ra rằng đôi khi sau một chuyển động, gia tốc tạo ra các giá trị tương đương theo hướng ngược lại và nó gây ra sự thay đổi. Tôi cần phải có hướng với độ chính xác tương tự như chuột có phong cách cũ (có hình cầu) ít nhất. Bạn có mẹo nào không? –

+0

Chào mừng Marcos. Bạn nên cập nhật câu hỏi của mình vì cố gắng làm cho điện thoại của bạn hoạt động như một con chuột không giống với hướng phát hiện. Tôi không chắc gia tốc kế được thiết kế cho loại điều bạn muốn làm. Vì nó đo gia tốc, bạn có thể không đạt được sự phát hiện chuyển động hạt mịn mà bạn đang tìm kiếm. – Louth

+0

Tôi đã cập nhật câu trả lời của mình để xem xét nhận xét của bạn. Vui lòng cập nhật câu hỏi của bạn và xem xét chấp nhận câu trả lời này. – Louth

0

Từ những gì tôi đã đọc, với cảm biến, người ta chỉ có thể phát hiện sự tăng tốc và hướng điện thoại. Vì vậy, bạn có thể dễ dàng phát hiện sự khởi đầu của chuyển động (và theo hướng nào) và điểm dừng của chuyển động, vì vận tốc đang thay đổi nên có gia tốc (khi dừng gia tốc theo hướng vận tốc).

Nếu điện thoại di chuyển với vận tốc không đổi, gia tốc kế sẽ cho giá trị bằng không (gia tốc tuyến tính trừ đi trọng lực). Vì vậy, để biết nếu điện thoại đang chuyển động, bạn nên tính toán vận tốc tại mỗi ngay lập tức, bởi

V(t)=V(t0)+a*dt 

trong đó:

  • V(t0) là vận tốc được biết đến ở ngay lập tức trước đó,
  • V(t) là vận tốc tại thời điểm hiện tại,
  • a là gia tốc (xem xét gia tốc trong tức thời trước hoặc tăng tốc trung bình giữa tức thời và hiện tại).

Vấn đề là do sự không chắc chắn của các giá trị cảm biến, bạn có thể kết thúc tổng hợp các lỗi nhỏ tại mỗi thời điểm, điều này sẽ dẫn đến các giá trị vận tốc sai. Có lẽ bạn sẽ phải điều chỉnh một bộ lọc thông thấp để các giá trị.

Các vấn đề liên quan