Platform Android menyediakan beberapa sensor yang memungkinkan Anda memantau gerakan perangkat.
Kemungkinan arsitektur sensor bervariasi menurut jenis sensor:
- Sensor gravitasi, akselerasi linier, vektor rotasi, gerakan signifikan, penghitung langkah, dan detektor langkah berbasis hardware atau software.
- Sensor akselerometer dan giroskop selalu berbasis hardware.
Sebagian besar perangkat yang didukung Android memiliki akselerometer, dan banyak perangkat kini menyertakan giroskop. Ketersediaan sensor berbasis software lebih bervariasi karena sering kali bergantung pada satu atau beberapa sensor hardware untuk mendapatkan datanya. Bergantung pada perangkat, sensor berbasis software ini dapat memperoleh data dari akselerometer dan magnetometer atau dari giroskop.
Sensor gerakan berguna untuk memantau gerakan perangkat, seperti kemiringan, goyangan, rotasi, atau ayunan. Pergerakan biasanya merupakan cerminan dari input pengguna langsung (misalnya, pengguna mengemudikan mobil dalam game atau pengguna mengontrol bola dalam game), tetapi juga dapat mencerminkan lingkungan fisik tempat perangkat berada (misalnya, bergerak bersama Anda saat Anda mengemudikan mobil). Dalam kasus pertama, Anda memantau gerakan relatif terhadap kerangka acuan perangkat atau kerangka acuan aplikasi Anda; dalam kasus kedua, Anda memantau gerakan relatif terhadap kerangka acuan dunia. Sensor gerakan sendiri biasanya tidak digunakan untuk memantau posisi perangkat, tetapi dapat digunakan dengan sensor lain, seperti sensor medan geomagnetik, untuk menentukan posisi perangkat relatif terhadap frame referensi dunia (lihat Sensor Posisi untuk mengetahui informasi selengkapnya).
Semua sensor gerak menampilkan array multi-dimensi dari nilai sensor untuk setiap SensorEvent
. Misalnya, selama satu peristiwa sensor, akselerometer akan menampilkan data gaya akselerasi untuk tiga sumbu koordinat, dan giroskop akan menampilkan data laju rotasi untuk tiga sumbu koordinat. Nilai data ini ditampilkan dalam array float
(values
) bersama dengan parameter SensorEvent
lainnya. Tabel 1 merangkum sensor gerak yang tersedia di platform Android.
Tabel 1. Sensor gerakan yang didukung di platform Android.
Sensor | Data peristiwa sensor | Deskripsi | Satuan ukuran |
---|---|---|---|
TYPE_ACCELEROMETER |
SensorEvent.values[0] |
Gaya akselerasi di sepanjang sumbu x (termasuk gravitasi). | m/s2 |
SensorEvent.values[1] |
Gaya akselerasi di sepanjang sumbu y (termasuk gravitasi). | ||
SensorEvent.values[2] |
Gaya akselerasi di sepanjang sumbu z (termasuk gravitasi). | ||
TYPE_ACCELEROMETER_UNCALIBRATED |
SensorEvent.values[0] |
Akselerasi terukur di sepanjang sumbu X tanpa kompensasi bias. | m/s2 |
SensorEvent.values[1] |
Akselerasi terukur di sepanjang sumbu Y tanpa kompensasi bias. | ||
SensorEvent.values[2] |
Akselerasi terukur di sepanjang sumbu Z tanpa kompensasi bias. | ||
SensorEvent.values[3] |
Akselerasi terukur di sepanjang sumbu X dengan estimasi kompensasi bias. | ||
SensorEvent.values[4] |
Akselerasi terukur di sepanjang sumbu Y dengan estimasi kompensasi bias. | ||
SensorEvent.values[5] |
Akselerasi terukur di sepanjang sumbu Z dengan estimasi kompensasi bias. | ||
TYPE_GRAVITY |
SensorEvent.values[0] |
Gaya gravitasi di sepanjang sumbu x. | m/s2 |
SensorEvent.values[1] |
Gaya gravitasi di sepanjang sumbu y. | ||
SensorEvent.values[2] |
Gaya gravitasi di sepanjang sumbu z. | ||
TYPE_GYROSCOPE |
SensorEvent.values[0] |
Laju rotasi di sekitar sumbu x. | rad/s |
SensorEvent.values[1] |
Laju rotasi di sekitar sumbu y. | ||
SensorEvent.values[2] |
Laju rotasi di sekitar sumbu z. | ||
TYPE_GYROSCOPE_UNCALIBRATED |
SensorEvent.values[0] |
Laju rotasi (tanpa kompensasi drift) di sekitar sumbu x. | rad/s |
SensorEvent.values[1] |
Laju rotasi (tanpa kompensasi drift) di sekitar sumbu y. | ||
SensorEvent.values[2] |
Laju rotasi (tanpa kompensasi drift) di sekitar sumbu z. | ||
SensorEvent.values[3] |
Estimasi drift di sekitar sumbu x. | ||
SensorEvent.values[4] |
Estimasi drift di sekitar sumbu y. | ||
SensorEvent.values[5] |
Estimasi drift di sekitar sumbu z. | ||
TYPE_LINEAR_ACCELERATION |
SensorEvent.values[0] |
Gaya akselerasi di sepanjang sumbu x (tidak termasuk gravitasi). | m/s2 |
SensorEvent.values[1] |
Gaya akselerasi di sepanjang sumbu y (tidak termasuk gravitasi). | ||
SensorEvent.values[2] |
Gaya akselerasi di sepanjang sumbu z (tidak termasuk gravitasi). | ||
TYPE_ROTATION_VECTOR |
SensorEvent.values[0] |
Komponen vektor rotasi sepanjang sumbu x (x * sin(θ/2)). | Tanpa unit |
SensorEvent.values[1] |
Komponen vektor rotasi sepanjang sumbu y (y * sin(θ/2)). | ||
SensorEvent.values[2] |
Komponen vektor rotasi di sepanjang sumbu z (z * sin(θ/2)). | ||
SensorEvent.values[3] |
Komponen skalar vektor rotasi ((cos(θ/2)).1 | ||
TYPE_SIGNIFICANT_MOTION |
T/A | T/A | T/A |
TYPE_STEP_COUNTER |
SensorEvent.values[0] |
Jumlah langkah yang dilakukan pengguna sejak reboot terakhir saat sensor diaktifkan. | Langkah |
TYPE_STEP_DETECTOR |
T/A | T/A | T/A |
1 Komponen skalar adalah nilai opsional.
Sensor vektor rotasi dan sensor gravitasi adalah sensor yang paling sering digunakan untuk deteksi dan pemantauan gerakan. Sensor vektor rotasi sangat serbaguna dan dapat digunakan untuk berbagai tugas terkait gerakan, seperti mendeteksi gestur, memantau perubahan sudut, dan memantau perubahan orientasi relatif. Misalnya, sensor vektor rotasi ideal jika Anda mengembangkan game, aplikasi augmented reality, kompas 2 dimensi atau 3 dimensi, atau aplikasi stabilisasi kamera. Dalam sebagian besar kasus, menggunakan sensor ini adalah pilihan yang lebih baik daripada menggunakan sensor medan geomagnetik dan akselerometer atau sensor orientasi.
Sensor Proyek Open Source Android
Android Open Source Project (AOSP) menyediakan tiga sensor gerakan berbasis software: sensor gravitasi, sensor akselerasi linier, dan sensor vektor rotasi. Sensor ini diperbarui di Android 4.0 dan kini menggunakan giroskop perangkat (selain sensor lain) untuk meningkatkan stabilitas dan performa. Jika ingin mencoba sensor ini, Anda dapat mengidentifikasinya menggunakan metode getVendor()
dan metode getVersion()
(vendornya adalah Google LLC; nomor versinya adalah 3). Mengidentifikasi sensor ini berdasarkan vendor dan nomor versi diperlukan karena sistem Android menganggap ketiga sensor ini sebagai sensor sekunder. Misalnya, jika produsen perangkat menyediakan sensor gravitasi mereka sendiri, maka sensor gravitasi AOSP akan muncul sebagai sensor gravitasi sekunder. Ketiga sensor ini mengandalkan
giroskop: jika perangkat tidak memiliki giroskop, sensor ini tidak akan muncul dan tidak
tersedia untuk digunakan.
Gunakan sensor gravitasi
Sensor gravitasi menyediakan vektor tiga dimensi yang menunjukkan arah dan magnitudo gravitasi. Biasanya, sensor ini digunakan untuk menentukan orientasi relatif perangkat di ruang. Kode berikut menunjukkan cara mendapatkan instance sensor gravitasi default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
Unitnya sama dengan yang digunakan oleh sensor akselerasi (m/s2), dan sistem koordinatnya sama dengan yang digunakan oleh sensor akselerasi.
Catatan: Saat perangkat dalam keadaan istirahat, output sensor gravitasi harus sama dengan output akselerometer.
Gunakan akselerometer linear
Sensor akselerasi linear memberi Anda vektor tiga dimensi yang merepresentasikan akselerasi di sepanjang setiap sumbu perangkat, tidak termasuk gravitasi. Anda dapat menggunakan nilai ini untuk melakukan deteksi gestur. Nilai ini juga dapat berfungsi sebagai input ke sistem navigasi inersia, yang menggunakan perhitungan posisi mati. Kode berikut menunjukkan cara mendapatkan instance sensor akselerasi linear default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
Secara konseptual, sensor ini memberi Anda data akselerasi sesuai dengan hubungan berikut:
linear acceleration = acceleration - acceleration due to gravity
Anda biasanya menggunakan sensor ini saat ingin mendapatkan data akselerasi tanpa pengaruh gravitasi. Misalnya, Anda dapat menggunakan sensor ini untuk melihat seberapa cepat mobil Anda berjalan. Sensor akselerasi linear selalu memiliki offset, yang harus Anda hapus. Cara paling sederhana untuk melakukannya adalah dengan membuat langkah kalibrasi ke dalam aplikasi Anda. Selama kalibrasi, Anda dapat meminta pengguna untuk meletakkan perangkat di atas meja, lalu membaca offset untuk ketiga sumbu. Anda kemudian dapat mengurangi offset tersebut dari pembacaan langsung sensor akselerasi untuk mendapatkan akselerasi linear yang sebenarnya.
Sistem koordinat sensor sama dengan yang digunakan oleh sensor akselerasi, begitu juga dengan satuan ukurnya (m/s2).
Gunakan sensor vektor rotasi
Vektor rotasi merepresentasikan orientasi perangkat sebagai kombinasi sudut dan sumbu, yang di dalamnya perangkat telah berputar melalui sudut θ di sekitar sumbu (x, y, atau z). Kode berikut menunjukkan cara mendapatkan instance sensor vektor rotasi default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR);
Tiga elemen vektor rotasi dinyatakan sebagai berikut:

Dengan besarnya vektor rotasi sama dengan sin(θ/2), dan arah vektor rotasi sama dengan arah sumbu rotasi.

Gambar 1. Sistem koordinat yang digunakan oleh sensor vektor rotasi.
Tiga elemen vektor rotasi sama dengan tiga komponen terakhir quaternion unit (cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)). Elemen vektor rotasi tidak memiliki satuan. Sumbu x, y, dan z ditentukan dengan cara yang sama seperti sensor akselerasi. Sistem koordinat referensi ditentukan sebagai basis ortonormal langsung (lihat gambar 1). Sistem koordinat ini memiliki karakteristik berikut:
- X didefinisikan sebagai produk vektor Y x Z. Arahnya tangensial ke tanah di lokasi perangkat saat ini dan mengarah kira-kira ke Timur.
- Y bersinggungan dengan tanah di lokasi perangkat saat ini dan mengarah ke Kutub Utara geomagnetik.
- Z menunjuk ke arah langit dan tegak lurus dengan bidang tanah.
Untuk aplikasi contoh yang menunjukkan cara menggunakan sensor vektor rotasi, lihat RotationVectorDemo.java.
Gunakan sensor gerak yang signifikan
Sensor gerakan signifikan memicu peristiwa setiap kali gerakan signifikan terdeteksi dan kemudian menonaktifkan dirinya sendiri. Pergerakan signifikan adalah pergerakan yang dapat menyebabkan perubahan lokasi pengguna; misalnya, berjalan kaki, bersepeda, atau duduk di dalam mobil yang bergerak. Kode berikut menunjukkan cara mendapatkan instance sensor gerakan signifikan default dan cara mendaftarkan pemroses peristiwa:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val mSensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION) val triggerEventListener = object : TriggerEventListener() { override fun onTrigger(event: TriggerEvent?) { // Do work } } mSensor?.also { sensor -> sensorManager.requestTriggerSensor(triggerEventListener, sensor) }
Java
private SensorManager sensorManager; private Sensor sensor; private TriggerEventListener triggerEventListener; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_SIGNIFICANT_MOTION); triggerEventListener = new TriggerEventListener() { @Override public void onTrigger(TriggerEvent event) { // Do work } }; sensorManager.requestTriggerSensor(triggerEventListener, mSensor);
Untuk informasi selengkapnya, lihat TriggerEventListener
.
Gunakan sensor penghitung langkah
Sensor penghitung langkah memberikan jumlah langkah yang dilakukan pengguna sejak dimulai ulang terakhir kali saat sensor diaktifkan. Penghitung langkah memiliki latensi yang lebih tinggi (hingga 10 detik), tetapi akurasi yang lebih tinggi daripada sensor pendeteksi langkah.
Catatan: Anda harus mendeklarasikan izin
ACTIVITY_RECOGNITION
agar aplikasi Anda dapat menggunakan sensor ini di perangkat yang menjalankan
Android 10 (level API 29) atau yang lebih tinggi.
Kode berikut menunjukkan cara mendapatkan instance sensor penghitung langkah default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
Untuk menghemat baterai di perangkat yang menjalankan aplikasi Anda, Anda harus menggunakan class JobScheduler
untuk mengambil nilai saat ini dari sensor penghitung langkah pada interval tertentu. Meskipun berbagai jenis aplikasi memerlukan interval pembacaan sensor yang berbeda, Anda harus membuat interval ini selama mungkin kecuali jika aplikasi Anda memerlukan data real-time dari sensor.
Gunakan sensor pendeteksi langkah
Sensor langkah detektor memicu suatu peristiwa setiap kali pengguna melangkah. Latensi diharapkan di bawah 2 detik.
Catatan: Anda harus mendeklarasikan izin
ACTIVITY_RECOGNITION
agar aplikasi Anda dapat menggunakan sensor ini di perangkat yang menjalankan
Android 10 (level API 29) atau yang lebih tinggi.
Kode berikut menunjukkan cara mendapatkan instance sensor detektor langkah default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
Bekerja dengan data mentah
Sensor berikut memberikan data mentah kepada aplikasi Anda tentang gaya linear dan rotasi yang diterapkan ke perangkat. Untuk menggunakan nilai dari sensor ini secara efektif, Anda perlu memfilter faktor dari lingkungan, seperti gravitasi. Anda mungkin juga perlu menerapkan algoritma perataan pada tren nilai untuk mengurangi derau.
Gunakan akselerometer
Sensor akselerasi mengukur akselerasi yang diterapkan pada perangkat, termasuk gaya gravitasi. Kode berikut ini menunjukkan cara mendapatkan instance sensor akselerasi default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Catatan: Jika aplikasi Anda menargetkan Android 12 (level API 31) atau yang lebih tinggi, sensor ini akan dibatasi lajunya.
Secara konseptual, sensor akselerasi menentukan akselerasi yang diterapkan ke perangkat (Ad) dengan mengukur gaya yang diterapkan ke sensor itu sendiri (Fs) menggunakan hubungan berikut:

Namun, gaya gravitasi selalu memengaruhi akselerasi yang diukur sesuai dengan hubungan berikut:

Oleh karena itu, saat perangkat berada di atas meja (dan tidak berakselerasi), akselerometer akan membaca besaran g = 9,81 m/s2. Demikian pula, saat perangkat dalam jatuh bebas dan oleh karena itu berakselerasi dengan cepat menuju tanah pada 9,81 m/s2, akselerometernya membaca besaran g = 0 m/s2. Oleh karena itu, untuk mengukur akselerasi perangkat yang sebenarnya, kontribusi gaya gravitasi harus dihapus dari data akselerometer. Ini dapat dilakukan dengan menerapkan filter high-pass. Sebaliknya, filter low-pass dapat digunakan untuk mengisolasi gaya gravitasi. Contoh berikut menunjukkan cara melakukannya:
Kotlin
override fun onSensorChanged(event: SensorEvent) { // 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. val alpha: Float = 0.8f // 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] }
Java
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 berbagai teknik untuk memfilter data sensor. Contoh kode di atas menggunakan konstanta filter sederhana (alfa) untuk membuat filter low-pass. Konstanta filter ini berasal dari konstanta waktu (t), yang merupakan representasi kasar latensi yang ditambahkan filter ke peristiwa sensor, dan kecepatan pengiriman peristiwa sensor (dt). Contoh kode menggunakan nilai alfa 0,8 untuk tujuan demonstrasi. Jika menggunakan metode pemfilteran ini, Anda mungkin perlu memilih nilai alfa yang berbeda.
Akselerometer menggunakan sistem koordinat sensor standar. Dalam praktiknya, ini berarti kondisi berikut berlaku saat perangkat diletakkan datar di atas meja dalam orientasi alaminya:
- Jika Anda mendorong perangkat di sisi kiri (sehingga bergerak ke kanan), nilai akselerasi x akan positif.
- Jika Anda mendorong perangkat di bagian bawah (sehingga menjauh dari Anda), nilai akselerasi y adalah positif.
- Jika Anda mendorong perangkat ke arah langit dengan akselerasi A m/s2, nilai akselerasi z sama dengan A + 9,81, yang sesuai dengan akselerasi perangkat (+A m/s2) dikurangi gaya gravitasi (-9,81 m/s2).
- Perangkat yang tidak bergerak akan memiliki nilai akselerasi +9,81, yang sesuai dengan akselerasi perangkat (0 m/s2 dikurangi gaya gravitasi, yaitu -9,81 m/s2).
Secara umum, akselerometer adalah sensor yang baik untuk digunakan jika Anda memantau gerakan perangkat. Hampir setiap handset dan tablet yang didukung Android memiliki akselerometer, dan menggunakan daya sekitar 10 kali lebih sedikit daripada sensor gerakan lainnya. Salah satu kekurangannya adalah Anda mungkin harus menerapkan filter low-pass dan high-pass untuk menghilangkan gaya gravitasi dan mengurangi kebisingan.
Gunakan giroskop
Giroskop mengukur tingkat rotasi dalam rad/s di sekitar sumbu x, y, dan z perangkat. Kode berikut menunjukkan cara mendapatkan instance giroskop default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
Catatan: Jika aplikasi Anda menargetkan Android 12 (level API 31) atau yang lebih tinggi, sensor ini akan dibatasi lajunya.
Sistem koordinat sensor sama dengan yang digunakan untuk sensor akselerasi. Rotasi positif dalam arah berlawanan arah jarum jam; yaitu, pengamat yang melihat dari beberapa lokasi positif pada sumbu x, y, atau z pada perangkat yang diposisikan di titik asal akan melaporkan rotasi positif jika perangkat tampak berputar berlawanan arah jarum jam. Ini adalah definisi matematika standar untuk rotasi positif dan tidak sama dengan definisi untuk roll yang digunakan oleh sensor orientasi.
Biasanya, output giroskop diintegrasikan dari waktu ke waktu untuk menghitung rotasi yang menjelaskan perubahan sudut selama langkah waktu. Contoh:
Kotlin
// Create a constant to convert nanoseconds to seconds. private val NS2S = 1.0f / 1000000000.0f private val deltaRotationVector = FloatArray(4) { 0f } private var timestamp: Float = 0f override fun onSensorChanged(event: SensorEvent?) { // This timestep's delta rotation to be multiplied by the current rotation // after computing it from the gyro sample data. if (timestamp != 0f && event != null) { val dT = (event.timestamp - timestamp) * NS2S // Axis of the rotation sample, not normalized yet. var axisX: Float = event.values[0] var axisY: Float = event.values[1] var axisZ: Float = event.values[2] // Calculate the angular speed of the sample val omegaMagnitude: Float = 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. val thetaOverTwo: Float = omegaMagnitude * dT / 2.0f val sinThetaOverTwo: Float = sin(thetaOverTwo) val cosThetaOverTwo: Float = cos(thetaOverTwo) deltaRotationVector[0] = sinThetaOverTwo * axisX deltaRotationVector[1] = sinThetaOverTwo * axisY deltaRotationVector[2] = sinThetaOverTwo * axisZ deltaRotationVector[3] = cosThetaOverTwo } timestamp = event?.timestamp?.toFloat() ?: 0f val deltaRotationMatrix = FloatArray(9) { 0f } 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; }
Java
// 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; }
Giroskop standar memberikan data rotasi mentah tanpa pemfilteran atau koreksi apa pun untuk derau dan penyimpangan (bias). Dalam praktiknya, derau dan penyimpangan giroskop akan menimbulkan error yang perlu dikompensasi. Anda biasanya menentukan penyimpangan (bias) dan derau dengan memantau sensor lain, seperti sensor gravitasi atau akselerometer.
Gunakan giroskop yang tidak dikalibrasi
Giroskop yang tidak dikalibrasi serupa dengan giroskop, kecuali tidak ada kompensasi penyimpangan giroskop yang diterapkan pada kecepatan rotasi. Kalibrasi pabrik dan kompensasi suhu masih diterapkan pada kecepatan rotasi. Giroskop yang tidak dikalibrasi
berguna untuk pasca-pemrosesan dan menggabungkan data orientasi. Secara umum,
gyroscope_event.values[0]
akan mendekati
uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]
.
Yaitu,
calibrated_x ~= uncalibrated_x - bias_estimate_x
Catatan: Sensor yang tidak dikalibrasi memberikan hasil yang lebih mentah dan mungkin menyertakan beberapa bias, tetapi pengukurannya berisi lebih sedikit loncatan dari koreksi yang diterapkan melalui kalibrasi. Beberapa aplikasi mungkin lebih memilih hasil yang tidak dikalibrasi ini karena lebih lancar dan lebih andal. Misalnya, jika aplikasi mencoba melakukan penggabungan sensornya sendiri, pengenalan kalibrasi justru dapat mendistorsi hasil.
Selain tingkat rotasi, giroskop yang tidak dikalibrasi juga memberikan estimasi penyimpangan di sekitar setiap sumbu. Kode berikut menunjukkan cara mendapatkan instance giroskop tidak terkalibrasi default:
Kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager val sensor: Sensor? = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED)
Java
private SensorManager sensorManager; private Sensor sensor; ... sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE_UNCALIBRATED);
Contoh kode lainnya
Contoh BatchStepSensor lebih lanjut menunjukkan penggunaan API yang dibahas di halaman ini.