Kamis, 27 Maret 2014

Sensor Gerak Menggunakan Accelerometer & Gyroscope

Platform Android menyediakan beberapa sensor yang bisa memonitor gerakan perangkat. Dua sensor ini selalu berbasis hardware (accelerometer dan gyroscope), dan tiga sensor ini dapat berupa hardware-based atau berbasis software (gravitasi, percepatan linear, dan sensor vektor rotasi). Sebagai contoh, pada beberapa perangkat sensor berbasis software memperoleh data dari accelerometer dan magnetometer, tapi pada perangkat lain mereka juga dapat menggunakan gyroscope untuk mendapatkan data mereka. Sebagian besar perangkat Android-powered memiliki accelerometer, dan banyak sekarang termasuk gyroscope. Ketersediaan sensor berbasis software lebih variabel karena mereka sering bergantung pada satu atau lebih sensor hardware untuk mendapatkan data mereka.

Sensor gerak berguna untuk gerakan perangkat monitoring, seperti miring, goyang, rotasi, atau ayunan. Gerakan ini biasanya merupakan cerminan dari input pengguna langsung (misalnya, pengguna kemudi mobil dalam permainan atau pengguna mengontrol bola dalam permainan), tetapi bisa juga menjadi cerminan dari lingkungan fisik di mana perangkat duduk (misalnya, bergerak dengan Anda saat Anda mengemudi mobil Anda). Dalam kasus pertama, Anda sedang memantau gerak relatif terhadap frame perangkat acuan atau kerangka aplikasi acuan anda, dalam kasus kedua Anda sedang memantau gerak relatif terhadap frame acuan dunia. Sensor gerak sendiri biasanya tidak digunakan untuk memantau posisi perangkat, tetapi mereka dapat digunakan dengan sensor lain, seperti sensor medan magnetik bumi, untuk menentukan perangkat posisi relatif terhadap frame acuan dunia.

Semua sensor gerak return multi-dimenstional array nilai sensor untuk setiap SensorEvent. Sebagai contoh, selama acara sensor accelerometer tunggal mengembalikan data yang berlaku untuk percepatan tiga sumbu koordinat, dan gyroscope mengembalikan tingkat data rotasi untuk tiga sumbu koordinat. Nilai data ini dikembalikan dalam float array (values) bersama dengan parameter SensorEvent lainnya.

Menggunakan Accelerometer
Sebuah sensor percepatan mengukur percepatan yang diterapkan untuk perangkat, termasuk gaya gravitasi. Kode berikut menunjukkan kepada Anda bagaimana untuk mendapatkan contoh dari sensor percepatan default:

private SensorManager mSensorManager;
private Sensor mSensor;
  ...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Secara konseptual, sebuah sensor percepatan menentukan percepatan yang diterapkan ke perangkat (Ad) dengan mengukur kekuatan yang diterapkan pada sensor itu sendiri (Fs) dengan menggunakan hubungan berikut:

Ad = - ∑Fs / mass
Namun, gaya gravitasi selalu mempengaruhi percepatan diukur sesuai dengan hubungan berikut:

Ad = -g - ∑F / mass

Untuk alasan ini, saat perangkat sedang duduk di meja (dan tidak dipercepat), accelerometer membaca besarnya g = 9,81 m/s2. Demikian pula, bila perangkat jatuh bebas dan karena itu cepat mempercepat ke tanah di 9,81 m/s2, accelerometer yang membaca besarnya g = 0 m/s2. Oleh karena itu, untuk mengukur percepatan nyata perangkat, kontribusi gaya gravitasi harus dihilangkan dari data accelerometer. Hal ini dapat dicapai dengan menerapkan filter high-pass. Sebaliknya, low-pass filter dapat digunakan untuk mengisolasi gaya gravitasi. Contoh berikut ini menunjukkan bagaimana Anda dapat melakukan ini:

public void onSensorChanged(SensorEvent event){
  // In this example, alpha is calculated as t / (t + dT),
  // where t is the low-pass filter's time-constant and
  // dT is the event delivery rate.

  final float alpha = 0.8;

  // Isolate the force of gravity with the low-pass filter.
  gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
  gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
  gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];

  // Remove the gravity contribution with the high-pass filter.
  linear_acceleration[0] = event.values[0] - gravity[0];
  linear_acceleration[1] = event.values[1] - gravity[1];
  linear_acceleration[2] = event.values[2] - gravity[2];

Catatan: Anda dapat menggunakan teknik yang berbeda untuk menyaring data sensor. Contoh kode di atas menggunakan filter konstan sederhana (alpha) untuk membuat low-pass filter. Konstan Filter ini berasal dari sebuah konstanta waktu (t), yang merupakan representasi kasar dari latency bahwa filter menambah peristiwa sensor, dan tingkat pengiriman acara sensor (dt). Contoh kode menggunakan nilai alpha dari 0,8 untuk tujuan demonstrasi. Jika Anda menggunakan metode penyaringan ini, Anda mungkin perlu memilih nilai alpha yang berbeda.

Accelerometers menggunakan sensor standar sistem koordinat. Dalam prakteknya, ini berarti bahwa kondisi berikut berlaku bila perangkat adalah meletakkan datar di atas meja dalam orientasi alam:

  • Jika Anda mendorong perangkat di sisi kiri (sehingga bergerak ke kanan), x nilai percepatan positif. 
  • Jika Anda mendorong perangkat di bagian bawah (sehingga bergerak menjauh dari Anda), nilai y percepatan positif. 
  • Jika Anda mendorong perangkat ke langit dengan percepatan A m/s2, nilai percepatan z sama dengan A + 9,81, yang sesuai dengan akselerasi perangkat (+ A m/s2) minus gaya gravitasi (- 9,81 m/s2). 
  • Perangkat stasioner akan memiliki nilai percepatan 9,81, yang sesuai dengan percepatan perangkat (0 m/s2 minus gaya gravitasi, yaitu -9,81 m/s2).

Secara umum, accelerometer adalah sensor yang baik untuk digunakan jika Anda sedang memantau gerakan perangkat. Hampir setiap handset Android-powered dan tablet memiliki accelerometer, dan menggunakan sekitar 10 kali lebih sedikit daya dibandingkan sensor gerak lainnya. Satu kelemahan adalah bahwa Anda mungkin harus menerapkan low-pass dan high-pass filter untuk menghilangkan gaya gravitasi dan mengurangi kebisingan.

Menggunakan Gyroscope
Gyroscope mengukur tingkat atau rotasi dalam rad/s sekitar perangkat x, y, dan sumbu z. Kode berikut menunjukkan kepada Anda bagaimana untuk mendapatkan contoh dari gyroscope default:

private SensorManager mSensorManager;
private Sensor mSensor;
...
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);

Sistem koordinat sensor adalah sama dengan yang digunakan untuk sensor percepatan. Rotasi adalah positif dalam arah berlawanan arah jarum jam, maka dari itu pengamat melihat dari beberapa lokasi positif pada x, y atau z sumbu pada perangkat diposisikan pada titik asal akan melaporkan rotasi positif jika perangkat tampaknya berputar berlawanan arah jarum jam. Ini adalah definisi matematika standar rotasi positif dan tidak sama dengan definisi untuk roll yang digunakan oleh sensor orientasi.

Biasanya, output dari gyroscope terintegrasi dari waktu ke waktu untuk menghitung rotasi menggambarkan perubahan sudut atas timestep tersebut. Sebagai contoh:

// Create a constant to convert nanoseconds to seconds.
private static final float NS2S = 1.0f / 1000000000.0f;
private final float[] deltaRotationVector = new float[4]();
private float timestamp;
public void onSensorChanged(SensorEvent event) {
  // This timestep's delta rotation to be multiplied by the current rotation
  // after computing it from the gyro sample data.
  if (timestamp != 0) {
    final float dT = (event.timestamp - timestamp) * NS2S;
    // Axis of the rotation sample, not normalized yet.
    float axisX = event.values[0];
    float axisY = event.values[1];
    float axisZ = event.values[2];

    // Calculate the angular speed of the sample
    float omegaMagnitude = sqrt(axisX*axisX + axisY*axisY + axisZ*axisZ);

    // Normalize the rotation vector if it's big enough to get the axis
    // (that is, EPSILON should represent your maximum allowable margin of error)
    if (omegaMagnitude > EPSILON) {
      axisX /= omegaMagnitude;
      axisY /= omegaMagnitude;
      axisZ /= omegaMagnitude;
    }

    // Integrate around this axis with the angular speed by the timestep
    // in order to get a delta rotation from this sample over the timestep
    // We will convert this axis-angle representation of the delta rotation
    // into a quaternion before turning it into the rotation matrix.
    float thetaOverTwo = omegaMagnitude * dT / 2.0f;
    float sinThetaOverTwo = sin(thetaOverTwo);
    float cosThetaOverTwo = cos(thetaOverTwo);
    deltaRotationVector[0] = sinThetaOverTwo * axisX;
    deltaRotationVector[1] = sinThetaOverTwo * axisY;
    deltaRotationVector[2] = sinThetaOverTwo * axisZ;
    deltaRotationVector[3] = cosThetaOverTwo;
  }
  timestamp = event.timestamp;
  float[] deltaRotationMatrix = new float[9];
  SensorManager.getRotationMatrixFromVector(deltaRotationMatrix, deltaRotationVector);
    // User code should concatenate the delta rotation we computed with the current rotation
    // in order to get the updated rotation.
    // rotationCurrent = rotationCurrent * deltaRotationMatrix;
   }
}
Standar gyroscope menyediakan data rotasi mentah tanpa penyaringan atau koreksi untuk kebisingan dan penyimpangan (bias). Dalam prakteknya, kebisingan gyroscope dan pergeseran akan memperkenalkan kesalahan yang perlu dikompensasi. Anda biasanya menentukan penyimpangan (bias) dan kebisingan dengan memantau sensor lain, seperti sensor gravitasi atau accelerometer.

Sumber: http://developer.android.com/guide/topics/sensors/sensors_motion.html

Tidak ada komentar:

Posting Komentar