NAOqi(ver2系)用 独自モジュールの作成


## はじめに

* [NAOqi(ver1系)用 独自モジュールの作成](http://qiita.com/Suna/items/eb1eee88984a168c6489) の続きです。
* アルデバラン・アトリエ秋葉原で NAOqi ver2系の SDK をコピーさせて頂きましたので、改めて Choregraphe のバーチャルロボットで動作を確認してみました。
* SDK、Choregraphe 等のバージョンは以下のものになります。

| ツール                     | バージョン                  |
|:--------------------------|:--------------------------|
| C++ SDK                   | naoqi-sdk-2.0.5.3         |
| C++ SDK (cross toolchain) | mac64-atom-pub-v2.0.5.4   |
| Python SDK                | pynaoqi-python2.7-2.0.5.3 |
| Choregraphe               | 2.1.2.17                  |

## モジュールの作成

手順は [NAOqi(ver1系)用 独自モジュールの作成](http://qiita.com/Suna/items/eb1eee88984a168c6489) と同じになります。

若干、コードを修正しましたので、修正部分のみ以下に書きます。

### コードの修正

#### helloworld.h

make したところ、以下のエラーが出ました。

```bash
$ qibuild make -c mytoolchain

...

/path/to/sdk/include/boost/signal.hpp:17:4: warning: "Boost.Signals is no
      longer being maintained and is now deprecated. Please switch to Boost.Signals2. To disable
      this warning message, define BOOST_SIGNALS_NO_DEPRECATION_WARNING." [-W#warnings]
#  warning                  "Boost.Signals is no longer being maintained and is now deprecat...
   ^

...
```

   メッセージの通り BOOST_SIGNALS_NO_DEPRECATION_WARNING を定義しました。
   
```helloworld.h
$ head helloworld.h

#ifndef HELLOWORLD_H
#define HELLOWORLD_H

#define BOOST_SIGNALS_NO_DEPRECATION_WARNING

#include <boost/shared_ptr.hpp>
#include <alcommon/almodule.h>

...
```

#### helloworld.cpp

このファイルでも 他の #include より先に BOOST_SIGNALS_NO_DEPRECATION_WARNING が定義されているほうが良さそうなので、#include "helloworld.h" を最初に移動しました。

```helloworld.cpp
#include "helloworld.h"
#include <iostream>
#include <alcommon/albroker.h>
#include <alproxies/altexttospeechproxy.h>

...
```

#### CMakeLists.txt

make したところ、以下のエラーが出ました。

```bash
$ qibuild make -c mytoolchain

...

Linking CXX shared library sdk/lib/naoqi/libHelloWorldModule.dylib
Undefined symbols for architecture x86_64:
  "AL::ALTextToSpeechProxy::say(std::string const&)", referenced from:
      HelloWorld::sayHello() in helloworld.cpp.o
  "AL::ALTextToSpeechProxy::ALTextToSpeechProxy(boost::shared_ptr<AL::ALBroker>)", referenced from:
      HelloWorld::sayHello() in helloworld.cpp.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make[2]: *** [sdk/lib/naoqi/libHelloWorldModule.dylib] Error 1
make[1]: *** [CMakeFiles/HelloWorldModule.dir/all] Error 2
make: *** [all] Error 2
[ERROR]:  BuildFailed Error occurred when building project HelloWorldModule
```

リンク時の Undefined symbols なので、ライブラリパスに関する問題かなぁ、とコードや環境変数を変えていろいろ試してみていましたが、最終的には以下の修正となりました。

qi_use_lib の行に ALPROXIES を追加しました。(ドキュメントのサンプルコードにこんな記述があったのを思い出しました)


```CMakeLists.txt
...

qi_use_lib(HelloWorldModule ALCOMMON ALPROXIES)
```

### バーチャルロボットへのモジュールのインストール

#### インストール先のパスについて

今回の確認は Choregraphe のバーチャルロボットで行います。

```bash
export NAOQI_RUNTIME=/path/to/Choregraphe.app/Contents/Resources
```

モジュールのインストール(コピー)と autoload.txt の修正は、前回と同じになります。

## 動作確認

### Choregraphe 起動

ログビューアの表示レベルを変えても、モジュールのロード状況は表示されないみたいですね。

### 接続ポートの確認

**編集 > 設定 > バーチャルロボット(タブ)**

「ポート60736で動作中」の番号を確認しておきます。

### ALProxy 経由でモジュールに接続してメソッド実行

```bash
$ /usr/bin/python
Python 2.7.6 (default, Sep  9 2014, 15:04:36)
[GCC 4.2.1 Compatible Apple LLVM 6.0 (clang-600.0.39)] on darwin
Type "help", "copyright", "credits" or "license" for more information.

>>> from naoqi import ALProxy

>>> hwm = ALProxy("HelloWorldModule", "localhost", 60736)
[I] 3343 qi.eventloop: Creating event loop while no qi::Application() is running
[I] 3343 qimessaging.session: Session listener created on tcp://0.0.0.0:0
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://10.168.19.164:60743
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://127.0.0.1:60743
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://10.211.55.2:60743
[I] 3343 qimessaging.transportserver: TransportServer will listen on: tcp://10.37.129.2:60743

>>> hwm.sayHello()
```

sayHello メソッド実行後、バーチャル Pepper くんが「HelloWorld」と言いました。

![2015010801.png](https://qiita-image-store.s3.amazonaws.com/0/20418/a9cb7dec-b89a-1b20-95ca-978cf6680dce.png "2015010801.png")

### Choregraphe 内の Python Script ボックスから実行

次に Choregraphe 内から作成したモジュールを使用してみます。
Python Script ボックスを配置し、コードを書いて実行。上と同じようにバーチャル Pepper くんが話します。

![2015010802.png](https://qiita-image-store.s3.amazonaws.com/0/20418/ea437990-26f6-961c-f7b8-14bb473e5c25.png "2015010802.png")

## 感想

* 標準出力に出した文字列は Choregraphe のログビューアに表示されないので、ロガーのオブジェクト経由で出力するような感じになるのでしょうか。そういえば、サンプルコードでそんなのを見た気もします。
* モヤモヤしていた点がいろいろ解決したので、割とすっきりしました。