Android platformu, cihazın hareketini izlemenize olanak tanıyan çeşitli sensörler sağlar.
Sensörlerin olası mimariler sensör türüne göre değişir:
- Yer çekimi, doğrusal ivme, dönme vektörü, önemli hareket, adım sensör ve adım dedektörü sensörleri donanım tabanlı veya her şeyi kapsıyor.
- İvme ölçer ve jiroskop sensörleri her zaman donanım tabanlı olur.
Android işletim sistemli cihazların çoğunda ivme ölçer bulunur ve çoğunda artık jiroskop da vardır. Yazılım tabanlı sensörlerin kullanılabilirliği Çünkü çoğu zaman bir veya daha fazla donanım sensörünü kullanarak dışı verilerdir. Cihazlara bağlı olarak bu yazılım tabanlı sensörler verilerini ivme ölçer ve manyetometreden veya jiroskoptan alabilir.
Hareket sensörleri; eğme, titreme, döndürme veya kullanabilirsiniz. Hareket genellikle doğrudan kullanıcı girişlerini (örneğin, bir kullanıcıyı doğrudan veya oyunda topu kontrol eden bir kullanıcı) temsil eder. Ancak bu durum, oyunun cihazın bulunduğu fiziksel ortamın (örneğin, araç kullanırken yanınızda olması) arabanızda . İlk örnekte, cihazın referans çerçevesine göre hareketi izliyorsunuz veya uygulamanızın referans çerçevesi; ikincide, hareketinizi gözlemlediğiniz gibi düşünülebilir. Hareket sensörleri genellikle cihaz konumunu izlemek için tek başına kullanılmaz ancak bir cihazın dünya referans çerçevesine göre konumunu belirlemek için jeomanyetik alan sensörü gibi diğer sensörlerle birlikte kullanılabilir (daha fazla bilgi için Konum Sensörleri bölümüne bakın).
Tüm hareket sensörleri, her bir SensorEvent
için çok boyutlu sensör değeri dizilerini döndürür. Örneğin, tek bir sensör etkinliği sırasında ivme ölçer üç koordinat ekseni için ivme kuvveti verilerini, jiroskop ise üç koordinat ekseni için dönme hızı verilerini döndürür. Bu veri değerleri bir float
dizisinde döndürülür
(values
) ve diğer SensorEvent
parametreleridir. Tablo 1'de Android platformunda bulunan hareket sensörleri özetlenmektedir.
Tablo 1. Android platformunda desteklenen hareket sensörleri.
Sensör | Sensör etkinliği verileri | Açıklama | Ölçü birimleri |
---|---|---|---|
TYPE_ACCELEROMETER |
SensorEvent.values[0] |
X ekseni boyunca ivme kuvveti (yerçekimi dahil). | m/s2 |
SensorEvent.values[1] |
Y ekseni üzerindeki ivme kuvveti (yer çekimi dahil). | ||
SensorEvent.values[2] |
Z ekseni boyunca ivme kuvveti (yer çekimi dahil). | ||
TYPE_ACCELEROMETER_UNCALIBRATED |
SensorEvent.values[0] |
X ekseni boyunca herhangi bir sapma telafisi olmadan ölçülen ivme. | m/s2 |
SensorEvent.values[1] |
Y ekseni boyunca herhangi bir sapma telafisi olmadan ölçülen ivme. | ||
SensorEvent.values[2] |
Sapma telafisi olmadan Z ekseni boyunca ölçülen ivme. | ||
SensorEvent.values[3] |
X ekseni boyunca tahmini sapma telafisi ile ölçülen ivme. | ||
SensorEvent.values[4] |
Tahmini önyargı telafisi ile Y ekseni boyunca ölçülen ivme. | ||
SensorEvent.values[5] |
Z ekseni boyunca tahmini sapma telafisi ile ölçülen ivme. | ||
TYPE_GRAVITY |
SensorEvent.values[0] |
X ekseni boyunca yer çekimi kuvveti. | m/s2 |
SensorEvent.values[1] |
Y eksenindeki yer çekimi kuvveti. | ||
SensorEvent.values[2] |
Z ekseni boyunca yer çekimi kuvveti. | ||
TYPE_GYROSCOPE |
SensorEvent.values[0] |
X ekseni etrafındaki dönme hızı. | rad/sn |
SensorEvent.values[1] |
Y ekseni etrafında dönme hızı. | ||
SensorEvent.values[2] |
Z ekseni etrafındaki dönme hızı. | ||
TYPE_GYROSCOPE_UNCALIBRATED |
SensorEvent.values[0] |
X ekseni etrafındaki dönme hızı (sapma telafisi olmadan). | rad/s |
SensorEvent.values[1] |
Y ekseni etrafındaki dönme hızı (sapma telafisi olmadan). | ||
SensorEvent.values[2] |
Z ekseni etrafında dönme hızı (kayma telafisi olmadan). | ||
SensorEvent.values[3] |
X ekseni etrafında tahmini kayma. | ||
SensorEvent.values[4] |
Y ekseni etrafında tahmini kayma. | ||
SensorEvent.values[5] |
Z ekseni etrafında tahmini kayma. | ||
TYPE_LINEAR_ACCELERATION |
SensorEvent.values[0] |
X ekseni boyunca ivme kuvveti (yer çekimi hariç). | m/sn2 |
SensorEvent.values[1] |
Y eksenindeki ivme kuvveti (yer çekimi hariç). | ||
SensorEvent.values[2] |
Z ekseni boyunca ivme kuvveti (yer çekimi hariç). | ||
TYPE_ROTATION_VECTOR |
SensorEvent.values[0] |
x ekseni boyunca dönme vektörü bileşeni (x * sin(θ/2)). | Birimsiz |
SensorEvent.values[1] |
Y ekseni boyunca dönme vektörü bileşeni (y * sin(θ/2)). | ||
SensorEvent.values[2] |
z ekseni boyunca dönme vektörü bileşeni (z * sin(θ/2)). | ||
SensorEvent.values[3] |
Dönme vektörünün skaler bileşeni ((cos(∧/2)).1 | ||
TYPE_SIGNIFICANT_MOTION |
Yok | Yok | Yok |
TYPE_STEP_COUNTER |
SensorEvent.values[0] |
Sensör son yeniden başlatmadan bu yana kullanıcının gerçekleştirdiği adım sayısı etkinleştirildi. | Adımlar |
TYPE_STEP_DETECTOR |
Yok | Yok | Yok |
1 Skaler bileşen isteğe bağlı bir değerdir.
Dönüş vektörü sensörü ve yerçekimi sensörü hareket için en sık kullanılan sensörlerdir tespiti ve takibidir. Dönme vektör sensörü özellikle çok yönlüdür ve çeşitli açılardan hareketleri algılama, açısal değişiklikleri izleme ve göreceli yön değişikliklerini izleme. Örneğin, bir oyun, artırılmış gerçeklik uygulaması, 2 boyutlu veya 3 boyutlu pusula ya da kamera sabitleme uygulaması geliştiriyorsanız dönme vektörü sensörü idealdir. Çoğu durumda, bu sensörleri kullanmak, ivmeölçer ve jeomanyetik alan sensörü veya yön sensörünü kullanmaktan daha iyi bir seçimdir.
Android Açık Kaynak Projesi sensörleri
Android Açık Kaynak Projesi (AOSP), üç yazılım tabanlı hareket sensörü sağlar: yerçekimi sensörü, doğrusal hızlanma sensörü ve dönme vektörü sensörü. Bu sensörlerin güncellendiği zaman:
Android 4.0 çalıştıran ve artık stabiliteyi artırmak ve diğer sensörlere ek olarak bir cihazın jiroskopunu
bazı yolları da görmüştük. Bu sensörleri denemek istiyorsanız getVendor()
yöntemini ve getVersion()
yöntemini kullanarak tanımlayabilirsiniz (tedarikçi firma Google LLC; sürüm numarası 3'tür). Bu sensörleri tedarikçi firmaya ve
Android sistemi bu üç sensörü ikincil sensör olarak algıladığı için sürüm numarası gereklidir
olabilir. Örneğin, bir cihaz üreticisi kendi yerçekimi sensörünü sağlıyorsa AOSP
yer çekimi sensörü ikincil yer çekimi sensörü olarak görünür. Bu sensörlerin üçü de
jiroskop: Bir cihazda jiroskop yoksa bu sensörler görünmez ve
kullanılabilir.
Yer çekimi sensörünü kullanın
Yerçekimi sensörü, yerçekiminin yönünü ve büyüklüğünü gösteren üç boyutlu bir vektör sağlar. Bu sensör genellikle cihazın uzayda göreceli yönünü belirlemek için kullanılır. Aşağıdaki kodda bu işlemin nasıl varsayılan yer çekimi sensörünün bir örneğini alın:
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);
Birimler, hızlanma sensörü tarafından kullanılanlarla (m/s2) aynıdır ve koordinat sistemi, hızlanma sensörü tarafından kullanılanla aynıdır.
Not: Cihaz hareketsizken yerçekimi sensörünün çıkışı, ivme ölçerin çıkışıyla aynı olmalıdır.
Doğrusal ivmeölçeri kullanma
Doğrusal ivme sensörü, size üç boyutlu bir vektörel yerçekimi hariç her bir cihaz eksenindeki ivmeyi temsil eder. Tekliflerinizi otomatikleştirmek ve optimize etmek için bu değeri kullanabilirsiniz. Bu değer, seyir hesabı kullanan bir eylemsiz navigasyon sistemine giriş olarak da kullanılabilir. Aşağıdaki kodda, varsayılan doğrusal hızlanma sensörünün bir örneğinin nasıl alınacağı gösterilmektedir:
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);
Kavramsal olarak bu sensör, aşağıdaki değerlere göre size ivme verilerini sağlar. ilişki:
linear acceleration = acceleration - acceleration due to gravity
Bu sensörü genellikle yerçekimi etkisi olmadan hızlanma verileri elde etmek istediğinizde kullanırsınız. Örneğin, aracınızın ne kadar hızlı gittiğini görmek için bu sensörü kullanabilirsiniz. Doğrusal hızlanma sensöründe her zaman bir ofset bulunur. Bu ofseti kaldırmanız gerekir. Bunu yapmanın en basit yolu bir kalibrasyon adımı oluşturmanız gerekir. Kalibrasyon sırasında kullanıcıdan cihazı bir masaya koymasını ve ardından üç eksenin de ofsetlerini okumasını isteyebilirsiniz. Daha sonra bu değerden gerçek doğrusal değeri elde etmek için ivme sensörünün doğrudan ölçümlerinden uzaklık ivme artışı.
Sensör koordinatı sistemi, ölçü birimleri ve ivme sensörü tarafından kullanılan sistemle aynıdır. (m/sn.2).
Döndürme vektör sensörünü kullanma
Dönme vektörü, cihazın bir eksen (x, y veya z) etrafında θ açısıyla döndüğü bir açı ve eksen kombinasyonu olarak cihazın yönünü temsil eder. Aşağıdakiler kodu, varsayılan dönme vektör sensörünün bir örneğini nasıl alacağınızı gösterir:
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);
Döndürme vektörünün üç öğesi şu şekilde ifade edilir:

Dönme vektörünün büyüklüğü sin(∧/2) ve dönüş vektörünün yönünün dönme vektörü, dönme ekseninin yönüne eşittir.

Şekil 1. Döndürme vektör sensörü tarafından kullanılan koordinat sistemi.
Döndürme vektörünün üç öğesi, bir birim dört boyutlu vektörün son üç bileşenine (cos(θ/2), x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)) eşittir. Dönme vektörünün öğeleri birimsizdir. x, y ve z eksenleri, ivme sensörüyle aynı şekilde tanımlanır. Referans koordinat sistemi, doğrudan ortonormal temel olarak tanımlanır (bkz. Şekil 1). Bu koordinat sistemi aşağıdaki özelliklere sahiptir:
- X, Y x Z vektör çarpımı olarak tanımlanır. Cihazın mevcut konumunda yere teğet geçer ve yaklaşık olarak doğuyu gösterir.
- Y, cihazın mevcut konumunda yere teğet geçer ve coğrafi Kuzey Kutbu'nu gösterir.
- Z gökyüzünü işaret eder ve yer düzlemine diktir.
Dönme vektörü sensörünün nasıl kullanılacağını gösteren örnek bir uygulama için RotationVectorDemo.java dosyasını inceleyin.
Önemli hareket sensörünü kullanın
Önemli hareket sensörü, önemli bir hareket her algılandığında bir etkinlik tetikler ve ardından kendini devre dışı bırakır. Önemli bir hareket, değişime yol açabilecek bir harekettir kullanıcının konumu; Örneğin yürüme, bisiklete binme veya hareket eden bir arabada oturma gibi. Aşağıdaki kodda, varsayılan önemli hareket sensörünün bir örneğinin nasıl alınacağı ve bir etkinlik dinleyicisinin nasıl kaydedileceği gösterilmektedir:
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);
Daha fazla bilgi için TriggerEventListener
inceleyin.
Adım sayacı sensörünü kullanma
Adım sayacı sensörü, kullanıcının son yeniden başlatmadan bu yana attığı adım sayısını sağlar sensör etkinleştiğinde. Adım sayacında daha fazla gecikme (10 saniyeye kadar) ancak daha fazla gecikme var daha doğru sonuçlar verir.
Not:
ACTIVITY_RECOGNITION
uygulamanızın bu sensörü çalışan cihazlarda kullanması için izin verin
Android 10 (API düzeyi 29) veya sonraki sürümler.
Aşağıdaki kodda, varsayılan adımın bir örneğini nasıl alacağınız gösterilmektedir sayaç sensörü:
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);
Uygulamanızı çalıştıran cihazların pilini korumak için
Geçerli değerin alınacağı JobScheduler
sınıf
adım sayacı sensörüne otomatik olarak eklenir. Her ne kadar farklı türde
için farklı sensör okuma aralıklarına ihtiyacınız varsa bu aralığı
mümkün olduğunca uzun süre tanıyın.
Adım algılayıcı sensörünü kullanma
Adım algılayıcı sensörü, kullanıcı her adım attığında bir etkinliği tetikler. Gecikme 2 saniyeden kısa olması beklenir.
Not: Uygulamanızın Android 10 (API düzeyi 29) veya sonraki sürümleri çalıştıran cihazlarda bu sensörü kullanabilmesi için ACTIVITY_RECOGNITION
iznini belirtmeniz gerekir.
Aşağıdaki kodda, varsayılan adımın bir örneğini nasıl alacağınız gösterilmektedir dedektör sensörü:
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);
Ham verilerle çalışma
Aşağıdaki sensörler uygulamanıza doğrusal ve örtüşen görüntüler hakkında ham veriler sağlar Cihaza uygulanan dönme kuvveti. Bu sensörlerden gelen değerleri etkili bir şekilde kullanmak için yerçekimi gibi çevresel faktörleri filtrelemeniz gerekir. Gürültüyü azaltmak için değerlerin eğilimine bir yumuşatma algoritması uygulamanız da gerekebilir.
İvme ölçeri kullanma
İvme sensörü, yer çekimi kuvveti de dahil olmak üzere cihaza uygulanan ivmeyi ölçer. Aşağıdaki kodda, varsayılan ivme sensörünün bir örneğinin nasıl alınacağı gösterilmektedir:
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);
Not: Uygulamanız Android 12 (API düzeyi 31) veya bu sensör daha yüksek sıralı olarak sınırlandırılmıştır.
Kavramsal olarak bir ivme sensörü, sensöre uygulanan kuvvetleri (Fs) ölçerek cihaza uygulanan ivmeyi (Ad) aşağıdaki ilişkiyi kullanarak belirler:

Ancak yer çekimi kuvveti, ölçülen ivmeyi her zaman aşağıdaki ilişkiye göre etkiler:

Bu nedenle, cihaz bir masanın üzerindeyken (ve ivmelenmiyorsa) ivmeölçer g = 9,81 m/s2 değerini okur. Benzer şekilde, cihaz serbest düşüşteyken ve dolayısıyla 9,81 m/s2 hızla yere doğru hızlanırken, ivmeölçeri g = 0 m/s2 değerini gösterir. Bu nedenle, cihazın gerçek ivmesini ölçmek için yerçekimi kuvvetinin katkısı, ivmeölçer verilerinden kaldırılmalıdır. Bu, yüksek geçiren filtre uygulayarak yapılabilir. Öte yandan, düşük geçişli yer çekimi kuvvetini izole etmek için kullanılabilir. Aşağıdaki örnekte, Veriye Dayalı İlişkilendirme özelliğinden nasıl bu:
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]; }
Not: Sensör verilerini filtrelemek için birçok farklı teknik kullanabilirsiniz. Yukarıdaki kod örneğinde, düşük geçiş filtresi oluşturmak için basit bir filtre sabiti (alfa) kullanılmaktadır. Bu filtre sabit değeri, zaman sabitinden (t) türetilir; bu, ilgili süreye ilişkin gecikmenin kabaca bir temsilidir. filtre, sensör etkinliklerini ve sensörün etkinlik iletim hızını (dt) ekler. Kod örneği özelliğinin alfa değeri olarak 0,8 kullanılmıştır. Bu filtreleme yöntemini kullanıyorsanız farklı bir alfa değeri seçmeniz gerekebilir.
İvme ölçerler standart sensör koordinatını kullanır hakkında bilgi edinin. Pratikte bu, cihaz döşeme sırasında aşağıdaki koşulların geçerli olduğu anlamına gelir bir tablo üzerinde doğal yönünde düz olarak:
- Cihazı sol tarafa iterseniz (sağa doğru hareket eder), x ivme değeri pozitiftir.
- Cihazı alttan iterseniz (sizden uzaklaşacak şekilde) y ivme değeri pozitif olur.
- Cihazı A m/s2 ivmesiyle gökyüzüne doğru iterseniz z ivme değeri A + 9,81'e eşittir. Bu değer, cihazın ivmesine (+A m/s2) yer çekimi kuvvetinin (-9,81 m/s2) eklenmesidir.
- Sabit cihazın ivme değeri +9,81'dir. Bu değer, cihazın ivmesine (0 m/s2 eksi yerçekimi kuvveti olan -9,81 m/s2) karşılık gelir.
Genel olarak, cihaz hareketini izliyorsanız ivme ölçer iyi bir sensördür. Android işletim sistemli hemen hemen her cep telefonu ve tablette bulunan ivmeölçer, diğer hareket sensörlerinden yaklaşık 10 kat daha az güç kullanır. Dezavantajlarından biri de düşük geçişli ve yüksek geçişli filtrelerle yer çekimi kuvvetlerini ortadan kaldırır ve gürültüyü azaltır.
Jiroskopu kullanma
Jiroskop, cihazın x, y ve z ekseni etrafındaki dönme hızını rad/sn cinsinden ölçer. Aşağıdaki kodda, varsayılan jiroskop örneğinin nasıl alınacağı gösterilmektedir:
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);
Not: Uygulamanız Android 12'yi (API düzeyi 31) veya daha yeni bir sürümü hedefliyorsa bu sensör hız sınırlıdır.
Sensörün koordinat sistemi ivme sensörü için kullanılanla aynıdır. Dönme, saat yönünün tersine doğru pozitiftir. Yani, x, y veya z eksenindeki pozitif bir konumdan bakıldığında, orijinde konumlandırılmış bir cihaz saat yönünün tersine dönüyorsa gözlemci pozitif dönme bildirir. Bu, pozitif dönme işleminin standart matematiksel tanımıdır ve yön sensörü tarafından kullanılan yuvarlanma tanımı ile aynı değildir.
Genellikle jiroskopun çıkışı, adım aralığındaki açı değişimini açıklayan bir dönme hesaplamak için zaman içinde entegre edilir. Örnek:
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; }
Standart jiroskoplar gürültü ve renk değişimleri için herhangi bir filtreleme veya düzeltme yapmadan ham dönme verileri sağlar. kayma (ön yargı). Pratikte, jiroskop gürültüsü ve kayması telafi edilmesi gereken hatalar oluşturur. Kaymayı (ön yargı) ve gürültüyü genellikle aşağıdakiler gibi diğer sensörleri izleyerek belirleyebilirsiniz: olarak kullanabilirsiniz.
Kalibre edilmemiş jiroskopu kullanma
Kalibre edilmemiş jiroskop, dönme hızına jiroskop kayması telafisi uygulanmaması dışında jiroskopa benzer. Fabrika kalibrasyon ve sıcaklık telafisi, dönme hızına uygulanmaya devam eder. Kalibre edilmemiş
jiroskop, yönlendirme sonrası işleme ve yön verilerinin birleştirilmesinde kullanışlıdır. Genel olarak
gyroscope_event.values[0]
, şuna yakın olacak:
uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]
.
Yani,
calibrated_x ~= uncalibrated_x - bias_estimate_x
Not: Kalibre edilmemiş sensörler daha fazla ham sonuç sağlar ve bazı sapmaları da içerir, ancak ölçümlerine kalibrasyondur. Bazı uygulamalar, daha düzgün ve güvenilir oldukları için kalibre edilmemiş sonuçları tercih edebilir. Örneğin, bir uygulama kendi sensör füzyonunu gerçekleştirmeye çalışıyorsa kalibrasyonların uygulanması sonuçları bozabilir.
Kalibre edilmemiş jiroskop, dönüş hızlarına ek olarak yaklaşık 80 metredir. Aşağıdaki kodda, varsayılan kalibre edilmemiş jiroskop örneğinin nasıl alınacağı gösterilmektedir:
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);
Diğer kod örnekleri
İlgili içeriği oluşturmak için kullanılan BatchStepSensor örneği ayrıca şunları gösterir: API'lerin kullanımını devre dışı bırakabilirsiniz.