แพลตฟอร์ม Android มีเซ็นเซอร์หลายตัวที่ช่วยให้คุณตรวจสอบการเคลื่อนไหวได้ ของอุปกรณ์
เซ็นเซอร์ สถาปัตยกรรมที่เป็นไปได้จะแตกต่างกันไปตามประเภทเซ็นเซอร์ ดังนี้
- เซ็นเซอร์แรงโน้มถ่วง ความเร่งเชิงเส้น เวกเตอร์การหมุน การเคลื่อนไหวที่สำคัญ ตัวนับก้าว และตัวตรวจจับการก้าวอาจทำงานด้วยฮาร์ดแวร์หรือซอฟต์แวร์
- ตัวตรวจวัดความเร่งและเซ็นเซอร์เครื่องวัดการหมุนจะทำงานโดยใช้ฮาร์ดแวร์เสมอ
อุปกรณ์ที่ใช้ระบบ Android ส่วนใหญ่มีตัวตรวจวัดความเร่ง และตอนนี้หลายเครื่องมีตัวตรวจวัดความเร่ง เครื่องวัดการหมุน ความพร้อมใช้งานของเซ็นเซอร์ที่ใช้ซอฟต์แวร์จะผันผวนมากกว่า เนื่องจากมักอาศัยเซ็นเซอร์ฮาร์ดแวร์อย่างน้อย 1 ตัวในการดึงข้อมูล โดยเซ็นเซอร์ที่ใช้ซอฟต์แวร์เหล่านี้จะดึงข้อมูล ข้อมูลจากตัวตรวจวัดความเร่งและเครื่องวัดค่าความเข้มข้นของสนามแม่เหล็ก หรือจากเครื่องวัดการหมุน
เซ็นเซอร์ตรวจจับการเคลื่อนไหวมีประโยชน์สำหรับการตรวจสอบการเคลื่อนไหวของอุปกรณ์ เช่น การเอียง การสั่น การหมุน หรือ แกว่งไกว ซึ่งมักเป็นไปตามข้อมูลจากผู้ใช้โดยตรง (ตัวอย่างเช่น ผู้ใช้บังคับ รถในเกมหรือผู้ใช้ควบคุมลูกบอลในเกม) แต่ก็อาจเป็นภาพสะท้อนของ สภาพแวดล้อมทางกายภาพที่อุปกรณ์นั่งอยู่ (เช่น เคลื่อนที่ไปกับคุณขณะขับรถ รถของคุณ) ในกรณีแรก คุณจะตรวจสอบการเคลื่อนไหวที่สัมพันธ์กับกรอบอ้างอิงของอุปกรณ์ หรือกรอบอ้างอิงของแอปพลิเคชัน ในกรณีที่ 2 คุณกำลังติดตามการเคลื่อนไหว กรอบอ้างอิงของโลกได้ ปกติแล้วเซ็นเซอร์ตรวจจับการเคลื่อนไหวจะไม่นำมาใช้เพื่อตรวจสอบ ตำแหน่งของอุปกรณ์ แต่สามารถใช้กับเซ็นเซอร์อื่นๆ เช่น เซ็นเซอร์สนามแม่เหล็กไฟฟ้า กำหนดตำแหน่งของอุปกรณ์ที่สัมพันธ์กับกรอบอ้างอิงของโลก (ดูข้อมูลเพิ่มเติมที่เซ็นเซอร์ตำแหน่ง ข้อมูล)
เซ็นเซอร์ตรวจจับการเคลื่อนไหวทั้งหมดจะแสดงผลอาร์เรย์หลายมิติของค่าเซ็นเซอร์สำหรับ SensorEvent
แต่ละรายการ เช่น ในระหว่างเหตุการณ์เซ็นเซอร์เดียว ตัวตรวจวัดความเร่งจะแสดงข้อมูลแรงเร่งสำหรับแกนพิกัดทั้ง 3 แกน และเครื่องวัดการหมุนจะแสดงข้อมูลอัตราการหมุนสำหรับแกนพิกัดทั้ง 3 แกน ค่าข้อมูลเหล่านี้จะแสดงในอาร์เรย์ float
(values
) รวมถึงSensorEvent
อื่นๆ
พารามิเตอร์ ตารางที่ 1 สรุปเซ็นเซอร์ตรวจจับการเคลื่อนไหวที่มีให้บริการบนแพลตฟอร์ม Android
ตารางที่ 1 เซ็นเซอร์ตรวจจับการเคลื่อนไหวที่รองรับในแพลตฟอร์ม Android
เซ็นเซอร์ | ข้อมูลเหตุการณ์เซ็นเซอร์ | คำอธิบาย | หน่วยวัด |
---|---|---|---|
TYPE_ACCELEROMETER |
SensorEvent.values[0] |
แรงเร่งตามแกน x (รวมแรงโน้มถ่วง) | m/s2 |
SensorEvent.values[1] |
แรงเร่งตามแนวแกน y (รวมถึงแรงโน้มถ่วง) | ||
SensorEvent.values[2] |
แรงเร่งตามแกน z (รวมถึงแรงโน้มถ่วง) | ||
TYPE_ACCELEROMETER_UNCALIBRATED |
SensorEvent.values[0] |
วัดความเร่งตามแกน X โดยไม่มีการชดเชยการให้น้ำหนักพิเศษ | ม./วินาที2 |
SensorEvent.values[1] |
วัดความเร่งตามแกน Y โดยไม่มีการชดเชยการให้น้ำหนักพิเศษ | ||
SensorEvent.values[2] |
ความเร่งที่วัดได้ตามแกน Z โดยไม่ชดเชยความเบี่ยงเบน | ||
SensorEvent.values[3] |
ความเร่งที่วัดได้ตามแกน X พร้อมการชดเชยการให้น้ำหนักพิเศษโดยประมาณ | ||
SensorEvent.values[4] |
การเร่งที่วัดได้ตามแกน Y พร้อมค่าชดเชยความเบี่ยงเบนโดยประมาณ | ||
SensorEvent.values[5] |
การเร่งความเร็วที่วัดได้ตามแกน Z พร้อมค่าชดเชยความเบี่ยงเบนโดยประมาณ | ||
TYPE_GRAVITY |
SensorEvent.values[0] |
แรงโน้มถ่วงตามแกน x | m/s2 |
SensorEvent.values[1] |
แรงโน้มถ่วงตามแกน y | ||
SensorEvent.values[2] |
แรงโน้มถ่วงตามแกน z | ||
TYPE_GYROSCOPE |
SensorEvent.values[0] |
อัตราการหมุนรอบแกน x | เรเดียน/วินาที |
SensorEvent.values[1] |
อัตราการหมุนรอบแกน y | ||
SensorEvent.values[2] |
อัตราการหมุนรอบแกน z | ||
TYPE_GYROSCOPE_UNCALIBRATED |
SensorEvent.values[0] |
อัตราการหมุน (ไม่มีการชดเชยการเลื่อน) รอบแกน x | rad/วินาที |
SensorEvent.values[1] |
อัตราการหมุน (โดยไม่ชดเชยความคลาดเคลื่อน) รอบแกน y | ||
SensorEvent.values[2] |
อัตราการหมุน (โดยไม่ชดเชยความคลาดเคลื่อน) รอบแกน z | ||
SensorEvent.values[3] |
การเคลื่อนที่โดยประมาณรอบแกน x | ||
SensorEvent.values[4] |
การดริฟต์โดยประมาณรอบแกน y | ||
SensorEvent.values[5] |
การดริฟต์โดยประมาณรอบแกน z | ||
TYPE_LINEAR_ACCELERATION |
SensorEvent.values[0] |
แรงเร่งตามแกน x (ไม่รวมแรงโน้มถ่วง) | m/s2 |
SensorEvent.values[1] |
แรงเร่งตามแกน Y (ไม่รวมแรงโน้มถ่วง) | ||
SensorEvent.values[2] |
แรงเร่งตามแกน z (ไม่รวมแรงโน้มถ่วง) | ||
TYPE_ROTATION_VECTOR |
SensorEvent.values[0] |
คอมโพเนนต์เวกเตอร์การหมุนตามแกน x (x * sin(θ/2)) | ไม่มีหน่วย |
SensorEvent.values[1] |
คอมโพเนนต์เวกเตอร์การหมุนตามแกน y (y * sin(θ/2)) | ||
SensorEvent.values[2] |
ส่วนประกอบของเวกเตอร์การหมุนตามแกน z (z * sin(เพื่อไม่ให้เป็นความจริง/2)) | ||
SensorEvent.values[3] |
องค์ประกอบเชิง scalar ของเวกเตอร์การหมุน ((cos(θ/2)).1 | ||
TYPE_SIGNIFICANT_MOTION |
ไม่มี | ไม่มีข้อมูล | ไม่มี |
TYPE_STEP_COUNTER |
SensorEvent.values[0] |
จำนวนขั้นตอนที่ผู้ใช้ทำตั้งแต่รีบูตครั้งล่าสุดขณะเซ็นเซอร์ เปิดใช้งาน แล้ว | จำนวนก้าว |
TYPE_STEP_DETECTOR |
ไม่มี | ไม่มีข้อมูล | ไม่มี |
1 คอมโพเนนต์สเกลาร์เป็นค่าที่ไม่บังคับ
เซ็นเซอร์เวกเตอร์การหมุนและเซ็นเซอร์แรงโน้มถ่วงเป็นเซ็นเซอร์สำหรับการเคลื่อนไหวที่ใช้บ่อยที่สุด การตรวจจับและการตรวจสอบ เซ็นเซอร์เวกเตอร์การหมุนมีความอเนกประสงค์เป็นพิเศษและสามารถใช้ในงานต่างๆ ที่เกี่ยวข้องกับการเคลื่อนไหวได้มากมาย เช่น การตรวจจับท่าทางสัมผัส การตรวจสอบการเปลี่ยนแปลงเชิงมุม และการตรวจสอบการเปลี่ยนแปลงการวางแนวแบบสัมพัทธ์ ตัวอย่างเช่น เซ็นเซอร์เวกเตอร์แบบหมุนเหมาะอย่างยิ่งหากคุณ กำลังพัฒนาเกม แอปพลิเคชันเทคโนโลยีความจริงเสริม (AR) เข็มทิศ 2 มิติหรือ 3 มิติ หรือแอปป้องกันภาพสั่นไหว ในกรณีส่วนใหญ่ การใช้เซ็นเซอร์เหล่านี้เป็นทางเลือกที่ดีกว่าการใช้ ตัวตรวจวัดความเร่งและเซ็นเซอร์สนามแม่เหล็ก หรือเซ็นเซอร์การวางแนว
เซ็นเซอร์ของโครงการโอเพนซอร์ส Android
โครงการโอเพนซอร์ส Android (AOSP) มีเซ็นเซอร์ตรวจจับการเคลื่อนไหวแบบซอฟต์แวร์ 3 ตัว ได้แก่ แรงโน้มถ่วง
เซ็นเซอร์ เซ็นเซอร์ความเร่งเชิงเส้น และเซ็นเซอร์เวกเตอร์การหมุน เซ็นเซอร์เหล่านี้ได้รับการอัปเดตใน
Android 4.0 และตอนนี้ใช้เครื่องวัดการหมุนของอุปกรณ์ (นอกเหนือจากเซ็นเซอร์อื่นๆ) เพื่อปรับปรุงความเสถียรและ
ด้านประสิทธิภาพ หากต้องการลองใช้เซ็นเซอร์เหล่านี้ คุณสามารถระบุโดยใช้เมธอด getVendor()
และเมธอด getVersion()
(ผู้ให้บริการคือ Google LLC หมายเลขเวอร์ชันคือ 3) ระบุเซ็นเซอร์เหล่านี้โดยผู้ให้บริการและ
หมายเลขเวอร์ชันเป็นสิ่งจำเป็นเนื่องจากระบบ Android ถือว่าเซ็นเซอร์ 3 ตัวนี้เป็นเซ็นเซอร์รอง
เซ็นเซอร์ ตัวอย่างเช่น หากผู้ผลิตอุปกรณ์มีเซ็นเซอร์แรงโน้มถ่วงของตัวเอง เซ็นเซอร์แรงโน้มถ่วงของ AOSP จะแสดงเป็นเซ็นเซอร์แรงโน้มถ่วงรอง เซ็นเซอร์ทั้ง 3 ตัวนี้อาศัย
เครื่องวัดการหมุน: หากอุปกรณ์ไม่มีเครื่องวัดการหมุน เซ็นเซอร์เหล่านี้จะไม่แสดงขึ้นและไม่
พร้อมให้ใช้งาน
ใช้เซ็นเซอร์แรงโน้มถ่วง
เซ็นเซอร์แรงโน้มถ่วงจะให้เวกเตอร์ 3 มิติที่ระบุถึง ทิศทางและขนาดของแรงโน้มถ่วง โดยทั่วไป เซ็นเซอร์นี้จะใช้เพื่อระบุการวางแนวสัมพัทธ์ของอุปกรณ์ในพื้นที่ โค้ดต่อไปนี้จะแสดงวิธีการ รับอินสแตนซ์ของเซ็นเซอร์แรงโน้มถ่วงเริ่มต้น
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);
หน่วยจะเหมือนกับหน่วยที่ใช้โดยความเร่ง เซ็นเซอร์ (m/s2) และระบบพิกัดเหมือนกับที่ เซ็นเซอร์การเร่งความเร็ว
หมายเหตุ: เมื่ออุปกรณ์อยู่ในสถานะหยุดนิ่ง ผลลัพธ์ของเซ็นเซอร์แรงโน้มถ่วงควรเหมือนกับผลลัพธ์ของตัวตรวจวัดความเร่ง
ใช้เครื่องวัดความเร่งเชิงเส้น
เซ็นเซอร์ความเร่งเชิงเส้นจะแสดงเวกเตอร์ 3 มิติ แสดงความเร่งตามแกนอุปกรณ์แต่ละแกน ยกเว้นแรงโน้มถ่วง คุณสามารถใช้ค่านี้เพื่อตรวจจับท่าทางสัมผัสได้ ค่านี้ยังใช้เป็นอินพุตสําหรับระบบนำทางด้วยอิเนอร์เชียซึ่งใช้การประมาณตำแหน่งด้วย โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์ความเร่งเชิงเส้นเริ่มต้น
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);
แนวคิดของเซ็นเซอร์นี้คือให้ข้อมูลการเร่งตามความสัมพันธ์ต่อไปนี้
linear acceleration = acceleration - acceleration due to gravity
ปกติแล้วคุณจะใช้เซ็นเซอร์นี้เมื่อคุณต้องการรับข้อมูลความเร่งโดยไม่ส่งผลกระทบต่อ แรงโน้มถ่วง ตัวอย่างเช่น คุณสามารถใช้เซ็นเซอร์นี้เพื่อดูว่ารถของคุณวิ่งเร็วแค่ไหน เชิงเส้น เซ็นเซอร์การเร่งความเร็วจะมีออฟเซ็ตเสมอ ซึ่งคุณต้องถอดออก วิธีที่ง่ายที่สุดในการดำเนินการนี้คือ เพื่อสร้างขั้นตอนการปรับเทียบในแอปพลิเคชันของคุณ ระหว่างการปรับเทียบ คุณสามารถขอให้ผู้ใช้ตั้งค่า อุปกรณ์บนโต๊ะ จากนั้นอ่านค่าออฟเซ็ตของแกนทั้ง 3 แกน จากนั้นจึงลบค่าออฟเซ็ตนั้นออกจากค่าที่อ่านโดยตรงจากเซ็นเซอร์ความเร่งเพื่อหาความเร่งเชิงเส้นจริง
พิกัดของเซ็นเซอร์ ระบบ เหมือนกับที่ระบบใช้โดยเซ็นเซอร์ความเร่ง เช่นเดียวกับหน่วยวัด (m/s2)
ใช้เซ็นเซอร์เวกเตอร์การหมุน
เวกเตอร์การหมุนแสดงการวางแนวของอุปกรณ์โดยเป็นการรวมมุมและ แกน ซึ่งอุปกรณ์หมุนผ่านมุม HIPAA รอบแกน (x, y หรือ z) โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์เวกเตอร์การหมุนเริ่มต้น
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);
องค์ประกอบ 3 รายการของเวกเตอร์การหมุนแสดงดังนี้

โดยที่ขนาดของเวกเตอร์การหมุนเท่ากับ sin(Authorization/2) และทิศทางของ เวกเตอร์การหมุนจะเท่ากับทิศทางของแกนของการหมุน

รูปที่ 1 ระบบพิกัดที่ใช้โดยเซ็นเซอร์เวกเตอร์การหมุน
องค์ประกอบสามอย่างของเวกเตอร์การหมุนเท่ากับองค์ประกอบ 3 ส่วนสุดท้ายของหน่วย quaternion (cos(การเป็นสมาชิก/2), x*sin(แข่งช่วงการนัดหมาย/2), y*sin(โปรดไปที่ ฟีเจอร์ใหม่ๆ ในรูปแบบของ z*sin(การเป็นสมาชิกในวันที่ 2) \ องค์ประกอบของเวกเตอร์การหมุนคือ แบบไม่มีหน่วย แกน x, y และ z จะกำหนดในลักษณะเดียวกับเซ็นเซอร์ความเร่ง ข้อมูลอ้างอิง ระบบพิกัดได้รับการกำหนดให้เป็นพื้นฐานทางคณิตศาสตร์โดยตรง (ดูรูปที่ 1) ระบบพิกัดนี้ มีลักษณะดังต่อไปนี้
- X หมายถึงผลคูณของเวกเตอร์ Y x Z เส้นนี้สัมผัสกับพื้นดินที่ตำแหน่งปัจจุบันของอุปกรณ์และชี้ไปทางทิศตะวันออกโดยประมาณ
- Y คือเส้นสัมผัสกับพื้นตรงตำแหน่งปัจจุบันของอุปกรณ์และชี้ไปยัง คลื่นแม่เหล็ก ขั้วโลกเหนือ
- Z ชี้ไปยังท้องฟ้าและตั้งฉากกับระนาบพื้นดิน
ดูตัวอย่างแอปพลิเคชันที่แสดงวิธีใช้เซ็นเซอร์เวกเตอร์การหมุนได้ที่ RotationVectorDemo.java
ใช้เซ็นเซอร์ตรวจจับการเคลื่อนไหวที่สำคัญ
เซ็นเซอร์ตรวจจับการเคลื่อนไหวที่มีนัยสำคัญจะทริกเกอร์เหตุการณ์ทุกครั้งที่มีการตรวจพบการเคลื่อนไหวที่มีนัยสำคัญ และ ก็จะปิดใช้งานไปเอง การเคลื่อนไหวที่สำคัญ คือการเคลื่อนไหวที่อาจนำไปสู่การเปลี่ยนแปลง ตำแหน่งที่ตั้งของผู้ใช้ เช่น การเดิน ขี่จักรยาน หรือนั่งในรถที่เคลื่อนที่ โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์ตรวจจับการเคลื่อนไหวที่สำคัญเริ่มต้นและวิธีลงทะเบียนโปรแกรมรับฟังเหตุการณ์
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);
ดูข้อมูลเพิ่มเติมได้ที่ TriggerEventListener
ใช้เซ็นเซอร์นับก้าว
เซ็นเซอร์ตัวนับก้าวจะแสดงจํานวนก้าวที่ผู้ใช้เดินนับตั้งแต่การรีบูตครั้งล่าสุดขณะที่เซ็นเซอร์เปิดใช้งาน ตัวนับก้าวมีเวลาในการตอบสนองมากกว่า (สูงสุด 10 วินาที) แต่มากกว่า ความแม่นยำมากกว่าเซ็นเซอร์ตรวจจับก้าวเดิน
หมายเหตุ: คุณต้องประกาศฟิลด์
ACTIVITY_RECOGNITION
สิทธิ์เพื่อให้แอปของคุณใช้เซ็นเซอร์นี้ในอุปกรณ์ที่ใช้
Android 10 (API ระดับ 29) ขึ้นไป
โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของขั้นตอนเริ่มต้น เซ็นเซอร์ตัวนับ:
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);
หากต้องการประหยัดแบตเตอรี่ในอุปกรณ์ที่ใช้แอปของคุณ คุณควรใช้คลาส JobScheduler
เพื่อดึงค่าปัจจุบันจากเซ็นเซอร์ตัวนับก้าวเป็นช่วงๆ แม้ว่าแอปประเภทต่างๆ
ต้องใช้ช่วงเวลาการอ่านเซ็นเซอร์ที่แตกต่างกัน คุณควรทำให้ช่วงเวลานี้เป็น
ให้นานที่สุดเท่าที่จะทำได้ เว้นแต่ว่าแอปของคุณต้องใช้ข้อมูลแบบเรียลไทม์จากเซ็นเซอร์
ใช้เซ็นเซอร์ตรวจจับก้าว
เซ็นเซอร์ตรวจจับการเดินจะทริกเกอร์เหตุการณ์ทุกครั้งที่ผู้ใช้เดิน โดยเวลาในการตอบสนองคาดว่าจะต่ำกว่า 2 วินาที
หมายเหตุ: คุณต้องประกาศฟิลด์
ACTIVITY_RECOGNITION
สิทธิ์เพื่อให้แอปของคุณใช้เซ็นเซอร์นี้ในอุปกรณ์ที่ใช้
Android 10 (API ระดับ 29) ขึ้นไป
โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของขั้นตอนเริ่มต้น เซ็นเซอร์ตรวจจับ:
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);
ใช้งานข้อมูลดิบ
เซ็นเซอร์ต่อไปนี้จะให้ข้อมูลดิบเกี่ยวกับแรงเชิงเส้นและแรงบิดที่กระทำกับอุปกรณ์แก่แอป หากต้องการใช้ค่าจาก เซ็นเซอร์เหล่านี้มีประสิทธิภาพ คุณจึงจำเป็นต้องกรองปัจจัยต่างๆ ออกจากสิ่งแวดล้อม เช่น แรงโน้มถ่วง คุณอาจต้องปรับอัลกอริทึมการปรับให้เรียบเนียนกับเทรนด์ด้วย ในการลดสัญญาณรบกวน
ใช้เซ็นเซอร์ความเร่ง
เซ็นเซอร์วัดความเร่งจะวัดความเร่งที่ใช้กับอุปกรณ์ ซึ่งรวมถึงแรงของ แรงโน้มถ่วง โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์การเร่งความเร็วเริ่มต้น
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);
หมายเหตุ: หากแอปกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) หรือ สูงกว่า เซ็นเซอร์นี้ ถูกจำกัดอัตรา
โดยหลักการแล้ว เซ็นเซอร์ความเร่งจะเป็นตัวกำหนดความเร่งที่ใช้ กับอุปกรณ์ (Ad) โดยวัดแรงที่กระทำต่อเซ็นเซอร์ (Fs) เองโดยใช้ความสัมพันธ์ต่อไปนี้

อย่างไรก็ตาม แรงโน้มถ่วงจะส่งผลต่อความเร่งที่วัดได้เสมอตามความสัมพันธ์ต่อไปนี้

ด้วยเหตุนี้ เมื่ออุปกรณ์วางอยู่บนโต๊ะ (และไม่เร่ง) มาตรวัดความเร่งจะอ่านค่า g = 9.81 m/s2 ในทำนองเดียวกัน เมื่ออุปกรณ์อยู่ใน การตกแบบอิสระและจะเร่งความเร็วขึ้นสู่พื้นดินอย่างรวดเร็วด้วยความเร็ว 9.81 เมตร/วินาที2 ตัวตรวจวัดความเร่งอ่านค่าขนาด g = 0 ม./วินาที2 ดังนั้น ในการวัดผล ความเร่งที่แท้จริงของอุปกรณ์ การนำการมีส่วนร่วมของแรงโน้มถ่วงออกจาก ข้อมูลจากตัวตรวจวัดความเร่ง ซึ่งทำได้โดยใช้ตัวกรอง High Pass ในทางกลับกัน คุณสามารถใช้ฟิลเตอร์ Low Pass เพื่อแยกแรงโน้มถ่วง ตัวอย่างต่อไปนี้แสดงวิธีดำเนินการ
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]; }
หมายเหตุ: คุณจะใช้เทคนิคต่างๆ เพื่อกรองข้อมูลเซ็นเซอร์ได้ ตัวอย่างโค้ดข้างต้นใช้ค่าคงที่ของตัวกรองแบบง่าย (อัลฟ่า) ในการสร้างตัวกรองโลว์พาส ตัวกรองนี้ ค่าคงที่ได้มาจากค่าคงที่เวลา (t) ซึ่งเป็นการแสดงเวลาคร่าวๆ ของเวลาในการตอบสนองที่ ตัวกรองจะเพิ่มไปยังเหตุการณ์เซ็นเซอร์และอัตราการนำส่งเหตุการณ์ของเซ็นเซอร์ (dt) ตัวอย่างโค้ดใช้ค่าอัลฟ่า 0.8 เพื่อสาธิต หากคุณใช้วิธีการกรองนี้ คุณอาจต้อง เพื่อเลือกค่าอัลฟ่าอื่น
ตัวตรวจวัดความเร่งใช้พิกัดเซ็นเซอร์มาตรฐาน ระบบ ในทางปฏิบัติ จะมีการใช้เงื่อนไขต่อไปนี้เมื่ออุปกรณ์วางอยู่ ราบเรียบบนโต๊ะตามแนวที่เป็นธรรมชาติ
- หากคุณกดอุปกรณ์ทางด้านซ้าย (เพื่อให้อุปกรณ์เคลื่อนที่ไปทางขวา) ค่าความเร่งในแนว x จะบวก
- หากคุณกดอุปกรณ์ที่ด้านล่าง (เพื่อให้อุปกรณ์เคลื่อนออกจากคุณ) ค่าความเร่งในแนวตั้งจะเป็นบวก
- หากคุณดันอุปกรณ์ขึ้นฟ้าด้วยความเร่ง A m/s2 ค่าความเร่ง z จะเท่ากับ A + 9.81 ซึ่งสอดคล้องกับความเร่งของอุปกรณ์ (+A m/s2) ลบด้วยแรงโน้มถ่วง (-9.81 m/s2)
- อุปกรณ์อยู่กับที่จะมีค่าความเร่งอยู่ที่ +9.81 ซึ่งสอดคล้องกับ ความเร่งของอุปกรณ์ (0 ม./วินาที2 ลบด้วยแรงโน้มถ่วง ซึ่งก็คือ -9.81 m/s2)
โดยทั่วไปแล้ว ตัวตรวจวัดความเร่งเป็นเซ็นเซอร์ที่ดีที่จะใช้หากคุณกำลังตรวจสอบการเคลื่อนไหวของอุปกรณ์ โทรศัพท์มือถือและแท็บเล็ตที่ใช้ Android เกือบทุกรุ่นจะมีมาตรวัดความเร่ง ซึ่งใช้พลังงานน้อยกว่าเซ็นเซอร์การเคลื่อนไหวอื่นๆ ประมาณ 10 เท่า ข้อเสียอย่างหนึ่งคือคุณอาจต้องใช้ตัวกรอง Low Pass และ High Pass เพื่อกำจัดแรงโน้มถ่วงและลดเสียงรบกวน
ใช้เครื่องวัดการหมุน
เซ็นเซอร์วัดความเฉื่อยจะวัดอัตราการหมุนเป็น rad/s รอบแกน x, y และ z ของอุปกรณ์ โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของไจโรสโคปเริ่มต้น
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);
หมายเหตุ: หากแอปกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป เซ็นเซอร์นี้จะจำกัดอัตรา
ระบบพิกัดของเซ็นเซอร์จะเหมือนกับที่ใช้กับเซ็นเซอร์ความเร่ง การหมุนเวียนเป็นค่าบวกใน ทิศทางทวนเข็มนาฬิกา ซึ่งก็คือผู้สังเกตการณ์ที่มอง จากตำแหน่งที่เป็นบวกบนแกน x, y หรือ z บนอุปกรณ์ที่อยู่ในตำแหน่งต้นทางจะรายงาน การหมุนบวกหากดูเหมือนว่าอุปกรณ์หมุนทวนเข็มนาฬิกา นี่คือ คำจำกัดความทางคณิตศาสตร์มาตรฐานของการหมุนเวียนเชิงบวก และไม่เหมือนกับคำนิยามสำหรับ การหมุนที่เซ็นเซอร์การวางแนวใช้
โดยปกติแล้ว เอาต์พุตของเครื่องวัดการหมุนจะรวมอยู่เสมอเพื่อคำนวณหาการหมุนที่อธิบาย การเปลี่ยนแปลงมุมต่างๆ เมื่อเวลาผ่านไป เช่น
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; }
อุปกรณ์วัดการหมุนมาตรฐานจะให้ข้อมูลการหมุนดิบโดยไม่มีการกรองหรือการแก้ไขสัญญาณรบกวนและค่าเบี่ยงเบน (ความคลาดเคลื่อน) ในทางปฏิบัติ เสียงและการเลื่อนจากเครื่องวัดการหมุนจะก่อให้เกิดข้อผิดพลาดที่จำเป็น ที่ได้รับค่าตอบแทน โดยปกติแล้ว คุณมักจะพิจารณาการลอยตัว (อคติ) และเสียงรบกวนโดยการตรวจสอบเซ็นเซอร์อื่นๆ เช่น เป็นเซ็นเซอร์แรงโน้มถ่วงหรือตัวตรวจวัดความเร่ง
ใช้เครื่องวัดการหมุนที่ไม่ได้ปรับเทียบ
เครื่องวัดการหมุนที่ไม่ได้ปรับเทียบจะคล้ายกับเครื่องวัดการหมุน ยกเว้นว่าจะไม่มีการใช้การชดเชยความคลาดเคลื่อนของเครื่องวัดการหมุนกับอัตราการหมุน อัตราของการหมุนจะยังคงใช้การปรับเทียบจากโรงงานและการชดเชยอุณหภูมิ ที่ไม่ได้ปรับเทียบ
เครื่องวัดการหมุนมีประโยชน์สำหรับข้อมูลการวางแนวภายหลังการประมวลผลและการรวม โดยทั่วไปแล้ว
gyroscope_event.values[0]
จะอยู่ใกล้กับ
uncalibrated_gyroscope_event.values[0] - uncalibrated_gyroscope_event.values[3]
กล่าวคือ
calibrated_x ~= uncalibrated_x - bias_estimate_x
หมายเหตุ: เซ็นเซอร์ที่ไม่ได้ปรับเทียบจะให้ผลดิบมากกว่า และอาจ มีการให้น้ำหนักพิเศษอยู่บ้าง แต่การวัดผลมีการข้ามจากการแก้ไขผ่านการแก้ไขน้อยกว่า การเทียบมาตรฐาน แอปพลิเคชันบางอย่างอาจชอบผลลัพธ์ที่ไม่มีการปรับเทียบเหล่านี้ ซึ่งมีความราบรื่นและมากกว่า เชื่อถือได้ ตัวอย่างเช่น หากแอปพลิเคชันพยายามทำการผสานเซ็นเซอร์ของตนเอง การใส่การสอบเทียบอาจทำให้ผลลัพธ์บิดเบือนได้
นอกจากอัตราการหมุนแล้ว เครื่องวัดการหมุนที่ไม่ได้ปรับยังให้ค่าประมาณ ลอยไปรอบๆ แต่ละแกน โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของ Gyroscope เริ่มต้นที่ไม่มีการสอบเทียบ
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);
ตัวอย่างโค้ดเพิ่มเติม
สาธิตเพิ่มเติมเกี่ยวกับตัวอย่าง BatchStepSensor การใช้ API ที่ระบุไว้ในหน้านี้