Kinect & OSVR : Position tracking avancé et RoomScale

Nous avons vu dans le dernier article consacré à OSVR que la solution de suivi de position (position tracking) était encore très expérimentale. Même terminée et parfaitement fonctionnelle, elle souffrira de plusieurs problèmes, à savoir par exemple

  • Un champs de vision trop petit
  • Tracking à +/- 180° difficile voir impossible
  • Obligation d’ajouter une ou plusieurs caméras supplémentaires

Dans l’état, il est impossible d’envisager créer des expériences RoomScale digne de ce nom, à cause de ces limitations. Cependant, il existe un accessoire qui pourrait bien répondre à une partie de cette problématique, je veux bien entendu parler de la caméra Kinect pour Xbox 360 et Xbox One !


Demonstration !

Sans contrôleurs

Avec un PS Move dans The Lab

Pré-requis

Voici ce dont vous avez besoin pour utiliser Kinect avec OSVR :

  • Un capteur Kinect pour Xbox 360, Windows ou Xbox One
  • [Xbox 360] Un adaptateur Kinect Xbox 360 vers PC
  • [Xbox One] Un adaptateur Kinect Xbox One vers PC
  • [Xbox 360] Le Runtime (ou le SDK) Kinect V1 pour Windows
  • [Xbox One] Le Runtime (ou le SDK) Kinect V2 pour Windows
  • Le plugin OSVR-Kinect (onglet release)
  • Le plugin OSVR-Fusion (idem)

Et celui de Kinect pour Xbox 360

Si vous avez acheté votre caméra Kinect en boite alors vous devriez avoir l’adaptateur qui va avec car il permet aussi le branchement en USB sur la Xbox 360 non slim. Si vous n’avez pas ce câble, vous pouvez vous en procurer un pour moins de 10 € !

A propos de l’adaptateur Kinect Xbox One

Malheureusement, l’adaptateur pour brancher Kinect au PC n’est pas fourni comme c’était le cas avec Kinect pour Xbox 360. Cet adaptateur est obligatoire et se trouve entre 40 et 50 €. Cependant, si vous êtes bidouilleur, vous pouvez fabriquer un câble.

Je vous recommande de placer Kinect face à vous, il faut un espace d’environ 60 cm minimum pour que le capteur puisse vous reconnaître.

  • Vous pouvez l’utiliser en étant assis ou debout
  • Kinect doit voir vos mains pour vous détecter
  • Le RoomScale à 360° est possible si Kinect déctecte vos mains…

Installation des plugins

Les deux archives que vous avez récupéré contiennent deux plugins, celui pour Kinect et un autre qui va nous servir à réaliser une fusion de capteurs ! Malheureusement les archives sont incomplètes, vous devez télécharger en plus les fichiers je_nourish_kinect.json et je_nourish_fusion.json.

Copiez ensuite les fichiers je_nourish_fusion.dll et je_nourish_kinect.dll ainsi que les fichiers json que vous venez de récupérer dans le dossier osvr-plugins-0. Voilà c’est terminé ! Généralement un plugin a un fichier de configuration au format json.

OSVR_Plugins_Dist
Vous devez utiliser je_nourish_kinect.dll/json (cette capture utilise une vielle version du plugin qui ne gérait que Kinect V2)

Utilisation avec le serveur OSVR

Avec OSVR, tout est une affaire de fichier de configuration, nous allons donc modifier le fichier osvr_server_config.json localisé dans le dossier d’installation d’OSVR. Vous pouvez soit adapter votre fichier de configuration, soit le remplacer par celui-ci.

Attention car ce fichier utilise le mode direct pour un HDK 1.3/1.4, si votre casque fonctionne en mode étendu il faut par exemple changer les deux lignes suivantes

"display": "displays/OSVR_HDK_1_3_with_mesh.json",
"renderManagerConfig": "sample-configs/renderManager.direct.landscape.json",

Et mettre plutôt (remplacez landscape par portrait suivant votre mode d’affichage)

"display": "displays/OSVR_HDK_1_3_with_mesh.json",
"renderManagerConfig": "sample-configs/renderManager.extended.landscape.json",

Vérification et tests

Vous pouvez lancer OSVRTrackerView.exe, il se trouve dans le dossier d’installation d’OSVR, il vous permettra de voir si tout fonctionne bien.

OSVR_TrackerView

Vous devez voir 3 choses, votre tête ainsi que vos deux mains. Oui vos deux mains 🙂 car le fichier de configuration du plugin Kinect expose la tête et les mains (25 points du corps peuvent être utilisés en réalité). Vous pouvez désormais lancer SteamVR et constater un réel changement dans vos déplacement !

info-xxl

Si vos les axes de position sont inversés alors il faut lancer l’utilitaire osvr_reset_yaw.exe qui se trouve comme toujours… dans le dossier d’installation d’OSVR

 

Des contrôleurs VR avec OSVR-Fusion

Le plugin je_nourish_fusion va créer un appareil virtuelle possédant une position et une rotation, il a donc besoin d’une source de position et d’une autre de rotation. Examinons le fichier de configuration de plus près :

"drivers": [{
	"plugin": "je_nourish_fusion",
	"driver": "FusionDevice",
	"params": {
		"name": "HDK_Kinect",
		"position": "/je_nourish_kinect/Kinect/semantic/body1/head",
		"orientation": "/com_osvr_Multiserver/OSVRHackerDevKitPrediction0/semantic/hmd",
		"alignInitialOrientation": false,
		"offsetFromRotationCenter": {
			"x": 0,
			"y": 0.01,
			"z": -0.05
		}
}],
"aliases": {
	"/headSpace": {
		"translate": [0.0, 0.0, 0.04141],
		"child": "/org_osvr_filter_videoimufusion/HeadFusion/semantic/fused"
	},
	"/me/head": "/je_nourish_fusion/HDK_Kinect/tracker/0"
}

Nous lui donnons la rotation du HDK et la position de la tête renvoyée par Kinect. Il en résulte un nouveau appareil, totalement virtuelle qui est ensuite utilisé à la fin (/me/head) pour la tête.

Vous avez vu plus haut que le plugin Kinect récupérait aussi les positions et les rotations des mains… En mixant ça avec par exemple… deux Wiimotes… vous pouvez créer des contrôleurs VR utilisables dans vos applications et avec SteamVR* ! L’intégration des Wiimotes dans OSVR se fait en installant, exactement comme nous l’avons fait plus haut, le plugin OSVR-Wiimote.

* 18/07/2016 Le support dans contrôleurs dans OSVR-SteamVR est actuellement en cours d’implémentation

Modification de osvr_server.json

Vous pouvez récupérer le contenu du fichier de configuration serveur ici.

Démonstration (encore!)

Gestion des input dans OSVR avec Unity

Le SDK OSVR permet d’utiliser assez facilement des contrôleurs, il suffit de glisser deux scripts sur un GameObject afin que celui-ci soit automatiquement mis à jour avec la position et la rotation du contrôleur. La gestion des boutons est cependant plus contraignante. Ouvrez un nouveau projet Unity et ajoutez y le SDK OSVR pour Unity. Pour cet exemple j’utilise le prefab VRPlayerController fourni par le SDK, mais vous pouvez utiliser votre propre prefab.

Dans un premier temps, nous allons créer un GameObject vide, parent du GameObject du joueur et nous l’appellerons Controllers.  Ce nœud est un conteneur dans lequel nous attachons deux autre GameObjects qui seront en réalité nos contrôleurs. Appelez les Controller Left et Controller Right et attachez y les scripts PositionInterface.cs, OrientationInterface.cs et ButtonInterface.cs. Enfin attachez un cube à ces GameObjects avec un scaling à 0.2. Vous devriez avoir quelque chose comme ça :

OSVR_Unity_Controllers
Il y a une petite faute de frappe sur cette capture, c’est bien /me/hands/left (hands prend un s)

Les scripts prennent en paramètre un chemin (variable path) vers la partie du corps à utiliser. Si vous reprenez le fichier de configuration du haut, vous verrez qu’en alias nous avons

  • /me/head : Votre tête qui a une position et une rotation
  • /me/hands/left : Votre main gauche (Wiimote 1)
  • /me/hands/right : Votre main droite (Wiimote 2)

Pour le bouton on utilise le chemin /me/controller/left/1. Les chemins qui définissent des parties du corps sont exprimés comme suis : /me/partie_du_corps/[droite ou gauche]. Pour les boutons c’est /me/controller/droite_ou_gauche/numéro_du_bouton.

Les deux premiers scripts sont autonomes, mais si vous voulez lire la valeur du bouton, il va falloir utiliser un script. Créez un nouveau script que vous appellerez InputHandler et attachez le sur le contrôleur de droite. Regardons ensemble son contenu :

using UnityEngine;
using OSVR.Unity;

public class InputHandler : MonoBehaviour
{
    OSVR.ClientKit.ButtonInterface _buttonInterface = null;

    void Start()
    {
        var button = GetComponent<ButtonInterface>();
        _buttonInterface = button.Interface;
        _buttonInterface.StateChanged += Interface_StateChanged;
        
    }

    // En utilisant un évenement.
    private void Interface_StateChanged(object sender, OSVR.ClientKit.TimeValue timestamp, int sensor, byte report)
    {
        Debug.LogFormat("[Event] The button 1 is {0}", _buttonInterface.GetState().Value > 0 ? "Pressed" : "Released");
    }
    
    // Dans une fonction
    void Update()
    {
        if (_buttonInterface.GetState().Value > 0)
            Debug.Log("[Update Method] The button 1 is pressed");
        else
            Debug.Log("[Update Method] The button 1 is released");
    }
}

Les choix qui ont été fait pour le module des inputs et très discutable…  On récupère l’objet OSVR.ClientKit.ButtonInterface qui dispose d’un événement, mais aussi d’une variable donnant l’état du bouton. Sachez qu’il existe un tas d’interfaces ! AnalogInterface, EyeInterface, SkeletonInterface, etc…

Et maintenant ?

Maintenant vous avez les cartes en main pour développer du contenu RoomScale avec votre casque Razer HDK. Il est aussi possible d’utiliser Kinect en tant que solution de tracking de position avec SteamVR, vous permettant si vous avez des contrôleurs compatibles de profiter d’une bonne partie de la ludothèque VR de Valve. Evidemment Kinect n’est pas LA solution, car le capteur fonctionne à 30 Hz, ce qui va occasionner une sensation de lag entre vos mouvements et ce que vous verrez dans le casque. Cela reste cependant très acceptable, surtout si vous vous limitez à des expériences n’exigent pas une rapidité exemplaire 😛