OmniAICreator/Qiita-1.07M huggingface dataset:
full stuck engineerへの道 第0層電力編

# 前書き

full stuck engineer(完全に立ち往生エンジニア)には、やはり機材を動かすための電力から引けないとだめでは？
と思い立ったので二種電工をとることにした。

# 実行環境

- 開始時点で覚えてたのは高校物理でやったオームの法則ぐらい
- 案件の間で閑散期ほぼ定時帰り
- とはいえ毎日は不可（先約etc）
- 前期試験

# 実際に行った試験勉強
## 筆記

申し込み完了時点でとりあえず、過去問をやってみた。
→10～20点ぐらいだった。

どうしようもないので、本でまず通しで目を通すことにした。
使用した本は[いちばんやさしい 第2種電気工事士【筆記試験】 最短テキスト&出る順過去問集](http://amzn.to/2xcmC8z)
出退勤のときにチマチマ読み進めて大体２週ぐらいで１周
※２日に1回ぐらいしかできていない

残りの期間は過去問が公開されているので、それを解いてできていないところを補完するようにした。
過去問はECEE 一般財団法人電気技術者試験センターの[「試験の問題と回答」](http://www.shiken.or.jp/answer/index_list.php?exam_type=50)ページから
解説は実教出版の[「第二種電工　過去問解説・解答」](http://www.jikkyo.co.jp/kakomon/denko2_kakomon/index.html)を利用
解答用紙は[しゅうにゃん大作戦（リンク元エントリ）](http://shunyan.seesaa.net/article/373061108.html)のPDFを印刷して利用

平日は週に2,3回分（隔日）　土日は一日2，3回分づつ進めていった。

ちなみに試験当日はマーク試験なので、ちゃんと回答を控えておいて自己採点できるようにしました。

## 実技

筆記はまず問題ないことが自己採点でわかった段階で、練習機材発注
質問もできると言うことで準備万端シリーズを購入
ちなみに販売元サイトだと工具セットだと安くなったので、もしそろえるなら同時がよいかと思います。
使用した工具はホーザンのDK-18の工具セット
※ネット見てるとMCCのVS-4Aのほうが使いやすいというのも見て両方使ってみたがそんなに言うほどは変わらない気がする。
※リングスリーブの圧着工具がセットのは小さいやつで
　キーボードしか打つ力ないよって人は重いのを我慢して大型の方がよいと思います。刻印不良になると目も当てられないので、、、

筆記の時と大体同じペースで（平日は週に2,3回分（隔日）　土日は一日2，3回分づつ）
実技問題を解いて練習　最終的には2セット弱を解いた。
※3回分買ったけどそこまでは要らなかった。。。

初めて使う部品の時はセット付属のDVDとホーザンのyoutube動画で
差異を気にしながらトライ。
※輪作りはペンチで一度やった後は、ずっとVVFストリッパーで行った。ペンチはめんどいし時間かかる。。。

練習時は必ずタイムも測ってやっていた。
最初が1hぐらいで最終的には20minを切るぐらい

# 後書き

まだ合格しただけで申請は時間の都合上まだしてない。
申請が済めばちゃんと合法にコンセントが触れるよ！やったね！

自分が毎日はやらないのを見越して、期間として長めに取ったのは正解だった。
実技は自己採点ができないのでずっと気がかりだった。。。

# 影響元
http://qiita.com/rukihena/items/a30f07f93ca1718dff8e
Windows10でプロダクトキーの下5桁を表示するコマンド

```
slmgr -dli
```

複数台PCを使っていて、とりあえず調べたい場合にコマンドプロンプトとかで行けるので便利かと。

ついでにライセンスされているかどうか？も分かります。
全体を調べるには、フリーソフトとか使うしか無いですかね？
【React Native】iOS アーカイブでエラー　備忘録【CocoaPods】

# 経緯

今までビルド通ってて、申請しようと思ったけども、アーカイブした時だけなぜかエラーが起こったのでその時の対処法。あんまり大した内容ではないですが、忘れたくないので・・・。
原因はCocoaPodsにありました。

# 状況
エミュレーター、実機でも、debug, releaseでも正常に動いてたけど、アーカイブしたらダメでした。

```
_JSNoBytecodeFileFormatVersion, referenced from
...
facebook::react::parseTypeFromHeader()
...
symbol(s) not found for architecture x86_64
```

といった感じののエラーが出ました。

調べてみたらRN 0.46以上は、PodFileにBatchBridgeを追加しなきゃいけないみたいで、

```objc
pod "React", :path => react_native_path, :subspecs => [
    .....
    'Core',
    'BatchedBridge'
  ]
```

こんな感じにして`pod update`で解決。

# 次の問題

```
480 duplicate symbols for architecture arm64
```

という感じでエラーが出てきたのです。

ネイティブエンジニアの方と話ながら、podInstallに余分なものが含まれすぎているということに行き着きました。
たしかにPodInstallには色々はいってて、"RCTXX"といったRN系のものも多く入っていたし、あとで入れてきてたネイティブ系のライブラリもたくさん入ってた。
ので試しに色々削ってみることにしました。

削る度にduplicationの数が減っていき、最終的に


```objc
pod "React", :path => react_native_path, :subspecs => [
    'Core',
    'BatchedBridge'
  ]
```

でおちつきました。

#　終えてみて
正直うごいているから大丈夫と思ってきたけどもここでひっかかることになるとは思ってもみなかったです。

色々と経験してみて、RNエンジニアとネイティブのエンジニアってドメイン被ってるようで被ってなかったりして、独特の知識が必要だなと改めて気づきました。
ブリッジの部分弄ったりとかするときもRN固有の知識がいるのだとも感じてたりして、もっとネイティブ側の知識もないといけないなぁと思うこの頃でした。
SwiftyJSONでちょっと階層深くしたときのやり方

# 概要
与えられるJSONはこんな感じで，`hobbies`の部分のデータ取得方法がわからなかった．
そこについて説明する．

```
{
    "users":[
        {
            "name": "太郎",
            "age": 23,
            "hobbies": [
                {
                    "id": 1,
                    "name": "野球"
                },
                {
                    "id": 5,
                    "name": "ダーツ"
                },
                {
                    "id": 20,
                    "name": "缶蹴り"
                }
            ]
        },
        .
        .
        .
    ]
}
```

# 実際のコード

```swift
Alamofire.request(requestUrl).responseJSON{ response in
    switch response.result {
        case .success(let value):
            let json = JSON(value)
            json["users"].forEach{(_, data) in
                let name = data["name"].string!
                let age = data["age"].int!

                let hobbyList = data["hobbies"].array
                hobbyList?.forEach{(data) in
                    let hobbyId = data["id"].int!
                    let hobbyName = data["name"].string!
                }
            }
        case .failure(let error):
            print("エラーだよー")
    }
}
```
こんな感じで取得することが出来ます．

`let hobbyList = data["hobbies"].array`
ここが対象のところで，`.array`とすることで，jsonの"hobbies"のデータを取得しています．

`.arrayObject`もあるのですが，"hobbies"の中身をオブジェクトに変換してしまい？`:`のところが`=`になり，上手く出来ませんでした．

```text:.arrayの場合
{
    "id": 1,
    "name": "野球"
}
```
```text:.arrayObjectの場合
{
    "id" = 1,
    "name" = "野球"
}
```
Jupyter > keyboard shortcut > 行番号表示 | PEP8 online

```txt:動作環境
GeForce GTX 1070 (8GB)
ASRock Z170M Pro4S [Intel Z170chipset]
Ubuntu 16.04 LTS desktop amd64
TensorFlow v1.2.1
cuDNN v5.1 for Linux
CUDA v8.0
Python 3.5.2
IPython 6.0.0 -- An enhanced Interactive Python.
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
GNU bash, version 4.3.48(1)-release (x86_64-pc-linux-gnu)
```

### 行番号表示

Jupyterにて行番号を表示するkeyboard shortcut。
Esc + L
> toggle line numbers

https://www.cheatography.com/weidadeyue/cheat-sheets/jupyter-notebook/

### PEP8 online

http://pep8online.com/
Ubuntu 14.04の自動ログインを無効にできない妙な現象を直した

### 要約

Ubuntu 14.04で自動ログインをONにした後に再度OFFにしても元通りのパスワード入力のログインができない不具合があります。ユーザーアカウント情報をidコマンドで見ると、nopasswdloginグループに入ったままになっています。gpasswdコマンドでnopasswdloginグループを消したら元のパスワード入力のログインに戻りました。


### 自動ログインをOFFにできないんですけど…

Ubuntuで`システム設定 > ユーザーアカウント > 自動ログインON/OFF` から自動ログインをONにしてしばらく使ったのですが、パスワードキーリングが毎回パスワードを聞いてくるのが面倒くさくて自動ログインを再びOFFにしました。

![Ubuntu14でログインパスワードが入力できない](https://qiita-image-store.s3.amazonaws.com/0/197109/0b45caaa-8a24-064d-3771-1cb009edb12a.jpeg)


しかし、こんな感じでログイン画面でパスワードを入力できません。自動ログインはしませんが、パスワード入力はできずクリックするログインできます。確かにシステム設定上では自動ログインは無効になっているのですが、元のパスワード入力のログインに戻ってくれません。パスワードを変更しても直りません。


### デスクトップマネージャーのLightDMの設定いじったら痛い目をみました

ログインの問題だからLightDMの設定がおかしいのかと思い、

```bash:ターミナル
$ sudo rm /etc/lightdm/lightdm.conf
$ sudo rm -r -d /var/lib/lightdm/.cache/
$ sudo rm -r -d /var/lib/lightdm/.config/
```

と設定ファイルを削除して再起動しましたが直りません。血迷ったというか、まぁ大丈夫かと思って

```bash:ターミナル
$ sudo rm -r -d /var/lib/lightdm/
```

と`/var/lib/lightdm/`を丸ごと消したら、ログインできなくなっちゃいました…。リカバリモードを起動して、

```:Ubuntuリカバリモード
# mount -o remount, rw /
# apt-get remove lightdm
# apt-get install lightdm
# dpkg-reconfigure lightdm
```

とLightDMを再インストールして再設定したらログインできるようになったので良かったです。焦りました…。


### gpasswdコマンドでnopasswsloginグループを消せばよい

なかなか同じ問題を解決した話がウェブで見つからないのですが、usermodやnopasswdloginグループが関係してそうなことがわかり、askubuntu.comで同じ質問を見つけました。

[ubuntu 15.04 can't turn off auto login for specific account - Ask Ubuntu](https://askubuntu.com/questions/639179/ubuntu-15-04-cant-turn-off-auto-login-for-specific-account)

この質問の答えの通りに

```bash:ターミナル
$ id
uid=1000(user_name) gid=1000(user_name) groups=1000(user_name),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),119(nopasswdlogin),124(sambashare)
```

idコマンドでユーザーアカウントのグループ情報を見ると、確かに私のアカウントは`119(nopasswdlogin)`グループに入っています。

```bash:ターミナル
$ sudo gpasswd --delete user_name nopasswdlogin
Removing user user_name from group nopasswdlogin
```

gpasswdコマンドでnopasswdloginグループを消しました。再度、idコマンドでユーザーアカウント情報を見ると

```bash:ターミナル
$ id user_name
uid=1000(user_name) gid=1000(user_name) groups=1000(user_name),4(adm),24(cdrom),27(sudo),30(dip),46(plugdev),108(lpadmin),124(sambashare)
```

nopasswdloginグループは消えています。再起動してログイン画面は

![Ubuntu14でログインパスワードが入力できないエラーを直した1](https://qiita-image-store.s3.amazonaws.com/0/197109/2291d0d2-902b-7738-69d9-688273fad1c8.jpeg)

![Ubuntu14でログインパスワードが入力できないエラーを直した2](https://qiita-image-store.s3.amazonaws.com/0/197109/498c9f78-1970-179c-2236-23c2ec610070.jpeg)

となりパスワード入力できます。やっと直りました！ふう。
Chromeの開発ツールをNode.jsのコンソールとして使う

Node.js のコマンド `node` を引数なしで実行するとREPL(コンソール画面)が起動します。REPL では `require()` でライブラリをロードしたり、任意のJavaScriptの式を評価できるのでとても便利なのですが、同様の目的の Chrome の開発ツールに比べるとユーザインタフェースが今ひとつですし、デバッガの機能もついていません。

ですが、以下の方法で Chrome の開発ツールを Node.js のコンソールとして使用することができます。

REPL をオプション `--inspect` を指定して起動します。

```
$ node --inspect
```
すると、以下のようなメッセージが表示されますが、`ws://` のアドレスにアクセスしてもダメです。

```
Debugger listening on ws://127.0.0.1:9229/12119db3-101c-403b-b5b2-d4c4749f093c
For help see https://nodejs.org/en/docs/inspector
>
```
Chrome から `chrome://inspect/` にアクセスします。以下のような表示がされるので、**Remote Target** の **inspect** のリンクをクリックします。
<img width="833" alt="スクリーンショット 2017-09-09 11.40.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/153417/91fbb739-1395-c950-9b02-0ce8053c7f03.png">
開発ツールが起動しました。
<img width="1092" alt="スクリーンショット 2017-09-09 11.40.54.png" src="https://qiita-image-store.s3.amazonaws.com/0/153417/0ae88e22-22cf-fac5-d09e-8130835f24bc.png">
これで使い慣れたChromeの開発ツールをNode.jsのコンソールとして使用できます。
sedとtrでcssのコメントなどを削除してファイルをダウンサイジングする

ウェブページの表示を早くするために、サーバーにアップロードするcssファイルのサイズを小さくしたいときがあります。

例えば、あるスタイルシート`file.css`が次の場合、

```css:file.css
/*  import normalize */
/*! normalize.css v3.0.1 | MIT License | git.io/normalize */
/**
 * 1. Set default font family to sans-serif.
 * 2. Prevent iOS text size adjust after orientation change, without disabling
 *    user zoom.
 */
html {
  font-family: sans-serif;
  /* 1 */

  -ms-text-size-adjust: 100%;
  -webkit-text-size-adjust: 100%;
  /* 2 */

}
```

ターミナルで、次のコマンドを打つと、

```bash:ターミナル
# /*コメント*/を削除 | \nを削除 | 複数の連続スペースをスペース1つに置換
$ cat file.css | sed -r ':a; s%(.*)/\*.*\*/%\1%; ta; /\/\*/ !b; N; ba' | tr -d '\n' | tr -s ' ' > file-downsize.css
```

sedコマンドで/\*と\*/で囲まれたコメント(複数行にまたがったコメントでもオーケー)を削除し、trコマンドで改行コードを削除し、trコマンドで複数の連続スペースを1つのスペースに文字列置換します。正確には、/\*と\*/で囲まれた複数行を削除します。あまりないかもしれませんが、/\* comments \*/ code のようにコメントと同じ行にコードがあるとコードも削除されます。動作はUbuntu 14.04で確かめました。

ダウンサイジングした出力ファイル`file-downsize.css`は次のとおりです。

```css:file-downsize.css
html { font-family: sans-serif; -ms-text-size-adjust: 100%; -webkit-text-size-adjust: 100%; }
```

コメント量などによりますが、ファイルサイズを半分くらいに削減できます。削減できるスペースがまだありますが、`tr -d ' '`とコマンドして全てのスペースを削除するとcssの書き方によってはブラウザのレンダリングが正常に動作しない場合がありますので、スペースの全削除はしていません。また、はてなブログユーザーの方は、`/* Responsive: yes */`というコメントをcssの先頭に書かないとレスポンシブ対応されないので、これを追記する必要があります。

複雑なコマンド`sed -r ':a; s%(.*)/\*.*\*/%\1%; ta; /\/\*/ !b; N; ba'`は、[Remove multi-line comments - Stack Overflow](http://stackoverflow.com/questions/13061785/remove-multi-line-comments/13062074)から使わせてもらいました。`-r`オプションは[拡張正規表現](https://linuxjm.osdn.jp/html/GNU_sed/man1/sed.1.html)を使用するの意味です。シングルクォートに囲まれた部分は複数行に分けて書けます。

```:sedスクリプト
:a
s%(.*)/\*.*\*/%\1%
ta
/\/\*/ !b
N
ba
```

プログラムは次のフローで動作します。[Sed - An Introduction and Tutorial by Bruce Barnett](http://www.grymoire.com/Unix/Sed.html)を参考にして解読しました。

1. sedはファイルを1行ずつ読み込み、パターンスペースというメモリに保存します。
2. /\*が見つからない場合は(`/\/\*/ !b`)、次の行へ(`N`, Nextのこと)、
3. /\*が見つかる場合は、その行をパターンスペースに入れたままラベルaへ(`ba`, branch to label a:のこと)、
4. \*に囲まれている文字列を見つけるまで繰り返し1行ずつ読み込み(`s%(.*)/\*.*\*/%\1%`と`ta`, substitute, test to label a:のこと)、
5. \*コメント\*にマッチするすべての行を削除します。

%は他のどんな文字(例えば半角スペース)で置き換えてもよいです（[sed, a stream editor - gnu.org](https://www.gnu.org/software/sed/manual/sed.html)の3.2より）。

このスクリプトを少し改造すれば、htmlやjavascriptなど他のソースファイルのダウンサイジングもできると思います。
Rで重複のない組み合わせをexpand.grid()とsubset()で作る

Rのexpand.grid関数を使って、引数のベクトルの全組み合わせを作ることができます。例えば、こんな風に作れます。

```r:Rコンソール
> expand.grid(1:2,1:3)
  Var1 Var2
1    1    1
2    2    1
3    1    2
4    2    2
5    1    3
6    2    3
```

この時、1 1、2 2というように値がかぶっている組み合わせ、1 2、2 1という重複している組み合わせを除きたいときがあります。そういうときはsubset関数も使って

```r:Rコンソール
> combi <- expand.grid(1:2,1:3)
> subset(combi, Var1 < Var2)
  Var1 Var2
3    1    2
5    1    3
6    2    3
```

とすると簡単にできます。この方法だとpipeRパッケージ、gtoolsパッケージを使わなくてよいです[^1]。

[^1]: この記事は[メモ: 重複の無いネストループを作る - Momentum](http://nekopuni.holy.jp/2015/02/r%E3%83%A1%E3%83%A2-%E9%87%8D%E8%A4%87%E3%81%AE%E7%84%A1%E3%81%84%E3%83%8D%E3%82%B9%E3%83%88%E3%83%AB%E3%83%BC%E3%83%97%E3%82%92%E4%BD%9C%E3%82%8B/)の補完になればと思い書きました。pipeRだとうまくいかなくて考えました。

A, B, Cなどの文字の組み合わせの時もほとんど同じなのですが、unclass関数でクラスを取り除かなければいけません。

```r:Rコンソール
> combi <- expand.grid(c("A","B"), c("A","B","C"))
> combi
  Var1 Var2
1    A    A
2    B    A
3    A    B
4    B    B
5    A    C
6    B    C

> subset(combi, Var1 < Var2)
[1] Var1 Var2
<0 rows> (or 0-length row.names)
Warning message:
In Ops.factor(Var1, Var2) : < not meaningful for factors

> subset(combi, unclass(Var1) < unclass(Var2))
  Var1 Var2
3    A    B
5    A    C
6    B    C
```
R ScriptやR Markdownからinstall.packages()を呼び出す場合はレポジトリを指定しないとエラーになる

Rのコンソールでパッケージをインストールするなら、

```r:Rコンソール
> install.packages("package_name")
```

という様にパッケージ名を引数にしてinstall.packages関数を呼びだせばよいです。

しかし、R Script（.Rファイル）やR Markdown（.Rmdファイル）で同じように

```r:Rスクリプト
install.packages("package_name")
```

と書いて実行すると、次のようなエラーが出ます。

```:Rコンソール
Error in contrib.url(repos, type) : 
  trying to use CRAN without setting a mirror
Calls: <Anonymous> ... eval -> eval -> install.packages -> grep -> contrib.url
Execution halted
```

このエラーは[rstudio - Package error when running r code on command line - Stack Overflow](http://stackoverflow.com/questions/17705133/package-error-when-running-r-code-on-command-line)によると、R ScriptやR Markdownファイル内でinstall.packages関数を呼び出すときに、`repos`オプションでレポジトリを指定していないために起きるとのことです。

```r:Rスクリプト
install.packages("package_name", repos="http://cran.rstudio.com/")
```

R ScriptまたはR Markdownに上記のように書けば、エラーが出ずにパッケージがインストールされます。
複数テキストファイルの文字エンコードをfindとnkfでUTF-8に統一する

過去にWindowsで書いたテキストファイルは、文字エンコードが原因でLinuxではそのままでは読めません。エディタで文字エンコードを手動で変えるか自動検知するかすればよいのですが、ファイルの整理をしていることもあって文字エンコードをUTF-8に一括変換しました。

```bash:unity-ja-chara-encoding-by-nkf.sh
#!/bin/sh
find . -type f -exec grep . -Iq {} \; -exec nkf -w -Lu --overwrite {} \; -and -print
# The function of this script is to convert the character encoding
# of all japanese text files under current direcotory to UTF-8
# (-w option in nkf).
# When you want to unify a different character encoding,
# change the option -w in nkf as
# -j ISO-2022-JP,
# -s Shift-JIS,
# -e EUC-JP,
# -w UTF-8.
# When you want other newline character, change the option -Lu in nkf as
# -Lw CRLF(for Windows),
# -Lm CR,
# -Lu LF.
# If your os don't have nkf, you need to install nkf.
# (i.e. $ sudo apt-get install nkf)
# The parts of the script is quoted by
# http://stackoverflow.com/questions/4767396/linux-command-how-to-find-only-text-files
# for extract all text files under current directory:
# $ find . -type f -exec grep . -Iq {} \; -and -print
```

このスクリプトはカレントディレクトリ下にあるすべてのテキストファイルの文字エンコードをUTF-8に、改行コードをLFに変換して統一します。カレントディレクトリ以下の階層にディレクトリがあっても機能します。nkf（Network Kanji Filter）を使うので、使用環境にインストールされていない場合は`$ sudo apt-get install nkf`などでインストールする必要があります。nkfがサポートしている文字エンコードのShift-JISやEUC-JPなどのすべてのテキストファイルをUTF-8に変換して**上書き保存**します。文字エンコードを変換・上書き保存したテキストファイルのパスを標準出力して終了します。

findとgrepでカレントディレクトリ以下のすべてのテキストファイルを得る方法は、[Linux command: How to 'find' only text files? - Stack Overflow](http://stackoverflow.com/questions/4767396/linux-command-how-to-find-only-text-files) に習いました。`grep -I`オプションはバイナリファイルを無視する役割です。他にも役に立つ説明が書いてあります。

nkfの使い方について[nkfコマンド - hydroculのメモ](https://hydrocul.github.io/wiki/commands/nkf.html)を読みました。`nkf -w -Lu`オプションを変えることで他の文字エンコードに変換することもできます。上記スクリプトのコメントにオプションを簡単にまとめています。

他の方法で、例えば`$ iconv -f Shift-JIS -t UTF-8 filename`でも文字エンコードの変換はできますが、iconvでは、変換前の文字エンコードを指定する必要があります。

はじめはfileコマンドでファイル毎に文字エンコードを判別して、iconvで文字エンコード変換しようと思いました。

しかし、試しにEUC-JP、Shift-JIS、UTF-16、UTF-8の4種類のテキストファイルを用意して、fileで文字エンコードを判別しようとすると

```bash
# 文字エンコードが異なる4つのテキストファイルを用意する
$ iconv -f UTF-8 -t EUC-JP testfile_utf8 > testfile_eucjp
$ iconv -f UTF-8 -t Sihft-JIS testfile_utf8 > testfile_sjis
$ iconv -f UTF-8 -t UTF-16 testfile_utf8 > testfile_utf16
# 4つのテキストファイルそれぞれの文字エンコード方式を得る
$ for f (*) {file --mime-encoding $f}
testfile_eucjp: unknown-8bit
testfile_sjis: unknown-8bit
testfile_utf16: utf-16le
testfile_utf8: utf-8
```

となり、EUC-JPとShift-JISがどちらもunknown-8bitとなり区別できません。

この点nkfはよくできていて、nkfが対象のテキストファイルの文字エンコードを判別するので、ユーザーは変換前の文字エンコードを指定しなくてよいです。

以上、文字エンコード方式が異なる複数テキストファイルを一括変換して文字エンコードを統一するTipsでした。
WinMR(ImmersiveDevice)の環境構築

#はじめに
 この情報は2017/09/09現在の情報です、今後Unityのバージョンなどが変わり現在の情報が役に立たない場合もあります。
#環境
Windows 10 16278.1000(Insider Preview Slow配信版)
Unity 2017.2.0b10
Visual Studio 2017 15.3.2
Acer製 HMD AH100
#環境構築
1.Windows Insider Previewにする
 まずWindows Insider Previewにします(**重要**)
なぜかというと今現在最新であるUnity 2017 2.0 b10 は
今現在のWindowsのCreators Update版では動かないためです。

2.Visual Studio 2017をインストールする
ここからVisual StudioをDLしてください
https://www.visualstudio.com/ja/downloads/
この時今回の開発では少なくともUWPの開発環境が必要なため、
**ユニバーサルWindowsプラットフォーム開発** にはチェックを入れてください。

3.Unity 2017 2.0 をインストールする
https://unity3d.com/jp/unity/beta?_ga=2.72549909.742736717.1504923261-44826192.1503844330
ここからUnity Beta版のインストールをしてください、この時少なくとも
![image.png](https://qiita-image-store.s3.amazonaws.com/0/124028/41b52c2c-6e45-4334-856c-2f0171aa2873.png)
この.net scriptingにチェックを入れて下さい(.net側しか確認してないんですけど、どうやら  @k0rin さんのブログ https://framesynthesis.jp/tech/unity/windowsmixedreality/ によるとIL2CPPは動かないらしい)

4.適当なプロジェクトを動かす
 ![image.png](https://qiita-image-store.s3.amazonaws.com/0/124028/dd15455d-b30f-f34c-3275-6dfb149a0c9f.png)
自身の環境ではこのような形にして、正常に動くことを確認しています。
あとは、Editor上で確認するとか、Buildするとかしてください

#トラブルシューティング
ここでは自分が困ったこととかを書いていきます
##なんかうまく認識されない
**まずWindowsを再起動させましょう**
こいつ、まだ開発版だけあっていろいろと動作が不安定らしくいろいろなとこでこけます、とにかく困ったら再起動。
**次にデバイスマネージャで!マークとか?マークがついていないかを確認しましょう**
ついてた場合は、デバイスマネージャー上で、ドライバー更新とか、再起動とかしましょう。
あとこれは自分の環境で発生した事案ですがイヤフォンをつけてたら、急激に不安定になって外したとたんにすごく安定しだしました(どうやら電力がギリギリらしい？900mAぐらい流れているとの情報もあり)
##UnityEditor上でうまく認識されない
上のことが起きていなく、MixedRealityポータル上で、HMDが見えているとき
うまく動かないときはHMDを被るタイミングを調節してみてください、
自分の環境ではPlayボタンを押して、**映像が出てから被る**と、問題なく動作します。
(以下問題があれば追記)

#最後に
以下のページを参考にさせていただきました
Immersiveヘッドセット向けアプリ開発落とし穴集(http://www.xvi.co.jp/blog/)
Unity＋Windows Mixed Realityヘッドセット開発メモ(https://framesynthesis.jp/tech/unity/windowsmixedreality/)
Twitterのツイート #WinMRのタグ
AWX はいいぞ : 実機確認編 1. WORKFLOWS (2017/09)


# 前回までのあらすじ

* AWX Installation
  * http://qiita.com/takaidohigasi/items/fb1e4c8c822893532496
  * インストールについては、ansible-galaxyを利用すれば時間はかかるがエラーは発生せずにインストールできることを確認。
* AWX/Ansible Towerでは何ができるか: 机上調査編
  * http://qiita.com/takaidohigasi/items/77a481e89b387a942899
  * 机上だと機能がほとんど使えそうではあるが... 果たして.

# ユーザー機能確認編

## WORKFLOWS

複数playbookの順序制御機能は利用できるのか...!

Ansible Tower公式ドキュメント
http://docs.ansible.com/ansible-tower/latest/html/userguide/workflows.html

### 設定

TEMPLATES > ADD

![スクリーンショット 2017-09-09 11.33.57.png](https://qiita-image-store.s3.amazonaws.com/0/7625/358fa983-3680-471d-6b23-425b1c6551f2.png "スクリーンショット 2017-09-09 11.33.57.png")

一度保存(SAVE)すると、「WORKFLOW EDITOR」からいわゆるワークフローのGUI的設定ができる
![スクリーンショット 2017-09-09 11.39.12.png](https://qiita-image-store.s3.amazonaws.com/0/7625/f76c948f-b386-74ae-a0b2-c00d7452c756.png "スクリーンショット 2017-09-09 11.39.12.png")

それぞれのJOB(playbook実行)のあとに下記条件で後続ジョブが設定できる

* on Success
* on Failure
* Always

![スクリーンショット 2017-09-09 11.37.07.png](https://qiita-image-store.s3.amazonaws.com/0/7625/410b6f45-6b36-d11c-f9f6-7ed952562e89.png "スクリーンショット 2017-09-09 11.37.07.png")


![スクリーンショット 2017-09-09 11.37.34.png](https://qiita-image-store.s3.amazonaws.com/0/7625/8fb4b93e-63dc-3312-9732-4322c7226670.png "スクリーンショット 2017-09-09 11.37.34.png")

### 実行

定義したworkflowに対して手動実行、スケジュールジョブ実行ができるが手動実行で動作確認

![スクリーンショット 2017-09-09 11.43.01.png](https://qiita-image-store.s3.amazonaws.com/0/7625/6a0485f3-ba3b-379d-d8a3-93e88cb9a26c.png "スクリーンショット 2017-09-09 11.43.01.png")

トリガー引くと、どこを実行しており、何に何秒かかっているかも素敵に表示してくれる
![スクリーンショット 2017-09-09 11.43.38.png](https://qiita-image-store.s3.amazonaws.com/0/7625/ce7791c1-75d7-1767-f8a1-2dbb1f129ad8.png "スクリーンショット 2017-09-09 11.43.38.png")

![スクリーンショット 2017-09-09 11.44.07.png](https://qiita-image-store.s3.amazonaws.com/0/7625/984a715e-923f-fafc-46f0-7e3db55e848f.png "スクリーンショット 2017-09-09 11.44.07.png")

いまのところドキュメントどおり、すばらし。
node.js 超入門 ①node.jsでwebサーバを作ってみる


## nodeって何？

- サーバ側で動くjavascript
- リアルタイムで高速
- 大量のリクエストも高速に捌けるので、APIなどで利用される

[公式](https://nodejs.org/en/)

## 自分のPCにnodeの環境を作る

[node](https://nodejs.org/ja/)から推奨版をインストールする。
自動的に自分のPCの環境にあったパッケージが表示されるのでインストールすればOKです。

```
$ node -v
v6.11.2
```

インストール出来ました。


## とりあえずhelloworld

```hello.js
$ cat hello.js
console.log('hello world')
```

```
$ node hello.js
hello world
```

簡単ですね

## サーバの仕組みを知っておく

#### スレッドモデル

- Apache等で使われている
- 基本的に1リクエストに対して、1スレッドで処理を対応する
- スレッドはメモリを消費するため、瞬間的に大量のリクエストが来ると結果として多くのスレッドが立ち上がる
- スレッドが多く立ち上がり、メモリが足りなくなり、待ちリクエスト等が発生する


#### イベントループモデル

- スレッドは1つだけのシングルスレッド
- リクエストが来る度に、スレッドのキューにリクエストをためていく
- 裏で動いているプログラムがキューに溜まった処理を順次処理していく
- なので、リクエスト待ちは発生しない
- ただし、イベントをブロックしてしまうような書き方をすると、実際待ちが発生してしまう
	- 後述する`ノンブロッキングな処理`を意識して実装する必要がある

## ノンブロッキングな処理の書き方

まずはブロッキングな処理を見てみます。

```
// ブロッキングな書き方

var start = new Date().getTime();

// 1秒待つ
while (new Date().getTime() < start + 1000);
console.log('world');
```

この処理を実行すると、while文の処理を待つため、1秒後に`world`が表示されます。

ではノンブロッキングな処理とはどのように書くのか。

```
// ノンブロッキングな書き方

setTimeout(function() {
    console.log('hello');
}, 1000);

console.log('world');
```

実行してみましょう。

```bash
$ node hello.js
world
hello
```

setTimeoutの処理を待たずに、先に`world`が処理されました。
これが、ノンブロッキングな処理です。

前者のように、ブロッキングな書き方をしてしまうと、
イベントループモデルのnode.jsでも、処理待ちが発生してしまうので、
処理に時間が掛かりそうな処理に関してはcallback関数を使って処理していくのがnodeの常套手段のようです。

## いよいよwebサーバを作ってみる

まずは見るのが簡単だと思うので、実際に作ってみます。

```server.js
// nodeのコアモジュールのhttpを使う
var http = require('http);
var server = http.createServer();

server.on('request', function(req, res) {
    res.writeHead(200, {'Content-Type' : 'text/plain'});
    res.write('hello world');
    res.end();
});

// サーバを待ち受け状態にする
// 第1引数: ポート番号
// 第2引数: IPアドレス
server.listen(3000);
```

この状態で、自分のブラウザから`localhost:3000`にアクセスしてみるとどうでしょうか。

![スクリーンショット 2017-09-09 11.46.01.png](https://qiita-image-store.s3.amazonaws.com/0/23276/702a3a55-a2a9-7bea-8a34-82f3ae66987e.png "スクリーンショット 2017-09-09 11.46.01.png")

ちゃんと表示されましたね。
これまでjavascriptはブラウザ側で動くものでしたが、node.jsはこのように簡単にwebサーバとして動かす事が出来ます。

次回以降、より具体的にwebサーバを実装していこうと思います。
macOS Sierraで5ボタンマウスを使う

Sierra以前ではKarabinerを使っていたが、SierraではKanabinerは使えない。かといってその代替であるKanabiner-elementsでもマウスボタンのバインドは今のところ出来ない。なのでHammerspoonを使って設定する。

```lua
local function mousePress(eventobj)

  if eventobj:getButtonState(4) then
    hs.eventtap.event.newKeyEvent({'cmd'}, ']', true):post()
    hs.eventtap.event.newKeyEvent({'cmd'}, ']', false):post()
  end

  if eventobj:getButtonState(3) then
    hs.eventtap.event.newKeyEvent({'cmd'}, '[', true):post()
    hs.eventtap.event.newKeyEvent({'cmd'}, '[', false):post()
  end

  return false
end

hs.eventtap.new({25}, mousePress):start()
```

こんな感じで設定すればOK。自分は5ボタンのうち2つのボタンをブラウザバックフォワードに割り当てている。Chromeでブラウザバックやフォワードのショートカットキーが ` ⌘　+ [ `なのでマウスボタンが押されたらそれらのショートカットキーが発火するように設定してる。

参考 https://github.com/tarpdalton/dotfiles/blob/tarp/.hammerspoon/init.lua


**追記: 2017/10/4 12:45**

キーボードがJIS配列の場合、Hammerspoonが `[` などを別のキーと認識してしまうので、上記のスクリプトではうまく動かない。なので下記のような設定が必要。@keroxpさんコメントありがとうございます！
https://qiita.com/shim0mura/items/96fad93b2696bc073d23#comment-f56d88456d43739448ad
maplotlibの棒グラフに累積比率を追加する

`matplotlib`のグラフに累積比率を追加するシリーズ。棒グラフに累積比率を追加。完成プロットはこちら
![mlt_barplot_with_ratio.png](https://qiita-image-store.s3.amazonaws.com/0/47296/56c7687c-c418-cad9-5acb-54294886d190.png)


ポイントしては、`matplotlib.bar()`は`bar`と名を打つ割にカテゴリカルな変数をそのまま指定できないから、x軸のどこにプロットするか教えてあげる必要がある。具体的には、`numpy.arange()`などでカテゴリの数だけ連番・インデックスを生成して　x軸の場所を教えてあげている。


```python
"""maptlolibの棒グラフに累積比率を追加する例"""
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import seaborn as sns

# seabornスタイルでかっこよくプロットする
# % matplotlib inline
sns.set(style="darkgrid", palette="muted", color_codes=True)

# トイデータ生成
df = pd.DataFrame({'group': ['A', 'B', 'C', 'D', 'E'],
                   'value': [20, 30, 10, 50, 40]})

# x軸のプロット位置を指定
# 勝手にやってくれないから生成する必要あり。
x_idx = np.arange(df.shape[0])

# プロット用のfigとaxを取得
fig, ax = plt.subplots()

# 棒グラフを追加（第1軸）
bar = ax.bar(left=x_idx,
             height=df['value'],
             align='center',
             tick_label=df['group'],
             alpha=0.7
             )

# 第2軸用の累積比率を計算
df['accumulative_ratio'] = df['value'].cumsum() / df['value'].sum()

# 第2軸に累積の折れ線グラフを追加
ax2 = ax.twinx()
line = ax2.plot(x_idx,
                df['accumulative_ratio'],
                ls='--',
                marker='o',
                color='r'
                )
ax2.grid(visible=False)
plt.show()
```

凡例など追加した完成版のコードは[Gist](https://gist.github.com/messefor/ced20e0d74fa5b24d4a41db899f55940)にあげてます。
AWX/Ansible Towerでは何ができるか: 机上調査編 (2017/09)


本エントリではAnsible Towerの各プラン、およびAWXで何ができるかの机上調査結果をまとめます

製品全体の構想として何ができるかは公式のトップページを御覧ください

https://www.ansible.com/tower

## Ansible Tower Enterprise機能

まずは現在のAnsible Towerの機能を値段、機能マトリクスから再確認

大雑把に、ユーザー観点だとplaybookの順序制御(workflow)が有償、管理者観点だと認証、監査、サポート、高可用構成などが有償

ノード数に対する制約: 現在Standard以上だと100ノード以上、との表記が確認できる. 

* 機能マトリクス: https://www.ansible.com/tower-editions
* お値段: https://www.ansible.com/pricing

### Standard

Standard以上のプランで追加で利用可能になる機能

* CONTROL
  * WORKFLOWS : 複数playbookの順序制御
* KNOWLEDGE
  * INTEGRATION WITH ENTERPRISE ACCOUNTS: LDAP連携など
  * AUDIT TRAIL: 監査
  * MULTI-TENANCY: 複数ORGANIZATIONを利用した権限制御
  * LOGGING AND ANALYTICS INTEGRATION: ログ出力連携
* DELEGATION
  * SURVEYS: EASY FORM-BUILDER  
* SUPPORT
  * INSTALLATION SUPPORT
  * ENTERPRISE SUPPORT: 8 x 5 サポート(日勤帯サポート?)
  * ANSIBLE ENGINE BUNDLE
* AND MORE...
  * SCALE-OUT CLUSTERING


### PREMIUM

PREMIUMプランで利用可能になる機能

* SUPPORT
  * PREMIUM SUPPORT: 24 x 7 サポート
  * NETWORKING ADD-ON: ネットワーク関連モジュールのサポート

# AWX

AWXとAnsible Towerは何が違うの？

https://www.ansible.com/awx-project-faq

AWXはAapach 2.0ライセンス、開発版(not stable)と思えば良さそう、Ansible TowerはAWXの特定バージョンからリリースされ長期サポートできるようにしている、と理解。

つまりサポート、高可用などを除けばユーザー機能、管理機能、は全部使えてしまうのではないか... このプロジェクト素敵すぎる...

# 関連

* インストール編
http://qiita.com/takaidohigasi/items/fb1e4c8c822893532496
* 実機確認編
(建設予定)
STM32CubeMXのC++プロジェクトでEclipseのエディタがシンボルが見つけられない問題への対処

STM32CubeMXで生成したプロジェクトをSystem Workbench for STM32 (AC6)でC++プロジェクトに変換してソースコードを開いたときに、AC6 (Eclipse)のエディターがSTM32のペリフェラルライブラリやHALライブラリのシンボルが見つからないという問題があります。これは標準のインデクサーの設定が適切ではないためです。
この問題を解消するには、プロジェクトの「Properties」を開き設定パネルを表示し、「C/C++ General」の「Preprocessor include Paths, MAcros etc.」の設定を変更します。

- ProvidersタブでCDT Cross GCC Built-in Compiler Settingsにチェックを入れる
- Use global provider shared between projectsのチェックを外す
- Command to get compiler specsに -std=c++11 を追加する

この設定をしてApplyをクリックして設定パネルを閉じます。(またはOKをクリックする)

![](http://blog.tsubakicraft.jp/assets/post-images/resolve_symbol_cubemx_project.png)

次に「Project」メニューの「C/C++ Index」から「Rebuild」を選択するか、Project Explorerでプロジェクトを選択した状態で右クリックしてコンテクストメニューを開き「Index」から「Rebuild」を選んで、インデックスを再構成します。

これでAC6のエディタで快適にプログラミングができます。
AribaWebのAWTDataTableのソート機能のカスタマイズ

AWTDataTableはカラムヘッダーをクリックすることでそのカラムの値を使ってテーブルに表示されるデータをソートする仕組みがありますが、ソートはAWTSortOrderingというオブジェクトが行っています。

ソートされる値は文字列として扱われているので、

- C
- A
- B

は

- A
- B
- C

または

- C
- B
- A

と正しくソートされますが、

- 2
- 100
- 45

は

- 100
- 2
- 45

または

- 45
- 2
- 100

とソートされてしまい、数量や金額といった数値が正しくソートされません。

また製品番号や伝票番号などでよく使われる

- No2
- No10
- No9

のような場合も正しくソートされません。

これを解決するには、

- Compareインターフェースを実装したFormatterを追加する
- カラムにそのFormatterをバインディングする

ということを行います。

以下に実装例を示します。



#### MyFormatter.java
まずFormatterです。AWFormatterのサブクラスでCompareインターフェースを実装します。
	package app.util;
	
	import java.text.ParseException;
	
	import ariba.ui.aribaweb.util.AWFormatter;
	import ariba.util.core.Compare;
	
	public class MyFormatter extends AWFormatter implements Compare {
	
		@Override
		public Object parseObject(String stringToParse) throws ParseException {
			return stringToParse;
		}
	
		@Override
		public String format(Object objectToFormat) {
			return (String)objectToFormat;
		}
	
		/**
		 * ソート対象の値から数値部分だけを抜き出して数値として比較する
		 */
		@Override
		public int compare(Object o1, Object o2) {
			String s1, s2;
			s1 = o1 == null ? null : (String)o1;
			s2 = o2 == null ? null : (String)o2;
			if(s1 != null && s2 != null) {
				int l1 = Integer.parseInt(s1.replaceAll("[^0-9]", ""));
				int l2 = Integer.parseInt(s2.replaceAll("[^0-9]", ""));
				return l1 - l2;
			} else {
				if(s1 == null && s2 == null) {
					return Compare.EqualTo;
				} else if(s1 == null) {
					return Compare.LessThan;
				} else {
					return Compare.GreaterThan;
				}
			} 
		}
	
	}
	

#### Application.java
アプリケーション起動時に作成したFormatterをシステムに登録する。例ではMyFormatterを"myformatter"という名前で登録しています。この名前はテンプレートファイル(AWL）の<t:DataTable><t:Column>のバインディングを行うときに参照される名前です。

	...
	...
	
	@Override
	public void init() {
		super.init();

		installFormatters();

	}
	...
	...
	
	private void installFormatters() {
		AWVFormatterFactory.registerProvider(new FormatterProvider() { 
			@Override
			public void populateFormatters(Map<String, Object> formatters, Locale locale, TimeZone timeZone) {
			Map<String, AWFormatter> map = MapUtil.map();
			map.put("myformatter", new MyFormatter());
			for(Map.Entry<String, AWFormatter> entry : map.entrySet()) {
				formatters.put(entry.getKey(), entry.getValue());
			}
			
		}}); 
	}

	
#### テンプレートファイル（AWL）を修正する

	<t:DataTable ....>
	...
	...
		<t:Column key="orderNo" label="Order #" formatter="$formatters.myformatter" />
	...
	...
	
	</t:DataTable>
Spring Bootでアプリケーション起動時の処理

Spring Bootアプリケーションでアプリケーション起動時に何らかの処理を実行するコード例です。

	package mypackage;
	
	import org.slf4j.Logger;
	import org.slf4j.LoggerFactory;
	import org.springframework.boot.SpringApplication;
	import org.springframework.boot.autoconfigure.SpringBootApplication;
	import org.springframework.context.ConfigurableApplicationContext;
	
	
	@SpringBootApplication
	public class MyApplication {
	
		private static Logger log = LoggerFactory.getLogger(MyApplication.class);
		
		public static void main(String[] args) {
			ConfigurableApplicationContext ctx = SpringApplication.run(MyApplication.class, args);
			MyApplication app = ctx.getBean(MyApplication.class);
			app.execStartup(args);
		}
			
		public void execStartup(String[] args) {
	    		// ここにアプリケーション起動時に実行したい処理を書く
	  	}
	}
EclipseでクロスコンパイルしてリモートのRaspberry Piで動かす

 [ブログ](https://tsubakicraft.wordpress.com)からの転載です。

### 概要

Raspberry Piで動くプログラムをC言語などで開発する際に、Raspberry Pi上でソース作成、コンパイル、リンクを行っても良いのですが、使い慣れたIDEを使いたいことがあります。ここではEclipse CDTでRaspberry Pi用のプログラムをクロスコンパイルして、sshを使ってネットワーク接続したRaspberry Piにプログラムをインストールする方法を紹介します。Eclipse CDTがすでにインストールされていることを前提とします。（Ubuntu 16.04LTSでEclipse CDT 4.6.0 を使いました）

### １． Raspberry Piツールのインストール

Raspberry Piのgitリポジトリからツールをクローンします。ここにはビルドツールが入っています。

これを例えば $HOME/RaspberryPi にgit cloneコマンドでクローンします。

	$ mkdir $HOME/RaspberryPi
	$ cd $HOME/RaspberryPi
	$ git clone https://github.com/raspberrypi/tools.git
	
コンパイラやリンカは

	$HOME/RaspberryPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin
	
にあります。

### ２． Cプロジェクトの作成

Eclipse CDT上で新規Cプロジェクトを作ります。ウィザードの画面は以下の通り。

![](https://tsubakicraft.files.wordpress.com/2017/06/011.png)

![](https://tsubakicraft.files.wordpress.com/2017/06/021.png)

大事なところ。

クロスコンパイラのprefixは arm-linux-gnueabihf- です。コンパイラーのパスは$HOME/RaspberryPi/tools/arm-bcm2708/gcc-linaro-arm-linux-gnueabihf-raspbian-x64/bin です。

![](https://tsubakicraft.files.wordpress.com/2017/06/031.png?w=616)

### ３． プログラムの作成

プロジェクトにソースフォルダーを作成。

![](https://tsubakicraft.files.wordpress.com/2017/06/04.png)

ソースフォルダーのCのソースファイルを作成。


![](https://tsubakicraft.files.wordpress.com/2017/06/05.png)

### 4. プログラムのビルド

“Hello Raspberry Pi!”をstdoutに出力する簡単なプログラム。これをReleaseターゲットでビルドします。

![](https://tsubakicraft.files.wordpress.com/2017/06/06.png?w=616)

### ５． 実行の設定と実行

「Run」メニューの「Run Configurations…」を選択。下のスクリーンショットのように設定。

C/C++ ApplicationにはReleaseビルドしたもの、Build ConfigurationはRelease、Remote Absolute File Path for C/C++ Applicationには /home/pi/rpi/HelloRpi（/home/pi/rpiディレクトリは事前にRaspberry Piに作成しておく）、Commands to execute before applicationにはプログラムへの実行権の付与を行うコマンドを設定します。Connectionを設定するまで「Run」を押さない。


![](https://tsubakicraft.files.wordpress.com/2017/06/07.png?w=616)


ConnectionはSSH接続情報を設定します。上の画面で「New」ボタンを押して、こんな感じに設定。Connection nameはお好みで、HostはRaspberry Piのホスト名かIPアドレス、UserとPasswordは上の画面で設定したRemote Absolute File Path for C/C++ Applicationを書き込みできるユーザー名とパスワードです。

![](https://tsubakicraft.files.wordpress.com/2017/06/08.png?w=616)

ここで「Run」をクリックすると、リモートのRaspberry Piにプログラムを転送して実行します。

### 6. 実行結果

下のスクリーンショットはRaspberry Piのターミナルでプログラムを実行した様子です。

![](https://tsubakicraft.files.wordpress.com/2017/06/09.png?w=616)

デバッグをしたい場合は、５の「実行の設定」部分をデバッグの設定（「Run」メニューの「Debug Configurations…」を選択して設定する）にして、デバッグを実行すればいいです。
[CEDEC2017]本当にリアルなMixed Realityコンテンツを実現するための技術開発

#本当にリアルなMixed Realityコンテンツを実現するための技術開発

##講演者
和泉澤　稔　さん（株式会社Cygames）
川上　智弘　さん（株式会社Cygames）
石山　英俊　さん（株式会社Cygames）

##講演内容
エンターテイメントとしてのリアルなMRコンテンツの開発に関してのお話がされた。

###リアルなMRコンテンツとは？
- 空間に浮かぶUI?
- 現実空間に現れるモンスター？

これは確かに表現のインパクトが強く目を引くことができるかもしれないが、
リアルかと言われると違和感がある。

今回、求めたものは以下の項目に対応したものを開発してみることとなった。

- 高い応答性
- 高い実在感
- 体験の共有

###リアルなMRコンテンツの前提
- 現実世界との正確なオクルージョン
- 現実のライティングがオブジェクトに反映できる
- 同時に複数人が同じような体験を行うことが出来る

####高い応答性
- デバイスを通して正確な姿勢として描画すること
- 遅滞なく連動することができること。

が求められる。

####高い実在感
- 写実性の高さ
- 空間表現の高さ
- 環境音や効果音
- 現実世界らしい演出（エフェクトなどで誇張するのではなく、地味な方がいいのかも）

が求められる。

####体験の共有
- 同じ空間にいるユーザーが同じコンテンツに接することが出来る


###デバイス
####Optical See-Through
Microsoft社から販売されているHoloLensがこれに当たる。

- メリット

視界がクリアなため、現実世界との融合性が高く安全性がある。
大規模コンテンツにマッチしている。

- デメリット

視野角が狭く、オブジェクトが半透明になってしまう

####Video See-Through
HMDやスマホなどのカメラを通して表示するもの

- メリット

視野角問題がなく、スマホなどで体験することができるため
お手軽間がある。
閉鎖空間など狭い箇所での体験に適している。

- デメリット

遅延が大きく、HMDだと敷居が高い

###実現するために行ったこと

今回のMRデモではHoloLensを使用して行っている。

####仮想空間の共有
複数のWebカメラを設置し、クライアントの共有のためにネットワークをしようしている。
サーバー側で起動したunityを各HoloLensに共有する形をとっている。

#####HoloLensの問題点と解決策
アプリケーション起動時の姿勢や向きが基準となってしまうため、
絶対的な基準姿勢が定まっていない。

そのため、HoloLensの固有機能のWorldAnchorを使用して空間上にオブジェクトを固定化するにしている。
これを各ユーザーがHoloLensを通して見つけることでオブジェクトの位置の共有を行うことが出来た。

ただし、このWorldAnchorからある程度の離れてしまうと仮想空間上のオブジェクトの位置がずれてしまうことがある。
この対応として、デモ空間内に複数のWorldAnchorを配置し、各ユーザーの座標からそのAnchorの影響係数を求めてオブジェクトの反映させることでズレを少なくすることができるようになった。

####インタラクション
仮想空間上に配置しているキャラクターの視線は首の角度などを調整して
ユーザーに反応させMRをより深く体験できるように対応している。

####空間環境は反映
仮想空間上にいるキャラと実空間の環境の状態（ライト）が一致していないと
キャラが浮いてしまうため、リアル感が損なわれてしまう。

この対応としてWebカメラからキャラ周辺の画像を元に、
仮想空間上のキャラにリアルタイムに反映させる対応を行った。
この手法を**ImageBasedLighting(IBL)**という。

このIBLの手法を使いキャラにライトの情報を反映できたが、処理負荷が高かったため
サーバー上で計算処理をおこない、各端末上では描画だけを行うようにして対策を行っていた。

####オクルージョン
HoloLensには形状を認識できるセンサーがついており、
これを使いリアルタイムなメッシュ生成ができるが、処理が重くメッシュの精度が荒いという問題があった。
また、一定距離以上の形状を認識できないため、オクルージョンの処理を行うことが出来ない。

この対応として、予め用意していたデモルームのメッシュを使うことで、
オクルージョン処理が可能且つメッシュ自体の精度が高いものが出来た。

デモルームメッシュを使用することで、Unityエディター上でも確認することができるようになり、
開発方法も今まで通りでできるようになった。

###デバイスに依存しないMR
スマホやHMD（+ステレオカメラ）の光学カメラを利用して、多くの人に手軽にMRを体験してもらうことが狙い
これを実現するために、カメラ画像から正確な位置や姿勢などを求める必要がある。

####実装するに当たっての課題
- 常に環境に対しての正確な位置情報を得る
- 位置情報のずれを蓄積させたくない
- 基準マーカー（ARマーカー）を使用したくない

#####マーカーレス型の問題点
このマーカーレス型の場合、開始時の位置や姿勢が不確定なため位置ずれなどが発生しやすい

####対策
カメラの画像から位置を特定するために、
画像とメッシュとの輝度差を求めて、輝度差が少なくなるところをカメラの推定位置を判定して
処理を行う。

カメラ画像とメッシュの描画結果との輝度差を最小化するために**ヒストグラムの平坦化**という手法を
使い対応をおこなった。
この処理を行った場合でも一定のノイズが残ってしまうので、直前の結果画像とのパターンマッチングを行い、
パターンが一致しないものを除去する手法をとっている。

また、誤差の最小化を行う際には**ガウス・ニュートン法**を用いて計算を行っている。
この技術に関してはIEEE ISM2016にて[論文](http://ieeexplore.ieee.org/document/7823703/?reload=true)を発表している。

##感想
リアルなMRを実現するための試行錯誤をされていた点のお話を聞くことが出来ました。
今後、業務などで携わることがあれば参考にしてみたいものばかりでした。
UbuntuへのJackのインストールとMAudio Fast Trackの接続

[ブログ](https://tsubakicraft.wordpress.com)からの転載です。

### 概要

UbuntuにJackをインストールしてMAudio Fast Trackを接続する方法を紹介します。Ubuntuのバージョンは16.0.4LTSです。

### Jackのインストール

まずはjackを次のコマンドでインストール。

	$ sudo apt-get install qjackctl
	
### Qjackctlを設定してギターの音を入力する

Fast Trackをコンピューターに接続してQjackctlを起動。

![](https://tsubakicraft.files.wordpress.com/2017/08/screenshot-from-2017-08-03-14-38-04.png?w=494&h=128)

入力をFast Trackに出力を内蔵スピーカーに設定。（jackのメインウィンドウで「設定」をクリックして、「Advanced」タブで出力デバイスと入力デバイスを選択）

![](https://tsubakicraft.files.wordpress.com/2017/08/screenshot-from-2017-08-03-14-37-36.png?w=640&h=460)

入力と出力の経路の接続。（jackのメインウィンドウで「接続」をクリック）

![](https://tsubakicraft.files.wordpress.com/2017/08/screenshot-from-2017-08-03-14-38-42.png?w=547&h=306)

これでギターのシールドケーブルをFast Trackのギター入力に挿してギターを弾くとPCの内蔵スピーカーからギターの音が聞こえます。

### Audacityで波形を見る

jackに対応したAudacityなどで波形をモニターすることもできます。

![](https://tsubakicraft.files.wordpress.com/2017/08/screenshot-from-2017-08-03-14-43-14.png?w=640&h=510)


### ギターアンプシミュレーター guitarix

Ubuntuソフトセンターを使ってguitarixというギターのアンプとエフェクターをシミュレートするアプリケーションをダウンロード。これでPCがギターアンプになります。

![](https://tsubakicraft.files.wordpress.com/2017/08/2017-08-03-15-26-39.jpg?w=640&h=480)

ここまでできれば自分でギターの信号を加工するアプリケーションを作って実験できます。
KXStudioのような音楽制作に向けて構成されたLinuxのディストリビューションを利用すれば面倒なインストールや設定の作業は必要ありませんし、Linuxで動くDAWアプリケーションもいくつかあるので本格的なレコーディングなども行えます。
SDL - Simple DirectMedia Layer の初歩

SDLはOpenGLとDirect3Dを経由して、オーディオ、キーボード、マウス、ジョイスティック、およびグラフィックス・ハードウェアへの低レベルアクセスを提供するために設計されたクロスプラットフォーム開発ライブラリで、
Windows、Mac OS X、Linux、iOS、Androidをサポートしています。
SDLはCで書かれており、C++でネイティブに動作しその他の言語とバインディングが可能です。
ライセンス形態はzlibライセンス。

SDLを使ったアプリケーション開発ができるようになれば、例えばRaspberry Piに小さな液晶パネルを取り付けた機動性の高いアプリケーションを開発することができてモノづくりの幅も広がりそうです。

今回、[良いチュートリアル](http://lazyfoo.net/tutorials/SDL/index.php#Hello SDL)を見つけたのでその紹介です。プログラミングについてはチュートリアルの紹介に留めますので、詳細はチュートリアルを見てください。
Ubuntu 16.0.4LTSを対象に書きます。


### SDLのインストール

SDL 2.0のソースコードのリポジトリはmercurialで管理されています。ソースコードをクローンするにはmercurialがインストールされている必要がありますので、もしインストールされていなければ次のコマンドでmercurialをインストールします。

	$ sudo apt-get install mercurial

#### ソースコードのダウンロード

カレントディレクトリにリポジトリからソースコードをSDLという名前でクローンします。

	$ hg clone https://hg.libsdl.org/SDL SDL

#### SDLのコンパイルとインストール

	$ cd SDL
	$ mkdir build
	$ cd build
	$ ../configure
	$ make
	$ sudo make install

### 入門プログラムの作成

Eclipse CDTを使って簡単なプログラムを書いてみます。
SDLプログラミングの[チュートリアル](http://lazyfoo.net/tutorials/SDL/index.php#Hello SDL)を参考にして動作確認をしました。なかなか親切なチュートリアルだという感じがします。

#### Eclipse CDTでプロジェクトを作成

新規C++プロジェクトを作成してヘッダーファイルのインクルード設定とライブラリのリンク設定を行います。

インクルード設定

![](http://blog.tsubakicraft.jp/assets/post-images/include_setting.png)

*スクリーンショットではGCCのIncludes設定になっていますが、G++のIncludes設定を行ってください*

リンク設定

![](http://blog.tsubakicraft.jp/assets/post-images/link_setting.png)

#### ウィンドウを表示して画像表示

[Lesson 02
](http://lazyfoo.net/tutorials/SDL/02_getting_an_image_on_the_screen/index.php)の説明を読みながらチュートリアルコードを実行したところ。
このようなウィンドウが開くはずです。(画像ファイルだけ差し替えました）

![](http://blog.tsubakicraft.jp/assets/post-images/my_second_window.png)



ほんの導入部を紹介しただけですが、この後もチュートリアルを見ながら学習を進めていけば良いと思います。

GCCでコンパイルするとSegmentation faultになります。G++でコンパイルされるようにソースコードはC++のソースコード (拡張子 .cpp)にしてください。

[https://github.com/kazz12211](https://github.com/kazz12211)
phpMyAdminをphp-fpmをやめてNGINX Unitで動かす　

# Install

https://github.com/nginx/unit#ubuntu-packages をみながら

```shell-session
$ wget http://nginx.org/keys/nginx_signing.key
$ sudo apt-key add nginx_signing.key
$ sudo su
# echo 'deb http://nginx.org/packages/mainline/ubuntu/ xenial nginx' >> /etc/apt/sources.list.d/nginx.list 
# echo 'deb-src http://nginx.org/packages/mainline/ubuntu/ xenial nginx' >> /etc/apt/sources.list.d/nginx.list 
# apt-get update
# apt-get install unit
```

# Run
```shell-session
 # service unitd start
```

# Configuration
```js:/etc/unit/phpmyadmin.json
{
     "listeners": {
         "*:8300": {
             "application": "phpmyadmin"
         }
     },
     "applications": {
         "phpmyadmin": {
             "type": "php",
              "workers": 20,
              "root": "/usr/share/phpmyadmin",
              "index": "index.php"
         }
     }
}
```
起動時にjsonを読み込ませるわけではなく
APIを通して設定を動的に変更するようだ

# Install the configuration
```shell-session
# service unitd restoreconfig /etc/unit/phpmyadmin.json
Restoring configuration from /etc/unit/phpmyadmin.json..
{
        "success": "Reconfiguration done."
}
```

# Reconfigure nginx
```nginx:/etc/nginx/sites-available/phpmyadmin.conf
server {
        server_name phpmyadmin.example.com;

        root        /usr/share/phpmyadmin;
        index       index.html index.php;
        access_log  /var/log/nginx/phpmyadmin.example.com.access_log;
        error_log   /var/log/nginx/phpmyadmin.example.com.error_log;
        #fpmの設定をコメントアウト
        #location ~ \.php {
        #        fastcgi_pass    unix:/var/run/php5-fpm.phpmyadmin.example.com.sock;
        #        fastcgi_index   index.php;
        #        fastcgi_param   SCRIPT_FILENAME $document_root$fastcgi_script_name;
        #        include fastcgi_params;
        #}
　　　　 #あらたにunitdのための設定を追加
        location / {
            proxy_pass http://127.0.0.1:8300/;
        }
}
```
#Restart nginx
```shell-session
# service nginx restart
```
#Check
ブラウザで　 phpmyadmin.example.comにアクセス

![phpmyadmin-result.png](https://qiita-image-store.s3.amazonaws.com/0/1817/1dc44690-a800-35df-a1fb-f4f3c65d47e6.png)

うごいた。。けど権限周りのエラーがでるようだ
あとで調べよ
TensorFlowでKernel法


# TL;DR

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">TensorFlowでカーネル法ができるように。これに伴いSVMも実装可能。<br><br>カーネル法&amp;トリックについてはこちらの資料がわかりやすい。復習してTensorFlowで使ってみよう！<a href="https://t.co/eWtFSNSDHn">https://t.co/eWtFSNSDHn</a> <a href="https://t.co/5XasiCjfNs">https://t.co/5XasiCjfNs</a></p>&mdash; piqcy (@icoxfog417) <a href="https://twitter.com/icoxfog417/status/906139462073122816">2017年9月8日</a></blockquote>


# TensorFlowでKernel法

## 動機

次のツイートを見かけたので試してみました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">まじでか <a href="https://t.co/5XasiCjfNs">https://t.co/5XasiCjfNs</a></p>&mdash; piqcy (@icoxfog417) <a href="https://twitter.com/icoxfog417/status/905969736122433536">2017年9月8日</a></blockquote>

結果、たしかに動きました。Gistに公開してます。

* [Linear+models+using+explicit+kernel+methods.ipynb](https://gist.github.com/Ryuichirou/a9993ad3faf58bd04eecaf76e9da137e)

# Kernel法

`tf.contrib.learn`にKernel法の実装があるのでそれを使います。

## 実装

こんな感じで動きます。

```python
image_column = tf.contrib.layers.real_valued_column('images', dimension=784)
optimizer = tf.train.FtrlOptimizer(learning_rate=50.0, l2_regularization_strength=0.001)

kernel_mapper = tf.contrib.kernel_methods.RandomFourierFeatureMapper(input_dim=784, output_dim=2000, stddev=5.0, name='rffm')
kernel_mappers = {image_column: [kernel_mapper]}
estimator = tf.contrib.kernel_methods.KernelLinearClassifier(n_classes=10, optimizer=optimizer, kernel_mappers=kernel_mappers)

# Train.
start = time.time()
estimator.fit(input_fn=train_input_fn, steps=2000)
end = time.time()
print('Elapsed time: {} seconds'.format(end - start))

# Evaluate and report metrics.
eval_metrics = estimator.evaluate(input_fn=eval_input_fn, steps=1)
print(eval_metric
```

`tf.contrib.kernel_methods.KernelLinearClassifier(n_classes=10, optimizer=optimizer, kernel_mappers=kernel_mappers)`でRandom Fourier Featuresを使っています(これが何者なのかはまだフォローできていないです)。Gaussian Kernelの近似になっているみたいですね。

## 残念だったこと

上記のコードを実行すると次のWARNINGが出ます。

> WARNING:tensorflow:From /usr/local/lib/python3.5/dist-packages/tensorflow/contrib/learn/python/learn/estimators/head.py:642: scalar_summary (from tensorflow.python.ops.logging_ops) is deprecated and will be removed after 2016-11-30.
> Instructions for updating:
> Please switch to tf.summary.scalar. Note that tf.summary.scalar uses the node name instead of the tag. This means that TensorFlow will automatically de-duplicate summary names based on the scope they are created in. Also, passing a tensor or list of tags to a scalar summary op is no longer supported.

これは`tf.contrib.learn`を使わなければ出ませんが、Kernel法を使うためには`tf.contrib.learn`を使うのが楽というジレンマに陥りました。
Numpy > link > [-1, 1]を取得する方法

```txt:動作環境
ideone (Python 3)
```


### numpyで[-1, 1]を取得する方法

numpyで[0, 1]の値を得るにはどうするか。
以下を見つけた。

https://stackoverflow.com/questions/11673124/what-is-the-best-way-of-getting-random-numbers-in-numpy

### 実装

https://ideone.com/m6PXFv

```py
import numpy as np


def eq1(P):
	return 1.0 - 2.0 * P

def eq2(P):
	return 2.0 * P - 1.0

P0t1 = np.random.uniform(0, 1, size=5)
print(P0t1)

theta = np.arccos(eq1(P0t1))
print('theta     ', theta)
print('cos(theta)', np.cos(theta))
print('sin(theta)', np.sin(theta))

theta = np.arccos(eq2(P0t1))
print('theta     ', theta)
print('cos(theta)', np.cos(theta))
print('sin(theta)', np.sin(theta))

```

```txt:run
[ 0.50798821  0.26962258  0.89942646  0.64179179  0.19686876]
theta      [ 1.58677343  1.09195082  2.49618217  1.85832537  0.91944392]
cos(theta) [-0.01597643  0.46075484 -0.79885292 -0.28358357  0.60626248]
sin(theta) [ 0.99987237  0.88752745  0.6015264   0.95894753  0.79526462]
theta      [ 1.55481922  2.04964183  0.64541048  1.28326729  2.22214873]
cos(theta) [ 0.01597643 -0.46075484  0.79885292  0.28358357 -0.60626248]
sin(theta) [ 0.99987237  0.88752745  0.6015264   0.95894753  0.79526462]
```

@ 計算物理I by 夏目 雄平さん、小川 健吾さん
10.3 メトロポリス法を利用したシミュレーション
My Operating System

Its my operating system. Its called Gramado. Take a look at this project on Github. https://github.com/frednora/gramado

![shell.jpg](https://qiita-image-store.s3.amazonaws.com/0/201377/782e1463-95ef-634e-a24d-924c2ceec9b4.jpeg)

![message-box.jpg](https://qiita-image-store.s3.amazonaws.com/0/201377/cc64f156-ee36-9dba-6462-5c99b62ae18b.jpeg)

![gramado.png](https://qiita-image-store.s3.amazonaws.com/0/201377/c0ef29ac-9c19-3add-2a4d-4824394eaf17.png)
IPv4アドレスはどうして今でももらえるの？

### 概要

新しくVPSをレンタルすると今でもIPv4アドレスが割り当てられて使えます。IPv4アドレスの割り振りは2011年に終了しているのに、2016年の今でもIPv4アドレスが使える理由をさくらVPSを例にとって話します。


### IPv4アドレスの疑問

2016年5月にさくらVPSを使い始めて、当たり前ですがIPv4とIPv6の両方のIPアドレスが割り当てられました。改めて考えるとどうして未だにIPv4のIPアドレスがあるのでしょうか。IPv6が登場したのは何年も前のことですが、IPv4アドレスはまだ余ってるのでしょうか。


### IPv4アドレスの分配状況

IPv4アドレスは 0.0.0.0 - 255.255.255.255 まであり、約43億個(8ビット×4)あります。図1はIPv4アドレスの分配状況の推移を示していて、縦軸は各RIR(地域インターネットレジストリ)に割り当てられたアドレス[/8ブロック(=約1,670万個)]で、横軸は時間です[^1]。

[^1]: [地域インターネットレジストリ(RIR)ごとのIPv4アドレス、IPv6アドレス、AS番号配分状況 - JPNIC](https://www.nic.ad.jp/ja/stat/ip/world.html)より引用

![IPv4アドレスの割り振りの推移](https://www.nic.ad.jp/ja/stat/ip/img/graph-3-201603.png)
[tc]図1 IPv4アドレスの割り振りの推移[/tc]

未割り振り分である茶色の領域が2011年初頭になくなっいることがわかります。2011年以降、アジア太平洋地域のRIRであるAPNICが割り振られたアドレスは45[/8ブロック]です(水色の領域)。45[/8ブロック]は約7億5,000万個(1,670万×45)です。日本のNIR(国別インターネットレジストリ)であるJPNICはAPNICが割当たられたアドレスの一部を管理しています。

図2はJPNICが管理しているIPv4アドレス数の推移です。2011年4月以降、APNICから新たにアドレスを割り振られることはなくなったので、約9,600万個で頭打ちしています[^2]。日本国内のIPv4アドレスのリソースは9,600万ほどしかありません。

[^2]: [IPアドレスに関する統計・各種リスト - JPNIC](https://www.nic.ad.jp/ja/stat/ip/index.html)より引用

![日本国内で使用できるIPv4アドレス数の推移](https://www.nic.ad.jp/ja/stat/ip/img/graph-1-201604.png)
[tc]図2 日本国内で使用できるIPv4アドレス数の推移[/tc]

JPNICは割り振り終了について次のように書いています[^3]。

[^3]: [IPv4アドレスの在庫枯渇に関して - JPNIC](https://www.nic.ad.jp/ja/ip/ipv4pool/index.html)より引用

> 2011年4月15日には、アジア太平洋地域のRIR(地域インターネットレジストリ)であるAPNICにおいても、通常の申請により割り振り可能であるIPv4アドレスの在庫がなくなり、アジア太平洋地域は、いわゆる「IPv4アドレス在庫枯渇」の 状態となりました。JPNICでは独自のアドレス在庫を保有せず、APNICと共有しているため、APNICでの通常割り振り終了に伴い、JPNICでの通常の割り振りも終了しました。

JPNICは日本国内のIPアドレス管理指定事業者(IP指定事業者と略します)に9,600万個すべてのIPv4アドレスの割り振りを終えており、新しく割り振れるアドレスは何もありません。


### IP指定事業者間でIPv4アドレスの移転

そうすると、私が借りたばかりのさくらVPSのIPv4アドレスはどこから来たのでしょうか。もう5年も前に全てのアドレスの割り振りは終わっていますし、全部で9,600万しかありません。

JPNICが公開している[IPアドレス管理指定事業者リスト](https://www.nic.ad.jp/ja/ip/member/cidr-block-list.txt)によると、JPNICと契約しているIP指定事業者は2016年5月時点で412社あり、さくらVPSサービスを運営しているさくらインターネット株式会社もその内の1つです。

IP指定事業者の間でIPv4アドレスの移転をしていて、さくらインターネットも他のIP指定事業者からIPv4アドレスを購入し、IPv4アドレスを確保しています。[IP指定事業者間のIPv4アドレス移転の履歴](https://www.nic.ad.jp/ja/ip/transfer/ipv4-log.html)はJPNICが公開しています。移転履歴から計算すると、さくらインターネットは2011年から2016年までの5年間に約58万個のIPv4アドレスを取得しています。

私が借りているさくらVPSに割り当てられたIPv4アドレス(153.126.x.x)もこの中にありました。さくらインターネットはIPv4アドレス移転制度を使い、他のIP指定事業者から何らかの理由で使われていないIPv4アドレスを集めています。そうして新たなVPSユーザーなどにIPv4アドレスを割り当てています。さくらインターネットに限らずGMOインターネット等の他の通信業者も同様です。


### 結論

IPv4アドレスの全体の数は約43億と変わることがなく、各国への割り振りも2011年に終了しています。さくらインターネットはアドレス移転制度を使い、過去5年間で約58万個のIPv4アドレスを集めて、それらを新規のユーザーに割り当ててます。私が借りたVPSに割り当てられたIPv4アドレスも過去にさくらインターネットがアドレス移転制度で取得したものでした。


### おわりに

RIRを超えたアドレス移転も行われていますが（例えばアメリカから日本へなど）、全アドレス数は32ビット(約43億)と有限なのでいつかアドレスが本当に足りなくなる時はきます。現在は、使われていないアドレスなどをアドレス移転で確保して、新たなVPSユーザーに割り当てたりとアドレスの有効利用をしつつ、IPv6に移行している過渡期だということが分かりました。IPv6への移行の具体的な進捗度などが気になりますので、今後調べるかもしれません。