カテゴリー別アーカイブ: センサ

HotS のミニマップみようツールの作成(5)

前回インストーラを作ってみて「今の実装だとインストーラで作った実行ファイルは起動できない」という現実を知ってしまったので、今回はとりあえずアプリが落ちないように調整します。
私は知っている、こういう自分の知ってる知識で作れる機能は集中して数日のうちに実装を終えてしまった方がいいことを…

まぁ、そんな数日集中できるほど元気はないので、少しずつやりましょう。集中すると疲れるし。

今回やろうと思っていることは

  • 効果音があるパスなどを格納する設定ファイルを作って Document に配置されるようにする。
  • 効果音がなくてもアプリが起動するようにする。
  • 視線検出デバイスが動作してなくてもアプリが起動するようにする。

です。
そして、今回変更したコミットはこれです。

https://bitbucket.org/satofumi/hots_tools/commits/b7c44a5412623a506adbcd65c0be3f139fdce322

オチとしては、アプリが起動しなかった理由は Tobii の tobii_stream_engine.dll がインストーラに含まれてなかったせい、でした。もっと早く気づきたかった。

ともあれ、アプリとしては適切に動作しませんが、インストールしたアプリが落ちないようにはなりました。

いい感じです。

HotS のミニマップみようツールの作成(4)

ぶっちゃけ、とりあえず最低限の動作をするようになってから進捗がないのもよくないなと思ったので、今回はインストーラを作ります。とはいえ、Visual Studio Installer のプロジェクトを作るだけです。ライセンスとかのファイルも次回以降に配置しようと思います。

https://bitbucket.org/satofumi/hots_tools/src/d237a3e83f476ff09e505db6b03ccbdda98f0840/hots_minimap_instructor/?at=default

そして、インストーラを作ってインストールできるのが確認できたところまでが、これです。インストールしたアプリを実行してみて気づいたことは

  • 見てね効果音、見たね効果音を指定がないとアプリが落ちる。
  • Tobii アイトラッキングのデバイスが起動してないとアプリが落ちる。

うん。
使ってみると実装がまだ全然終わってないことを実感できて良いですね。
次回はこのインストールしたアプリが落ちなくなる調整をしようと思います。

進捗があるの、大事。
いい感じだと思います。

HotS のミニマップみようツールの作成(3)

今回は、視線検出した結果に基づいてミニマップを見てないときに警告音を出力するあたりを実装します。

で、実装したメインのロジックはこのあたり。

        private void UpdateWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            int nextAudioPlayMsec = NoCheckMsec;
            var noCheckElapsed = new System.Diagnostics.Stopwatch();
            noCheckElapsed.Start();

            var previousGameState = state;
            while (!updateWorker.CancellationPending)
            {
                System.Threading.Thread.Sleep(20);
                
                if (IsLookingMinimap)
                {
                    if (nextAudioPlayMsec != NoCheckMsec)
                    {
                        okSound.Play();
                    }

                    noCheckElapsed.Restart();
                    nextAudioPlayMsec = NoCheckMsec;
                }
                else if (noCheckElapsed.ElapsedMilliseconds > nextAudioPlayMsec)
                {
                    warningSound.Play();
                    nextAudioPlayMsec += 2000;
                }
                ...
             }
        }

抜粋でないソースコードはこちら。 https://bitbucket.org/satofumi/hots_tools/src/cf889c6dc2389ea045709e29c03e4e7bf9093a75/hots_minimap_instructor/hots_minimap_instructor/MainWindow.xaml.cs?at=default&fileviewer=file-view-default

このコードでは、定期的に視線がミニマップの中にあるかをチェックした結果の IsLookingMinimap プロパティを利用して、「見てないね効果音」や「見たね効果音」を鳴らしてる。
定期的にポーリングしてるのが微妙によくないけど気にしないことにしたい。イベントトリガをがんがん使ったコードは私には読みにくいので。

で、ここまででとりあえずゲームで使えるレベルのツールにはなったので利用していこうと思う。
次回は、ゲームのロード中か死んでないかを判断するための処理をスクリーンショットから取得するあたりのコードを作成していこうと思う。

いい感じです!

HotS のミニマップみようツールの作成(2)

今回は Tobii Eye Tracking 4C から視線位置を取得するあたりを実装します。
で、作ったのがこれです。作ってみるとわかる。私は C# の勉強が不足している。 理解が Thread までで止まってて少し恥ずかしい。
https://bitbucket.org/satofumi/hots_tools/src/8548dbecc7af809faf053d7d173b2d73ce3afecf/hots_minimap_instructor/hots_minimap_instructor/EyeTracking.cs?at=default&fileviewer=file-view-default

まぁ、とりあえずこれで動くので良いことにする。気になったらまた修正すればいい。
次回は、この得られた視線情報を用いてミニマップの領域を見ているかどうかで警告音を鳴らすあたりを実装します。

HotS のミニマップみようツールの作成(1)

Heroes of the Storm というゲームが好きだ。好きだけど上手くない。
なので、上手くなるためのツールを作ろうと思う。
ゲーム画面のミニマップを見るのが重要だけど見てないことが多いので、ミニマップを5秒ほど見なかったら音を出して警告するツールを作る。

使うのは視線検出デバイスの Tobii Eye Tracking 4C で、.NET で C# なアプリケーシンを実装する。

仕様としては

  • ゲーム中にミニマップを5秒見ないことを検出したら警告音を数秒おきに鳴らす。
  • ミニマップを見ない状態からミニマップを見たら、いいね音を鳴らす。
  • ゲーム中とはゲームが開始して死んでない状態とする。

くらい。

まずは簡単なあたり、ゲームが始まったかどうかを検出するあたりから実装する。

最初の実装内容は

  • HotS のゲームが開始しているかを Path.Combine(Path.GetTempPath(), “Heroes of the Storm\\TempWriteReplayP1”) フォルダの有無で監視する。
  • ゲームが開始したら Tobii Eye Tracking 4C からの視線位置の取得を開始する。

を実装する。

で、とりあえずフォルダがあるかどうかを検出して状態遷移をし始めるあたりまで実装した。

https://bitbucket.org/satofumi/hots_tools/src/2a980fbeb6d7bec4c1ce739d84d4591b23390ec9/HotsMinimapInstructor/HotsMinimapInstructor/MainWindow.xaml.cs?at=default&fileviewer=file-view-default

いい感じだ。
次は、視線位置に基づいて音を再生するあたりを実装したい。

HTC Vive を使ったゲームを作りたい

体調がよくなってコーディングできる状態になったので HTC Vive のコーディングを開始した。

  • Steam VR Plugin ありがとう!
  • Update(), FixedUpdate() のどっちで何をすべきか忘れてるね!
  • Vive コントローラの操作をコンソール出力したいな。

ってあたりを調べながらやる。

Unity の Update(), FixedUpdate() のどっちを入力に使うべきかは検索したら下記ページがでてきた。 Google さんありがとう!

Unity 〜UpdateとFixedUpdateの違い〜

理解した内容を1行で書くと「Update() フレーム描画ごとに呼び出されて、FixedUpdate() は物理演算のときに呼び出されるから、物理演算の処理だけ FixedUpdate() に書こうね」だった。

SteamVR Plugin の SteamVR_TestThrow.cs のサンプルで入力処理を含めて全ての処理が FixedUpdate() に記述してあった理由はよく理解できてない。まぁ、気にせず進めようと思う。大丈夫、まだサンプルを作ってる段階じゃないか。動けばオッケーさ!

SteamVR の Prefabs フォルダにあった [CameraRig] をシーンに追加して、その Controller(left) / Model に下記 C# スクリプトをアタッチしたら動作した。
https://bitbucket.org/satofumi/vr_quest/src/21e36a750cf38cd01e5cbcabb862371682d1d519/vr_quest/Assets/Samples/ControllerSample_PrintInput.cs?at=default&fileviewer=file-view-default

楽しい!

SteamVR Plugin の使い方については下記ページを参考にした。
https://framesynthesis.jp/tech/unity/htcvive/

HTC Vive を注文したので、いろいろ準備することにした

知人宅で HTC Vive を体験させてもらって

「これは良いものだ!」

って思ったので、HTC Vive を注文した。
だが、PC に必要なスペックすら調べずに購入したので、調べたりしたことを書いていこうと思う。

調査前になんとなく理解していることは

  • 部屋を片付ける必要がある。
  • 5年前の PC ではなく、割とよさ気な PC を用意する必要がある。
  • 次世代の VR が発表されたら、それも買えばよい。

ということくらい。

HTC Vive の公式ページを見てみよう

見てみた。
トップページは英語だったけど、FAQ ページは日本語で表示された。

  • GPU:NVIDIA® GeForce® GTX 970 または AMD Radeon™ R9 290以上
  • CPU:Intel® Core™ i5-4590 または AMD FX™ 8350以上
  • RAM:4 GB以上
  • 映像出力:HDMI 1.4 または DisplayPort 1.2以上
  • USBポート:USB 2.0以上 1ポート
  • オペレーティングシステム:Windows® 7 SP1, Windows® 8.1以降、Windows® 10

(上記は http://www.htcvive.com/jp/support/faqs/GUID-ABA623FC-B51F-43F7-B2B5-D4C83A37C992.html より抜粋)

とりあえず、GPU と CPU は良い物を使え、という風に理解した。 それ以外は今どき USB 2.0 未満な環境は少ないだろうし、特に気にしないでよさそうだ。

次は、この要件を満たしたモデルの PC を買うか、今の PC の CPU, GPU を更新するかを決めないといけない。

使いたい GPU, CPU を決めて値段をまた調べたら続きを書こうと思う。

半田ゴテの電源入れたままにしてしまうのを何とかしたい (その2)

検討しなおした結果「消費電力を監視できるセンサを半田ゴテを主電源の根本に設置する」というので良い気がした。

F-PLUG
http://www.bsc.fujitsu.com/services/f-plug/

半田付けを行うテーブルの上にあるテーブルタップの根本にコレを使えば、消費電力を監視することで半田ゴテが使用中であることがわかるはず。

実際にそういうシステムを実現するとした場合、Bluetooth でもって ECHO NET を処理するあたりを用意する必要がある。

ECHO NET の実装としては GonyCSL がいくつかのライブラリを提供しているので、使うと楽かもしれない。
https://github.com/SonyCSL/OpenECHO

次の記事があるとしたら、このあたりのライブラリを使ってみた感想になると思う。 次の記事があれば。

記録済みデータのフォーマットを Ruby で変更する

あるツールを使ってデータを記録したが、ツールに手を加えたためにデータの互換性がなくなってしまったのを「互換性がないなら、スクリプトで変更すればいいじゃない」という作業の流れを書きだしたものが、この記事です。

どういう仕組みで何を記録したのか

LMS511 という平面の距離を計測できるセンサがあるのですが、そのセンサとの通信内容を全て記録しました。通信データの記録は LMS11 から距離データを取得するために C++ で実装した Lms_driver というクラスで行なっています。

この Lms_driver クラスは Connection インターフェースを継承させていて、Connection インターフェースはセンサに対する open, read, write を提供します。そのため、Connection インターフェースの中身を差し替えることで、センサからのデータ取得、センサからデータを取得しつつログを記録、ログからデータを読み出して再生、ということが実現できます。

lms_driver_usage_2013_1228

ただ、この仕組みでデータの記録と再生を実現しようとすると Lms_driver でセンサとの通信に使っているコマンドの順番を変えると記録済みのデータが再生できなくなる、という欠点があります。今回は、いろいろ機能を追加すべく Lms_driver を変更した結果、過去に記録したデータが再生できなくなってしまいました。

行う必要があること

過去の実装から変更した点は、センサに発行するコマンドを追加した程度なので、そのセンサからの応答を過去のデータに追加してしまえば O.K. です。

実際に行ったこと

LMS511 との通信は STX, ETX が付加された以外は普通の ASCII 文字列で行われるため、Ruby スクリプトを用いて必要な箇所を置換していくことにします。

具体的に行う処理は

  • 追加したコマンドぶんの応答を追加
  • データ取得コマンドの変更による、データ先頭のコマンド文字列の置換

くらいかな。
改めて書きだしてみると、大したことはないですね。作成するスクリプトの方針としては、引数で与えたファイルの内容を読み込んで、置換でどうにかすることにします。

まず、引数で与えたファイル名を読み出すあたりまでの実装は、こんな感じでしょうか?

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  original = File.open(log_file).read

  # コマンドの応答を追加する
  # !!!

  # 必要な置換を行う
  # !!!
}

次に、置換まわりのコードを追加します。(コードの一部の通信データを省略しています)

# -*- coding: utf-8 -*-
# LMS のログデータを変換するスクリプト

# 引数で渡されたファイルを順に処理する
ARGV.each { |log_file|
  converted = File.open(log_file).read

  # 最初のコマンド応答の部分を切り取る
  converted.sub!(/.+?/, "")

  # 必要な置換を行う
  converted.gsub!(/sRA/, "sSN")

  # 最初のコマンド応答を追加する
  converted = "sRA (省略) sEA LMDscandata 1" + converted

  # ファイル名を変更して出力する
  output_file = "converted_" + log_file
  File.open(output_file, "w").write(converted)
}

いつものことですが、実際に手を動かしてみると簡単です。
個人的には、面倒くさがらずに簡単ならもう少し早く取りかかれるようになりたいのですが「怠惰」はプログラマにとって美徳なので悩ましいところです。

まとめ

これからは怠惰な気持ちで楽することを考えつつも、実際には怠惰にならないようにする。