はむすたーの巣

ちょっとかじって見たこととか興味持ったこととか記事というよりメモな感じにまとめます。たまに消します。きっと。

HTCViveのTrackerをHMDなしで動かしつつ、ポゴピンのボタン入力イベントを受け取ろうとしたらハマった話

はじめに

HTCViveのTracker、便利ですよね。

なにが便利なの

  • 圧倒的な安価で光学式トラッキングが行える
  • お手軽に使える
  • ポゴピン使えば少し入力もできる

という感じで非常に優秀です。
そこで、これVRコンテンツに限らず普通にトラッキングバイスとして使いたいなぁ....という願望が出てきました。 研究で使いたいなぁ、ということで使ってみることに。

TrackerをHMD抜きで動かす方法

先人の方々の知見を参考にしながら、触って行きます。

shop-0761.hatenablog.com 構築した環境では過去にHMDを接続したことがなかったため、以下のサイト様の記事を参考に追加の作業が必要でした。

syan0.hatenadiary.org

以上の記事を参考にしながら、Unity上でTrackerの座標を取得することができました。

おまけ(MacUbuntuでも挑戦してる人いるみたいです、僕は試せていません)

qiita.com

bluelet.sakura.ne.jp

ポゴピンを使って入力を行ってみる

何故か反応しなかったです、 で、その原因(あっけない)が以下でした。

ハマりどころ

そもそもTrackerのポゴピンは、SteamVRのトラッカーの管理からハンドヘルドを選択していないと反応しないよって話でした。
すごい時間を使ったのにあっけない....
TargetClassがGenericTrackerになったりControllerになったりすることがあるみたいですが、どちらでも反応はする模様です。
一度GenericTrackerでなくControllerとして認識されたときに、たまたまその時に反応するようになったことから、Controllerであることがイベント反応の要因か?と考えたりもしたのですが、GenericTrackerと認識されている状態でもトラッカーの管理からハンドヘルドを選択することでポゴピンが反応するようになりましたとさ...

動作が確認できた環境

こちらの記事に掲載されているソースコードを用いてトラッキングを行っている状態で同ソースコードに追記する形で動作を確認しました。

shop-0761.hatenablog.com

openvr_api.cs

このあたりを参考に

valvesoftware.github.io

vr-lab.voyagegroup.com

var system = OpenVR.System;
system.GetControllerState((uint) _validDeviceIds[0], ref state,(uint)System.Runtime.InteropServices.Marshal.SizeOf(typeof(VRControllerState_t)));
Debug.Log(state.ulButtonPressed);

として、ピンの操作でulongの値が変動することを確認しました。

SteamVRPlugin v1.2.3

こちらの記事の中程に掲載されている入力を取得するコードを組み合わせて動作を確認しました。

framesynthesis.jp

deviceは var device = SteamVR_Controller.Input(_validDeviceIds.First()); とすることで取得できました(今回はTracker一つだけ接続しています)。

SteamVRPlugin v2.5.0

いまテストしてます(設定が上手にできない)
- できそうかハッキリしたら追記

まとめ

steamVRのトラッカーの管理画面の設定をちゃんとやらないとポゴピン使ったイベントは握りつぶされるよ。
OpenVR_Api経由で直に叩いてもだよ。
変則的な環境で混乱したけどこれ別に普通のViveな環境でも起きることなんだろうな...(大昔触ったときは特にこの手のハマりは発生しなかったので、アップデートで増えた機能なのかな....)

お礼

てんちょー様( てんちょー / 筑野(ちくの)えり💕🍱 (@shop_0761) | Twitter )、本記事で挙げました問題について、初歩的で急な質問にもかかわらず、親身になって相談に乗っていただき、大変ありがとうございました。

今からI`m Watchに自作アプリを焼くにはどうするか

そもそもとして...

こんな記事ニーズあるんか...?
 
 
 
 
 
 
俺が必要だと思った時に既に書いていた奴が居なかったから書いたんだよぉ!

始めに

I`m Watchとは

i'm Watch - Wikipedia

大昔にでたスマートウォッチです
Android1.6搭載です
(wikiにはAndroid OS 2.1って書かれてるけど、それはカスタムOSであるWatchOSのバージョンであって、根っこのAndroid自体は1.6のままのはず...)

そしてなんとこのスマートウォッチ、公式ページが消滅しています
故に公式から情報やソフトウェアを入手することが不可能です
同時に公式ストアも死んでいるので、普通に使う上でアプリを追加することは難しいです

Android1.6 (Donut)について

古のAndroidOSです、有名どころだとIS01なんかがこのバージョンです。
IS01等は人気がありカスタムOSでひっそりバージョンを上げることが可能ですが、I`m Watchにはもちろんそのような物は無いので、Android1.6のまま戦う必要があります。
ちなみにこのAndroid1.6、現行のAndroid Studio等ではとっくにサポートを打ち切られていて、プロジェクト作成時のminSdkに入れることすら(多分)不可能に近いです、茨の道を渡れば使えるのかも?自分は諦めました。

I`m WatchにADBで接続できるようにする(下準備)

I`m WatchAndroidバイスとしてかなり特殊な作りになっている模様で、標準のファームウェアではADB接続することはできません。そのためファームウェアの更新が必要になります。

d.hatena.ne.jp

上記リンクを参考にしながら、下記リンクより入手したファームウェアを焼いていきます(ここ以外でI`m Watchファームウェアが手に入る所が見つからなかったです、ここのリンクが切れたら多分終わりなのでは...

Firmware Revision History | Sky of Ducks

そもそもこの二つのサイトくらいしか日本語でI`m Watchでの開発周りの話を沢山してる所が見つからなかったです...

I`m WatchにADBで接続できるようにする

d.hatena.ne.jp

こちらを参考にしながら入れてください
尚解説されているサイト様では、RNDISで設定するIPアドレスを'10.0.0.168'とされていましたが、自分の環境ではこのIPはI`m Watch自身が取ってしまっていましたので、'10.0.0.167'と設定することで無事接続されました。
なお、linuxwindowsでの接続方法(RNDISの設定方法)はわからないです(windowsはさっきのファームウェア配ってくれてたサイト様にドライバが落ちていたはずですが、試していません)

Android1.6向けのビルドを行える環境を用意する(多分もっと良い手段がある)

ここを参考にしました

www.suke-blog.com

ただし、2.xバージョンよりも古いバージョン(1.5)を利用しました、特別な理由があるわけではないんですが、2.3で同じことをやろうとしたらどうやってもminSDKの選択肢にAndroid1.6が入らなかったためです。

Android Studio 1.5 - Android Studio Project Site

IDE+SDK bundle をダウンロードしちゃいましょう。
インストール後、以下のパッケージを追加でインストールする、と解説されているサイト様には記載されていましたが

Android 5.1.1(API 22)
Android 1.6(API 4)
Extras > Android Support Repository
Extras > Android Support Library (Obsolete)

Android Support Library (Obsolete)についてはAndroidStudio1.5でも見つからなかった(パッケージ取得先でそもそも消失してる?)ので入れずに行いましたが、ひとまず問題は起きませんでした。
また、Instant Run機能の無効化についても、特に触れることなく実行ができました。

あとは解説されているサイト様の通りにやれば大丈夫な筈です。

さいごに

参考サイト様のコードを丸パクリ()して実行が確認できました!
GithubにBluetoothSPPで通信をさせるようなコードがあったので、近々試してみたいなぁと思っています

github.com

Atom Z3740搭載のタブレット(Acer iconia W4-820)にAndroid x86を焼こうとしたら詰んだ話

はじめに

皆さんは初期のAtomが出た時期に流行ったミニノートやBayTrailが出た時期に流行ったWindowsタブレット等は購入されましたか? それは今でも現役で使われてますか?
以前僕はWindowsタブレットを買いました、でも今はタンスの肥やしになってます。
そこで、今回は使わなくなった(というかタブレットサイズで使うには微妙な使い勝手な)WindowsタブレットAndroidタブレットとして使おうとして、そして失敗した話を書きます。

Android x86とは

WindowsPC等で用いられるx86_64互換の環境上で、AndroidOSを実行するプロジェクトです。
詳しくはこちら

Android-x86 - Porting Android to x86

Acer iconia W4-820とは

Acerが2013年の末ごろに出したWindows8.1搭載の8インチタブレットです。
僕が所有しているモデルは
CPU : Atom Z3740
メモリ : 2GB
ストレージ : 32GB OS : Windows8.1 with bing (後にwindows10にアップグレード)

なにをやろうとしたか

購入当初は持ち運んでツクール製のゲームをプレイするなどの目的を主として利用して居ましたが、スペック不足やキーボードマウスが無い状態での利用の不便さから現在はほぼ使っていません。
そこで、最近デレステに復帰したこともあり、快適にデレステができる(外部出力してPVを眺める等もしたい)タブレットとして、復活させようと考えました。

問題

Baytrail以降によくある問題として、UEFIは32bitオンリーだが、CPUは64bit対応というものがありますが、それについての問題は現在では修正済みなようで、普通に焼くことでブートが可能でした。
また、インストール作業についても、GRUBの自動インストールに失敗する以外の問題は起きませんでした。(それ以前の問題にぶつかってしまっているため、この問題は後ほど調査します、恐らく手動でインストールすれば解決するような気がしています)

画面が正常に表示されない

GRUBカーネル起動まではタブレット本体の液晶に表示が行われますが、カーネル起動後はなぜか画面が真っ暗なままバックライトのみが点灯しているという状態になってしまいます。
この時、タブレットについているmicroHDMIポートにモニタを接続すると、タブレット本体の液晶の解像度で映像が出力されます(正確には外部ディスプレイのEDIDを読み、その最適解像度で出力を行いつつ、その中にレターボックスの形でタブレットの解像度で映像が出力されているようにみえます)、この時、動作は非常にスムーズで正しいドライバが当たっているように思えました。

nomodesetでKMSを無効にするとやけに重い

このような表示関係の問題への解決策として、KMS(Kernel Mode Setting)を無効にすることがよく挙げられます、今回の問題は、KMSに映像出力の管理が移った時に発生するものであることからも、この解決策は有効であるように考えられます。
実際にGRUBカーネル起動部分に " nomodeset i915.modeset=0"と追記することでKMSを無効にしてみると、タブレット画面でAndroidを起動することが可能でした。
しかし、KMSを無効にした弊害として、汎用ドライバが当たってしまい、動作が非常に重くなってしまいました。
これでは、デレステはおろか、ブラウジングすら快適に行うことは不可能であったため、KMSを無効化するという方法では解決できませんでした。

試したこと

インストールするAndroid x86のバージョンを変えてみる

Android x86には、対象としたAndroidのバージョンやその他設定を追加したビルドなど、複数存在しました。
その中でも、下記のバージョンは今回の問題に関係がありそうな以下のイメージを焼いて動作を試しました。
しかし、どのイメージにおいても同様の問題が発生し、問題部分については各イメージごとに挙動の違いなどはありませんでした。

  • Android x86 6.0 r3
    これより古いバージョンで近い問題を抱えていた人が、このバージョンにすることで解決したとの投稿があったため
  • Android x86 7.1 r2
    ダウンロード数が最も多く、かつこの問題がほぼ報告されていないため、最もポピュラーなバージョンでは発生していない可能性があると考えたため
  • Android x86 8.1 rc1
    リリースノートに、Intel HDグラフィックスのハードウェアアクセラレーション対応が記載されていたため
  • Android-x86-7.1.0_Baytrail-k4.12-T100TA_Jul12-2017
    BaytrailCPU向けのビルドであり、またT100TAの中にはW4-820同様にz3740搭載モデルが存在するため

videoコマンドで出力先を変更する

ここまでで、恐らく問題はKMSにあることがわかっており、つまりKMSの設定を行えば問題は解決するのではないか、と考えるのが順当です。
まずは、KMS上での出力先デバイスが異なることなどが要因なのではないかと考え、/sys/class/drm/以下を参照し現在接続扱いになっているモニタの一覧を確認しました。
確認をすると、以下のデバイスが接続状態となっていました

このDSI-1とは恐らくDisplay Serial Interfaceを指しているものと考えられるので、これが内蔵ディスプレイだと思われます。
また、HDMI-a-1は本体についているmicroHDMI出力ポートのことを指すと思われます。

つまり、HDMI-a-1の出力を強制的に無効にして、DSI-1の出力を強制的に有効にすれば、KMSを介しても内蔵ディスプレイに出力を行えるのではないかと考えました。
そのため、カーネル起動時に "video=HDMI-a-1:d video=DSI-1:800x1280@60e" と記載しDSIからの出力を強制してみました。
しかし、残念ながらこの時も内蔵ディスプレイからの出力は得られず、結果としてHDMIに出てきていた映像出力が無効になるだけでした。

さらに、試しにDSI-1の出力を無効にしたところ、HDMIからHDMIのEDIDに合わせた最適解像度でAndroidが起動したため、未変更状態でもDSIは自動的に選択されEDIDを読みに行くことができているように思えました。

gfxpayloadで出力解像度を一度変更してみる

https://groups.google.com/forum/#!topic/android-x86/t8I2JER2C5g

上記リンクではBayTrailタブレットのblankscreenの問題のひとまずの改善案として、gfxpayloadで一度最適解像度でない解像度を設定するというものが投稿されていました。(なんかどうしてこれでいい感じになるのかはっきりしていないっぽい? ぶら下がってる投稿的にも解決したりしなかったりしてる模様)
これを参考にして、 "set gfxpayload=800x600" をセットしてみましたが、kms立ち上げ前の解像度が変わるだけで特に変化は見られませんでした。

考察

原因として考えられるもの

同様の問題について投稿をしている人が極端に少ないこと、同様の症状が起きている人はCPUが同じ(Z3740)であり、また同じインタフェース(DSI)で内蔵ディスプレイと接続されていることから、特定CPUと特定インタフェースのディスプレイ(Z3740&DSI接続ディスプレイ)との組み合わせで起きる問題?であるように考えられました。(もしかしたらCPUが同じだけでも近い状態になるのかも、近い症状をZ3740で訴えている人は居ました)

同じ問題と思しき人

同じ症状で、同じようなところまで試されている模様。

https://groups.google.com/forum/#!topic/android-x86/IvjwbGB-HjA

おわりに

くわしいマンたすけて!!!!!!
もう僕にはわからんw

ATtiny13Aでシリアル通信をする

お久しぶりです。
特に書くことがなかったわけでもないんですけど、書かなくていっかみたいな流れで書いてませんでした。

ATtiny13Aとは

f:id:Kenoji:20171230232007j:plain
ATtiny13Aとは、Atmel社が製造しているAVRマイコンの中の一つで、低性能ではあるが小さくて安い(50円!)のが特徴です。
安く遊べるものを探しているときにたまたま見かけて興味本位で手をだしてみました。

むずかしそう

と僕も思っていて素のAVRマイコンから少し逃げ腰だったのですが、ほぼArduinoと同じように開発することもできることを知り、以下の記事を参考にさせて頂きながら、ウキウキでライタまで準備してしまいました(ライタ作成には家に転がっていたDavinci32Uを利用しました)
マイコンボード「Da Vinci 32U」でAVRISP mkII クローンを作る | Make | kosakalab
f:id:Kenoji:20171230232018j:plain
また、Arduino環境でATtiny13Aを利用する手順については、以下の記事を参考にさせて頂きました。
Arduino IDE に ATtiny10/13 の開発環境を組み込む | Make | kosakalab

シリアル通信を行う

シリアル通信の確認は、以下の環境で行いました。

USB<->Serial Aitendoで購入したUSB-TTL変換(PL2303HX搭載品)
書き込み装置 AVRISPmkII化済Davinci32U
表示確認 TeraTerm

f:id:Kenoji:20171230231041j:plain

セットアップは、こちら
ATtiny13Aでシリアル通信(UART)を行う: 猫にコ・ン・バ・ン・ワ
Nerd Ralph: AVR half-duplex software UART supporting single pin operation

を参考にさせていただきながら行いました。
また、Rx,Txを一つのピンにまとめることはせず、PB3,PB4に別々に割り当てました。

説明通りにセットアップを行ったはずですが、何故か自分の環境では正しく文が表示されませんでした。
以下その試行錯誤の結果です

安定して通信できるようにする


自分の環境では、クロック1.2Mhzボーレート19200bpsとすると文字が受け取れるようになりましたが、時折文字が送られてこなかったり、ゴミが混ざった状態でした。

クロックの分周設定を適切に行っていなかったのが原因でした、初期状態では8分周のままであったのでそれを解除することで安定して値を受け取れるようになりました。
こちらの記事
My Blog
AVRの内蔵CRクロックを校正する
から、クロックのズレが原因ではないかと考え、記事内に記載されているコードを用いて校正値を求めました。

f:id:Kenoji:20171231000552p:plain

校正値が103であることが分かったため、この値をOSCCALレジスタにセットしてやることで、無事安定した文字列の受け取りが可能になりました。

#include <BasicSerial3.h>//ここは半角にしてください
void setup() {
    OSCCAL=103;
}

void serOut(const char* str) {
    while (*str) {TxByte (*str++);}
}

void loop() { 
    serOut("ATtiny13Aかわいいよぅ\n\r");
}

f:id:Kenoji:20171231001357p:plain






参考にさせていただいたサイト様

make.kosakalab.com
make.kosakalab.com
nuneno.cocolog-nifty.com
www.inoshita.jp
www.chibiegg.net
nerdralph.blogspot.jp

やってたことその3 戦車コントローラーみたいなやつ

f:id:Kenoji:20170726201031j:plain

なんだいそれは

  • 実際の操縦艇に近いサイズの自作コントローラーを操作して戦車を動かせるコンテンツ。
  • Android用のアプリも作成しておりCardBoardを用いて車長視点で見ることもできる。

どうやってつくったんだい

  • 操縦桿の棒の根本の部分の回転をスライドボリュームで取得
  • Arduinoを用いて片方128段階で読み取り、シリアル通信でUnityに送信
  • Unityは受け取った値をもとに戦車を動かす
  • Android用の車長視点のCardBoard対応アプリとは、UNETで通信。

どんなかんじなんだい

こんなかんじ、たのしい。


戦車コントローラー

やってたことその2 光る天板

何だいソレ

f:id:Kenoji:20170726191219j:plain

ノートパソコン(ThinkpadX220)の天板にフルカラーシリアルLEDをとりつけ、ノートパソコン上からArduino経由で制御できるようにしたものですね

どうやったんだい

その1

f:id:Kenoji:20170726191211j:plain

PCとArduinoの間でシリアル通信を行い、PCから送られた情報をもとにws2812b(neopixel)を制御するプログラムをArduinoに書き込む。このときLEDを十分に駆動できるだけの電流が取れるかも確認。

その2

f:id:Kenoji:20170726191216j:plain

ノートパソコンのmini-pcieポートにMini-pcie to USBの変換ボードを差し込み、そのUSBポートにArduino(pro micro)を接続、今回はLEDを153個利用するので、電流不足を補うため別のUSBポート (出力 1A)からも電源を引いてくる。この時、ThinkpadはMini-pcieに接続されるデバイスホワイトリスト形式で監視しているため、それを回避するModBiosの導入も同時に行う。

その3

f:id:Kenoji:20170726191214j:plain

天板にws2812b(neopixel)のLEDテープを貼り付け、配線する。

かんせい!

 

どう使うんだい

使い道としては、液晶パネル側の補助としてとか、天板だからこそみたいなモノとか…。一例として

デスクトップの映像をそのまま持ってくる


デスクトップキャプチャからの天板表示

キャプる部分はProcessingで書きました

ソースコードはこちら(後でgithubにのせたらリンク張ります)

スペクトルアナライザにしてみる


光る天板(すぺあな)

音の処理とかはC#とNaudioでやりました

ソースコードはこちら(後でgithubにのせたらリンク張ります)

ゲームの画面にしてみる


天板で動く迷路

ロジックは全部Unity上で走ってて、描画を天板でやってるだけなのでれっきとしたUnity製のゲームですよ

ソースコードはこちら(後でgithubにのせたらリンク張ります)

やってたことその1 けのじばくだん

 


けのじばくだん

(大体インターン用に適当に書いたドキュメントから引っ張ってきてますよ)

なんだっけそれ

  • VRHMDをかぶった解除者と、解除の手助けをするオペレーターの二人で協力して実ハードウェアの爆弾(を模したもの)を解除するコンテンツ
  • 解除者とオペレーターはそれぞれしか持ち得ない情報を持っており、協力しないと絶対に解除できない(例:解除者はHMD越しでは色が見えないが、どの色からピンを引き抜けばいいか知っている。オペレーターはどこのピンがどの色かを知っている)
  • 解除者はHMD越しに両眼カメラで前方を見ることができるが、解像度が低く色も白黒になって居るため視界が悪く、手探りで解除しなければならない。
  • 下記記事に掲載されました
    1. http://panora.tokyo/3977/
    2. http://forest.watch.impress.co.jp/docs/serial/oculusclub/745772.html
    3. https://www.famitsu.com/news/201602/22099910.html

どうやったん

f:id:Kenoji:20170726183009j:plain

ハードウェア

  • 爆弾側

 爆弾側は、Arduinoとmbedの2台のマイコンを用いて制御、そのうちArduinoは入力処理、mbedは出力処理を担当、2台に分けたのはより爆弾らしい風体にするためでもある。

入力に用いたギミックは、ブレッドボード上に配線したピンの引き抜き、タクトスイッチを複数並べ番号を割り振りナンバー入力、トグルスイッチを3つ並べて順に操作、最後にミサイルスイッチの操作である。

出力に用いたギミックは、8連リレーモジュールをON/OFFさせることで時限爆弾にありがちな「カチカチ」という音と振動を発生させる、圧電ブザーを用いて、カウント開始時に「ピピッ」という音を鳴らしたり、解除失敗時に「ビーッビーッ」という警告音を鳴らしたりする、7セグ2連LEDを用いて残り時間を表示するなどである。

 HMD側はOculusRift DK2を用いて、DK2の前面にOvrVisionを取り付けて解除者の視界として利用した。

ソフトウェア

 ソフトウェアは、Unityを使用し、UnityとArduino、mbed間はシリアル通信でやり取りを行わせた。

 爆弾解除のステート管理は、Arduinoが行っており、UnityはArduinoから送られてきたステート番号に沿って、VR空間内での情報表示等を行う。

 また、制限時間の管理はUnity上で行っており、現在の残り時間の数値をmbed上に送信することで、mbedはリレーのカチカチというスイッチのタイミングを変化させ、また、残り時間を7セグLEDに表示させる。