Android platformu, hareketi izleyebilmenizi sağlayan çeşitli sensörler sağlar. bir şekilde tanımlar.
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ıdır.
Android destekli çoğu cihazda ivme ölçer bulunur ve artık çoğunda bir ivme ölçer vardır. jiroskop. 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. Cihaza bağlı olarak bu yazılım tabanlı sensörler, ya da ivme ölçerden veya jiroskoptan alınan verileri toplar.
Hareket sensörleri; eğme, titreme, döndürme veya kullanabilirsiniz. Bu 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; ikincisinde gözlemlediğiniz özelliklere göre düşünülebilir. Hareket sensörleri genellikle izleme amacıyla kullanılmaz. Ancak daha başka sensörlerle örneğin, jeomanyetik alan sensörü gibi bir cihazın konumunu dünyanın referans çerçevesine göre belirler (daha fazla bilgi için Konum Sensörleri konusuna bakın ) ekleyin.
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 olayı sırasında ivme ölçer
Üç koordinat eksenine ilişkin ivme kuvveti verileri ve jiroskop dönüş hızını döndürür
verileri de içerir. 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.
Sensör | Sensör etkinlik verileri | Açıklama | Ölçü birimleri |
---|---|---|---|
TYPE_ACCELEROMETER |
SensorEvent.values[0] |
X ekseni boyunca ivme kuvveti (yer çekimi dahil). | m/sn2 |
SensorEvent.values[1] |
Y ekseni üzerindeki ivme kuvveti (yer çekimi dahil). | ||
SensorEvent.values[2] |
Z ekseni üzerindeki ivme kuvveti (yer çekimi dahil). | ||
TYPE_ACCELEROMETER_UNCALIBRATED |
SensorEvent.values[0] |
X ekseni boyunca herhangi bir sapma telafisi olmadan ölçülen ivme. | m/sn2 |
SensorEvent.values[1] |
Y ekseninde herhangi bir sapma telafisi olmadan ölçülen ivme. | ||
SensorEvent.values[2] |
Z ekseni boyunca herhangi bir sapma telafisi olmadan ölçülen ivme. | ||
SensorEvent.values[3] |
X ekseni boyunca tahmini sapma telafisi ile ölçülen ivme. | ||
SensorEvent.values[4] |
Y ekseninde tahmini sapma telafisi ile ölçülen ivme. | ||
SensorEvent.values[5] |
Z ekseni boyunca tahmini sapma telafisi ile ölçülen ivme. | ||
TYPE_GRAVITY |
SensorEvent.values[0] |
X eksenindeki yer çekimi kuvveti. | m/sn2 |
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ında dönme hızı. | rad/sn |
SensorEvent.values[1] |
Y ekseni etrafında dönme hızı. | ||
SensorEvent.values[2] |
Z ekseni etrafında dönme hızı. | ||
TYPE_GYROSCOPE_UNCALIBRATED |
SensorEvent.values[0] |
x ekseni etrafında dönme hızı (kayma telafisi olmadan). | rad/sn |
SensorEvent.values[1] |
y ekseni etrafında dönme hızı (kayma 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 (x * sin(∧/2)) boyunca döndürme vektör bileşeni). | Birimsiz |
SensorEvent.values[1] |
Y eksenindeki döndürme vektör bileşeni (y * sin(∧/2)). | ||
SensorEvent.values[2] |
Z ekseni boyunca döndürme vektör bileşeni (z * sin(∧/2)). | ||
SensorEvent.values[3] |
Dönme vektörünün skaler bileşeni ((cos(başladı/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, dönme jenerasyonunu oyun, artırılmış gerçeklik uygulaması, 2 boyutlu veya 3 boyutlu pusula, kamera sabitleme uygulaması kullanabilirsiniz. Çoğu durumda, bu sensörleri kullanmak ivme ölçer ve jeomanyetik alan sensörü veya yön sensörü olabilir.
Android Açık Kaynak Projesi sensörleri
Android Açık Kaynak Projesi (AOSP) yazılım tabanlı üç hareket sensörü sağlar: yerçekimi
doğrusal ivme sensörü ve dönüş vektörü sensörünü içerir. 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. Denemek istediğiniz bu sensörleri, getVendor()
ve getVersion()
yöntemleriyle tanıyabilirsiniz
(tedarikçi firma Google LLC'dir; 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 bir
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ü, bu hareketin yerini gösteren üç boyutlu bir vektör yer çekiminin yönünü ve büyüklüğünü değiştirirsiniz. Genellikle bu sensör, cihazın cihazın uzaydaki göreceli yönünü. Aşağıdaki kodda bu işlemin nasıl varsayılan yer çekimi sensörünün bir örneğini al:
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ızlandırma tarafından kullanılanlarla aynıdır. sensör (m/sn2) ve koordinat sistemi ivme sensörüne sahiptir.
Not: Cihaz aktif değilken yerçekimi sensörünün çıkışı ivme ölçerinkiyle 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. Değer, aynı zamanda bir aracılı hareket ettirme sistemidir. Aşağıdaki kodda varsayılan doğrusal ivme sensörünün bir örneğini nasıl alırsınız:
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
Genellikle bu sensörü, hızın etkisi olmadan ivme verilerini elde etmek istediğinizde yerçekimi. Örneğin, arabanızın ne kadar hızlı gittiğini görmek için bu sensörü kullanabilirsiniz. Doğrusal ivme sensöründe her zaman bir ofset bulunur. Bunu 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 ardından, üç eksenin ofsetlerini okumak. 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ı sistem, ö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öndürme vektörü, açı ile cihazın yönünün bir kombinasyonu olarak cihazın bir eksen (x, y veya z) eksenindeki bir engelleme açısıyla döndürüldüğü eksendir. 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.
Döndürme vektörünün üç elemanı, bir birimin son üç bileşenine eşittir kuaterniyon (cos(∧/2), x*sin(∧/2), y*sin(∧/2), z*sin(∧/2)). Döndürme 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. Bu, projenin ve yaklaşık Doğu'yu işaret ediyor.
- Y, cihazın mevcut konumunda zemine teğettir ve jeomanyetik kuzey Kutbu.
- 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 bkz. RotationVectorDemo.java işlemiyle bağlantılıdır.
Önemli hareket sensörünü kullanın
Anlamlı hareket sensörü, önemli bir hareket algılandığında bir etkinliği tetikler ve 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 örneği nasıl alınır ve bir etkinlik nasıl kaydedilir? dinleyici:
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 bilgiyi TriggerEventListener
sayfasında bulabilirsiniz.
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:
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 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ışın
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. Arkadaş Bitkiler projesinin bu sensörleri etkili şekilde kullanmak için çevresel, yer çekimi gibi. Trende bir yumuşatma algoritması uygulamanız da gerekebilir. farklı değerler kullanabilirsiniz.
İvme ölçeri kullanma
Bir ivme sensörü, cihaza uygulanan ivmeyi ölçer. Buna kuvvet de dahildir yerçekimi. Aşağıdaki kodda, varsayılan hızlanma sensörünün bir örneğini nasıl alacağınız 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 ivme sensörü, uygulanan ivmeyi belirler sensöre uygulanan kuvvetleri ölçerek (d) cihaza şu ilişkiyi kullanarak kendisi (Fs) olarak değiştirin:
Ancak yer çekimi kuvveti her zaman şu ilişki:
Bu nedenle, cihaz bir masada durduğunda (ve hızlanmadığında) ivme ölçer, g = 9,81 m/sn2 büyüklüğünü okur. Benzer şekilde, cihaz Yere doğru 9,81 m/sn2 hızla hızlanıyorsa, ivme ölçer, g = 0 m/sn2 büyüklüğünü okur. Bu nedenle, cihazın gerçek ivmesi, yer çekimi kuvvetinin katkısı ivme ölçer verilerini görebilirsiniz. Bu, yüksek geçiş filtresi uygulayarak elde edilebilir. Öte yandan, düşük geçişli yerçekimi kuvvetini izole etmek için kullanılabilir. Aşağıdaki örnekte, farklı reklam biçimlerini 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şli filtre 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çin.
İ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 pozitif.
- Cihazı aşağı iterseniz (yani sizden uzaklaşır) y ivme değeri pozitif olmalıdır.
- Cihazı gökyüzüne doğru A m/s2 ivmeyle iterseniz z ivmesi değeri A + 9,81'e eşittir; bu, cihazın ivmesine (+A) karşılık gelir. m/sn2) eksi yerçekimi kuvveti (-9,81 m/sn2).
- Sabit cihazın +9,81 ivme değeri vardır.Bu değer, cihazın ivmesi (0 m/sn2 eksi yer çekimi kuvveti, yani -9,81'dir) m/sn.2).
Genel olarak, cihaz hareketini izliyorsanız ivme ölçer iyi bir sensördür. Android destekli hemen hemen her telefon ve tablette bir ivme ölçer bulunur ve bu cihaz yaklaşık 10 kez ivme ölçer. daha az güç tüketiyor. 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, bir cihazın x, y ve etrafında dönme hızını rad/s cinsinden ölçer z eksenini seçin. Aşağıdaki kodda, varsayılan jiroskopun bir örneğini nasıl alacağınız 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 (API düzeyi 31) veya bu sensör daha yüksek sıralı olarak sınırlandırılmıştır.
Sensörün koordinat sistemi ivme sensörü için kullanılanla aynıdır. Rotasyon pozitif saat yönünün tersine; gözlemci tarafından başlangıç noktasında bulunan bir cihazdaki x, y veya z eksenindeki bazı pozitif konumlardan cihaz saat yönünün tersine dönüyormuş gibi görünüyorsa pozitif döndürme. Bu, pozitif rotasyonun standart matematiksel tanımıdır ve Yön sensörü tarafından kullanılan rulo.
Genellikle, jiroskopun çıktısı zaman içinde entegre edilerek açıklığa kavuşturulan bir döndürme hareketi açı değişimini görebilirsiniz. Ö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ı, dikkat edilmesi gereken hatalara neden olacaktır. yardımcı olur. 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 jiroskop'a benzer,
Tek fark, dönüş hızına jiroskop telafisi uygulanmamasıdır. Fabrika kalibrasyonu
ve sıcaklık dengelemesi, dönüş hızına uygulanmaya devam etmektedir. Kalibre edilmemiş
jiroskop, ileri işleme ve yön verilerinin eritilmesinde yararlı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, kalibre edilmemiş bu sonuçları daha akıcı ve etkili olduğu için tercih edebilir. yardımcı olur. Örneğin, bir uygulama kendi sensör füzyonunu yapmaya çalışıyorsa Hatta kalibrasyon uygulamak sonuçları bozabilir.
Kalibre edilmemiş jiroskop, dönüş hızlarına ek olarak yaklaşık 80 metredir. Aşağıdaki kodda, varsayılan öğenin bir örneğini nasıl alacağınız gösterilmektedir kalibre edilmemiş jiroskop:
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);
Ek 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.