HTC Viveでテレポート機能を実装する方法
HTC Viveでコントローラーを利用したテレポートの方法です
こんなのです
ライブラリとしてgithubで公開されている以下のライブラリを利用させていただきます
github.com
環境
HTC ViveをUnityで開発するにはSteamVR PluginというPluginを利用することになりますが、Unity5.x系とは相性が悪くコントローラーが表示されなかったり一部機能がうまく動かなかったりするので、そういう場合は素直にUnity2017を利用するとすんなり動くことが多いです
(この記事はところどころ5.6.3で書いていますが)
https://www.assetstore.unity3d.com/jp/#!/content/32647
ライブラリimport
import Vive-Teleporter library
テレポート用のライブラリをimportします
githubからそのままダウンロードしてUnityにimportします
https://github.com/Flafla2/Vive-Teleporter
importすると設定を最適なものにするかどうか聞かれるダイアログが表示されるので、問題なければAcceptを選択します
今回は上記のライブラリにSteamVR Pluginも入っているため、追加でSteamVR Pluginをimportする必要はありません
テレポート機能の作成
地面の作成
まずは移動するための地面を作ります
Groundという名前でCubeを作成し、地面っぽく引き伸ばします
- position: 0, -0.5, 0
- Scale: 10, 1, 10
- (Staticにチェック)
- (LightProbeをOff)
- (Lightmap Staticにチェック)
Windows > Navigationを選び、Groundを選択します
- Objectタブ
- Navigate Staticにチェックをチェック
- Generate OffMeshLinksのチェックを外す
- bakeタブ
- bakeをクリックして実行
bakeがうまくいくと以下のようにcubeの上面に水色のエリアが表示されます
NavMeshの作成
NavMesh prefabをヒエラルキーにD&Dします
InspectorのVive Nav Mesh(Script)の項目でUpdate Navmesh Dataをクリックして実行します
そうすると以下のようなマス目と移動の境界線にエフェクトが表示されます
Cameraの設定
まずは不要なMain Cameraを削除して、Camera Rig prefabをヒエラルキーにD&Dします
次にInspectorから各項目を設定していきます
Camera Rig本体
- Steam VR_Play Area(script)を削除
- (Mesh Filter)を削除
- Mesh Rendererを削除
Camera(eye)
- Vive Teleporterスクリプトをadd component
- (Border ReferererとTeleport Viveの項目が追加されます)
- Teleport Vive
- Border renderer
- Border MaterialでRoom Area Borderを選択
以上で設定は完了です
おまけ
侵入禁止エリアの設定
Cube等のcolliderの設定されている障害物を作成し、Groundに接地させる(めりこませてもよい)
Inspectorタブでstaticにし、Navigationタブでbakeします
すると以下のようにCubeのまわりだけの水色のスペースが除外されます
次に忘れずにNavmeshからUpdate Navmesh Dataをクリックします
この状態でデモを実行するとCubeのまわりだけテレポートできないようになります
arduinoを最小構成で自作する(atmega328/8MHz/3.3V/内部クロック)
arduinoはいまや様々な種類が出ていて、かつ安価に購入できるので、IoTなどの分野でも幅広く利用されています
しかしarduinoを利用したシステムなどを量産する際に、更に小型化・省コストを狙う際にはarduinoのチップ(atmega328)を利用してarduino自体を自分の必要な構成で自作することが可能です
今回は以下の最小構成で自作します
- 8MHz(既製品は16MHz)
- 3.3V駆動(既製品は入力電圧:7V-12V, 駆動電圧:5V)
- atmega328(既製品についているマイコンチップ)
- 内部クロックを利用(既製品は外部クリスタルを利用)
必要なもの
- atmega328
- Arduino Uno(初期設定/FW書き込み用)
- ジャンパーケーブル(初期設定/FW書き込み用)
- ブレッドボード(初期設定/FW書き込み/確認用)
- LED(確認用)
手順
1. ライブラリやIDEのダウンロード
以下のリンクのMinimal Circuitの項目にあるBreadboard-1-x-x.zipをダウンロードして解凍し、arduinoのhardwareフォルダに配置します
Arduino - ArduinoToBreadboard
2. arduino ISPの書き込み
Arduino UNOへISPスケッチを書き込みます
サンプルにデフォルトで入っているので、Open > ArduinoISPを選択してそのままUploadします
4. ブートローダー書き込み
atmegaを利用する際に、何も書き込まれていない素のままのTipを購入した際は一番最初にbootloaderを書き込まなければいけません
書き込み済みのものを購入した場合はスキップしてOKですが、16MHz用のブートローダーが書き込まれている場合は上書きしなければならず、その場合には外部発振子(水晶やセラロック)が必要になります。今回は割愛します
手順1でライブラリをarduinoのhardwareフォルダに配置している場合、boardの項目にAtmega328という項目が追加されているのでそれを選択します
次にTools > Programmerの項目からArduino as ISPを選択します
(AVR ISPでもArduino ISPでもなくArduino as ISPです)
そうしたらTools > Burn Bootloaderを選択すればブートローダーの書き込みが行われます
reference
Raspberry PiとArduinoをGPIOでシリアル接続する場合は電圧に注意(3.3V/5V)
Raspberry PiとArduinoをシリアル接続する際は単純につなぐとそれぞれ電圧が違うので壊れてしまう可能性がある(主にラズパイの方が)
入出力電圧
- 入力電圧
- 0~0.8V : LOW(OFF)として判断
- 0.8~1.3V : 不定(不安定でどっちになるかわからない)
- 1.3~3.3V: HIGH(ON)として判断
- 出力電圧
- ON : 3.3V出力
- Off : GND(出力)
- 入力電圧
- 0~2.5V : LOW(OFF)として判断
- 2.5~5.0V: HIGH(ON)として判断
- 出力電圧
- ON : 5.0V出力
- Off : 0V
Windows Subsystem for Linux(Bash on Windows)をインストールしてみた(英語OS)
2016年に発表されて2017年に正式リリースされ、最近Windows 10 Fall Creators Updateによって簡単にインストールができるようになったWindows Subsystem for Linuxをインストールしてみた
ちなみに正式名称として「Windows Subsystem for Linux」になったらしく、発表当時のBash on Windowsという名前は非推奨になった
Windows Subsystem for Linuxのインストール
Windows Setting画面を開いて
Appsを選択して
Programs and Featuresを選択して
Turn Windows features on or offを選択して
Windows Subsystems for LinuxにチェックをいれてOKを押すとダウンロードがはじまる
ダウンロードが完了すると再起動の確認ダイアログが出るので再起動すればインストール完了
ubuntuのインストール
次に実際にubuntuをインストールする
Microsoft Storeでubuntuを検索してインストールする
インストールが完了したら起動をクリック
起動するとターミナルが開いてubuntuで利用するユーザー名とパスワードの入力が促される
Installing, this may take a few minutes... Installation successful! Please create a default UNIX user account. The username does not need to match your Windows username. For more information visit: https://aka.ms/wslusers Enter new UNIX username: ユーザ名入力 Enter new UNIX password: パスワード入力 Retype new UNIX password: パスワード再入力 passwd: password updated successfully Default UNIX user set to: *** To run a command as administrator (user "root"), use "sudo <command>". See "man sudo_root" for details.
メッセージにも書いてあるがwindows アカウントとは関係ないので一致させる必要はない
以上で設定完了
確認とか
$ cat /etc/issue Ubuntu 16.04.3 LTS \n \l $ cat /etc/lsb-release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=16.04 DISTRIB_CODENAME=xenial DISTRIB_DESCRIPTION="Ubuntu 16.04.3 LTS" $ uname -a Linux DESKTOP-Q0FRENB 4.4.0-43-Microsoft #1-Microsoft Wed Dec 31 14:42:53 PST 2014 x86_64 x86_64 x86_64 GNU/Linux $ echo $SHELL /bin/bash $ cat /etc/shells # /etc/shells: valid login shells /bin/sh /bin/dash /bin/bash /bin/rbash /usr/bin/tmux /usr/bin/screen
とりあえずライブラリのupdateとかしておくといいと思う
$ sudo apt-get update [sudo] password for hogehoge: Hit:1 http://archive.ubuntu.com/ubuntu xenial InRelease Get:2 http://security.ubuntu.com/ubuntu xenial-security InRelease [102 kB] Get:3 http://archive.ubuntu.com/ubuntu xenial-updates InRelease [102 kB] Get:4 http://security.ubuntu.com/ubuntu xenial-security/main amd64 Packages [408 kB] Get:5 http://archive.ubuntu.com/ubuntu xenial-backports InRelease [102 kB] Get:6 http://archive.ubuntu.com/ubuntu xenial/universe amd64 Packages [7,532 kB] Get:7 http://security.ubuntu.com/ubuntu xenial-security/main Translation-en [179 kB] Get:8 http://security.ubuntu.com/ubuntu xenial-security/restricted amd64 Packages [7,472 B] Get:9 http://security.ubuntu.com/ubuntu xenial-security/restricted Translation-en [2,412 B] Get:10 http://security.ubuntu.com/ubuntu xenial-security/universe amd64 Packages [190 kB] Get:11 http://security.ubuntu.com/ubuntu xenial-security/universe Translation-en [99.0 kB] Get:12 http://security.ubuntu.com/ubuntu xenial-security/multiverse amd64 Packages [3,208 B] Get:13 http://security.ubuntu.com/ubuntu xenial-security/multiverse Translation-en [1,408 B] Get:14 http://archive.ubuntu.com/ubuntu xenial/universe Translation-en [4,354 kB] Get:15 http://archive.ubuntu.com/ubuntu xenial/multiverse amd64 Packages [144 kB] Get:16 http://archive.ubuntu.com/ubuntu xenial/multiverse Translation-en [106 kB] Get:17 http://archive.ubuntu.com/ubuntu xenial-updates/main amd64 Packages [681 kB] Get:18 http://archive.ubuntu.com/ubuntu xenial-updates/main Translation-en [284 kB] Get:19 http://archive.ubuntu.com/ubuntu xenial-updates/restricted amd64 Packages [8,072 B] Get:20 http://archive.ubuntu.com/ubuntu xenial-updates/restricted Translation-en [2,672 B] Get:21 http://archive.ubuntu.com/ubuntu xenial-updates/universe amd64 Packages [565 kB] Get:22 http://archive.ubuntu.com/ubuntu xenial-updates/universe Translation-en [229 kB] Get:23 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse amd64 Packages [16.2 kB] Get:24 http://archive.ubuntu.com/ubuntu xenial-updates/multiverse Translation-en [8,052 B] Get:25 http://archive.ubuntu.com/ubuntu xenial-backports/main amd64 Packages [4,860 B] Get:26 http://archive.ubuntu.com/ubuntu xenial-backports/main Translation-en [3,220 B] Get:27 http://archive.ubuntu.com/ubuntu xenial-backports/universe amd64 Packages [6,612 B] Get:28 http://archive.ubuntu.com/ubuntu xenial-backports/universe Translation-en [3,768 B] Fetched 15.1 MB in 3min 59s (63.3 kB/s) Reading package lists... Done
Unityで3D空間をコントローラーで移動させて、障害物に衝突したらちゃんと止まるようにする
コントローラーを使ってキャラクターを移動させて、障害物にぶつかったら止まるという基本の動作をUnityで実装する方法
つかったもの
Unity version
- unity 5.6.4f1
ユニティちゃん
- なんでもいいんだけど、以前から使ってみたかったユニティちゃんを利用
- ダウンロード - UNITY-CHAN!
Oculus Utilities
- versionは1.20.0(2017/11/09 release)
- https://developer.oculus.com/downloads/package/oculus-utilities-for-unity-5/
コントローラー
- みんな大好き箱〇コントローラー(PC用)
準備
床と障害物となる柱を設置
- 床は3D object > Terrain
- 柱は3D object > Cylinder
その前にユニティちゃんを配置
- import package > custom packageでダウンロードしてきたユニティちゃんパッケージをimport
- unitychan prefabsをHierarchyにD&Dして配置、位置調整
スクリプト(今回はunityWalking.cs)を作成してunitychanにセット
- create > C# script
Oculus Utilityのimport
- import package > custom packageでダウンロードしてきたOculus Utilityパッケージをimport
(コントローラーの十字キーの設定)
開発
以下のサイト様がとてもわかりやすかったので、上から試していってみた
tama-lab.net
1. transform.position
- 座標を直接書き換えることで移動する
- 移動というより瞬間移動的なもの
- 上記の理由より衝突判定を抜けてしまうことが多い
using System.Collections; using System.Collections.Generic; using UnityEngine; public class unityWalking : MonoBehaviour { public float speed = 3f; void Update () { if (Input.GetAxis("Vertical") > 0){ transform.position += transform.forward * speed * Time.deltaTime; } if (Input.GetAxis("Vertical") < 0){ transform.position -= transform.forward * speed * Time.deltaTime; } if (Input.GetAxis("Horizontal") > 0){ transform.position += transform.right * speed * Time.deltaTime; } if (Input.GetAxis("Horizontal") < 0){ transform.position -= transform.right * speed * Time.deltaTime; } } }
これで移動はできるようになったがcylinderを突き抜けていってしまうので衝突判定の設定をする
cylinderにはデフォルトでCapsule colliderがセットされているので、unitychanの方にcolliderとrigitbodyを設定する
- rigidbody
- use Gravity:オフ
- Is Kinematic:オフ
- capsule collider
- height: 2
- Center: 0, 1, 0
これで衝突判定されるようになったが、柱にぶつかった時の挙動がちょっと微妙。
調べればよい解決法があるのかもしれないがとりあえず次の方法を試してみる
2. RigidBody
Rigidbody.AddForce
- rigidbody
- use Gravity:オフ
- Is Kinematic:オフ
- capsule collider
- height: 2
- Center: 0, 1, 0
using System.Collections; using System.Collections.Generic; using UnityEngine; public class unityWalking : MonoBehaviour { public float speed = 10f; public Rigidbody rb; void Start(){ rb = GetComponent<Rigidbody> (); } void FixedUpdate () { float x = Input.GetAxis ("Horizontal") * speed; float z = Input.GetAxis ("Vertical") * speed; rb.AddForce (x, 0, z); } }
rigidbodyに力を加えて押す感じ?慣性で動き続けてしまうので微妙
Rigidbody.Velocity
using System.Collections; using System.Collections.Generic; using UnityEngine; public class unityWalking : MonoBehaviour { public float speed = 3f; float moveX = 0f; float moveZ = 0f; Rigidbody rb; void Start(){ rb = GetComponent<Rigidbody> (); } void Update () { moveX = Input.GetAxis ("Horizontal") * speed; moveZ = Input.GetAxis ("Vertical") * speed; Vector3 direction = new Vector3 (moveX, 0, moveZ); } void FixedUpdate(){ rb.velocity = new Vector3 (moveX, 0, moveZ); } }
- 慣性はなくなった
- ただ衝突判定時に回転してしまう
これもちゃんと調べればきちんと動く方法があるかもしれないのだが、とりあえず次を試してみる
3. CharacterController
CharacterController.SimpleMove
結論から言うとこのCharacter Controllerを使うと自分の意図してた動きを実現することができた
このCharacter Controllerとはカプセルcolliderと移動機能をセットにしたものでrigidbodyもセットしても反映されないらしいので、上の方法でセットしていたcolliderとrigidbodyは今回はセットしない
その代わりにCharacter Controllerをセットする
- Character Controller
- Center : 0, 1, 0
- Height : 2
using System.Collections; using System.Collections.Generic; using UnityEngine; public class unityWalking : MonoBehaviour { public float speed = 3f; float moveX = 0f; float moveZ = 0f; CharacterController controller; void Start(){ controller = GetComponent<CharacterController> (); } void Update () { moveX = Input.GetAxis ("Horizontal") * speed; moveZ = Input.GetAxis ("Vertical") * speed; Vector3 direction = new Vector3 (moveX, 0, moveZ); controller.SimpleMove (direction); } }
Unityでシーン遷移するとライトが暗くなる問題
UnityでSceneManager.LoadScene ("scene名")でシーンを移動すると、移動先のシーンのライトが暗くなる問題が発生した。
問題のシーンを遷移せずに初期画面として実行すると正常にライトが表示されるにも関わらず、他のシーンから移動すると暗くなってしまう。
調べてみると何時の頃からかライト情報の取り扱いが変更になったらしい
解決法
- 問題のシーンを開く
- Window > Lighting > Settingsでライトの設定を開く
- 一番下に表示されるAuto Generateのチェックを外し、その隣のGenerate Lightingをクリックする
以上でシーン遷移後もライトが暗くなる問題は解決できた
raspberryPi3にinfluxdb v1.3をインストールする
以前ラズベリーパイにv1.2のinfluxdbをインストールしましたが、今回はv1.3です
portaltan.hatenablog.com
Install InfluxDB
# ライブラリ設定 $ curl -sL https://repos.influxdata.com/influxdb.key | sudo apt-key add - OK $ source /etc/os-release $ test $VERSION_ID = "7" && echo "deb https://repos.influxdata.com/debian wheezy stable" | sudo tee /etc/apt/sources.list.d/influxdb.list $ test $VERSION_ID = "8" && echo "deb https://repos.influxdata.com/debian jessie stable" | sudo tee /etc/apt/sources.list.d/influxdb.list deb https://repos.influxdata.com/debian jessie stable $ sudo apt-get update # インストール $ sudo apt-get install influxdb $ sudo service influxdb start # 確認 $ ps aux | grep influx nouziru 8210 0.0 0.2 4276 2012 pts/1 S+ 12:59 0:00 grep influx influxdb 29797 13.1 4.3 800484 38508 ? Ssl 11:15 13:40 /usr/bin/influxd -config /etc/influxdb/influxdb.conf $ ss -lntp | grep 808 LISTEN 0 128 127.0.0.1:8088 *:* LISTEN 0 128 :::8086 :::* $ influxd config ### 各種項目が表示される
influxコマンド確認
$ influx Connected to http://localhost:8086 version 1.3.7 InfluxDB shell version: 1.3.7 > show databases name: databases name ---- _internal > create database debug > show databases name: databases name ---- _internal debug > use debug Using database debug > show measurements
ちなみにssl化しているときやport番号を変更しているときはssl, unsafeSsl, portオプションが必要
> influx -ssl -unsafeSsl -port 10443
API確認
# pingチェック $ curl -sl -I http://localhost:8086/ping HTTP/1.1 204 No Content Content-Type: application/json Request-Id: 0c85b3cf-d3f2-11e7-8003-000000000000 X-Influxdb-Version: 1.3.7 Date: Tue, 28 Nov 2017 04:10:20 GMT # database確認 $ curl http://localhost:8086/query --data-urlencode "q=SHOW DATABASES" {"results":[{"statement_id":0,"series":[{"name":"databases","columns":["name"],"values":[["_internal"],["debug"]]}]}]} # テストデータ投入(measurement: test_measurement / field: record1, 2) $ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record1=100' $ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record2=200' $ curl -i -XPOST "http://localhost:8086/write?db=debug" --data-binary 'test_measurement record1=300,record2=400' # テストデータ確認 $ curl -G 'http://localhost:8086/query?db=debug' --data-urlencode 'q=SELECT * FROM test_measurement' {"results":[{"statement_id":0,"series":[{"name":"test_measurement","columns":["time","record1","record2"],"values":[["2017-11-28T04:16:19.266486831Z",100,null],["2017-11-28T04:16:28.640633831Z",null,200],["2017-11-28T04:16:44.255827602Z",300,400]]}]}]} # テストデータ確認(pretty=trueをつけると改行されて表示される) $ curl -G 'http://localhost:8086/query?db=debug&pretty=true' --data-urlencode 'q=SELECT * FROM test_measurement' { "results": [ { "statement_id": 0, "series": [ { "name": "test_measurement", "columns": [ "time", "record1", "record2" ], "values": [ [ "2017-11-28T04:16:19.266486831Z", 100, null ], [ "2017-11-28T04:16:28.640633831Z", null, 200 ], [ "2017-11-28T04:16:44.255827602Z", 300, 400 ] ] } ] } ] } # influxコマンドで確認すると $ influx Connected to http://localhost:8086 version 1.3.7 InfluxDB shell version: 1.3.7 > use debug Using database debug > select * from test_measurement name: test_measurement time record1 record2 ---- ------- ------- 1511842579266486831 100 1511842588640633831 200 1511842604255827602 300 400
tips
status確認スクリプト
#!/bin/sh HOST="https://localhost" PORT=443 echo "**********************************************************************************************************************" echo "[ping]" ping=`curl -ksI ${HOST}:${PORT}/ping` echo "$ping" echo "************************************************************************************************************************" echo "[db]" db=`curl -sk ${HOST}:${PORT}/query --data-urlencode "q=SHOW DATABASES"` echo "$db" echo "************************************************************************************************************************" echo "[latest records]" desc=`curl -skG "${HOST}:${PORT}/query?db=DEBUG&pretty=true" --data-urlencode "q=SELECT * FROM test_measurement ORDER BY time DESC LIMIT 1"` echo "$desc"
追記
csvでデータをexportする方法
$ curl -H "Accept: application/csv" -skG "${HOST}:${PORT}/query?db=${DB_NAME}" --data-urlencode "q=SELECT * FROM ${measurement_name}" > test.csv