โปรโตคอลอุปกรณ์เชื่อมต่อมนุษย์ (HID) ตัวติดตามศีรษะใช้งานได้กับอุปกรณ์ที่ใช้ Android 13 ขึ้นไป ช่วยให้อุปกรณ์ติดตามศีรษะเชื่อมต่อกับอุปกรณ์ Android ผ่าน USB หรือบลูทูธ และสัมผัสกับเฟรมเวิร์ก Android และแอปผ่าน เซ็นเซอร์ ได้ กรอบ. โปรโตคอลนี้ใช้สำหรับควบคุมเอฟเฟกต์เสียงเสมือนจริง (เสียง 3 มิติ) หน้านี้ใช้คำว่า อุปกรณ์ และ โฮสต์ ในแง่บลูทูธ โดยที่ อุปกรณ์ หมายถึงอุปกรณ์ติดตามศีรษะ และ โฮสต์ หมายถึงโฮสต์ Android
ผู้ผลิตอุปกรณ์จะต้องกำหนดค่าอุปกรณ์ Android ของตนเพื่อให้รองรับโปรโตคอล HID ตัวติดตามส่วนหัว สำหรับข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับการกำหนดค่า โปรดดูที่ Dynamic Sensors README
หน้านี้ถือว่ามีความคุ้นเคยกับแหล่งข้อมูลต่อไปนี้:
โครงสร้างระดับบนสุด
กรอบงาน Android ระบุอุปกรณ์ติดตามส่วนหัวเป็นอุปกรณ์ HID
สำหรับตัวอย่างที่สมบูรณ์ของตัวอธิบาย HID ที่ถูกต้อง โปรดดู ภาคผนวก 1: ตัวอย่างของตัวอธิบาย HID
ที่ระดับบนสุด อุปกรณ์ติดตามส่วนหัวคือคอลเลกชันแอปที่มีหน้า Sensors
( 0x20
) และ Other: Custom
( 0xE1
) ภายในคอลเลกชันนี้ประกอบด้วยช่องข้อมูลหลายช่อง ( อินพุต ) และคุณสมบัติ ( คุณสมบัติ )
คุณสมบัติและฟิลด์ข้อมูล
ส่วนนี้อธิบายคุณสมบัติและฟิลด์ข้อมูลในคอลเลกชันแอปพลิเคชันของอุปกรณ์ติดตามส่วนหัว
คุณสมบัติ: คำอธิบายเซนเซอร์ ( 0x0308
)
คุณสมบัติ Sensor Description ( 0x0308
) เป็นคุณสมบัติสตริง ASCII (8 บิต) แบบอ่านอย่างเดียวซึ่งต้องมีค่าต่อไปนี้:
#AndroidHeadTracker#1.0
คาดว่าจะไม่มีตัวสิ้นสุดค่า null ซึ่งหมายความว่าขนาดรวมของคุณสมบัตินี้คือ 23 อักขระ 8 บิต
คุณสมบัตินี้ทำหน้าที่เป็นตัวแบ่งแยกเพื่อหลีกเลี่ยงการชนกับเซ็นเซอร์แบบกำหนดเองอื่นๆ
คุณสมบัติ: ID เฉพาะถาวร ( 0x0302
)
คุณสมบัติ Persistent Unique ID ( 0x0302
) เป็นอาร์เรย์แบบอ่านอย่างเดียวที่มี 16 องค์ประกอบ แต่ละองค์ประกอบ 8 บิต (รวม 128 บิต) คาดว่าจะไม่มีตัวยุติที่เป็นค่าว่าง คุณสมบัตินี้เป็นทางเลือก
คุณสมบัตินี้อนุญาตให้อุปกรณ์ติดตามศีรษะที่รวมอยู่ในอุปกรณ์เสียงสามารถอ้างอิงอุปกรณ์เสียงที่เชื่อมต่ออยู่ รองรับโครงร่างต่อไปนี้
เครื่องติดตามศีรษะแบบสแตนด์อโลน
หากไม่มีคุณสมบัติ Persistent Unique ID ( 0x0302
) หรือตั้งค่าเป็นศูนย์ทั้งหมด หมายความว่าอุปกรณ์ติดตามส่วนหัวไม่ได้เชื่อมต่อกับอุปกรณ์เสียงอย่างถาวร และสามารถใช้แยกต่างหากได้ เช่น โดยให้ผู้ใช้ด้วยตนเอง เชื่อมโยงอุปกรณ์ติดตามศีรษะกับอุปกรณ์เสียงแยกต่างหาก
อ้างอิงโดยใช้ที่อยู่ MAC ของ Bluetooth
ออคเต็ต | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
ค่า | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | บี | ต | บลูทูธ แมค |
ในรูปแบบนี้ 8 ออคเต็ตแรกต้องเป็น 0
ออคเต็ต 8 และ 9 จะต้องมีค่า ASCII B
และ T
ตามลำดับ และ 6 ออคเต็ตต่อไปนี้จะถูกตีความว่าเป็นที่อยู่ MAC ของบลูทูธ โดยสมมติว่าอุปกรณ์ติดตามส่วนหัวใช้กับอุปกรณ์เสียงใดๆ ที่มี ที่อยู่ MAC นี้
การอ้างอิงโดยใช้ UUID
เมื่อใดก็ตามที่ตั้งค่าบิตที่สำคัญที่สุด (MSB) ของ octet 8 ( ≥0x80
) ฟิลด์จะถูกตีความว่าเป็น UUID ตามที่ระบุไว้ใน RFC-4122 อุปกรณ์เสียงที่เกี่ยวข้องจะมี UUID เดียวกันซึ่งลงทะเบียนบนเฟรมเวิร์ก Android ผ่านกลไกที่ไม่ระบุรายละเอียดซึ่งเฉพาะเจาะจงกับประเภทของการขนส่งที่ใช้
คุณสมบัติ: สถานะการรายงาน ( 0x0316
)
คุณสมบัติ Reporting State ( 0x0316
) เป็นคุณสมบัติการอ่าน/เขียนที่มีความหมายมาตรฐานตามที่กำหนดไว้ในข้อกำหนด HID โฮสต์ใช้คุณสมบัตินี้เพื่อระบุให้อุปกรณ์ทราบว่าเหตุการณ์ใดที่จะรายงาน ใช้เฉพาะค่า No Events ( 0x0840
) และ All Events ( 0x0841
) เท่านั้น
ค่าเริ่มต้นสำหรับฟิลด์นี้จะต้องเป็น No Events และอุปกรณ์จะต้องไม่ได้รับการแก้ไข โดยโฮสต์เท่านั้น
คุณสมบัติ: สถานะพลังงาน ( 0x0319
)
คุณสมบัติ Power State ( 0x0319
) เป็นคุณสมบัติการอ่าน/เขียนที่มีความหมายมาตรฐานตามที่กำหนดไว้ในข้อกำหนด HID โฮสต์ใช้คุณสมบัตินี้เพื่อระบุอุปกรณ์ว่าจะต้องอยู่ในสถานะพลังงานใด โดยจะใช้เฉพาะค่า Full Power ( 0x0851
) และ Power Off ( 0x0855
) เท่านั้น
ค่าเริ่มต้นสำหรับฟิลด์นี้จะถูกกำหนดโดยอุปกรณ์และจะต้องไม่ได้รับการแก้ไขโดยอุปกรณ์ มีเพียงโฮสต์เท่านั้น
คุณสมบัติ: ช่วงเวลารายงาน ( 0x030E
)
คุณสมบัติ Report Interval ( 0x030E
) เป็นคุณสมบัติการอ่าน/เขียนที่มีความหมายมาตรฐานตามที่กำหนดไว้ในข้อกำหนด HID โฮสต์ใช้คุณสมบัตินี้เพื่อระบุให้อุปกรณ์ทราบว่าจะรายงานการอ่านข้อมูลบ่อยเพียงใด หน่วยเป็นวินาที ช่วงที่ถูกต้องสำหรับค่านี้จะถูกกำหนดโดยอุปกรณ์และอธิบายโดยใช้กลไก Physical Min/Max ต้องรองรับอัตราการรายงานอย่างน้อย 50 Hz และอัตราการรายงานสูงสุดที่แนะนำคือ 100 Hz ดังนั้น ช่วงเวลารายงานขั้นต่ำต้องน้อยกว่าหรือเท่ากับ 20 ms และแนะนำให้มากกว่าหรือเท่ากับ 10 ms
ช่องข้อมูล: ค่าที่กำหนดเอง 1 ( 0x0544
)
ช่องค่าที่กำหนดเอง 1 ( 0x0544
) เป็นช่องป้อนข้อมูลที่ใช้สำหรับรายงานข้อมูลการติดตามส่วนหัวจริง เป็นอาร์เรย์ 3 องค์ประกอบ ซึ่งตีความตามกฎ HID ปกติสำหรับค่าฟิสิคัลตามที่ระบุไว้ในส่วน 6.2.2.7 ของข้อกำหนด HID ช่วงที่ถูกต้องสำหรับแต่ละองค์ประกอบคือ [-π, π] rad หน่วยเป็นเรเดียนเสมอ
องค์ประกอบต่างๆ ถูกตีความว่าเป็น: [rx, ry, rz]
โดยที่ [rx, ry, rz]
เป็น เวกเตอร์การหมุน ซึ่งแสดงถึงการแปลงจากหน้าต่างอ้างอิงไปยังกรอบส่วนหัว ขนาดต้องอยู่ในช่วง [0..π]
หน้าต่างอ้างอิงนั้นกำหนดเองได้ แต่โดยทั่วไปจะได้รับการแก้ไขและจะต้องถนัดขวา ยอมรับการดริฟท์เล็กน้อยได้ แกนของหัวคือ:
- X จากหูซ้ายไปขวา
- Y จากด้านหลังศีรษะถึงจมูก (ด้านหลังไปด้านหน้า)
- Z จากคอถึงด้านบนของศีรษะ
ช่องข้อมูล: ค่าที่กำหนดเอง 2 ( 0x0545
)
ช่องค่าที่กำหนดเอง 2 ( 0x0545
) เป็นช่องป้อนข้อมูลที่ใช้สำหรับรายงานข้อมูลการติดตามส่วนหัวจริง เป็นอาร์เรย์จุดคงที่แบบ 3 องค์ประกอบ ซึ่งตีความตามกฎ HID ปกติสำหรับค่าฟิสิคัล หน่วยเป็นเรเดียน/วินาทีเสมอ
องค์ประกอบต่างๆ ถูกตีความว่าเป็น: [vx, vy, vz]
โดยที่ [vx, vy, vz]
เป็น เวกเตอร์การหมุน ซึ่งแสดงถึงความเร็วเชิงมุมของกรอบส่วนหัว (สัมพันธ์กับตัวมันเอง)
ช่องข้อมูล: ค่าที่กำหนดเอง 3 ( 0x0546
)
ฟิลด์ค่าที่กำหนดเอง 3 ( 0x0546
) เป็นฟิลด์อินพุตที่ใช้สำหรับการติดตามความไม่ต่อเนื่องในหน้าต่างอ้างอิง เป็นจำนวนเต็มสเกลาร์ขนาด 8 บิต อุปกรณ์จะต้องเพิ่มขึ้น (โดยมีการพันรอบ) ทุกครั้งที่กรอบอ้างอิงมีการเปลี่ยนแปลง ตัวอย่างเช่น หากอัลกอริธึมตัวกรองการวางแนวที่ใช้สำหรับกำหนดการวางแนวมีการรีเซ็ตสถานะแล้ว ค่านี้ถูกตีความตามกฎ HID ปกติสำหรับค่าฟิสิคัล อย่างไรก็ตาม มูลค่าทางกายภาพและหน่วยไม่สำคัญ ข้อมูลเดียวที่เกี่ยวข้องกับโฮสต์คือค่าที่เปลี่ยนแปลง เพื่อหลีกเลี่ยงปัญหาตัวเลขที่เกี่ยวข้องกับการสูญเสียความแม่นยำในขณะที่แปลงจากหน่วยลอจิคัลไปเป็นหน่วยฟิสิคัล ขอแนะนำให้ตั้งค่าสำหรับค่าต่ำสุดจริง ค่าสูงสุดจริง และเลขชี้กำลังหน่วยเป็นศูนย์สำหรับฟิลด์นี้
โครงสร้างรายงาน
การจัดกลุ่มคุณสมบัติลงในรายงาน (ตามการกำหนดรหัสรายงาน) มีความยืดหยุ่น เพื่อประสิทธิภาพ เราขอแนะนำให้แยกคุณสมบัติอ่านอย่างเดียวออกจากคุณสมบัติอ่าน/เขียน
สำหรับช่องข้อมูล ช่องค่าที่กำหนดเอง 1, 2 และ 3 ต้องอยู่ในรายงานเดียวกันและอยู่ในรายงานเดียวเท่านั้นสำหรับอุปกรณ์ที่กำหนด (คอลเลกชั่นแอป)
ส่งรายงานอินพุต
อุปกรณ์จะต้องส่งรายงานอินพุตเป็นระยะและไม่พร้อมกัน (ผ่านข้อความ HID INPUT) เมื่อตรงตามเงื่อนไขทั้งหมดเหล่านี้:
- คุณสมบัติ Power State ถูกตั้งค่าเป็น Full Power
- คุณสมบัติสถานะการรายงานถูกตั้งค่าเป็นเหตุการณ์ทั้งหมด
- คุณสมบัติช่วงการรายงานไม่เป็นศูนย์
คุณสมบัติช่วงเวลาการรายงานจะกำหนดความถี่ในการส่งรายงาน เมื่อไม่เป็นไปตามเงื่อนไขใดๆ ข้างต้น อุปกรณ์จะต้องไม่ส่งรายงานใดๆ
ความเข้ากันได้ไปข้างหน้าและย้อนกลับ
โปรโตคอล HID ตัวติดตามส่วนหัวใช้รูปแบบการกำหนดเวอร์ชันที่ช่วยให้สามารถอัปเดตได้ ในขณะเดียวกันก็อนุญาตให้มีการทำงานร่วมกันระหว่างโฮสต์และอุปกรณ์ที่ใช้โปรโตคอลเวอร์ชันต่างกัน เวอร์ชันสำหรับโปรโตคอลจะถูกระบุด้วยตัวเลขสองตัว หลักและรอง ซึ่งมีความหมายที่แตกต่างกันตามที่อธิบายไว้ในส่วนต่อไปนี้
เวอร์ชันที่อุปกรณ์รองรับสามารถกำหนดได้โดยการตรวจสอบคุณสมบัติคำอธิบายเซ็นเซอร์ ( 0x0308
)
ความเข้ากันได้ของเวอร์ชันรอง
การเปลี่ยนแปลงในเวอร์ชันรองจะเข้ากันได้แบบย้อนหลังกับเวอร์ชันรองก่อนหน้าซึ่งใช้เวอร์ชันหลักเดียวกัน ในการอัปเดตเวอร์ชันรอง โฮสต์จะละเว้นฟิลด์ข้อมูลเพิ่มเติมและคุณสมบัติ ตัวอย่างเช่น อุปกรณ์ที่ใช้โปรโตคอลเวอร์ชัน 1.6 เข้ากันได้กับโฮสต์ที่รองรับโปรโตคอลเวอร์ชัน 1.x รวมถึงเวอร์ชัน 1.5 ด้วย
ความเข้ากันได้ของเวอร์ชันหลัก
อนุญาตให้ทำการเปลี่ยนแปลงที่เข้ากันไม่ได้กับการเปลี่ยนแปลงเวอร์ชันหลัก เพื่อรองรับเวอร์ชันหลักหลายเวอร์ชันสำหรับการทำงานร่วมกันกับโฮสต์เก่าและใหม่ อุปกรณ์สามารถระบุคอลเลกชันแอปได้หลายรายการในตัวอธิบายรายงาน ตัวอย่างเช่น:
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.5"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
HID_COLLECTION(HID_APPLICATION),
// Feature report 12 (read-only).
HID_REPORT_ID(12),
// Magic value: "#AndroidHeadTracker#2.4"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
...
HID_END_COLLECTION,
};
ในกรณีนี้ โฮสต์สามารถระบุคอลเลกชันแอปต่างๆ ทั้งหมดที่โฆษณาโดยอุปกรณ์ โดยตรวจสอบคุณสมบัติคำอธิบายเซ็นเซอร์เพื่อระบุเวอร์ชันโปรโตคอลที่แต่ละแอปใช้งาน จากนั้นเลือกเวอร์ชันโปรโตคอลล่าสุดที่โฮสต์รองรับ เมื่อเลือกแล้ว โฮสต์จะทำงานกับโปรโตคอลเดียวที่เลือกไว้ตลอดอายุการใช้งานของการเชื่อมต่ออุปกรณ์
ภาคผนวก: ตัวอย่างของตัวอธิบาย HID
ตัวอย่างต่อไปนี้แสดงให้เห็นถึงตัวอธิบาย HID ที่ถูกต้องโดยทั่วไป โดยจะใช้มาโคร C ที่ใช้กันทั่วไป ซึ่งมีอยู่ใน การใช้งานเซ็นเซอร์ HID (ส่วนที่ 4.1)
const unsigned char ReportDescriptor[] = {
HID_USAGE_PAGE_SENSOR,
HID_USAGE_SENSOR_TYPE_OTHER_CUSTOM,
HID_COLLECTION(HID_APPLICATION),
// Feature report 2 (read-only).
HID_REPORT_ID(2),
// Magic value: "#AndroidHeadTracker#1.0"
HID_USAGE_SENSOR_PROPERTY_SENSOR_DESCRIPTION,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(23),
HID_FEATURE(HID_CONST_VAR_ABS),
// UUID.
HID_USAGE_SENSOR_PROPERTY_PERSISTENT_UNIQUE_ID,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(0xFF),
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(16),
HID_FEATURE(HID_CONST_VAR_ABS),
// Feature report 1 (read/write).
HID_REPORT_ID(1),
// 1-bit on/off reporting state.
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_NO_EVENTS,
HID_USAGE_SENSOR_PROPERTY_REPORTING_STATE_ALL_EVENTS,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 1-bit on/off power state.
HID_USAGE_SENSOR_PROPERTY_POWER_STATE,
HID_LOGICAL_MIN_8(0),
HID_LOGICAL_MAX_8(1),
HID_REPORT_SIZE(1),
HID_REPORT_COUNT(1),
HID_COLLECTION(HID_LOGICAL),
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D4_POWER_OFF,
HID_USAGE_SENSOR_PROPERTY_POWER_STATE_D0_FULL_POWER,
HID_FEATURE(HID_DATA_ARR_ABS),
HID_END_COLLECTION,
// 6-bit reporting interval, with values [0x00..0x3F] corresponding to [10ms..100ms].
HID_USAGE_SENSOR_PROPERTY_REPORT_INTERVAL,
HID_LOGICAL_MIN_8(0x00),
HID_LOGICAL_MAX_8(0x3F),
HID_PHYSICAL_MIN_8(10),
HID_PHYSICAL_MAX_8(100),
HID_REPORT_SIZE(6),
HID_REPORT_COUNT(1),
HID_USAGE_SENSOR_UNITS_SECOND,
HID_UNIT_EXPONENT(0xD), // 10^-3
HID_FEATURE(HID_DATA_VAR_ABS),
// Input report 1
// Orientation as rotation vector (scaled to [-pi..pi] rad).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_1,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_32(0x60, 0x4F, 0x46, 0xED), // -314159265
HID_PHYSICAL_MAX_32(0xA1, 0xB0, 0xB9, 0x12), // 314159265
HID_UNIT_EXPONENT(0x08), // 10^-8
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Angular velocity as rotation vector (scaled to [-32..32] rad/sec).
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_2,
HID_LOGICAL_MIN_16(0x01, 0x80), // LOGICAL_MINIMUM (-32767)
HID_LOGICAL_MAX_16(0xFF, 0x7F), // LOGICAL_MAXIMUM (32767)
HID_PHYSICAL_MIN_8(0xE0),
HID_PHYSICAL_MAX_8(0x20),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(16),
HID_REPORT_COUNT(3),
HID_INPUT(HID_DATA_VAR_ABS),
// Reference frame reset counter.
HID_USAGE_SENSOR_DATA_CUSTOM_VALUE_3,
HID_LOGICAL_MIN_16(0x00, 0x00), // LOGICAL_MINIMUM (0)
HID_LOGICAL_MAX_16(0xFF, 0x00), // LOGICAL_MAXIMUM (255)
HID_PHYSICAL_MIN_8(0x00),
HID_PHYSICAL_MAX_8(0x00),
HID_UNIT_EXPONENT(0x00), // 10^0
HID_REPORT_SIZE(8),
HID_REPORT_COUNT(1),
HID_INPUT(HID_DATA_VAR_ABS),
HID_END_COLLECTION,
};