• Tidak ada hasil yang ditemukan

Orientasi: Yaw (Azimuth), Pitch & Roll

Dalam dokumen IF MATERI MOBILE PROGRAMMING (Halaman 93-101)

Dengan mengkombinasikan sensor accelerometer dan magnetometer maka dapat diperoleh pitch, roll dan yaw. Khusus untuk yaw, posisi yang didapat sesuai dengan medan magnet bumi sehingga dapat digunakan sebagai kompas. Ini sebabnya posisi yaw sering disebut disebut azimuth.

Gambar berikut memperlihatkan dengan jelas apa yang disebut yaw, pitch dan roll.

Ketiga informasi ini (azimuth, roll, pitch) dapat dimanfaaatkan untuk banyak hal. Azimuth dapat digunakan untuk kompas dan dikombinasikan dengan GPS bermanfaat untuk augmented reality. Dengan GPS kita bisa mengetahui posisi device, tapi kita tidak mengetahui ke arah mana device menghadap. Tetapi jika GPS dikombinasikan dengan informasi azimuth dan pitch maka dapat diketahui ke arah mana device menghadap. Roll dan pitch juga dapat digunakan untuk mengontrol game.

Contoh Augmented Reality

(diambil dari: nilsmengedoht http://www.flickr.com/photos/nilsmengedoht/5109833017/)

Berikut adalah contoh kode untuk mendapatkan tiga orientasi tersebut, penjelasan ada di dalam kode. Pertama, tambahkan tiga Large textview pada layout, beri nama tvAzimuth, tvPitch dan tvRoll.

import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.view.Menu; import android.widget.TextView;

public class MainActivity extends Activity implements SensorEventListener {

private SensorManager mSensorManager;

private Sensor accel;

mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); if (mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){

//device memiliki accelerometer,lanjutkan

accel = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); magneto = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

//register listener

mSensorManager.registerListener(this, accel,

SensorManager.SENSOR_DELAY_NORMAL);

mSensorManager.registerListener(this, magneto,

SensorManager.SENSOR_DELAY_NORMAL);

tvAzimuth = (TextView) findViewById(R.id.tvAzimuth); tvPitch = (TextView) findViewById(R.id.tvPitch); tvRoll = (TextView) findViewById(R.id.tvRoll); }

else {

//tidak punya sensor , tampilkan pesan error

} } float[] mGravity; float[] mGeomagnetic; float azimuth; float pitch; float roll;

public void onSensorChanged(SensorEvent event) { //menggunakan clone, agar persis sama

if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) mGravity = event.values.clone();;

if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) mGeomagnetic = event.values.clone();;

if (mGravity != null && mGeomagnetic != null) { float R[] = new float[9];

float I[] = new float[9]; //ambil rotationmatrix

boolean success = SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic); if (success) {

float orientation[] = new float[3];

SensorManager.getOrientation(R, orientation); // orientation akan terisi: azimut, pitch and roll

// orieantation[0]:azimuth; orieantation[1]:pitch orieantation[2]:roll

// azimuth adalah arah utara-selatan-timur-barat

//dengan Math.toDegreee hasilnya -180 sd 180

azimuth = (float)Math.toDegrees((double)orientation[0]);

//dikonversi jadi 0 sd 360

// 0=Utara, 90=Timur, 180=Selatan, 270=Barat

azimuth = (azimuth + 360) % 360;

//print dua angka belakang koma, agar mudah dibaca

tvAzimuth.setText("Azimuth="+String.format("%6.2f",azimuth));

//pitch adalah rotasi kedepan & belakang

//bayangkan pesawat yg sedang dogfight dikejar musuh

//kemudian naik berputar sehingga berada di belakang musuhnya

pitch = (float) Math.toDegrees((double)orientation[1]); pitch = (pitch + 360) % 360;

tvPitch.setText("Pitch="+String.format("%6.2f",pitch));

//roll adalah rotasi ke kiri dan kekanan

//bayangkan pesawat yg sedang berbelok kekiri dan ke kanan

roll = (float) Math.toDegrees((double)orientation[2]); roll = (roll+ 360) % 360;

tvRoll.setText("roll="+String.format("%6.2f",roll)); }

} } @Override

protected void onPause() {

//app kehilangan fokus (misal user menerima telp),

//lepaskan listener sensor

super.onPause();

mSensorManager.unregisterListener(this); }

@Override

protected void onResume() {

//app kembali, daftarkan lagi listener

super.onResume();

mSensorManager.registerListener(this, accel, SensorManager.SENSOR_DELAY_NORMAL); mSensorManager.registerListener(this, magneto,

SensorManager.SENSOR_DELAY_NORMAL); }

@Override

public void onAccuracyChanged(Sensor arg0, int arg1) {

// TODO Auto-generated method stub

} }

Jalankan di device dan coba lakukan gerakan pitch, roll dan yaw dan perhatikan angka yang didapat.

Catatan: Penjelasan rinci tentang rotationmatrix dapat diperoleh di: http://gentlenav.googlecode.com/files/DCMDraft2.pdf

Location API

Dengan GPS (Global Positioning Service), suatu device dapat diketahui posisi geolokasinya. GPS menggunakan 24 satelit yang memancarkan sinyal secara bersamaan. Sinyal berisi waktu kirim dan posisi satelit. Device akan menerima sinyal satelit itu secara pasif (device tidak memancarkan sinyal, hanya menerima). Berdasarkan kecepatan sinyal sampai ke device maka dapat ditentukan jarak antara device dengan satelit. Minimal diperlukan 4 satelit berbeda untuk menentukan lokasi. Selain GPS, Rusia mengembangkan sistem serupa yang disebut GLONASS dan Eropa mengembangkan

yang memanfaatkan cell tower dan wifi. GPS lebih akurat dibandingkan network location provider, tetapi membutuhkan waktu lebih lama, akses ke langit dan lebih boros batere. Android menyediakan location API yang mengatur provider lokasi (GPS, network atau pasif).

Kita akan mencoba membuat aplikasi sederhana yang memanfaatkan lokasi. Untuk lebih memahami proses pengambilan lokasi, jalankan app langsung pada device (lihat subbab accelerometer untuk caranya).

Buat project baru. Edit AndroidManifest.xml karena app membutuhkan ijin dari user untuk mengakses lokasi. Gunakan ACCESS_COARSE_LOCATION untuk lokasi berdasarkan network dan ACCESS_FINE_LOCATION untuk lokasi berdasarkan GPS. Jika kita menggunakan FINE_LOCATION maka tidak perlu lagi meminta COARSE_LOCATION karena otomatis akan masuk.

Untuk mengambil lokasi, kita akan activity yang meng-implement LocationListener dan kemudian dipassing ke LocationManager.

Pertama tambahkan tiga textview dalam activity_main.xml. Ganti id dengan tvStatus, tvLat dan tvLng.

Berikut adalah code untuk class MainActivity, perhatikan comment yang ada. Jalankan langsung di-device.

import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Bundle; import android.app.Activity; import android.content.Context; import android.text.format.Time; import android.view.Menu; import android.widget.TextView;

public class MainActivity extends Activity implements LocationListener {

TextView tvLat; TextView tvLng; TextView tvStatus; double lat; double lng; long minTime; float minDistance; String locProvider; LocationManager locMgr; @Override

protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

tvStatus = (TextView) findViewById(R.id.tvStatus); tvLat = (TextView) findViewById(R.id.tvLat); tvLng = (TextView) findViewById(R.id.tvLng); // ambil location manager

locMgr = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);

//ambil lokasi terakhir berdasarkan network agar cepat

//user dapat kesal jika diawal menunggu terlalu lama app mendapatkan lokasi

tvStatus.setText("ambil lokasi terakhir berdasarkan network"); locProvider = LocationManager.NETWORK_PROVIDER;

Location lastKnownLocation = locMgr.getLastKnownLocation(locProvider); lat = lastKnownLocation.getLatitude();

lng = lastKnownLocation.getLongitude(); tvLat.setText(String.valueOf(lat)); tvLng.setText(String.valueOf(lng));

//sambil user melakukan aktivitas2 (misalnya)

//maka ambil lokasi yang lebih akurat dan terus mendengarkan

//perubahan lokasi device

//selanjutnya plih provider yang tinggi akurasinya

//dengan mengeset Criteria, tapi ingat semakin tinggi

//akurasi maka semakin boros menggunakan batere

//berdasarkan kriteria, sistem akan memberikan

//provider yang paling tepat

locProvider = locMgr.getBestProvider(cr, false);

//1 menit: waktu refresh lokasi dalam milidetik (1*60*1000)

//pilih selama mungkin untuk menghemat batere tapi

//user masih bisa menerima

//long minTime = 1 * 60 * 1000;

minTime = 5 * 1000; //lima detik

//posisi pergeseran dalam meter

//lokasi akan diupdate jika telah melewati batas distance

minDistance = 1;

//onResume akan dipanggil dan mulai mendengarkan pergantian lokasi

}

@Override

protected void onResume() {

//mulai mendengarkan dari awal dan juga saat dibangunkan dari pause

super.onResume();

locMgr.requestLocationUpdates(locProvider, minTime, minDistance, this); }

@Override

protected void onPause() {

//lepaskan listener, agar tidak memakan resources saat dipause

super.onPause();

locMgr.removeUpdates(this); }

@Override

public void onLocationChanged(Location loc) {

//dipanggil saat lokasi berubah atau waktu refersh

lat = loc.getLatitude(); lng = loc.getLongitude();

tvLat.setText(String.valueOf(lat)); tvLng.setText(String.valueOf(lng));

Time now = new Time(); now.setToNow();

tvStatus.setText("Direfresh berdasarkan: "+locProvider +" Waktu: "+now.hour+":"+now.minute+":"+now.second);

}

@Override

public void onProviderDisabled(String provider) { }

@Override

public void onProviderEnabled(String provider) { }

@Override

public void onStatusChanged(String provider, int status, Bundle extras) { }

@Override

public boolean onCreateOptionsMenu(Menu menu) {

// Inflate the menu; this adds items to the action bar if it is present.

getMenuInflater().inflate(R.menu.main, menu);

return true; }

}

Jika dijalankan maka pada saat awal lokasi akan diisi dengan cepat berdasarkan data terakhir (network). Perhatikan icon GPS di kiri atas yang menyatakan GPS diaktifkan.

Setelah beberapa saat (bawa device ke dekat jendela atau ruang terbuka). Maka akan muncul lokasi berdasarkan GPS yang diupdate setiap 5 detik. Jika anda berada di dalam ruangan tertutup, maka layar dibawah tidak akan pernah muncul karena lokasi GPS tidak pernah didapatkan:

TBD: caching lokasi (http://developer.android.com/guide/topics/location/strategies.html). Tip: Untuk mendapatkan lokasi berdasarkan GSM, pastikan uncheck Settings -> Applications -> Development -> Allow mock locations

Latihan:

Buatlah app yang menyimpan data lokasi latitude, longitude, dan data

Dalam dokumen IF MATERI MOBILE PROGRAMMING (Halaman 93-101)

Dokumen terkait