ごあいさつ
初めて投稿します。私立の医大で情報系教員をしています黄色い戌です。不定期ですが、研究で生まれてきたシステム(知財にはならないようなもの)を他のユーザーさんと共有して情報交換する目的でQiita始めました。UnityもC#も初心者です・・・公開した情報はガンガン活用していただいて大丈夫です!(寧ろ手直ししてくれたら教えてください)
KATVRとは
KATVRとは、VR内で使用できる歩行型デバイスを開発している企業で、KATWALK(全方位トレッドミル)やKAT loco S(慣性式歩行センサ)などのデバイスが知られています。歩行センサとしては、非常に優秀なデバイスなのですが、なにぶん「対応しているアプリ・デバイスが少ない!!」というのが、非常にもったいないシステムです。
特にデフォルトでは、PCVRのみの対応だったので、Stand aloneで動作するHMD(Meta Questとか)には対応していないなどの問題がありました。そこで、KATVRとHMDを無線接続して、VRアプリで動かすことができるシステムを開発してみました。但し、Oculus公式のアプリには非対応で、OSC(Open Sound Control)に対応しているアプリのみを動かせます。
システム構成(センサの使い方は説明書を見てください)
システムの構成は非常に単純で、、、
- KATVRシステムによる計測(今回は、KAT loco Sを対象としています)
- KATSDKによるUnity Appへのデータの取り込み
- OscJack(OscJack)を利用した、Meta Quest2へのデータ転送です
KATSDKは、同社に利用申請することで、無償で使用することができます。但し、KATVR SDKは、Windowsのみの対応となっております。そのため、Meta Questで利用するのも、必ずWindowsのPCを間に挟んで使用する必要があります。今回の記事では、PCでKATVRで計測した速度・回転などのデータをOSCで送信するアプリまでを作っていきます。
KATSDKの基本
1.KATSDKのインポート
KATVR社に利用申請することで、SDKのリンクを教えてもらえます。Unityフォルダ内の"KAT Universal SDK 0.99.unitypackage"というファイルがあるので、こちらをダウンロードし、Unity Editorで「Assets=>Import Package=>Custom Package...」により、プロジェクトのAssetフォルダにインポートします。
2. KATSDKの基本的な使い方
現在のところ、歩行に関するデータは、速度(Vector3型)と回転(Quaternion型)のみ取得できます。Assets/KAT/KATNativeSDK.csがKATVRからデータを取り出す際に使用するスクリプトです。下記のようなプログラムを適当なGameObjectにアタッチすることで、Consoleに速度とrotationを投げ込むことができるようになります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KAT_basic_function : MonoBehaviour
{
private Vector3 speed;
private Quaternion rotation;
void Start()
{
}
void Update()
{
var data = KATNativeSDK.GetWalkStatus();//KATVRライブラリへのアクセス
speed = data.moveSpeed;//歩行速度(x,y,z)の取得
rotation = data.bodyRotationRaw;//回転(x,y,z,w)の取得
Debug.Log("speed: "+ speed);
Debug.Log("rotation: " + rotation);
}
}
簡単ですね。
3. KATVRでCubeを動かしてみよう
では実際にKATSDKを使用してCubeを動かしてみましょう。初めに、ヒエラルキーにCubeを追加して、scaleを(1,1,1)、positionとrotationは両方とも(0,0,0)に設定します。Main Cameraはposition (0,15,0)、rotation (90,0,0)に、つまりは真上からキューブを見るように設定してください。
次に、以下のC#スクリプトをCubeにアタッチします。KATSDKでは3次元の速度を出力しますが、ポジションの出力はありません。そのため、Translateにより相対的な移動距離を算出する必要があります。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class KAT_cube_move : MonoBehaviour
{
private Vector3 speed;
private Quaternion rotation;
void Start()
{
}
void Update()
{
var data = KATNativeSDK.GetWalkStatus();//KATVRライブラリへのアクセス
speed = data.moveSpeed;//歩行速度(x,y,z)の取得
rotation = data.bodyRotationRaw;//回転(x,y,z,w)の取得
this.transform.Translate(speed * Time.deltaTime, Space.Self);//移動
this.transform.rotation = rotation;//回転
}
}
これまた、簡単ですね。
4. KATVRで取得したデータをOSCで送信する
それでは、無事にCubeが動いたところで、今回の記事のクライマックス、OSCでのデータ転送にトライします。OSCは、keijiroさんのOscJackを利用します。
Edit=>Project settingからPackage Managerを選択して、Scoped Registriesに、Name:Keijiro、URL: https://registry.npmjs.com, Scopes: jp.keijiroを追加します。その後、package managerのmy registoriesからOscJackをインポートします。
先ほどのCubeに以下のスクリプトをアタッチしてみてください。このスクリプトは、Cubeの速度と回転、歩行判定、座標を/KAT/xxxというアドレスに0.025秒ごとに送信します。送信先はローカルホストにしていますので、WindowからOSC Monitorを選択して、Playボタンを押してみましょう。変数isWalkは、アニメーター用(アバターを使用する人向け)に作ったものです。各自の環境でPortは変えてください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using OscJack;
public class OSC_stream : MonoBehaviour
{
private Vector3 speed;//歩行速度
private Quaternion rotation;//回転
private float speed2;//歩行の速さ(絶対値)
private int isWalk = 0;//0:停止、1:歩行、2:走行
public int thr_walk_run = 8;//歩行とランニングの境界線
[SerializeField] string ipAddress = "127.0.0.1";//送信先のIPアドレス
[SerializeField] int port = 9000;//Port番号
OscClient client;//Clientの変数宣言
[SerializeField] float sendInterval = 0.025f;// OSCメッセージの送信間隔(秒)
private float lastSendTime = 0f;
void Start()
{
client = new OscClient(ipAddress, port);//Clientの起動
}
void OnDestroy()
{
client.Dispose();//Clientの停止
}
void Update()
{
var data = KATNativeSDK.GetWalkStatus();//KATVRライブラリへのアクセス
speed = data.moveSpeed;//歩行速度(x,y,z)の取得
rotation = data.bodyRotationRaw;//回転(x,y,z,w)の取得
this.transform.Translate(speed * Time.deltaTime, Space.Self);//移動
this.transform.rotation = rotation;//回転
speed2 = speed.magnitude;//速さの絶対量
if (speed2 > 0)
{
if (speed2 >= thr_walk_run)//速さが閾値を超えた場合
{
isWalk = 2;//走行
}
else
{
isWalk = 1;//歩行
}
}
else
{
isWalk = 0;//停止
}
// 一定間隔でOSCメッセージを送信する
if (Time.time - lastSendTime >= sendInterval)
{
client.Send("/KATVR/position", this.transform.position.x, this.transform.position.y, this.transform.position.z);
client.Send("/KATVR/rotation", this.transform.rotation.x, this.transform.rotation.y, this.transform.rotation.z, this.transform.rotation.w);
client.Send("/KATVR/status", isWalk);
client.Send("/KATVR/speed", speed.x, speed.y, speed.z);
lastSendTime = Time.time;
}
}
}
移動と同時に、データがモニターに表示されますね。例えば、IPアドレスを同じネットワークに接続しているOculusやスマホに設定すれば、KATVRをケーブルなしで、各デバイスで使用できるようになります。動作未確認ですが、このコードは、KAT Walk C2でも使用可能です。そのうち、動作確認をしてみようと思います。
今回の記事は、ここまでで、次回にMeta Quest2で接続できるようなアプリを作っていきます。