2016年9月18日日曜日

CentOS7でOpenStackをAll in oneで構成した

はじめに

自宅のサーバ上にOpenStack環境がほしいと思い構築しました。AWSなどをレンタルするのではなく,自宅の物理マシン上にOpenStackがあれば便利です.
サーバ構成は以下の通り

  • CentoOS7
  • Core i7 Skylake
  • 32GB RAM
  • HDD 2TB

OSのセットアップ

CentOS7 x86_64を新規にセットアップしました.手順通り最小構成でインストールします.気をつけることは次の1点のみ
  • 固定IPアドレスにする(インストール後に変更も可能)
構築後はSSHログインの設定をしたり,`sudo apt-get install emacs net-tools sysstat`などしたりです.


OpenStackの構築

基本的にはこのページの通り進めていきました.RDOというCentOSなどにかんたんなOpenStackの構築を提供します.
https://www.rdoproject.org/install/quickstart/

ただし,ネットワークの設定をするために,Step3の`$ packstack --allinone`を実行する前に次のページを確認しましょう.こちらの手順に従ってすすめていきました。
https://www.rdoproject.org/networking/neutron-with-existing-external-network/

多くの人々が'packstack allinone'で既存の外部ネットワークを使った構築をどうやって使うのか疑問に思ってきました.こちらで紹介する方法で同一ネットワーク上のどのマシンもfloating IPを介して起動中のインスタンスにアクセスできるようになります. "Many people have asked how to use packstack –allinone with an existing external network. This method should allow any machine on the network to be able to access launched instances via their floating IPs.

その他のトラブル

ドメインでdashboard(horizon)につながらない。

最初はhttp://192.168.../dashboardとIPアドレスをWebブラウザに入力してアクセスしていました。しかしせっかくなのでドメインを割り当ててアクセスするようにしました。しかし、Openstackのdashboardではなく、apacheの空白ページが表示されてしまいます。これは次のように解決しました。
  1. /etc/httpd/conf.d/15-horizon_vhost.confを開く
  2. ServerAliasを追加する

参考にした書籍


2016年7月6日水曜日

Windows10でWiiリモコンを使うために wiiuse

Windows10とWiiリモコンをインターフェイス

今更感のある話題ですが、Windows10のPCとWiiリモコンをインターフェイスをして,アプリの開発をしたいと思い立ちました。Wiiリモコンとのインターフェイスのためのツールはいくつかあるようですが、今回はwiiuseというものを使います。理由は2つ
  • C言語で提供されている.
  • Windows, Mac, Linuxでビルド・利用ができる.
  • 従って,特定のプラットフォームに依存することなく自分の開発するプログラムに組み込むことができそう。
  • Githubでstarが多い(←結構てきとう)

ビルド

ともかくまずはビルドしてみることにしました。README.mdの手順に従います。
まずは、Visuals Studio 2015はもちろんですが、CMakeWDKをが必要です。

CMakeでビルドプロジェクトを作成しようとすると、WINHIDの設定がなされていませんでした。
きっとWindows Driver Develop Kit(DDK)に付属したライブラリやインクルードディレクトリが見つけられなかったんだろうなぁ。。
CMakeでWINHIDの探索を定義したFindWinHID.cmakeを確認すると

set(WINHID_ROOT_DIR "$ENV{DDKROOT}")


とあるように環境変数DDKROOT以下を探していますが、そもそもDDKROOTという環境変数は定義されていません。一方で、次のようにhid.libというライブラリを探索しています。

find_library(WINHID_LIBRARY
  NAMES
  hid
  libhid
  HINTS
  "${WINHID_ROOT_DIR}"
                ・・・
そこで、エクスプローラからhid.libを検索してみました。
見つけたーーー!複数個所で見つけていますが、「C:\Program Files (x86)\Windows Kits\10\Lib\10.0.xxxx\um\x64」が妥当なのでしょうか。 ということは、、同じように探していって、、
  • WINHID_LIBRARY: C:\Program Files (x86)\Windows Kits\10\Lib\10.0.xxxx\um\x64\hid.lib
  • WINHID_INCLUDE_DIR: C:\Program Files (x86)\Windows Kits\10\Include\10.0.xxxx\shared
  • WINHID_CRT_INCLUDE_DIR: C:\Program Files (x86)\Windows Kits\10\Include\10.0.xxxx\ucrt
  • WINHID_ROOT_DIR: null (空白のまま)
(um, kmについてはおそらくドライバー モデルの選択に書いてある通りだと思う。)
そしてCmakeで「Configure」ボタンを押すと今度は次のメッセージが
SDLもいるのか。。公式サイトからVisualStudio向けのdevelパッケージをダウンロードします。展開して適切なディレクトリにおいてやります。(C:\usr以下がいいかな。)
で、それぞれINCLUDEとLIBRARYを定義します。SDL_LIBRARY_TEMPについては、FindSDL.cmakeに


# Additional Note: If you see an empty SDL_LIBRARY_TEMP in your
# configuration and no SDL_LIBRARY, it means CMake did not find your SDL
# library (SDL.dll, libsdl.so, SDL.framework, etc).  Set
# SDL_LIBRARY_TEMP to point to your SDL library, and configure again.
と書いてあるので、LIBRARYのディレクトリを指定してやりましょう。

これでようやくよさげ??(こういうときWindowsは面倒くさい)
CMakeで「Generate」ボタンを押すと、CMakeのbuildディレクトリにVisualStudioのソリューションファイルであるWiiUse.slnなどが生成されるので開きます。

Visual Studioのツールバーのビルド→バッチビルドを開いて、以下のようにビルドしたい項目にチェックを入れてビルドボタンをクリックしましょう。ALL_BUILDやINSTALLだとよくわからなかったのでPACKAGEにチェック入れてビルドしました。src以下にDebugやReleaseのディレクトリができてlibやdllのファイルができてました。
ビルドを完了しました.これらをc:/usr/以下など適切なディレクトリに配置してやりましょう.

2016年4月19日火曜日

Open Hack Day 2016で作った作品の紹介

Open Hack Day 2016 の展示会

先日、ヤフー株式会社が主催したOpen Hack Day の展示会に出展してきました。Open Hack Day当日に体調を崩してしまったため出場を断念したので、開発する予定だった作品を後日の展示会に向けて制作し、披露してきました。

この展示会は、Open Hack Dayで開発した作品を展示するという内容でした。

自転車に合わせて景色が動く

作った作品はこちら。一緒に出場したメンバが動画にまとめてくれました。


自転車を漕ぐとセンサが回転したことを読み取り、漕いだタイヤの回転速度に応じて映像が進行します。自転車のブレーキを掛けてタイヤが止まると映像も静止します。

複数台のプロジェクタで部屋一面に映像を投影し、部屋に居ながらにして違う場所の景色の中をサイクリングできたら楽しいだろうなという発想です。今回はTheta Sで撮影した映像を素材として使っていますが、コンピュータグラフィックスで作られたファンタジの世界を冒険できたら素敵ですね。
また、スポーツジムなどで自転車を漕いだり、ランニングしたりするマシンがありますが、同じ景色ではなく景色が変わったら運動もより一層捗るのではないかと思います。

展示では、諸事情の関係でプロジェクタの投影ではなくノートPCでの表示となっております。

センシングの仕組み

自転車にホールセンサ(磁気センサ)を取り付け、後輪ホイールの各所にネオジウム磁石を取り付けます。ホールセンサは磁石が近づくと反応します。ネオジウム磁石が近づく度に反応するため、その周期から速度を算出します。シリアル通信でPCに値を送信します。

映像はUnity

Theta Sで撮影した映像をUnityにMovieTextureとしてSphereオブジェクトに割り当てます。SerialPortでセンサから速度を取得し、それに応じてMovieTextureの再生速度を変えています。
Unityによって映像を作成しているため3次元情報を持っています。カメラオブジェクトを複数個設けることで複数台のプロジェクタにそれぞれの角度の映像を投影できます。また、ゲームの箱庭世界を冒険することや、OculusなどのVRデバイスに入力することにもつなげられます。

まとめ

今回は、Open Hack Dayの展示会で自転車を漕ぐと、その速度に合わせて映像が動く作品を展示しました。

2016年3月30日水曜日

UnityとAVRのUSART シリアル通信とReadLineで問題

概要

Unityからシリアルポートの入出力を行います。入出力先はAVRマイコンです。AVRマイコンはUSART機能を使って通信を行います。

これまで

UnityのC#ではなく、通常のWindows .NetFrameworkでシリアル通信を実装してきました。(最新バージョンの.Netでも.Net2.0でも正しく動作しました。)

Unityでシリアル通信

Unity(mono)と.Netの違いはあるとはいえ、同じ実装でシリアル通信できるはずです。
ただし、使用するフレームワークを.Net2.0に指定しなければいけません。
ツールバのEditor→Project Settings→PlayerからApi Compability Levelを.Net2.0にします。
.Net2.0を選択

ReadLineで通信が途絶える問題

基本的には通常のC#の実装と同じです。しかし、次の問題に遭遇し、苦労しました。(おそらくUnityに付属するライブラリに問題があると思われます。)
  • SerialPort#ReadLine() で入力できない。
ReadLine()を実行する場所で止まってしまいます。また、タイムアウトするように設定したら、毎回タイムアウトしてしまいます。

1バイトずつ読みこむように変更

SerialPort#ReadLine()は文字通り、改行コードまでの1行を取得するメソッドです。
AVRマイコン側も
    uint16_t hallCount = 0;
・・・・
    printf("%d\n", hallCount);
とprintf()で改行コードを書き出しているため問題ないはずです。ところが、通信が止まってしまいます。
そこで、諦めて1バイトずつ入出力するようにしました。

  • AVR側は、16bit int型をビットシフトして1バイトずつ2回に分けて送信レジスタに登録する。
  • C#側はSeralPort#ReadByte()メソッドを使って2回に分けて取得する。
C#のコードは前回実装したコードと同じですが、次の変更を行いました。
var high = serialPort.ReadByte();
var low = serialPort.ReadByte();
var val = (high << 8) + low;
また、AVRのコードもこのように1バイトずつ書き込むように変更しました。

これで通信ができるようになりました。

まとめ

Unityでシリアル通信をするとき、SerialPort#ReadLine()では通信が止まってしまうため、ReadByte()で1バイトずつ通信することで問題を回避しました。

2016年3月22日火曜日

基本: AVRのUARTとC#でシリアル通信 (受信割り込み)

概要

今回は、AVRでUSART受信割り込みを使ったプログラムを作成したいと思います。

要件

  • AVRはPCから送信された値を受信し、受信割り込みを発生する。
  • 受信割り込み時に"echo back: <val> \n"という文字列をPCに送信できる。
  • <val>はPCから送信された値で置換する。

準備

ハードウェア

もちろんこれは必須ではなく、AVR168Pもしくはこれと互換性のあるAVRマイコンとFT232RLが実装されており、USBでパソコンと接続できればOKです。
AVRとFT232RLの取り付けの解説は割愛しますが、次のように実装します。
  • AVRのTXDとFT232RLのRXDが接続されている。
  • AVRのRXDとFT232RLのTXDが接続されている。
AVRとFT232RLを使ったUSB-シリアル通信の実験に解説されているとおりです。

ライブラリ

UARTを使った処理をかんたんに実装するために、次のコードを実装しました。初期化と読み書き、割り込み処理といった基本的なレジスタ操作をまとめたものです。

開発

AVR

dev3/usartsample/main.cを作成しました。割り込みなしのコードとほぼ同じですが、割り込み設定をしている箇所が異なります。
/**
* 受信割り込み発生時に実行される関数
* @param data 受信データ
*/
void rxEventListener(uint8_t data) {    
    printf("echo back: %d \n", data);
}

int main(void) {
    // 受信割り込みありでUSARTを初期化(8MHzクロック時, 9600ボーレート)
    USART_init(RX_COMPLETION_INTERRUPT, 51);

    // 受信割り込み発生時に実行する関数を登録
    USART_setRxCompletionInterruptListener(*rxEventListener);

    // printfで使用する関数を登録
    fdevopen(*USART_sendData, NULL);

    // 割り込み全許可
    sei();

    printf("Initialized>>\n");
    while (1) {
    }
}
  • UCSRnBレジスタのRXCIEn(7bit目)を1(true)にして、受信割り込み許可を行っています。(該当コード
  • 割り込みベクタUSART_RX_vectで受信割り込みを駆動できます。(該当コード)
  • 初期化しても、sei()を唱えないと割り込みは発生しません。
これで、PC側からの値に応じて、処理を変えたり、レスポンスする内容を変更したりできますね。

C#

前回同様にSerialSample/Program.csを使用します。

基本: AVRのUARTとC#でシリアル通信

概要

AVRとPC間でシリアル通信する方法を確認しました。AVRでは、UART機能を使用し、C#では.NetFrameworkのSerialPortクラスを使用して実現します。
ここでは、通信の基本であるエコーバックを実装し、通信のやり方を確認します。

準備

ハードウェアの準備

もちろんこれは必須ではなく、AVR168Pもしくはこれと互換性のあるAVRマイコンとFT232RLが実装されており、USBでパソコンと接続できればOKです。

AVRとFT232RLの取り付けの解説は割愛しますが、次のように実装します。
  • AVRのTXDとFT232RLのRXDが接続されている。
  • AVRのRXDとFT232RLのTXDが接続されている。
AVRとFT232RLを使ったUSB-シリアル通信の実験に解説されているとおりです。

ライブラリ

UARTを使った処理をかんたんに実装するために、次のコードを実装しました。初期化と読み書き、割り込み処理といった基本的なレジスタ操作をまとめたものです。

サンプル

単純なエコーバック

  • パソコンから文字をAVRに送信する。
  • AVRは受信した文字のアスキコードをエコーバックする。

AVR

これを実現するために、AVRで実装したコードはdev1/usartsample/main.cです。

int main(void) {
    # USARTを初期化します。割り込みなし,ボーレート9600
    USART_init(NOMAL, 51);

    # printfをするときはUSART_sendData関数を利用するように登録します。
    fdevopen(*USART_sendData, NULL);

    # printfしてみます。
    printf("Enter>>\n");

    # 以下、データを受信して、受信したデータを送信するエコーバックを繰り返します。
    while (1) {
        uint8_t val = USART_recieveData();
        printf("%d\n", val);
    }
}


  • USART_initの2つ目の引数51はボーレート設定値を示します。
    • クロック8MHz動作時で9600のボーレートです。
    • データシートに値の設定方法が解説してありますので、参照してください。
  • fdevopen()でUSART_sendData関数を登録することでprintfを使えるようにしています。

C#

VisualStudioからC#プロジェクトを作成します。今回はコンソールアプリケーションとします。
コンソールアプリケーションの作成(C#)

SerialPortクラスを使用して、Read&Writeを行うプログラムを実装します。( SerialSample/Program.cs )

            if (!serialPort.IsOpen) {
                serialPort.Open();
            }

            while (true) {
                string val = System.Console.ReadLine();               
                serialPort.Write(val.Substring(0, 1));
                var readVal = serialPort.ReadLine();
                System.Console.WriteLine(readVal);
            }

  • AVR側は複数バイトの受信に対応していないため、Substringメソッドで先頭文字だけ抽出しています。
  • SerialPort.Write()で書き込み、SerialPort.ReadLine()で\nまで読み込みます。

実行結果

次のように、入力した文字に対するアスキーコードを返しています。アスキーコード表で確認すると正しくレスポンスされていることがわかります。
実行結果

補足

今回、C#でシリアル通信の実装を確認するためC#で通信を実装しましたが、TeraTermを用いても等価のことを実行できます。

2016年3月13日日曜日

Unity5 ThetaSの画像をSkyboxで動的にアニメーション

ThetaSの映像を動的アニメーションで表示したい


360度カメラThetaSで撮影した映像をUnityに取り込んで表示したいです。

要件

要件は次の通りです。
  1. 1人称視点でカメラの向きに応じた角度の映像を見れる。
  2. プログラムから映像の再生をコントロールできる(再生、停止、x倍速再生など)。
1.の要件だけであれば「360度カメラthetaで撮った写真をunityで使う」のやり方で実現できます(このブログエントリでは、Blenderで円球を作っていますが、通常のSphereでもこだわりを捨てれば問題ないと思います。)。
しかし、1.のやり方では、通常の再生のみで2.の再生をコントロールすることができません。現状、MovieTextureでは動画の再生コントロールには対応していないからです。

方針

  • 動画の各フレームを静止画に変換し、静止画のテクスチャを高速で切り替えることでアニメーションを実現する。
  • Sphereマテリアルではなく、Skyboxにアニメーションを投影する。
現状、MovieTextureによる動画の再生コントロールができないようです。そこで、ThetaSで撮影した360度動画の各フレームを静止画として出力して、高速で切り替えることによって上記の要件を実現します。静止画を割り当てたテスクチャを切り替えはプログラムからコントロールするため再生速度などの変更も可能と言えるでしょう。

また今回は、ThetaSで撮影した素材をSkyboxに割り当てます。他のオブジェクトを設置しやすくなるからです。(夜空のThetaS映像をSkyboxで投影し、UFOなどのオブジェクトが動いていたら素敵です。)

早速 作ってみましょう。

Theta Sの360度動画を静止画群に変換

Adobe PremiereとAdobe Media Encoderで動画の各フレームをJPEG画像に変換しました。
ThetaS動画を出力した静止画群

画像群をUnityに取り込み

作成した360度画像群をUnityに取り込みます。一つのディレクトリにまとめてます。
画像群を取り込み

取り込み後はテクスチャをCubeMapとして設定します。すべての画像を選んで、[Unity4,Unity5]thetaとかで撮った全球画像をSkyboxに指定する方法を適応します。すべての画像がCubeMap Typeとして設定されるまでしばらく時間がかかるかと思います。
取り込んだ全ての画像をCubemapテクスチャにする

Skyboxの作成とMain Cameraへアタッチ

  1. 新規マテリアルを作成し、Shaderを「Skybox/Cubemap」にします。
  2. HierarchyでMain Cameraを選択し、InspectorのAdd Componentボタンを押します。
  3. Rendering→Skyboxを選び、Skyboxコンポーネントを追加します。
  4. Custom Skyboxに1.で作成したSkyboxをドラッグし、設定します。
Skyboxを作成し、Main Cameraに登録

スクリプトの作成

Skyboxの設定はUnityEditor上で設定することが多いと思います。しかし、C#(もしくはJavaScript)のコード上からSkyboxのテクスチャを設定します。再生コントロールをするためです。
次の手続きの実装を行います。
  • 作成したコードはMain Cameraにアタッチする。
  • Startメソッドで、AssetDatabaseを使ってテクスチャを読み込み、リストに追加する。
  • UpdateメソッドでSkyboxのテクスチャを適切に切り替える。
まずは次のコードを書いてみました。Updateでは毎回フレームを切り替えています。テクスチャが繰り返し一定速度で再生されるはずです。(フレームレートは入力元の映像とおなじになるとは限らないです。)


// SkyboxRunner.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;

public class SkyboxRunner : MonoBehaviour {

    Skybox skybox;
    List skyboxTextures = new List();
    int index = 0;

    void Start () {
        // アタッチしたスカイボクスを取得
        skybox = GetComponent();

        // AssetDatabaseからテクスチャをロード
        var guids = AssetDatabase.FindAssets("t:Texture", new string[] { "Assets/SkyboxTex/nightsky1" });
        foreach (string guid in guids) {
            Texture texture = AssetDatabase.LoadAssetAtPath(AssetDatabase.GUIDToAssetPath(guid));
            skyboxTextures.Add(texture);
        }
    }
 
    void Update () {        
        // スカイボックスのテクスチャを切り替える
        skybox.material.SetTexture("_Tex", skyboxTextures[index]);
        index++;
        if (index >= skyboxTextures.Count) {
            index = 0;
        }
    }

}

ここでは、一定速度での繰り返し再生であるため、通常の再生と変わりません。Updateメソッドの内容を変更すれば、フレーム更新を自在に操ることができます。


まとめ

Theta Sで撮影した映像をUnityの3D空間に投影し、再生コントロールもしたかったのですが、MovieTextureなどでは実現できなかったため、各フレームを静止画に書き出してアニメーションすることで実現しました。
(もっといいほうがあればいいのですが、、、)