بروتوكول HID لتعقب الرأس

يسمح بروتوكول جهاز الواجهة البشرية (HID) لتعقب الرأس، المتوفر للأجهزة التي تعمل بنظام Android 13 والإصدارات الأحدث، بتوصيل جهاز تتبع الرأس بجهاز Android من خلال USB أو Bluetooth والتعرض لإطار عمل Android وتطبيقاته من خلال المستشعرات نطاق. يستخدم هذا البروتوكول للتحكم في تأثير أداة المحاكاة الصوتية (الصوت ثلاثي الأبعاد). تستخدم هذه الصفحة المصطلحين جهاز ومضيف بالمعنى الخاص بالبلوتوث، حيث يعني الجهاز جهاز تتبع الرأس والمضيف يعني مضيف Android.

يجب على الشركات المصنعة للأجهزة تكوين أجهزتها التي تعمل بنظام Android لتمكين دعم بروتوكول HID لتعقب الرأس. للحصول على معلومات أكثر تفصيلاً حول التكوين، راجع الملف README الخاص بأجهزة الاستشعار الديناميكية .

تفترض هذه الصفحة الإلمام بالموارد التالية:

هيكل المستوى الأعلى

يحدد إطار عمل Android جهاز تعقب الرأس كجهاز HID.

للحصول على مثال كامل لواصف HID صالح، راجع الملحق 1: مثال لواصف HID .

في المستوى الأعلى، جهاز تعقب الرأس عبارة عن مجموعة تطبيقات تحتوي على صفحة Sensors ( 0x20 ) Other: Custom ( 0xE1 ). يوجد داخل هذه المجموعة العديد من حقول البيانات ( المدخلات ) والخصائص ( الميزات ).

الخصائص وحقول البيانات

يصف هذا القسم الخصائص وحقول البيانات في مجموعة تطبيقات جهاز تعقب الرأس.

الخاصية: وصف المستشعر ( 0x0308 )

خاصية وصف المستشعر ( 0x0308 ) هي خاصية سلسلة ASCII (8 بت) للقراءة فقط والتي يجب أن تحتوي على القيمة التالية:

#AndroidHeadTracker#1.0

من غير المتوقع وجود فاصل فارغ، مما يعني أن الحجم الإجمالي لهذه الخاصية هو 23 حرفًا بطول 8 بت.

تعمل هذه الخاصية بمثابة أداة تمييز لتجنب الاصطدامات مع أجهزة الاستشعار المخصصة الأخرى.

الخاصية: المعرف الفريد المستمر ( 0x0302 )

خاصية المعرف الفريد المستمر ( 0x0302 ) عبارة عن مصفوفة للقراءة فقط مكونة من 16 عنصرًا، كل منها 8 بت (إجمالي 128 بت). من المتوقع عدم وجود فاصل فارغ. هذه الخاصية اختيارية.

تسمح هذه الخاصية لأجهزة تتبع الرأس المدمجة في الأجهزة الصوتية بالإشارة إلى جهاز الصوت المتصل بها. يتم دعم المخططات التالية.

جهاز تعقب الرأس المستقل

إذا كانت خاصية المعرف الفريد المستمر ( 0x0302 ) غير موجودة أو تم تعيينها على كافة الأصفار، فهذا يعني أن جهاز تعقب الرأس غير متصل بشكل دائم بجهاز صوتي ويمكن استخدامه بشكل منفصل، على سبيل المثال، عن طريق السماح للمستخدم يدويًا قم بربط جهاز تعقب الرأس بجهاز صوت منفصل.

مرجع باستخدام عنوان Bluetooth MAC

ثماني 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
قيمة 0 0 0 0 0 0 0 0 ب ت بلوتوث ماك

في هذا المخطط، يجب أن تكون الثمانيات الثمانية الأولى 0 ، ويجب أن تحتوي الثمانيات 8 و9 على قيم ASCII B و T على التوالي، ويتم تفسير الثمانيات الستة التالية كعنوان Bluetooth MAC، بافتراض أن جهاز تعقب الرأس ينطبق على أي جهاز صوتي به عنوان MAC هذا.

مرجع باستخدام UUID

عندما يتم تعيين البت الأكثر أهمية (MSB) للثمانية 8 ( ≥0x80 )، يتم تفسير الحقل على أنه UUID، كما هو محدد في RFC-4122 . يوفر جهاز الصوت المقابل نفس UUID المسجل في إطار عمل Android، من خلال آلية غير محددة خاصة بنوع النقل المستخدم.

الخاصية: حالة الإبلاغ ( 0x0316 )

خاصية حالة التقرير ( 0x0316 ) هي خاصية قراءة/كتابة لها دلالات قياسية كما هو محدد في مواصفات HID. يستخدم المضيف هذه الخاصية ليشير إلى الجهاز بالأحداث التي سيتم الإبلاغ عنها. يتم استخدام القيمتين No Events ( 0x0840 ) و All Events ( 0x0841 ) فقط.

يجب أن تكون القيمة الأولية لهذا الحقل هي "لا توجد أحداث" ويجب ألا يتم تعديلها مطلقًا بواسطة الجهاز، بل بواسطة المضيف فقط.

الخاصية: حالة الطاقة ( 0x0319 )

خاصية حالة الطاقة ( 0x0319 ) هي خاصية قراءة/كتابة لها دلالات قياسية كما هو محدد في مواصفات HID. يستخدم المضيف هذه الخاصية ليشير للجهاز إلى حالة الطاقة التي يجب أن يكون فيها. يتم استخدام القيم Full Power ( 0x0851 ) و Power Off ( 0x0855 ) فقط.

يتم تحديد القيمة الأولية لهذا الحقل بواسطة الجهاز ويجب عدم تعديلها أبدًا بواسطة الجهاز، ولكن بواسطة المضيف فقط.

الخاصية: الفاصل الزمني للتقرير ( 0x030E )

الخاصية "الفاصل الزمني للتقرير" ( 0x030E ) هي خاصية قراءة/كتابة لها دلالات قياسية كما هو محدد في مواصفات HID. يستخدم المضيف هذه الخاصية ليشير للجهاز إلى عدد مرات الإبلاغ عن قراءات البيانات الخاصة به. الوحدات هي ثواني. يتم تحديد النطاق الصالح لهذه القيمة بواسطة الجهاز ويتم وصفه باستخدام آلية الحد الأدنى/الحد الأقصى الفعلي. يجب دعم معدل الإبلاغ 50 هرتز على الأقل، والحد الأقصى الموصى به لمعدل الإبلاغ هو 100 هرتز. ولذلك، يجب أن يكون الحد الأدنى للفاصل الزمني للتقرير أقل من أو يساوي 20 مللي ثانية، ومن المستحسن أن يكون أكبر من أو يساوي 10 مللي ثانية.

حقل البيانات: القيمة المخصصة 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) إرسال تقارير الإدخال عند استيفاء جميع هذه الشروط:

  • تم تعيين خاصية حالة الطاقة إلى الطاقة الكاملة.
  • يتم تعيين خاصية حالة الإبلاغ إلى كافة الأحداث.
  • الخاصية الفاصل الزمني للتقرير غير صفر.

تحدد الخاصية "الفاصل الزمني للتقارير" عدد مرات إرسال التقارير. عند عدم استيفاء أي من الشروط المذكورة أعلاه، يجب ألا يرسل الجهاز أي تقارير.

التوافق إلى الأمام والخلف

يستخدم بروتوكول 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,
};