LoginSignup
13

More than 5 years have passed since last update.

Pepperのタブレット用フレームワークTapperを使ってみました

Posted at

 Pepperのアプリ開発でタブレットを使用しなければならないときに、まず困るのは仕組みが違うことです。Choregrapheのボックスでもできるのですが、タブレットの座標値で制御するのは面倒ですし、もう1つの手段として、HTML/CSS/JavaScriptで作るにも1からだと大変です。
 何かいい資料はないかと探していたらアトリエ秋葉原さんの過去のイベント【アトリエ秋葉原】ディスプレイ(タブレット)技術勉強会株式会社ヘッドウォータースさんの資料にTapperというフレームワークが紹介されていましたので、今回使用してみました。

参考

こちらの資料を参考にさせていただきました。
 株式会社ヘッドウォータースさんの資料 Pepperディスプレイのちょっとしたコツ

注意事項

 ソフトバンクロボティクス株式会社のPepperを活用し、独自開発したものです。

環境について

今回使用した環境です。
MacOS Sierra 10.12.2
Choregraphe 2.4.3.28
Pepper
Tapper 0.3
Python 2.7.10

Tapperについて

pepper-devさんが公開されている。ディスプレイ側の開発用フレームワークです。
BSD-Licenceの下でライセンスされています。
http://pepper-dev.github.io/tapper/
ドキュメントも充実しています。

インストール

次のコマンドでTapperコマンドをインストールします。

sudo pip install tapper

テンプレートの作成

 TapperはPepperのタブレット用のテンプレートを生成してくれます。
 tapper create を実行すると、カレントディレクトリにテンプレートが生成されます。
 以下は3画面のテンプレートの作成例です。
 -sceneオプションに画面数を指定します。

tapper create --scene 3
Tapper create.
  Scene 3
    mkdir: ./html
    mkdir: ./html/css
    mkdir: ./html/js
    mkdir: ./html/img
    mkdir: ./html/img/preloads
    create: ./html/index.html
    create: ./html/css/contents.css
    create: ./html/css/normalize.css
    create: ./html/js/tapper.js
    create: ./html/js/contents.js
  Succeeded.

プロジェクトへの組み込み

 Choregrapheのプロジェクトに組み込みます。
 ビヘイビアの位置はルートに変更しておいてください。
tapper1.png

sceneについて

 Tapperでは画面のことをsceneと呼びます。
 先ほどのコマンドで生成されたhtmlがこちらです。idがscene1からscene3までのsectionが作成されていますす。 また、最初に表示されるのは、scene1です。

/html/index.html(一部)
    <body>
        <section id="scene1" style="display: block;">
        </section>
        <section id="scene2" style="display: none;">
        </section>
        <section id="scene3" style="display: none;">
        </section>
    </body>

sceneの切り替え方法

scene2に切り替える場合、Pythonでは次のように行います。

 self.memory = ALProxy("ALMemory")
 self.memory.raiseEvent("Tapper/View/ChangeScene", "2")

タッチイベントについて

初期化時にhtml内のdata-btn-id属性を持つ全てのノード対して、touchstart、touchendのイベントが自動で割り当てられます。

/html/js/tapper.js(一部)
Tapper.view = {
    init: function(){
        $(document).on('touchstart', '[data-btn-id]', function(){
            var node = $(this);
            node.addClass('touched');
        }).on('touchend', '[data-btn-id]', function(){
            var node = $(this);
            node.removeClass('touched');
            node.addClass('selected');
            Tapper.utl.raiseEvent("Tapper/View/ButtonTouched", node.attr('data-btn-id'));
        });
    },
  :

また、touchend時にTapper/View/ButtonTouchedのイベントが発火するので、このイベントに対しての処理を記述することで、画面がタッチされたとか、ボタンが押されたとかの処理に対応することができます。

画像のプレロードについて

画像のプレロード機能もあります。html/img/preloads配下にhtmlで使用する画像を配置し、tapper updateコマンドを実行すると、tapper.jsが書き換えられ、プレロードの処理が追加されます。

tapper update
Tapper update.
    load: omocha_robot.png
    create: ./html/js/tapper.js
  Succeeded.
/html/js/tapper.js(一部)
Tapper.core = function($) {

    // T.B.D
    var PROXY_LEN = 2;

    // image preload
    var _preload_img = function() {
        var image = [
        'img/preloads/omocha_robot.png'
        ];
        $.each(image, function(i, src) {
            $('<img>').attr('src', src);
        });
    }

初期データについて

 タブレット側に渡す初期データをALMemoryのTapper/InitData経由で渡すことができます。htmlロード時(Tapper.coreの初期化時)に行われるため、Show Appボックスの実行前にセットする必要があります。値はTapper.init_dataに保持されます。

        fileName = self.framemanager.getBehaviorPath(self.behaviorId) + "/init_data.json"
        try:
            import json
            with open(fileName, 'r') as f:
                init_data = json.load(f)
                self.memory.insertData("Tapper/InitData", json.dumps(init_data))
       :

contents.js

tapper.jsはtapperコマンドで置き換わってしまうので、基本的にはcontents.jsに処理を記述することになります。自動生成されたコードには、onLoad、onStart、onScene_[n]_の関数が用意されています。それぞれのイベント時にこれらの関数が実行されれるようになっていますので、画面表示時に何か動的に表示させたいなどといったことが記述できます。 

/html/js/content.js
// pepper contents

Tapper.contents = {

    onLoad: function() {
        console.log("onLoad.");
    },

    onStart: function() {
        console.log("onStart.");
    },

    onScene1: function() {
        console.log("onScene1");
    },

    onScene2: function() {
        console.log("onScene2");
    },

    onScene3: function() {
        console.log("onScene3");
    }
}

例:メニューボタンの文字列をinit_dataから設定する

/html/js/content.js
   onScene2: function() {
        console.log("onScene2");
        $("#s2-menu1").append("<p>" + Tapper.init_data["scene2"]["menu1"]["title"]+ "</p>");
        $("#s2-menu2").append("<p>" + Tapper.init_data["scene2"]["menu2"]["title"]+ "</p>");
    },

contents.css

スタイルシートです。テンプレート生成時は、html, body, sectionの定義しかないので、作成するコンテンツに合わせて追加する必要があります。

contetns.css

/* contents.css */

html, body, section {
  height: 100%;
  width: 100%;
}

サンプル

実際にTapperを使用して作成したサンプルアプリがこちらです。
https://github.com/piroku/TapperSample
(HTML/CCS/JavaScriptは得意ではないので、あくまで参考ということで・・)

TapperApp1.png

sceneごとの処理はそれぞれのボックスに分けた方が良いです。
scene1がタイトル、scene2がメニュー、scene3がメッセージを表示するような画面といったサンプルを作りました。

TapperApp2.png

sceneのボックスの例がこちらです。scene2はメニュー画面としています。Tapper/View/ButtonTouchedが発火したら、対応するメッセージを発話して、次のボックスに遷移します。

TapperApp3.png

bx_イベント連携(一部)
   def onInput_onStart(self):
        import json
        #データの取得
        data = self.memory.getData("Tapper/InitData")
        self.initdata = json.loads(data)
        #シーン2:メニュー画面の開始
        self.memory.raiseEvent("Tapper/View/ChangeScene", "2")

    def onInput_onTapperButton(self, p):

        if(p == "btn-menu1"):
            sayText = self.initdata['scene2']['menu1']['say'].encode('utf-8')
            self.onMenu1(sayText)
            self.onStopped()

        elif(p == "btn-menu2"):
            sayText = self.initdata['scene2']['menu2']['say'].encode('utf-8')
            self.onMenu2(sayText)
            self.onStopped()

また、ボタンの表現ですが、data-btn-id属性のノードには selected, touchedクラスが自動付与されるので、メニューの押した感じを少し表現してみました。

/html/css/contents.css
#scene2 .selected, #scene3 .selected {
    background-color:#4d639f;
}

#scene2 .touched, #scene3 .touched{
    position: absolute;
    top: 20px;
}

感想

Tapperを使用することで、HTML/CCS/JavaScriptが苦手な私でも、Pepperのタブレット連携をあれこれ悩まずに開発することができました。Choregraphe(Python)側との切り分けが明確なので、タブレット側と、Choregraphe側の分担開発もしやすいのではと思います。
Tapperは、素晴らしいフレームワークですので、ぜひ一度使用してみてください。

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13