Choregraphe だけじゃない NAOqi。高速をローカルに、NAOqi C++ SDK 2.5.5 を使ってみる

# 概要
Pepperのアプリ開発、グラフィカルな開発環境でアプリ開発が可能な Choregraphe を使うのが一般的ですが、開発ツールのダウンロードサイト (https://developer.softbankrobotics.com/jp-ja/downloads/pepper) を見るとそれ以外にも選択肢があることがわかります。　ここではその中でもおそらく最も「マイナー」な C++ SDK の使い方を紹介し、これがどういったユースケースにおいて有効か見ていきたいと思います。 

# 対象
この記事は Choregraphe などなんらかの Pepper のアプリ開発環境を利用したことがある方を対象としています。 また C/C++ のプログラミングの経験があればこの記事を参考に自ら新しいアプリを作ることができるようになると思いますが、経験がない方でも作業概要とどういった場面で使うテクニックなのかということは記事を通して理解することができると思います。Pepper のアプリ開発の基本は[アトリエ秋葉原](https://pepper.doorkeeper.jp/)の[ワークショップの資料](http://pepper-atelier-akihabara.jp/archives/439) などが参考になるかと思います。

# NAOqi 各SDK、Choregraphe その関係

[Pepper 開発ツールのダウンロードサイト](https://developer.softbankrobotics.com/jp-ja/downloads/pepper)を見ると Pepperのアプリ開発には４つの選択肢があることがわかります、ChoregrapheまたはPython、C++、JavaのいずれかのSDKです。それぞれの特徴を簡単にまとめてみました。 なお、開発環境の選択肢は正確にはもう一つ Android SDK というのがPepperの開発SDKとしてひかえていますが、こちらは現行のPepperでは動かないので、調査の対象から外しています。 

|      | Choregraphe | Python SDK | C++ SDK | Java SDK |
|:-----|-----|-----|-----|-----|
| プログラムのPepper本体での実行 | ○ | ○ | ○ | × (Pepper本体にJavaランタイムをインストールできれば可能と思われるが、標準の方法はなし) |
| プログラムのPCでの実行 | × (再生ボタンでの実行は開発中のプログラムがその場でパッケージされてPepper本体に送られ、実行されているだけで、PCでプログラムを実行しているわけではない) | ○ | ○ | ○ |
| プログラミングのしやすさ(1-5)(5が最も簡単)| 5 | 4 | 2 | 3 |
| 処理速度(1-5)(5が最速) | 2 | 3 | 5 | 3 |
| NAOqiバージョンアップへの耐性(1-5)(5が最も容易)  | 4 | 4 | 1（リビルドなど必要） | 2(移植に関する情報が不整備) |
| 特徴 | ビジュアルな環境でプログラミング。ロジックは Python コードで | Python プログラムから NAOqi の各 API にアクセス。| C++ プログラムから NAOqi の各 API にアクセス。PC上で動く実行ファイル、Pepper本体上で動く実行ファイル、いずれも作成可能 | Java プログラムから NAOqi の各 API にアクセス。使い方に関する情報がいまいち整っていないかも　|
| 利点 | プログラミングの知識がない人から、プログラミングができる人まで、誰でも簡単にアプリ開発ができる | Pythonプログラミングができる人であれば、簡単にアプリ開発可能。PCでプログラムを動かし、遠隔操作でPepperを動かすことができるので、PC上で動く高度なPythonライブラリーなどとの連携が容易。 作成したPythonコードはChoregarapheとも親和性が高い | ネイティブコードで高速処理、OpenCV などを利用できるので、画像を解析する処理など比較的処理時間のかかるロジックをPepper本体で実行させることができる | Javaプログラミングができる人であれば、簡単にアプリ開発可能 |
| 欠点 | ボックスが増えると動作が不安定になりがち。複雑なアプリを安定稼働させるには様々な「コツ」が必要。画像の解析処理など、重たい処理をさせるには不向き(重たい処理はクラウドにさせるというのが常套手段) | 画像の解析処理など、重たい処理をさせるには不向き(重たい処理はクラウドにさせるというのが常套手段) | NAOqi OS のバージョンに依存しやすい（例えば NAOqi 2.5.5 のPepper本体で動くようビルドされたプログラムは NAOqi 2.4.3 のPepper では動かないなど）。 | 情報が不足している。 Pepper本体で動かすのは困難 |
     
# 前提条件
ここではLinux PCを使って開発環境のセットアップからプログラムのビルド、実行まで試しています。記事の内容は次の構成で動作確認をしています

- 開発 PC: Ubuntu 16.04 LTS 64bit
- ターゲットロボット(Pepper)： NAOqi 2.5.5 (Beta)
 
(※ NAOqi 2.5.5 はこの記事の執筆時点（2017/4/3)ではβ版です。最新の状況は [Pepper デベロッパーポータルサイト](https://developer.softbankrobotics.com/jp-ja/) を確認ください）

- 対象SDK： NAOqi C++ SDK Cross Toolchain 2.5 Linux 64(Beta)

# NAOqi C++ SDK をセットアップする
次にNAOqi C++ SDK のセットアップ手順を示します

### 1. CMake をインストール
NAOqi C++ SDK の開発環境はソースコードビルドツールとしてオープンソースのビルド環境 CMake を利用しています。まずこの ツールをインストールしておきます。次のコマンドを実行します

```
sudo apt-get install cmake
```

### 2. qibuildツールをインストール
NAOqi C++ SDK は qibuild という独自のコマンドラインベースの開発環境を提供しており、これを利用して一連の作業を行います。qibuildツールのインストールは次のようにして行います。

```
pip install qibuild --user
```
（pip コマンドの実行でエラーになった場合、pip コマンドがインストールされていないからかもしれません。この場合 sudo apt-get install python-pip と実行して pip コマンドをインストールします）

qibuild のインストールは --user オプションを指定してユーザー領域に行っています。　インストールされる場所はホームディレクトリ配下の .local/bin です。ターミナルを開くたびに自動的にこのインストール先にパスが通るように起動スクリプトを書き換えておくといいと思います。例えばこんな感じでコマンドを実行して起動スクリプトを書き換えます。

```
echo 'PATH=$PATH:$HOME/.local/bin' >> ~/.bashrc 
```

なお、これを実行したターミナルはまだパスが通っていませんので、次のコマンドで起動スクリプトを再読み込み、変更を現在のターミナルに反映させます

```
source ~/.bashrc 
```

### 3. qibuild ツールの基本設定
qibuild がビルドのために吐き出すコードと連携するIDEツールを設定します。 今回はそれぞれデフォルトの設定を選択します。

```
qibuild config --wizard
```

次のように表示されると思いますのでそれぞれデフォルトの 1 を入力して設定を済ませます。

```
Found CMake: /usr/bin/cmake
:: Please choose a generator
   1 Unix Makefiles 	(default)
   2 Ninja
   3 Watcom WMake
   4 CodeBlocks - Ninja
   5 CodeBlocks - Unix Makefiles
   6 CodeLite - Ninja
   7 CodeLite - Unix Makefiles
   8 Eclipse CDT4 - Ninja
   9 Eclipse CDT4 - Unix Makefiles
   10 KDevelop3
   11 KDevelop3 - Unix Makefiles
   12 Kate - Ninja
   13 Kate - Unix Makefiles
   14 Sublime Text 2 - Ninja
   15 Sublime Text 2 - Unix Makefiles
> 1
:: Please choose an IDE
   1 None 	(default)
   2 QtCreator
   3 Eclipse CDT
> 1
```

### 4. NAOqi C++ SDK をダウンロード
CMake はビルドツールであり、qibuild は開発環境です。 ここでは開発環境が扱う開発キット（SDK）をダウンロードし、qibuild から扱えるようにします。開発環境と開発キットが別々なのは面倒に思えはしますが、これらが分かれていることで、例えば、PC上で動く実行ファイルを作るためのSDK、ロボット上で動く実行ファイルを作るためのSDK、他のロボットのためのSDKが別々にあり、開発環境であるqibuildツールは同じままSDKを切り替えるだけでそれぞれに対応できるようにしています。

SDKダウンロードページにアクセスし、SDKをダウンロードしてきます。

https://developer.softbankrobotics.com/jp-ja/downloads/pepper

今回ダウンロードするのは Other SDKs and Utilities -> C++ -> 2.5.5 -> Linux にある 「Cross Toolchain 2.5 Unix 65(Beta)」です

![Screenshot_from_2017-03-31_10-22-04.jpg](https://qiita-image-store.s3.amazonaws.com/0/81650/59f42d6e-488a-51b6-699e-40cea58b4be7.jpeg)

（なお、C++ カテゴリには他にも各プラットフォームごとの SDK がありますが、これらはその「ターゲットプラットフォームで動く」プログラムを生成します。対してCross Toolchainは「ロボット本体で動く」プログラムを生成します。）

ファイルは zip ファイルとしてダウンロードされます。適当なディレクトリを作り、そこにダウンロードしたファイルを解凍し保存します。ここではホームディレクトリに naoqi というディレクトリを作り、ここにダウンロードしたファイル(ctc-linux64-atom-2.5.2.52.zip)を展開しています。

```
mkdir ~/naoqi
cd ~/naoqi
mv ~/Downloads/ctc-linux64-atom-2.5.2.52.zip  .
unzip ctc-linux64-atom-2.5.2.52.zip
```
（ダウンロードしたファイルが~/Downloads配下に保存されていると想定しています）

### 5. SDK をツールチェインとして登録する
ダウンロードした SDK をツールチェインとしてシステムに登録します。ツールチェインは qibuild において、ソースコードをビルドするときに扱われるコンパイラや依存ファイルなどの一式で、各 SDK にはこのためのファイルが収録されています。登録のために次のように実行します。

```
qitoolchain create mytoolchain ~/naoqi/ctc-linux64-atom-2.5.2.52/toolchain.xml 
```

これにより　「mytoolchain」　というツールチェインとして、今回ダウンロードした SDK が登録されました。

以上でセットアップの作業は終了です。

# サンプルプログラムを作成し、実行ファイルを生成してみる
次にサンプルプログラムを一つ作ってみたいと思います。今回作成するプログラムはNAOqiの中で「サービス」と呼ばれるものです。 NAOqiの中で「サービス」とは常駐型のプログラムの事を示しており、今回作るプログラムは一度実行されると、終了要求を受け取るまで、他のプログラムからの呼び出しを待ち続け、呼び出しに応じて都度、要求を処理します。

### 1. ワークツリーを作成する
まず qibuild の開発環境をセットアップします。これはワークツリーと呼ばれ、qibuild で作業を行うベースとなるディレクトリです。ここではホームディレクトリ直下に worktree というディレクトリ名のワークツリーを作成します。次のように操作します。

```
mkdir ~/worktree
cd ~/worktree/
qibuild init
```

qibuild init コマンドが現在のディレクトリに対してワークツリーとしての初期設定を行っています。(これにより .qi というディレクトリが作られ、配下にワークツリーとしての設定ファイルが管理されます）

### 2. mytoolchain を qibuild に登録する
前のセクションで登録した 「mytoolchain」 を今度は qibuild に登録します。またこれを(実行時オプションで --default を指定することで) qibuild のデフォルトのツールチェインにします。

```

qibuild add-config mytoolchain -t mytoolchain --default

```

### 3. プロジェクト helloworld を作成する
一つのプログラムの単位は一つのプロジェクトで管理され、プロジェクトは一つのワークツリーの中に複数存在できます。ワークツリーが作業場所で、プロジェクトはこの作業場所で実際に作られる一つ一つの製品というイメージです。 ROS など他のロボットOSの開発環境も似たような開発環境の構成を採用しており、複数のコンポーネントから構成されることが多いロボットOSの開発環境における一つの王道と言えるのかもしれません。

先ほど作成した worktree ディレクトリにいるとして、次を実行し、今回のプログラム用のプロジェクト helloworld 用のディレクトリを作成、ここに移動します。

```
mkdir helloworld
cd helloworld
```

次にプロジェクトに必要なファイルを編集します。必要なファイルは qiproject.xml と CMakeLists.txt　です。 gedit などのテキストエディタを用いてそれぞれ次のように編集します。

```xml:qiproject.xml
<!-- in qiproject.xml -->
<project version="3">
  <qibuild name="helloworld">
    <depends runtime="true" buildtime="true" names="libnaoqi" />
  </qibuild>
</project>
```

```cmake:CmakeLists.txt
cmake_minimum_required(VERSION 2.8)

project(HelloWorld)
find_package(qibuild)
include_directories(".")
qi_create_bin(HelloWorldService 
   SRC main.cpp helloworld.h helloworld.cpp
   DEPENDS BOOST QI)
```

ここではそれぞれのファイルについて詳細は説明しません。重要なポイントは qiproject.xml の \<depends\> 要素で依存ライブラリを指定しているところと、CmakeLists.txt の qi_create_bin でコンパイルするファイルを列挙しているところです。さらに詳しく知りたい方はこの辺りのドキュメントを参照されるといいでしょう。

qiBuild CMake API : [http://doc.aldebaran.com/qibuild/advanced/cmake/api.html] (http://doc.aldebaran.com/qibuild/advanced/cmake/api.html)
qiproject.xml syntax : [http://doc.aldebaran.com/qibuild/advanced/cfg/qiproject_xml_syntax.html](http://doc.aldebaran.com/qibuild/advanced/cfg/qiproject_xml_syntax.html)

### 4. ソースコードを作成する

ここでは HelloWorldService というサービスのプログラムを作成します。作成した helloworld ディレクトリファイル配下に次の３つのファイルを作成、保存します。

HelloWorldService サービスプログラムのヘッダファイル

```cpp:helloworld.h

#include <qi/anyobject.hpp>
#include <qi/applicationsession.hpp>

class HelloWorldService
{
public:
  HelloWorldService(qi::SessionPtr session);

  std::string say() const;

  int sayNumber(int i);

private:
  qi::SessionPtr _session;
};
QI_REGISTER_MT_OBJECT(HelloWorldService,say,sayNumber); // QI_REGISTER_MT_OBJECT for multithread support. QI_REGISTER_OBJECT for single thread

```

HelloWorldService サービスプログラムの実装

```cpp:helloworld.cpp

#include "helloworld.h"

HelloWorldService::HelloWorldService(qi::SessionPtr session)
  : _session(session)
{
}


std::string HelloWorldService::say() const
{
	std::cout << "say method called.\n";
	qi::AnyObject  tts = _session->service("ALTextToSpeech");

	std::string message = "ハローワールド";
	tts.call<void>("say", message);
	return message;
}

int HelloWorldService::sayNumber(int i) 
{
	std::cout << "sayNumber method called.\n";
	qi::AnyObject  tts = _session->service("ALTextToSpeech");

	tts.call<void>("say", std::to_string(i));
	return i;
}

```

HelloWorldService サービスプログラムの実行を開始する main関数

```cpp:main.cpp

#include <qi/applicationsession.hpp>
#include <boost/shared_ptr.hpp>
#include "helloworld.h"

int main(int argc, char* argv[])
{
  qi::ApplicationSession app(argc, argv);
  app.start();
  qi::SessionPtr session = app.session();
  session->registerService("HelloWorldService", qi::AnyObject(boost::make_shared<HelloWorldService>(session)));
  app.run();
  return 0;
}

```

### 解説
簡単に説明します。NAOqi OS では、サービスプログラムとして定義した一つの C++ クラスが、一つの「NAOqi OSから操作できるオブジェクト」として、インスタンス化されその後、消滅せずに動き続けます。ここの例ではこの NAOqi OS への登録と常駐化は main 関数の次の部分で行っています。

```cpp:
  qi::SessionPtr session = app.session();
  session->registerService("HelloWorldService", qi::AnyObject(boost::make_shared<HelloWorldService>(session)));
  app.run();
```

インスタンス化、常駐化は独立した一つのプロセスとして行われ、NAOqi 上で動く他のプログラムはここにプロセス間通信などの通信の仕組みを使ってアクセスします。この通信のとこについて特別なコーディングは必要ありません。helloworld.h　にある次のマクロが自動的に通信部分の実装を解決してくれます。ここで ( ) の一番最初に指定しているのが NAOqi に公開するクラスのクラス名、そのあとに続くのが、NAOqi に公開するクラス内のメソッドやインスタンス変数です。ここでは say と sayNumber という 2つのメソッドを公開するよう宣言しています。

```
QI_REGISTER_MT_OBJECT(HelloWorldService,say,sayNumber); // QI_REGISTER_MT_OBJECT for multithread support. QI_REGISTER_OBJECT for single thread

```

このクラスオブジェクトを NAOqi に公開するためのマクロには QI_REGISTER_MT_OBJECT と QI_REGISTER_OBJECT の２種類があります。違いは MT がつく方はマルチスレッド処理に対応し、 MT がつかないほうは NAOqi との通信を単一スレッドで行うという点です。

say メソッドは呼ばれると NAOqi の ALTextToSpeech API にアクセス、そこの say メソッドを呼び出し、「ハローワールド」と発話させています。

```cpp

std::string HelloWorldService::say() const
{
	std::cout << "say method called.\n";
	qi::AnyObject  tts = _session->service("ALTextToSpeech");

	std::string message = "ハローワールド";
	tts.call<void>("say", message);
	return message;
}
```

ここの例にあるように _session が格納する　qi::SessionPtr　にアクセスし（これはインスタンス作成時に渡されている）、そのサービスメソッドにアクセスすることで、各 NAOqi API にアクセスすることができます。また、実は NAOqi が標準で提供する各種APIも実はサービスとして公開されているもので、それにアクセスしているというのがここのコードであり、つまり、自身で作成、NAOqi に登録公開したサービスにも同じようにしてアクセスすることができます。例えば別の C++ プログラムがあったとして、そのプログラムは次のような感じで上記のコードを呼び出すことができます。

```cpp

	qi::AnyObject  helloWorld = _session->service("HelloWorldService");
	helloWorld.call<void>("say");

```  

より詳しくは次のページが参考になると思います。

C++ - How to write a qimessaging client　: http://doc.aldebaran.com/libqi/guide/cxx-client.html
Registering types in the type system : http://doc.aldebaran.com/libqi/guide/cxx-register-types.html

### 5. ビルドする
さてビルドしてみましょう。 qibuild ツールを使ったビルドの方法は次の通りです。

```
qibuild configure
```
これでビルドに必要な各種ファイルが生成されます。

```
qibuild make
```
これにより実際コンパイラが動作し、実行ファイルが生成されます。今回生成されるのは Pepper 本体で実行できる実行ファイルです。

ビルドがうまくいくと build-*ツールチェイン名*/sdk/bin 配下に実行ファイルが作成されます。今回の例ではこれは build-mytoolchain/sdk/bin です。
 
# サンプルプログラムを動かしてみる

サンプルプログラムは Pepper 本体でのみ動作します。生成したファイルを Pepper 本体に送り動作確認をしてみましょう。この次のセクションでは作成したプログラムを Choregraphe のプロジェクトに取り込む方法を説明しますが、まずは簡易的に Pepper 本体にログインをして動作を確認してみます。

### 1. ファイルを Pepper 本体に送る
生成された実行ファイルは build-mytoolchain/sdk/bin 配下にあります。ファイル名は HelloWorldService です。 scp コマンドでこれを Pepper 本体に送りましょう

```
scp HelloWorldService nao@<PepperのIPアドレス>:./
```
（パスワードはデフォルトは nao、Pepper 設定時、任意の文字列を設定した場合、その文字列です）

### 2. Pepper 本体にログインする

SSH で Pepper 本体にアクセスします。

```
ssh nao@<PepperのIPアドレス>
```
（パスワードはデフォルトは nao、Pepper 設定時、任意の文字列を設定した場合、その文字列です）

### 3. プログラムを実行する

まずファイルが正しく転送されているか確認してみましょう。 ls コマンドでファイルをリストし、ファイル HelloWorldService が保存されていることを確認します。

```bash
pepper001 [0] ~ $ ls -lrt
total 2700
drwxr-xr-x 3 nao nao    4096 Sep  1  2016 naoqi
drwxr-xr-x 2 nao nao   12288 Apr  3 10:39 diagnosis
-rwxr-xr-x 1 nao nao 2743720 Apr  3 18:53 HelloWorldService
```

./HelloWorldService として実際実行してみます。こんな感じの表示になると思います。

```bash
pepper001 [0] ~ $ ./HelloWorldService 
[I] 1491213486.380948 3722 qimessaging.session: Session listener created on tcp://0.0.0.0:0
[I] 1491213486.381813 3722 qimessaging.transportserver: TransportServer will listen on: tcp://127.0.0.1:33380
[I] 1491213486.381874 3722 qimessaging.transportserver: TransportServer will listen on: tcp://198.18.0.1:33380
[I] 1491213486.381971 3722 qimessaging.transportserver: TransportServer will listen on: tcp://192.168.1.69:33380
```

コンソールは戻ってこないのが正解です。プログラムは NAOqi OS に登録され、NAOqi OS からのリクエストを待っています

### 4. qicli 経由でサービスにアクセスする
Pepper のコマンドターミナルには qicli という NAOqi OS とのインターフェースを持つ非常に便利なツールが入っています。これを使って今回作成したサービスを呼び出してみましょう。

上記で起動したプログラムは止めないでください。 新しいターミナルを Linux 上で開き、このターミナルから再度 Pepper にアクセスします。

```
ssh nao@<PepperのIPアドレス>
```
（パスワードはデフォルトは nao、Pepper 設定時、任意の文字列を設定した場合、その文字列です）


次のコマンドを入力します。サービスが呼び出され、Pepper は「ハローワールド」と発話すると思います。

```
qicli call HelloWorldService.say
```

コマンド終了後

```
"\u30CF\u30ED\u30FC\u30EF\u30FC\u30EB\u30C9"
```

といった出力が表示されます。これは喋った言葉 「ハローワールド」 が return で返ってきたもので、これがユニコードのコードとして出力されています。

次に sayNumber メソッドを呼んでみます。これは数値型の引数を一つ持ち、Pepperは与えられた数値を発話します。

```
qicli call HelloWorldService.sayNumber 8
```

発話が終了するとターミナルに 8 と表示されます。これは与えられたパラメータを return で返しているからです。

HelloWorldService　を呼び出したターミナルを見てみてください。次の２行が表示されていると思います。

```
say method called.
sayNumber method called.
```

これはサービスプログラムが標準出力に出力した文字列で、標準出力の内容はこのようにサービスを呼び出したプロセス側に出力されます。

全て終わったらサービスプログラムを起動したターミナルは [Ctl] + c　を押してサービスを停止します。次はターミナルからの起動なしでサービスを立ち上げる方法を試してみます。

# サンプルプログラムを Chorerapeh のプロジェクトに取り込んでみる
qicli で動作の確認はできましたが、scp でファイルを送ったり、コマンドから呼び出したりとあまり実践的な方法ではありませんでした。
ここではサービスプログラムを Choregraphe のプロジェクトに取り組み、Choregarphe 経由でインストールができ、実行ができるようにしようと思います。

### 1. Choregraphe 2.5.5 でプロジェクトを作成
Choregraphe で新規にプロジェクトを作成し、ここに bin というフォルダーを作成、この中に今回作成したサービスプログラム HelloWorldService を保存します。 ここまで終わると Choregraphe の画面はこんな感じになっていると思います。

![Screenshot_from_2017-04-03_19-39-26.jpg](https://qiita-image-store.s3.amazonaws.com/0/81650/c6482d2f-0f62-4c35-6fa9-ae4e0b2f676c.jpeg)

### 2. manifest.xml を編集
Choregraphe プロジェクトの manifest.xml をテキストエディタなどで編集します。

```xml:manifest.xml
<?xml version='1.0' encoding='UTF-8'?>

    :           :

  </behaviorContent>
 </contents>
 <services>
  <service name="HelloWorldService" autorun="true" execStart="bin/HelloWorldService"/>
 </services>
</package>
```

\<service\> 要素を \</contents\> の下に追加しています。
ここで name 属性の値が NAOqi に公開するサービスの名前、execStart 属性の値が実行するファイルの名前です。 binフォルダーの中に HelloWorldService プログラムを保存したのでこの記述になっています。 

autorun 属性はサービスを自動起動するかどうかの設定で、true の時、Pepper が起動されるたびにサービスは自動起動され、常駐します。ここでのサービスの常駐はそれを内包している Choregraphe のプロジェクトのアプリが起動しているかどうかにかかわらず行われます（つまりアプリ自体が起動していなくても、autorun が true のサービスは常に動いている）。

これが false の時、サービスは自動起動されず次のような Python コードを Choregraphe のアプリなどで実行することにより起動させることができます。

```py:Choregraphe内のプログラム(Python)
serviceManager = self.session().service('ALServiceManager')
serviceManager.startService("HelloWorldService")
```

常駐しているサービスの停止は次のようにします。

```py:Choregraphe内のプログラム(Python)
serviceManager.stopService("HelloWorldService")
```

サービスが動いているかどうかの確認は次でできます。

```py:Choregraphe内のプログラム(Python)
if serviceManager.isServiceRunning("HelloWorldService"):

```
### 3. Choregraphe アプリからサービスを呼び出す

そしてサービスの中のメソッドの呼び出しはこんな感じでできます。

```py:Choregraphe内のプログラム(Python)

helloworld = ALProxy("HelloWorldService")
helloworld.say()
helloworld.sayNumber(100)

```

簡単ですね。サービスへのアクセスの考え方自体は、サービスがC++で動いていようとPythonで動いていようと変わりません。独自で作成したサービスの扱い方については次も参考になると思います。

Choregraphe プロジェクトの中にカスタムサービスを組み込む : http://qiita.com/tkawata1025/items/541f72074c80523c0848

# まとめ

ここでは、NAOqi C++ SDK の使い方について説明しました。
C++ SDK は OpenCV のライブラリなどを標準で搭載しており、例えば高度な画像処理をPepper本体内だけで処理することができるかもしれません。 SDK の toolchain.xml ファイルを見ると SDK は標準で次のライブラリを搭載しているようです。これらを使う C/C++ プログラムは比較的簡単に開発できますし、ここにないライブラリを使うものも CMake ファイルを適切に編集すれば取り組むことができると思います。

| ライブラリ名 |
|--- |
| acl |
| alsa |
| archive |
| attr |
| avahi |
| bfl |
| boost |
| bzip2 |
| c_ares |
| cgos |
| chunkware_simple_dynamics |
| console_bridge |
| curl |
| dbus-1 |
| dbus-glib-1 |
| dl |
| eigen3 |
| ffi |
| ffmpeg |
| flac |
| fuse |
| gdbm |
| glib2 |
| gstreamer |
| gstreamer-farsight |
| gtest |
| iconv |
| icu |
| idn |
| jpeg |
| json-c |
| libalmath |
| libalmathinternal |
| libasyncns |
| libevent |
| libftdi1 |
| liblttng_ust |
| libnaoqi |
| libqi |
| libqi-capi |
| libtheora |
| libtool |
| liburcu |
| lttng_tools |
| lz4 |
| octomap |
| ogg |
| opencore-amr |
| opencv2 |
| openni2 |
| openssl |
| opus |
| pam |
| pcre |
| png |
| pthread |
| pulseaudio |
| python |
| qiprobes |
| qt |
| rosbag |
| rt |
| samplerate |
| sndfile |
| soprano |
| soundtouch |
| speex |
| sqlite3 |
| systemd |
| tbb |
| tcp-wrappers |
| telepathy-farsight |
| telepathy-glib |
| tiff |
| tinyxml |
| trousers |
| urg |
| usb_1 |
| v4l |
| vo-aacenc |
| vo-amrwbenc |
| vorbis |
| xml2 |
| xz_utils |
| zbar |
| zlib |

サービスとして作った C/C++ プログラムは Python からも簡単に呼び出すことができます。
アプリの中でここはローカルで特別に高速に処理をしたい、というものがあれば C++ SDK はそれに対する選択肢になりえます。

実際には、例えば NAOqi のバージョンが上がるとそれに伴って NAOqi OS のカーネルバージョンが変わる場合もあり、ネイティブコードは再ビルドをしなければ動かなくなる可能性があり、メインテナンスには他のSDKを使うより、より手間がかかる可能性があります。

いくつか考慮すべき欠点はあるにせよ、同じことをするなら処理速度は最速です。また実装コードの隠蔽手段の一つとして使うこともできるかもしれません。この記事が Pepperのアプリ開発を行う際の一つの選択肢として C++ SDK も考えられるきっかけになれたとすると幸いです。