Hareket sensörleri

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:

x*sin(θ/2), y*sin(θ/2), z*sin(θ/2)

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:

A_D=-(1/kütle)∑F_S

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

A_D=-g-(1/kütle)∑F_S

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.

Ayrıca şunları da okumalısınız: