読者です 読者をやめる 読者になる 読者になる

dpkgのlock解除

最近全くブログ書いてない事に気づいた。*1
研究が忙しかったということにしておこう。

今回はVirtualBoxの話。というかUbuntuの話。

普段研究室でUbuntu使ってて、家で作業の続きをする時には家のWindowsPCにVirtualBox入れて仮想マシンとしてubuntuで作業をしてる。
また、個人的なファイルとかはDropboxで共有してるのだけれど家のUbuntuに入れてなかった事に気づいたので先日インストールしようとしたところ、なんか失敗した。*2

結論からいうと、インストール中にフリーズしたため強制的に再起動した所apt-get updateとかができなくなった。

E: /var/lib/apt/lists/lock が取得できませんでした - open (11: リソースが一時的に利用できません)
E: ディレクトリ /var/lib/apt/lists/ をロックできません
E: ロック /var/lib/dpkg/lock が取得できませんでした - open (11: リソースが一時的に利用できません)
E: 管理用ディレクトリ (/var/lib/dpkg/) をロックできません。これを使う別のプロセスが動いていませんか?

って感じの事言われた。


今回はこれの解除方法とかを書こうとおもう。
早速ググってみたらドンピシャな事書いてあった記事があった。ankyo.blog.so-net.ne.jp

大変ありがたいので、備忘録的に書いていく。

方法

まずリカバリーモードで立ち上げる。
shiftキー押しながら起動するとリカバリーモードになる。

リカバリーモードでrootを選択し、以下のコマンドを入力する。

rm /var/lib/apt/lists/lock
rm /var/lib/dpkg/lock
apt-get update
apt-get install -f

あとは再起動。

怒られた

僕が上記の方法でlockファイル削除しようとしたら「Read Onlyだから消せない」って怒られた。
これも調べてみると再マウントする事で解決出来るらしいということがわかった。qiita.com
大変ありがたい。いんたーねっとは偉大である。

というわけでこちらに書いてある通りに下記コマンドを入力してリマウント

mount -o remount,rw /

あとは上に書いたコマンドでlockファイルを削除して、アップデートと強制インストールをしたら再起動しておしまい。

ちゃんと上手くいった。
大変ありがたいので、今後忘れないようにしよう。

*1:めっちゃツイートしてるくせにブログ更新してない

*2:面倒臭がってソフトウェアセンター使ったのが問題

std::stringstreamをクリアする

やり方

すごく初歩的な事だけど、最近知ったので。
std::stringstreamに格納されてる値をクリアにして別の値を入れる時に必要な処理

#include <iostream>
#include <sstream>

using namespace std;
int main(int argc, char* argv[]){
  stringstream ss;
  ss << "hoge";

  cout << ss.str() << endl;

  //ssをクリアする
  ss.str("");
  ss.clear(stringstream::goodbit);

  ss << "fuga";
  cout << ss.str() << endl;

  return 0;
}
hoge
fuga

ソースコードから複数のディレクトリに入ってるファイルを逐次参照するプログラムとかに使える。

使ってみた

data
  L dir1
      L file1.dat
    dir2
      L file2.dat
    dir3
      L file3.dat
    dir4
      L file4.dat

みたいなディレクトリ階層を作って、各ディレクトリのfile*.datを見るプログラムを作ってみた。
各file*.datにはファイルパスを書いておく。

#include <iostream>
#include <sstream>
#include <fstream>

using namespace std;
int main(int argc, char* argv[]){
  stringstream dir;
  string path = "./data/dir";
  string file = "file"

  for(int i = 0; i < 4; i++){
    dir << path << i+1 << "/" << file << i+1 << ".dat";
    ifstream ifs(dir.str().c_str());
    string line;
    while(getline(ifs, line)){
      cout << line << endl;
    }
    dir.str("");
    dir.clear(stringstream::goodbit);
  }

  return 0;
}
./data/dir1/file1.dat
./data/dir2/file2.dat
./data/dir3/file3.dat
./data/dir4/file4.dat

といった感じ。
OpenCVとかで作った行列データをyamlにして別々のディレクトリに保存したり読みだしたりする場合とかに使える。
(std::ifstreamのところはdir.str().c_str()としててちょっとアレだけど…)

参考HP

stringstreamのクリアの仕方 - りんでん記


[追記 2015/3/18]
ファイル逐次読み出しのソースをちょっと改変

謹賀新年

あけましておめでとうございます。

去年は色々有りました。幾つかイベントに参加したし、いっぱい勉強になりました。
まだまだいっぱいやることあって未熟者ですが、いっぱい頑張っていきたいと思います。
今年2015年は過去のいくつものSF作品などの時代設定で使用されている年でもあるので、僕もいい感じの事を出来るように色々やっていきたいですね。(適当)

今年もよろしくお願いします。

出かける前に予定とかを教えてくれるシステムを作った話

この記事はお家ハックAdvent Calendar 2014の17日目の記事です。

今回は朝の外出前に予定とか天気とか携行品を通知してくれるシステムを作った話です。(実は今年の8月ぐらいに作ったというのは内緒)

コンセプト

忙しい現代人は朝ゆっくりする時間が無い人が多い*1
僕も朝は決まってドタバタしてる。しかも急いで色々準備するもんだから忘れ物などをよくする。*2
忘れ物は人によっては結構深刻な問題に発展しかねない。
そういう失敗を起こさないための予防策として、外出前に今日の携行品とか予定を確認できる様なシステムがあればすごく嬉しいなーと思い、そういうサポートをしてくれるシステムを作りました。

概要

前提

朝の行動として以下の行動が考えられる

  • 起床
  • 洗顔など
  • 朝食
  • 気象情報確認
  • 気象情報に基づいた着替え
  • 予定確認
  • 携行品準備
  • 消灯
  • 外出

上記のうち太字の行動に何らかのサポートを行う事で外出前に効率的かつ失敗の少ない行動を行うことが出来ると考えました。

システムについて

必要要件
  • 当日の予定をメール通知
  • 持ち物を音声で通知
  • 天候情報を音声で通知
  • 消灯機構

以上を行う

システム概略図

基本はPCとUSBカメラとマイクとスピーカーがあれば出来る様にしたいと考え下図のようにした。(ちょっとわかりにくいけど・・・)
f:id:i-hako:20141217222005p:plain
天気情報や予定、持ち物などを各種APIを使用してウェブから取得してくる。
また、ユーザインターフェースとして音声を用いることにした。
音声UIとしてrospeexというクラウド音声合成サービスを使用した。*3

動作概要

システムの動作の概要は下図の通り
f:id:i-hako:20141217230615p:plain

  • 事前作業として、ユーザはgoogleカレンダーに事前に予定と必要物品を登録しておく。
  • ユーザが音声で予定を尋ねると、それを認識しgoogleカレンダーに予め登録されている予定を読みだしてメールで送信する。
  • 更にその後ユーザが外出準備に取り掛かり、携行品を準備しようとすると、動体を検出してその日必要な携行品を音声で通知してくれる。
  • また、外出直前に天気などを尋ねると、yahoo! weatherから天気情報を取得してその日の天候について教えてくれる。
  • 最後に、「電気を消して」と言うと電気を消す。

という感じです。


まとめ

感想

実際にやった場所は研究室だったので、厳密な意味でのお家ハックかと言われるとちょっとあれな感じはあるけれど*4、カメラとスピーカーとマイクがあれば好きな所で必要な情報をサポートしてくれるので、割りと便利かも知れない。
むしろ頼りすぎて余計に物忘れが激しくなりそうな感じはある。
一番きつかったのは各状態の制御をrosmessageでやってるので、ちょっと同期などが難しかった感じがあります。
(ROSについてはググってください。僕はあまり説明出来ません…(申し訳ない))

今後について

結局リマインダーの強化版みたいな感じで、事前にgoogleカレンダーに手動で予定や必要物品を登録しなきゃいけないのでもうちょっと賢い感じで予定とか立ててくれると嬉しいなーとか…

*1:早起きすればいいとかそういう話もあるけど…

*2:予定をすっぽかす事も有ります

*3:画像はhttp://rospeex.org/top-ja/より拝借

*4:まぁでもほとんど住んでるも同然だし良いよね!!!!!

$ rm -rf で/tmpを削除してしまった話

つい4時間程前の話。
ubuntuで色々作業していた時に、一時作業ディレクトリとして適当な所に

:../hoge/fuga$ mkdir tmp

という感じでtmpディレクトリを作った。

その後作業が終わり、tmpというディレクトリがいらなくなったのでディレクトリごと削除しようとして何も考えずにtab連打で

$ rm -rf /tmp/

なんて打ち込んでしまった。

まぁこの結果はご想像の通り、/boot /devとかの中にある/tmpというディレクトリを削除してしまうことになるわけです。f:id:i-hako:20141209035231p:plain

あまりLinuxについて詳しくは知らないのですが、/tmpは基本的にはその名前の通り一時的なデータを保存するディレクトリらしいです。*1
ところが、このディレクトリには色々な設定とかが書かれているため、/tmpディレクトリごと削除すると色々問題があるわけです。*2



さぁ困った。
とにかく落ち着こう。
こういう時はどうするんだ。そうだ。まずは再起動してみよう。*3

。。。。。再起動。。。。。
起動した…が、おかしい。ログイン画面が現れた。これは設定した覚えがないぞ。
とりあえずパスワード入れてログインを試みる。ログインできない。
ゲストアカウントもダメだ。さてコイツはまずいぞ…


…という感じですごく焦っていたのですが、色々考えてみた所ubuntuをインストールしたLiveCDを使って、LiveCDの/tmpを、起動しないUbuntuが入ったデバイスのルートディレクトリに突っ込めば直せそうだという結論に達した。
とても簡単な話だった。

  1. LiveCDからブートする
    LiveCDを入れてCDブートする
  2. Ubuntuを試すとかでお試し版を起動
    /tmpディレクトリを持ってくるため、お試し版を起動
  3. 起動しないUbuntuが入ったドライブをマウント

    $ sudo su
    ...
    # cd /
    # mount /dev/<device> /mnt/

    とかでマウント。root権限じゃないとマウントできないっぽい

  4. LiveCD側の/tmp以下を/mntにコピー
    LiveCD側のルートディレクトリに移動して以下のコマンドでコピー

    # cp -a /tmp/ /mnt

    "-a"はディレクトリの構造や設定を保ったままコピーしてくれるオプションらしい

  5. 再起動
    あとは再起動してみてちゃんと起動したら成功。
    起動後にエラーメッセージ出るかもしれませんが、ちゃんと詳細を確認して適切な対処をしてください。

こんなんでいいのかどうかわからないけど、とりあえずちゃんと起動できるようになりました。
問題あったらどうしようかな


というわけで、今回はこれだけ。忘れないようにメモ。

*1:再起動の度にデータが掃除されるとかなんとか…

*2:terminal新しく立ち上げたらなんか「hoge.sh XXXXXがありません」的な感じで怒られました

*3:コイツが一番まずかった

Oculus Rift DK1でのプレゼン接続方法について

どうもこんにちは。
11/29、30に東京の目黒で第三回Oculus GameJam in Japanに参加してきました。
僕はプログラム苦手マンなので、今回はまともにスクリプト書いておりませんが、なかなか良い感じのゲームが出来たのではないかと思います.
(成果物を参照出来る何かが無いので詳しいゲーム内容とかについてはとりあえず割愛)

そんなOcuJamもゲームジャムなので、要所要所で参加者に自分たちのチームが作っているゲームを紹介したり進捗報告したりする必要があります。
ところが、実際に各自が作ったゲームのプレイ画面を見せながらプレゼンしようとすると、何故かOculus側に表示がされなかったり、トラッキングが出来なかったりなどで上手く行かなかったチームが割りといた気がします。*1
そこで今回はこの上手く行かなかった表示に対して解決策になるかもしれないアイディアについて述べたいと思います。
参加チームのほとんどがDK2でのアプリ開発で、DK1を使ってるのは僕らだけだったので、正確な問題の切り分けや、DK1/DK2での原因の違いなどはハッキリとわかりませんが、とりあえずDK1ゲームをプレゼンする方法として自分なりの解決策を見つけたので、備忘録的に書いておきます。

目的と構成

目的

「Oculusゲームをリアルタイムでプレイしながらプレゼンしたい」
「プレイ画面をプロジェクタのスクリーンで見せたい」
などのため、unityでビルドされたゲームをOculusで表示しながら且つスクリーンなどの大型ディスプレイに表示する。

構成
  • PC: G-tune i990 (ノートPC)
  • OS: Windows8.1 with Update
  • GPU: GTX 870M
  • メモリ: 16GB
  • Unity version: 4.6
  • Oculus: Developer Kit 1

下図の様な接続構成をとって「PC画面を見ながら、プロジェクタでPCディスプレイの複製を表示し、Oculus DK1でもゲームをプレイする」という構成を取りたい。
f:id:i-hako:20141201031438p:plain

Fig.1 構成図
(接続ポートが上図のようになっているのは、今回この構成のみでしか検証していないため。)

問題点

Fig.1のように3画面出力で構成しようとすると、何故かOculusのRuntimeがDK1を認識しなくなり、DK1のヘッドトラッキング機能が使用出来なかった。*2
結局、PCディスプレイとプロジェクタにはミラーリングが反映されているが、Oculus側の入力が全く得られないという問題点が発生した。

解決策

結論

先に結論から述べると、Fig.1の様に3画面同時出力はどうやら無理っぽいです。
そこで、PCディスプレイの画面表示を諦めて、Fig.2の様にプロジェクタとDK1のみに画面表示(複製モード)すると良い。
f:id:i-hako:20141201032327p:plain

Fig.2 成功した構成図
このようにすると、プロジェクタでプレイ画面を表示しながら、Oculusも使う事ができた。

手順

では、Fig.2の様にする構成について説明する。

  1. まずは接続
    PCの各ポートにプロジェクタとOculusを接続し、DK1のUSBケーブルを接続する。(Oculusは電源入れ忘れないように!)
  2. プロジェクタへミラーリング
    デスクトップで右クリックすると「画面の解像度」という項目があるはずです。これを使ってPCの画面をプロジェクタへミラーリングしましょう。
    これは「windowsキー+P」でも出来たと思います。この状態ではOculusは恐らく何も表示されていない筈です。
  3. 表示する画面をプロジェクタとOculusに変更
    ここでノートPCとプロジェクタのミラーリングから、プロジェクタとOculusのミラーリングへ切り替えて、PCに画面表示が出来ない様にしましょう。
    「画面の解像度」の項目で「複数ディスプレイ」というのの中に、「デスクトップを2と3のみに表示」というものがあると思いますので、それを選択し、
    PCディスプレイに画面が表示されない様にします。これで漸くプロジェクタとOculusのみにデスクトップが表示されているはずです。
  4. Oculus Runtimeの確認
    ここで、一度Oculus Runtimeを起動し、DK1が認識されているかどうか確認して下さい。僕の環境では必ずと言っていいほど認識されていない状態になっていました。
    Oculus Runtimeで認識されていなかった場合、一度DK1のUSBケーブルを抜き差しし、Oculus Runtimeで認識される事を確認して下さい。
  5. いざゲーム起動
    ここまで来たらあとはプレイするゲームを起動するだけです。恐らくプロジェクタにPCでのプレイ画面が表示され、DK1側にもちゃんと表示されているはずです。
    この状態ならば、DK1からの入力などをちゃんと得ることができ、ヘッドトラッキングなども問題なく作動しました
(画像などがなく、ちょっと分かり辛いかと思われますので、後日補完します。)

まとめ

あまり問題の切り分けとか他のパターンの検証とかちゃんとやっていないので、多分他にもいろんな問題あると思いますし、根本的な解決方法では無い気もする。
(なにせDK2持ってないので試せなかったし、DK2は他にも色々障壁があるらしいのでDK2勢はこれで上手くいかなくてもご容赦願います><)*3
もしかすると、ディスプレイとか関係無しに、単純にRuntimeの問題だったりするかも…
あるいは、GPU側の問題で接続するポートが物理的にこういうことが出来ない様な接続になっているのかも…
…と、まぁこんな感じで「なんとなく試行錯誤したら上手くいった」程度の解決策なので、試してみて上手く行けば儲けモンぐらいの軽い気持ちで参考にしていただけると助かります。
(すでに他の方法も沢山あると思うけど、僕は知らないのでご存知の方いたらコメントで教えていただけるとすごく嬉しいです。)

なにはともあれ、とりあえずこれで表示は出来ると思うので、困っている方がいらしたら一度試してみてください。

*1:全員の共通点として、「Oculus + PCディスプレイ + プロジェクタ」の構成で3画面出力しようとして上手く表示されなかったという感じ。

*2:僕らの場合、ヘッドトラッキングが要だったのでこれは大問題だった

*3:どなたかDK2僕に買ってください!!!!!!!!!

Ocufes@ニコニコ町会議in須坂に参加した事について

去る2014/7/19にドワンゴが主催する「ニコニコ町会議」なるイベントが長野県須坂市で開催され、そのイベントと併催して行われたOcufesというイベントにて出品(?)してきました。

Ocufesとは

経緯を書く前にとりあえずOcufesの概要的な何かを。
Ocufesとは、Oculus VR社が開発した没入型ヘッドマウントディスプレイを利用したアプリケーションをデベロッパーが作り、来場者にアプリケーションを体験させる会みたいなものです。(これであってるのかしら?)


出品の経緯

開催の1ヶ月前頃に長野県内でOcufesが開催される事を@takashiskiさん経由で知り、僕もOculus Riftを持っている事やAR/VRなどに大変興味を抱いている事などが有り、@yuujiiさんのお手伝いと言うことで立候補しました。
最初は特に出品する予定も無くただの手伝いのつもりだったのですが、いつの間にか@takashiskiさんと一緒に出品することになってました(ちなみにこの時開催1週間前)


やったこと

ARマーカー*1を使って現実世界に仮想の武器を作り、それをOVRvision*2を経由してOculus Riftで見るという感じのことをしました。
f:id:i-hako:20140723021856j:plain

ARマーカー(ID:22)
このアイディア自体はありふれた内容なので,技術的な事は僕が下手な説明をするよりも他の何処かいいかんじの人が説明してるHPを観たほうがいいと思うので割愛します。

僕らがやったのは下図のように棒の4面にARマーカーを貼り付けて実際に棒を振ることで擬似的に武器を振るってるようにする事です。
f:id:i-hako:20140723032847p:plain

イメージ
4面にマーカーを貼り付けることで手に持ってる棒を回転させて複数の武器を出現させることができます。
f:id:i-hako:20140724033126j:plain
実際にOVRvisionでみた状態


技術的ななにか

どのようにして実現したかという事を書こうとおもうけど、基本的に既に用意されているサンプルを少し改変した程度なのであまりまともなことは書けません。
OVRvisionのUnitySDKのサンプルにあるunity_ar_exampleをそのまま使いました。
このサンプルではマーカー上に白いcubeを出現させるやつだったので、そのcubeを武器にすげ替えることで実現しました。
また、ARマーカーについては@hecomiさんのブログを参考にして生成しました。
あとは上述したように棒の4面に貼り付けるためにダンボールをカットし、適当な棒*3に貼り付けました。


当日の反応

雨天にも関わらずたくさんの人が来ていて十数人が体験していった感じでした。
なんにせよ完成度が低かった*4ので、体験者の反応は割と微妙な感じだった。*5
ただ、数人は「これすごい!対戦とかのゲーム性があるともっといいかも!」と言った反応だったので、ひとまずは良いのかなぁと。


反省とか

今回の出品を通してかなりの問題点があったので、箇条書きにしてみました。

  1. 構想が固まるのが遅すぎた
  2. 2人で作る際に相互のビジョンに相違があった
  3. 完成が当日になってしまった
  4. ボランティアスタッフの方に説明ができてなかった
  5. 展示の時にいい感じの演出ができなかった
  6. 地味にクオリティが低い

それぞれの反省について

  1. とりかかったのが前日で、原因はそれまでに作ってたやつ*6が全然怖くなさ気だったため。これは最初の構想の段階で使えるデバイスとSDK周りを正確に把握できてれば回避できた可能性が高い。次回は最初から構想を深める必要がある。
  2. 話し合い不足が原因だった。@takashiskiさんが当日車を運転する事になっていた*7ので、先に休んでもらって、その間に僕が作業&ブラッシュアップをする予定だったが、お互いがこのアプリに対して違う捉え方をしていた。*8
    おそらくアプリの完成度重視か、演出重視かの違いも関わってくるとは思うけれど、ゲームやこういう体験には完成度・演出の両要素とも重要なので、ビジョン確認と同時に優先順位も決める必要が有りそう。*9
  3. 当日会場についた段階でα版程度だった。これは僕がUnityに全然慣れていないのもあるが、お互いのビジョンのズレというのもある。
  4. これは割と問題だった。当日僕が常にPCにつきっきりで作り直したりしてたので、ボランティアで来てくれた方にまともに説明出来なかったため、彼が体験者にする説明には一部誤りがあった。*10
    彼を責めるつもりは毛頭無いが、これを解決するには1〜3の事項が解決してようが居なかろうが必ず開始前にはちゃんと説明をしておく必要がある。
  5. これは僕の悪い癖である。なんだかんだ技術的なことを説明してもあまり理解できないかもしれないと思い面倒な説明を省いてしまうのだ。この原因はおそらく今回のアプリを「技術的な物」としてしか捉えておらず、エンターテインメント性を排除して考えてしまっていたからだ。
    来場者はエンターテインメントを求めて来ているので、もう少し世界観とか相手の驚きとかを考慮すべきだった。
    事前に文言とかを決めといたほうがいいのかな?
  6. 完成品はただARマーカーの紹介のようなものになってしまい、ゲーム性やエンタメ性が全くなかった。*11できれば対人戦とかモンスターを倒すとかのゲーム性が有ったほうがよかったなーと思う。

反省する点が多かったが、まとめると

開発エンジンに慣れたうえでもっと早くからちゃんと話しあって動いておけば解決できたね

ということだ。*12


全体を通した感想

以前からニコニコ技術部やOculus勢に憧れており、僕の中では「技術部タグ」をつけて動画サイトに投稿することはひとつのステータスになっており、ニコニコ町(超)会議やOcufesというのはそんな事をやってる人たちの作品に実際に触れることができる場だ。
そんな場に破れかぶれでも参加できたことはこの上なく素晴らしい経験で、大変貴重な経験ができたと考えておる。
これを一過性の体験で終わらせるのはあまりにも勿体無いので、これをきっかけにどんどん次の物を作っていきたいと思う。
また、今回は様々な人に助けてもらってなんとか完成に漕ぎつけた*13が、次回こそは一人で一からやってみたい。
もちろんそのためには技術的に向上させなきゃいけない事項が大量にあるが、焦らずやっていこうと思う。
最後に、お世話になった@takashiskiさんと@yuujiiさんにお礼を述べて締めたいと思う。
ありがとうございました。

*1:マーカーが置かれた現実をカメラを経由することで拡張情報を提示することを可能にするもの

*2:しのびや.comさんが開発したOculus Riftに装着出来るステレオカメラ

*3:今回使用したのは以前100均で購入したペンライト

*4:α版というのもおこがましい程度だった

*5:「おぉー…いいですね!」ぐらい

*6:ホラー?系

*7:僕が免許を持っていないため

*8:正確に言うと僕は「ARマーカーで武器を持つことができる体験」と考えており、@takashiskiさんは「ボロボロのただの棒をHMDを通して見ることでファンタジーな武器に変わる体験」という感じで捉えていた

*9:完成度と演出どちらにステ振りするかってことで

*10:僕も会場で彼の説明を聞いた時に違和感が有ったが、ある意味イメージしやすい説明だったのでスルーしてしまったのも問題

*11:人によってはそれでも面白かったようだが。

*12:多方面から「それが出来ればこんな苦労しない!」と言われそう…

*13:主に@takashiskiさんの足を引っ張ってただけだが…