STYLY 開発者ブログ -STYLY Developer's Blog-

Unityで2台のRealSense D435/D435iを1台のPCで動作させる

UnityでRealSense D435とD435iを1台のPCで動作させる方法をまとめました。

本記事ではPoinCloudDepthAndColorシーンで2台のRealSenseを動作させるまでを解説します。

 

確認環境

Windows 10

Unity 2017.4.15f1

RealSense SDK 2.0(build 2.18.0)

 

準備

  1. 2台のReal SenseをPCに接続する。
  2. RealSense SDK 2.0のIntel.RealSenseViewerをダウンロードして実行。
  3. RealSense Viewerで2台とも認識できていることを確認する。
    ※2台目は左上の「Add Source」から追加。
    Stereo ModuleとRGB Cameraを有効にして映像が取得出来ていることを確認する。
  4. infoボタンを押して2台のReal Senseの Selial Numberを控えておく。
    ※後でUnityで設定します。

確認出来たらRealSense Viewerは終了しましょう。

Unity側設定

  1. Unityで新規プロジェクトを作成
  2. RealSense SDK 2.0のIntel.RealSense.unitypackageをダウンロードしてインポートする
  3. Assets>RealSenseSDK2.0>Scenes>Samples>PoinCloudDepthAndColorシーンを開いて実行。
    1台のみ認識してPointCloudが表示されることを確認してください。

2台目のRealSenseを動作させる。

ここからが本題です。

HierarchyのRsDeviceを選択してInspectorを見ると「Required Serial Number」という項目があります。

ここにIntel.RealSenseViewerで調べたSerial Numberを入力すれば、RsDeviceの入力ソースとして使用するReal Senseを指定することが出来ます。

PointCloudの描画にはこのRsDevice(とその子供のPointCloud/Color)、RsProcessingPipeが関係しているようなので、これらを2つのデバイス分用意すれば良さそうです。

  1. RsProcessingPipeをRsDeviceの子に移動
    ※参照関係を維持したままコピーしたいので。
  2. 2台目用にRsDeviceをコピー

  3. RsDevice/RsDevice(1)のRequire Serial Numberにそれぞれ1台目、2台目のReal SenseのSerial Numberを入力

    これで実行すれば2台のRealSense分のPointCloudが表示される。。。と思いきや、2台とも動作はしているようですがPointCloudは1台目のものしか表示されません。
    PointCloudの描画に使われているMaterialも2台分用意しないといけないようです。

  4. 2台目用にPointCloudMatをコピー
    Assets>RealSenseSDK2.0>Materials>PointCloudMatをコピーする。
  5. RsDevice(1) > Color > Rs Stream Texture RendererコンポーネントへPointCloudMat 1を設定する。

    TextureBindingへPointCloudMat 1を設定。
    Material.mainTextureを選択(Material 1をセットするとここがNo Functionにクリアされるので再設定が必要です

  6.  RsDevice(1) > PointCloudへPointCloudMat 1を設定。

これで一通りの設定が完了しました。実行すると2台のReal Sense分のPointCloudが表示されると思います。

 

パフォーマンスについて

確認PCスペック

CPU:Core i7 4790K 4GHZ

GPU:GTX970M

UnityEditorで実行

2台同時接続でも1台の場合と比べパフォーマンスに大きな影響はなく、FPSは80台中ほどで推移。

遅延もほとんど感じられませんでした。

 

補足

Liveモードでの2台同時動作は出来ましたが、Recordモードでの2台同時記録はこの方法では出来ませんでした。

おわりに

本件はLooking GlassでRealSenseのPoint Cloudを表示するために試してみました。

1台ではどうしてもRealSenseからの死角部分が描画されないので、2台使って補完しようという意図です。

結果は以下のツイートの通り。

2台のRealSenseの位置合わせについても、後日記事にまとめたいと思います。

 

 

 

 

 

 

 

カテゴリー: RealSense, Unity

WordPressをCloudFrontで高速化(qTranslate X対応)

WordPressをAWSのCDNサービスであるCloudFrontを使って高速化する際に、サイト多言語化対応プラグインであるqTranslate Xが原因でハマったので、解決方法などをメモする。

qTranslate XTへの乗り換え

WordPress多言語化対応プラグインであるqTranslate Xは2016年以降更新されておらずバグが多数残っている現状である。有志が立ち上げたプロジェクトであるqTranslate XTはバグ対応を含めてよくメンテナンスされているので乗り換えを行いましょう。ただし、qTranslate XTはWordpress管理画面のPlugin検索では出てこないためGithubから最新版をダウンロードしてインストールする。

すでに、qTranslate Xを利用している人は下記の手順で乗り換えを行いましょう

  1. qTranslate XTのGithubページからZip形式でコードをダウンロード
  2. 管理画面のプラグインの追加からZipファイルをアップロードしてインストール
  3. qTranslate XTを有効化
  4. この時点ではqTranslate XとqTranslate XTの両方が有効化されている状況です。両方とも同じ設定情報利用するらしく、片方で更新した変更がもう片方に反映されます。
  5. qTranslate Xを停止
  6. qTranslate Xを削除

設定のIntegration – Configuration Files に
./i18n-config.json
以外のゴミが入っていてエラーになっている場合は削除しましょう

qTranslate XTの設定

Detect Browser Languageの
Detect the language of the browser and redirect accordinglyをオフにします。

ブラウザのAccept-Languageヘッダーを元にサーバー側で判断するロジックですが、CDNからオリジンサーバーへAccept-Languageを透過させるとキャッシュ効率がわるくなるためオフにしましょう。ちなみにブラウザからサーバーへ渡されるAccept-Languageはenやjpといった2文字列だけではなく
en-US,en;q=0.9,ja;q=0.8,it;q=0.7,ko;q=0.6,fr;q=0.5,ru;q=0.4,zh-CN;q=0.3,zh;q=0.2
の様にブラウザごとにある程度複雑な文字列になっています。

WordPressのindex.php / admin.phpの改造

qTranslateではソースコード中で$_SERVER[‘HTTP_HOST’]を参照している箇所が存在します。これが悪さをしてCDN経由時におかしな挙動がおこります。

ブラウザ=>1=>CDN=>2=>Origin サーバー(実際にWordpressが動作しているサーバー)

とデータが流れる際に、1は実際にユーザーがブラウザに入力するドメイン名が用いられます。しかし、2でCDNからOrigin サーバーにデータを取得する際には、ユーザーは知ることのないOriginサーバーに割りあてたドメイン名を使ってアクセスします。しかしながら、qTranslateのコードが利用している$_SERVER[‘HTTP_HOST’]はユーザーは知ることのないOriginサーバーに割りあてたドメイン名を返すため挙動がおかしくなります。

そこで、Wordpressルートディレクトリにあるindex.php内に下記のコードを加えて、$_SERVER[‘HTTP_HOST’]を上書きしておきましょう


/**
 * Front to the WordPress application. This file doesn't do anything, but loads
 * wp-blog-header.php which does and tells WordPress to load the theme.
 *
 * @package WordPress
 */

/**
 * Tells WordPress to load the WordPress theme and output it.
 *
 * @var bool
 */
define('WP_USE_THEMES', true);

/** Loads the WordPress Environment and Template */
require( dirname( __FILE__ ) . '/wp-blog-header.php' );

wp-admin/admin.phpの修正
同様に、コードの先頭にドメイン書き換えロジックを挿入します

<?php
$domain_origin = "origin.domain.com";
$domain_for_public = "domain.com";
$_SERVER['HTTP_HOST'] = str_replace($domain_origin,$domain_for_public,$_SERVER['HTTP_HOST'] );
$_SERVER['SERVER_NAME'] = str_replace($domain_origin,$domain_for_public,$_SERVER['SERVER_NAME'] );

HTTPヘッダーのhostを転送することで解決

AWS CloudFrontの設定

WordPressのためのCloudFrontの設定を行います。下記0から2の項目はWordPressサイトをCloudFrontで配信するを参考に設定してください。管理画面や.phpコードがCDNキャッシュされないようになります。すべてのパターンにおいてHTTPヘッダーのhostを転送するようにしましょう。

3のDefault(*)の設定をqTranslateを考慮して行います。

設定内容は下記のとおりです。
Cookieのホワイトリストにqtrans_front_languageを設定してあげます。

CDN経由ではVisual Editorが表示されない問題を解決

CloudFrontからオリジンサーバーへアクセスする際のUser-agentは「Amazon CloudFront」になるため、User-agentで処理を分岐しているコードがおかしな挙動になります。Visual EditorはEnable Visual Mode in CloudFrontプラグインを入れることでCloudFront利用時でも正常に表示されるようになります。

 

OriginサーバーをクローラーにIndexされないようにする

CDNを利用すると、CDNに割り当てたドメイン、Originサーバーに割り当てたドメインのどちらのURLでも同じコンテンツにアクセスできることになりSEO上よくありません。Originサーバーがサーチエンジンにクロールされないようにしましょう。

まず、Originサーバーに設置したrobots.txtにクローラー拒否の記述を行います

User-agent: *
Disallow: /

つぎに、CDNのrobots.txtにアクセスが有った場合に、別途S3に配置したrobots.txtを表示するように設定します。こちらの回答を参考にしています。

1) S3のBacketを作成し、robots.txtだけを配置します。その際、Publicに設定しブラウザからアクセスできるようにしておきます。内容は下記のようにします

User-agent: *
Disallow: /wp-admin/
Allow: /wp-admin/admin-ajax.php

2) CloudFrontのDistribution settingsでCreate originで1で作ったBacketを指定します

3) CloudFrontのBehaviorを作成し、下記の通り設定します
Path Pattern: robots.txt
Origin: 2で作成したOrigin

4) 3で作成したBehaviorのPrecedenceを0に設定します。

5) Invaridationで、/robots.txt を指定してCDNのキャッシュをクリアします

投稿時にCDNキャッシュをクリアする

記事投稿・更新時に、CloudFrontのキャッシュをPurge(Invaridate)するには、CloudFront Clear Cacheプラグインを利用します。記事を更新した場合、該当記事のキャッシュが自動的に削除されます。

追記(2019/03/19)

ログアウト時のクッキー削除。Wordpressでは一度管理者などでログインするとログアウトしても一部のクッキーが残ったままになり、CDNのキャッシュに影響を及ぼします。Logout Clear Cookiesプラグインをインストールしてログアウト時にクッキーを削除するようにしましょう。

カテゴリー: その他

Azure CDNのコンテンツをPHPからRest API経由でパージする

AzureをRest APIで操作してCDNにキャッシュされたコンテンツをPurgeする方法がうまくまとまったサイトがなかったので、関数を作ってみた。

まず、リソース作成者の取得方法(Rest API編)を参考に、各種キーを取得します。

一点上記のサイトと違うところは、今回はCDNを操作するため、IAMでアカウントのRoleにはCDN Profile Contributerを設定しておきましょう。

<?php


$cdnurl = "https://xxxxxxx.azureedge.net/Thumbnails/d7d7d572-c299-449a-a8af-5da785867310.png";

//パージ実行
purgeCdnURL($cdnurl, $cdn_purge_subscriptionId, $cdn_purge_resourceGroupName, $cdn_purge_profileName, $cdn_purge_directory_id, $cdn_purge_client_id, $cdn_purge_client_secret);


#設定情報
$cdn_purge_directory_id = "XXXXXX-fef8-46d0-9824-XXXXXXX";
$cdn_purge_client_id = "XXXXXX-XXXXX-456e-9836-XXXXXXXX";
$cdn_purge_client_secret = "XXXXXXXXXXXXXXXX1ZK78fuKC6mcmg=";

$cdn_purge_subscriptionId = "XXXXXX-XXXXX-XXXXX-XXXXX-4654b3f6ffe1";
$cdn_purge_resourceGroupName = "XXXXXXXXX";
$cdn_purge_profileName = "XXXXXXXXXXX";


$cdnurl = $_POST["cdnurl"];
if($cdnurl==""){print "cdnurlを設定してください";die();}

//CDNのURLを指定してパージする
function purgeCdnURL($CdnURL, $subscriptionId, $resourceGroupName, $profileName, $directory_id, $client_id, $client_secret){
	$contentPath = getContentPath($CdnURL);
	$endpointName = getEndpointName($CdnURL);
	$access_token = getBearerAccessToken($directory_id, $client_id, $client_secret);
	$ret = purgeCdn($subscriptionId, $resourceGroupName, $profileName, $endpointName, $contentPath, $access_token);
	if($ret == true){
		print "Purge succeeded.";
	}else{
		print "Purge failed.";
	}
}

//Authorization: Bearer用のAccess Token取得
//参考:https://tech-lab.sios.jp/archives/7239
function getBearerAccessToken($directory_id, $client_id, $client_secret){
	$ch = curl_init();
	curl_setopt_array($ch, [
	    CURLOPT_URL => 'https://login.windows.net/' . $directory_id . '/oauth2/token?api-version=1.0',
	    CURLOPT_RETURNTRANSFER => true,
	    CURLOPT_POST => true,
	    CURLOPT_POSTFIELDS => http_build_query(
	    	array(
		    'grant_type' => 'client_credentials',
		    'resource' => 'https://management.azure.com/',
		    'client_id' => $client_id,
		    'client_secret' => $client_secret,
	    	)
	    ),
	]);
	$response = curl_exec($ch);
	curl_close($ch);
	$response_decoded = json_decode($response);
	$access_token = @$response_decoded->{"access_token"};
	if($access_token==""){
		print_r("Error at getBearerAccessToken():" . $response);die();
	}
	return $access_token;
}


#CDNコンテンツをパージ
#参考:https://docs.microsoft.com/en-us/rest/api/cdn/endpoints/endpoints_purgecontent
function purgeCdn($subscriptionId, $resourceGroupName, $profileName, $endpointName, $contentPath, $access_token){
	
	$url = "https://management.azure.com/subscriptions/{$subscriptionId}/resourceGroups/{$resourceGroupName}/providers/Microsoft.Cdn/profiles/{$profileName}/endpoints/{$endpointName}/purge?api-version=2017-10-12";
	$ch = curl_init();
	
	curl_setopt($ch, CURLOPT_HTTPHEADER, 
		array(
			"Content-Type: application/json",
			"Authorization: Bearer " . $access_token
		)
	);
	curl_setopt_array($ch, [
	    CURLOPT_URL => $url,
	    CURLOPT_RETURNTRANSFER => true,
	    CURLOPT_POST => true,
	    CURLOPT_POSTFIELDS => '{contentPaths: ["' . $contentPath . '"]}',
	    
	]);
	$response = curl_exec($ch);
	curl_close($ch);
	
	if($response!=""){
		print_r("Error at purgeCdn():" . $response);die();
	}
	return true;
}


function getContentPath($cdnurl){
	preg_match('/^(http|https):\/\/(.*).azureedge.net/',$cdnurl,$matched);
	$tmp = @$matched[0];
	if($tmp==""){print "Error: This is not CDN URL";die();}
	return str_replace($tmp, "", $cdnurl);
}

function getEndpointName($cdnurl){
	preg_match('/^(http|https):\/\/(.*).azureedge.net/',$cdnurl,$matched);
	if(count($matched)==0){print "Error: This is not CDN URL";die();}
	return $matched[2];
}



?>

 

 

 

 

カテゴリー: その他

Project North Star キャリブレーション方法

はじめに

Leap Motionからオープンソースとして公開されたARヘッドセット「Project North Star」。

本記事ではexiii山浦氏が製作された簡易版Project North StarをUnityで動かす上で行った変更やキャリブレーションについて解説します。

公式のProject North Starとの違いは上記のブログをご参照ください。

Project North Starの構成

左右2枚のLCDに表示される映像を眼前のリフレクターで反射させ、現実と重ね合わせて表示させます。

キャリブレーションでは、表示された映像が現実空間上の正しい位置に表示されるように調節します。

引用元:http://blog.leapmotion.com/northstar/

PCとの接続

1.Leap Motion、HDMI2つを接続。

2.ディスプレイ設定

接続したLCDをディスプレイ2、3として設定します。

向きを縦(もう一方は縦[反対向き])、解像度はLCDに合わせて1080 x 1920とする。

Image [10]

 

 

Unity側準備

公式ドキュメント
https://github.com/leapmotion/ProjectNorthStar/blob/master/Software/README.md

・Unityバージョン:Unity 2018.1b13以上

・Project North StarのGitHubレポジトリから、LeapAR.unitypackageを入手してインポートする。
https://github.com/leapmotion/ProjectNorthStar/tree/master/Software

・LeapMotion/North Star/Scenes/NorthStar.unityシーンを開く

 

NorthStar.unityシーンについて

unity scene

シーン内の左右の目に当たるカメラで撮影した映像を歪めてプロジェクションし、

その映像を別のカメラで撮影してGame Viewに表示しています。

 

North StarにGame Viewを表示する

Game Viewを外部ディスプレイに移動、表示できるようにするため、ディスプレイ1の幅と外部ディスプレイの解像度を設定する必要があります。

AR Camera Rig設定

Window Offset Managerのxshiftにディスプレイ1の幅の値を設定する。
arcamerarig

ソースコード修正箇所

LCDの解像度が公式と異なるため、ソースコードを書き換える必要があります。

公式:(2880, 1600 )

簡易版:(1080*2, 1920)

 

変更箇所は以下の3か所。実際に使用するLCDの値に書き換えてください。
\Assets\LeapMotion\North Star\Scripts\CalibrationDeformer.cs 25行目
Vector2 screen = new Vector3(2880, 1600);

\Assets\LeapMotion\North Star\Scripts\WindowOffsetManager.cs 59行目
SetPosition(xShift, 0, 2880, 1600);

\Assets\LeapMotion\North Star\Editor\WindowOffsetManagerEditor.cs 43行目

var size = new Vector2(2880, 1600 + UNITY_MENU_HEIGHT);

 

上記設定後、AR Camera RigのWindow Offset Managerコンポーネントの

[Move Game View to Headset]ボタンを押すと、North StarにGame Viewが移動します。

movegameview

gameview

 

IMG_9079

Game Viewの表示が反転してNorth Starに表示される事を確認してください。

※Game Viewにフォーカスを当てないとキー操作出来ないので、移動後もう一つGame Viewを表示しておきましょう。

以上でUnityの映像がNorth Starで表示できるようになりました。

 

キャリブレーションファイルの設定

キャリブレーションの結果はUnityでの実中にSerialized Calibrationスクリプトでjsonファイルとして保存/読み込みできます。
Calibration Folder、Output/Input Calibration Fileを下記の通り設定してください。
保存はSキーを押すと実行されます。

Image [6]

保存される対象は、Left Eye/Right Eye/Left Screen/Right Screen/Leap Hand ControllerのTransformおよび、CalibrationDeformerコンポーネントの情報(Left Eye/Right Eyeのみ)。

※保存対象を追加することも可能。

公式のキャリブレーション手段で対応しきれない場合は、上記GameObjectのTransform/CalibrationDeformerの値を直接変更して対応しました。

Image [11]

 

キャリブレーションの実行

ここからは、Project North Starを被って映像を見ながら調整する作業になります。

以下の手順は、基本的に

UnityのPlayボタンで実行→見ながら調整→Sキーで保存

という流れになります。

 

キャリブレーションのポイント

・キャリブレーションバーを表示(Cキー押下)し、縦横のラインがまっすぐ表示される事。

・手を上下、水平、前後方向に動かし、Leap Motionの手も同様に移動していること。

・片目ずつ、実際の手とLeap Motionの手が合うように調整する。

 

前提条件.LCDのアスペクト比の違いを調整

公式とLCDのアスペクト比が異なるので、Left/RightScreenのScaleを変更する。

scale (1.1, 0.83333333, 1)
※xは解像度の比率では1440/1080 = 1.33333だが、LCDパネルのもともとの比率のためか、1.1くらいが丁度よかった。

Image [9]

ロゴなどを貼った立方体を置くと目視で合わせやすい。

 

手順1.IPD調整

目の位置、距離に関する設定。
基本的に現実の物理的な位置に合わせる。

→キー:IPDを広げる
←キー:IPDを狭める
↑キー:目の位置を上げる
↓キー:目の位置を下げる
[キー:リフレクターと目の距離を広げる
]キー:リフレクターと目の距離を縮める

ipd adjuster

手順2.Calibration Deformer調整

左右の映像のズレを個別に調整する。

映像が左右の目で上下左右にズレている場合にこの設定変更が有効です。

deformer2

公式の方法では、マウス左クリックでコントロールポイントを追加して、ドラッグで調整と書かれています。

  • Left Mouse on the Game View to Place and Drag Manual Calibration Distortion Pins
  • Right Mouse to Remove Manual Calibration Distortion Pins

ただ、この方法では細かい調整が難しかったのでLeftEye/RightEyeにあるCalibration Deformerコンポーネントの設定を直接変更して合わせました。

vetex Indices
size:1
Element 0:0(+1ごとに上下にずれ、+31ごとに左右に移動するようです)
Control Points
size:1
Element 0:

Xを変更すると上下移動
Yを変更すると左右移動
Zを変更すると奥行移動(基本0で良い)

deformer

 

手順3.手のトラッキング位置を調整

現実の手とLeap Motionの手が全体的に上下左右にズレている場合、Leap XR Providerの位置を調整して合わせます。

Image [4]

 

おわりに

Project North Starはオープンソースで自作する都合上、どうしても個体ごとに差異が出てしまいます。

その問題をキャリブレーション手段を提供することで対応するのは面白い試みと思いました。

他の方が作成されたNorth Star向けアプリケーションも、キャリブレーションファイルを置き換える事で自分のNorth Starで動作させる事が出来るのでアプリケーション配布の可能性も見えてきます(ソースコードを変更した箇所は難しいですが)。

とはいえ、正確なキャリブレーションは難しく、キャリブレーションされていなければ体験を損なうことになります。

Project North Starのキャリブレーションにあたり本記事が参考になれば幸いです。

公式のプロジェクトも今後さらにアップデートされていくと予想されますので、期待して待ちたいと思います。

カテゴリー: Leap motion, Project Noth Star, Unity

Cacheサーバーの設定を確認する

Unityエディタでキャッシュサーバーの設定がどうなっているかを確認するコードです。

エディタ拡張を作った際に、キャッシュサーバーがONになっていない場合にアラートを出したりする際に便利です。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

public class EditorScript : MonoBehaviour {

    /// <summary>
    /// Return cache server status 
    /// </summary>
    /// <returns>"Local", "Remote", "Disable"</returns>
    public static string checkCacheServer()
    {
        string[] CacheServerModeString = new string[3] { "Local", "Remote", "Disable" };
        var CacheServerMode = EditorPrefs.GetInt("CacheServerMode", (int)(EditorPrefs.GetBool("CacheServerEnabled") ? 1 : 2));
        return CacheServerModeString[CacheServerMode];
    }

    /// <summary>
    /// Call Cache server status function from menu
    /// </summary>
    [MenuItem("Editor Scripts/Check cache server", false, 10001)]
    private static void CallCheckCacheServer()
    {
        Debug.Log(checkCacheServer());
    }

}

 

メニューから実行してテストできます

cacheserver

カテゴリー: Unity

HOME / Coporate Site/ Careers

© Copyright 2018 STYLY..