Overview : 概要
HoloLens 2 から Eye Tracking
のデータを取得できるようになりました !ユーザーから取得した視線データの活用方法 ( 操作のトリガーやデータの可視化・分析など ) は数多く考えられ、今後 HoloLens 2 アプリケーション開発で重要なポイントとなると思われるため、基礎情報を整理しておきたいと思います。まず今回は Unity プロジェクトに対して Eye Tracking
機能を追加する方法を公式ドキュメント 「 Getting started with eye tracking in MRTK 」 に従って、解説 & 紹介します。
TOC ( Table of Contents ) : 目次
- Expected : 本記事を読んで実現できること
- Development Environment : 開発環境
- Detail of HoloLens 2's Hardware ( Sensor ) : ハードウェアについて
- Required : 必要事項
- Procedure : 導入手順
- Appendix : 追加情報
Expected : 本記事を読んで実現できること
- MRTK v2.3 を活用してアイトラッキングの挙動を検証すること
Development Environment : 開発環境
-
Windows PC ( Windows 10 /
SDK 10.0.18362
) -
Unity (
2018.4.3f1
) -
Visual Studio (
Community 2017
) -
Mixed Reality Toolkit (
MRTK v2.3
) -
HoloLens 2 (
OSビルド番号 : 10.0.18362.1053
)
Detail of HoloLens 2's Hardware ( Sensor ) : ハードウェアについて
実装を行う前に Microsoft HoloLens 2 に搭載されているセンサー系を簡単にご紹介したいと思います。
Microsoft HoloLens 2 には、以下のセンサー類 ( 下表 ) が搭載されています。
HoloLens 2 Sensor | 概要 |
---|---|
Head Tracking | 4台の可視光カメラ |
Eye Tracking | 2台の赤外線カメラ |
Depth | 1-MP ToF 深度センサー ( ※ Time of Flight ) |
IMU ( Inertial Measurement Unit ) |
加速度計、ジャイロスコープ、磁力計 |
Camera | 静止画 8MP/ 動画 1080p30 |
Eye Tracking
には、HoloLens 2 ディスプレイ部分に搭載されている 2つの赤外線センサー ( 参考 : 下図 ) が使用されます。
Required : 必要事項
Eye Tracking
機能を正しく動作させるためには、以下の要件に対応する必要があります。
- ✅ 入力システムに 「
Eye Gaze Data Provider
」 を追加する必要があります。
( これによりプラットフォーム側からアイトラッキングデータを取得することができるようになります。 ) - ✅ MixedRealityPlaySpace > Main Camera にアタッチされた
「 Gaze Provider ( Component ) 」 の [Use Eye Tracking
] 項目にチェックを入れる必要がります。 - ✅ Visual Stuido ビルドでビルドする際に
Package.appxmanifest
の 「Capability : GazeInput
」 を有効にする必要があります。 - ✅ HoloLens を装着しているユーザーにて
Eye Tracking
をキャリブレーションする必要があります。
【 重要 】 これらの要件が満たされていない場合は、「 Eye Tracking 」 ではなく、 「 Head Gaze Tracking 」 に自動的に切り替わります。
Procedure : 導入手順
それでは実際にアイトラッキングを動作させるサンプルアプリを作成してみたいと思います。
【 前提条件 】 以下、MRTK パッケージをインポート済みであること。
- Microsoft.MixedReality.Toolkit.Unity.Foundation.2.3.0.unitypackage
01. Unity プロジェクト 「New Scene」 を開きます。
02. グローバルメニュー [ Mixed Reality Toolkit ] > 「 Add to Scene and Configure ... ( 赤枠部分 ) 」 を実行します。
上記ボタンを押下すると、以下ゲームオブジェクトがヒエラルキーに追加されます。
- MixedRealityToolkit
- MixedRealityPlayspace
03. MRTK : Input System に Eye Gaze data Provider
を追加します。
既存の標準プロファイルでは、独自に設定の追加・変更できないので、新規プロファイルを作成します。
Hierarchy
より MixedRealityToolkit
を選択し、Inspector
を確認します。
MixedRealityToolkit ( Componet ) の最上部、プロファイルの Copy & Customize
ボタンを押下します。
上記ウィザードが表示されるので、「 Cloning Profile : DefaultHoloLens2ConfigurationProfile
」、「 Profile Name : EyeTrackingSampleMixedRealityToolkitConfigurationProfile
(任意) 」 の入力を確認し、Clone
ボタンを押下します。
( ※ カスタムプロファイルは、MixedRealityToolkit.Generated
> CustomProfiles
配下に格納されます。 )
続いて Input System のプロファイルを Clone
します。
さきほどと同様のウィザードが表示されるので、同じように Clone
します。
プロファイルの Clone
が完了すると、設定の変更が可能になります。
変更が可能になった Input System settings
内に Eye Tracking 用のデータプロバイダーを追加していきます。
まず、+ Add Data Provider
ボタンを押下します。
最下部に New Data Provider 10
という名前のデータプロバイダーが追加されます。
上記で追加したデータプロバイダーに、Eye Tracking
設定を追加します。
Type 項目の下矢印ボタンを押下し、[ Microsoft.MixedReality.Toolkit.WindowsMixedReality.Input
] > [ WindowsMixedRealityEyeGazeDataProvider
] を選択します。
これで Eye Gaze Provider の登録が完了します。
04. Gaze Provider にて Eye Tracking を有効化します。
MixedRealityPlayspace
> Main Camera
にアタッチされている Gaze Provider
の [ Use Eye Tracking ] にチェックをいれます。
05. EyeGazeProvider で取得できる主なデータ
EyeGazeProvider メンバ変数 | 型 | 概要 | 備考 |
---|---|---|---|
UseEyeTracking | bool | 使用ハードウェアがアイトラッキング可能かつ、アプリの権限 [視線入力] が有効になっている場合 true 、それ以外の場合は false を返す | |
IsEyeCalibrationValid | bool? ( null許容値 ) | 装着者のアイトラッキング機能のキャリブレーション有無 ( true / false ) を示す。アイトラッキングシステムからデータを受け取っていない場合は null を返す。 |
視線入力のパーミッションが有効ではない場合 null が返ってくる。 |
IsEyeGazeValid | bool | 現在のアイトラッキングデータが有効かどうか ( true / false ) を示す。 タイムアウト時間を超えた場合、ハードウェアのトラッキングが欠如している場合、パーミッションの問題などで無効になる可能性があります。 |
極度にディスプレイの外に視線を向けるとアイトラッキングが失われ、False が返ってくる。 |
GazeOrigin | Vector3 | 視線の原点。IsEyeGazeValid が false の場合、Head-Gaze の原点を返すので注意。 |
|
GazeDirection | Vector3 | 視線の向き。IsEyeGazeValid が false の場合、Head-Gaze の向きを返すので注意。 |
|
HitInfo, HitPosition, HitNormal | ー | 現在見ているターゲット ( GameObject ) の情報を返します。 |
06. Eye Gaze Provider から値を取得する
Data Provider は Mixed Reality Toolkit Service からデータを取得するコンポーネントです。
今回の場合、Input System ( Service ) から Eye Gaze Provider 経由でトラッキングデータの取得を行います。
アプリケーション内のソースコードから Data Provider へアクセスする場合、IMixedRealityDataProviderAccess
インターフェースを経由します。さらに 簡単に Data Provider へアクセスしたい場合は、 CoreService
という Helper Class を使用すると良いみたいです。
例えば、Eye Tracking のキャリブレーション有無を確認したい場合はこのような記述で値を取得することができます。
bool? CalibrationStatus = CoreServices.InputSystem?.EyeGazeProvider?.IsEyeCalibrationValid;
07. Package.appxmanifest の 機能 : 視線入力
を有効にします。
Visual Studio でビルドを実行する前に Package.appxmanifest の Capability 設定を下記の通り変更します。
※ この設定をしないと Eye Tracking データが取得できないので、必ずチェックを入れるようにしてください。
以上の手順を行うことで、Eye Tracking を既存プロジェクトに組み込むことができます。
Appendix
Calibration チェック用の Prefab
MRTK Example 内にキャリブレーションのチェックを行う EyeCalibrationChecker
という Prefab が公開されています。
( Path : Assets/MixedRealityToolkit.Examples/Demos/EyeTracking/General/Prefabs/EyeCalibrationChecker.prefab
)
こちらの Prefab にアタッチされている EyeCalibrationChecker.cs
スクリプト内でキャリブレーション有無のチェックを実行しているようです。
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See LICENSE in the project root for license information.
using Microsoft.MixedReality.Toolkit.Input;
using UnityEngine;
using UnityEngine.Events;
namespace Microsoft.MixedReality.Toolkit.Examples.Demos.EyeTracking
{
/// <summary>
/// Checks whether the user is calibrated and prompts a notification to encourage the user to calibrate.
/// </summary>
[AddComponentMenu("Scripts/MRTK/Examples/EyeCalibrationChecker")]
public class EyeCalibrationChecker : MonoBehaviour
{
[Tooltip("For testing purposes, you can manually assign whether the user is eye calibrated or not.")]
[SerializeField]
private bool editorTestUserIsCalibrated = true;
public UnityEvent OnEyeCalibrationDetected;
public UnityEvent OnNoEyeCalibrationDetected;
private bool? prevCalibrationStatus = null;
private void Update()
{
bool? calibrationStatus;
if (Application.isEditor)
{
calibrationStatus = editorTestUserIsCalibrated;
}
else
{
calibrationStatus = CoreServices.InputSystem?.EyeGazeProvider?.IsEyeCalibrationValid;
}
if (calibrationStatus != null)
{
if (prevCalibrationStatus != calibrationStatus)
{
if (calibrationStatus == false)
{
OnNoEyeCalibrationDetected.Invoke();
}
else
{
OnEyeCalibrationDetected.Invoke();
}
prevCalibrationStatus = calibrationStatus;
}
}
}
}
}