Tech Sketch Bucket of Technical Chips by TIS Inc.

ROS + Dockerを使ったロボットアプリケーション入門(2)実践編  ~Pepperでディープラーニングを使った画像識別に挑戦~

Pocket

前回の記事ROS + Dockerを使ったロボットアプリケーション入門(1)準備編では、ロボット用フレームワークであるROSの簡単な説明と、ROSをDocker環境で使う際に役立つ情報を紹介しました。

今回は、前回の内容を踏まえ、実際にROSのDockerイメージを使って、今話題のPepperを動かしてみます。具体的には、話題のディープラーニングを画像解析に応用した"Caffe"というフレームワークによって、Pepperの目の前にある物体を識別をさせて、識別結果をPepperに英語で喋らせてみたいと思います。ROS + Dockerというタイトル通り、これらをROSとDockerを用いて実現します。

では、さっそく始めてみましょう!

top_

作成するアプリケーションの概要

では、今回紹介するアプリの全体の概要図を以下に示します。

architecture

まず、Pepperが自身の頭部のRGBカメラで周辺を撮影します。それを、Dockerコンテナ1で取得します。 次に、コンテナ1で取得した画像を、ROS経由でコンテナ2に渡します。Dockerコンテナ2では、Caffe動作しており、物体の識別が行われます。この結果(上位5件)をコンテナ1に返します。 コンテナ1は識別結果からもっとも推定値の高いものを選び、Pepperに識別結果を英語で喋らせます。

Pepper開発では、Choregrapheを使って開発するのが一般的ですが、今回は使わずに作成してみます。

アプリケーションの内部処理の詳細

では、もう少し詳しく処理の流れを確認しておきます。下図で説明します。

architecture_detail

注目すべきROSノードは、Pepperノード、Caffeノード、発話文生成ノードです。そして、赤の矢印で表したROS通信部分が注目すべきデータの流れです。

Pepperノードは、内部でNaoqi SDKを使ってPepperの機能を呼び出しており、ブリッジの役割を果たします。クライアントPC上のPepperノードにより、Pepper本体から入力画像を得て、その画像をROSのデータ型としてPublishします。

Publishされた画像は、CaffeノードがSubscribeします。Caffeノードは内部でCaffeを呼び出すことでROSブリッジの役割を果たし、識別結果(上位5つ)を文字列としてPublishします。

このトピックを、発話文生成ノードがSubscribeして、最も確信度の高いラベルを選び、文字列としてPublishします。

Publishされた文字列をPepperノードがSubscribeして、内部のNaoqi SDK経由でPepper本体がしゃべる、という流れです。

既に用意されているPepperのROSブリッジを使うため、Naoqi SDKを使ったプログラム(水色の矢印)を独自に実装する必要はありません。

使用するDockerイメージ

次に、上記の二つのコンテナを実行するために使用する2つのDockerイメージの詳細を説明します。各イメージの構成要素は下図です。

required_images

どちらも、前回使用したosrf/ros:indigo-desktop-fullをROSのベースイメージとして使用します。 それに追加してイメージ1には、Naoqi SDKと、ROSでNaoqi SDKを介してPepperを制御できるROSパッケージ群をインストールします。 イメージ2には、画像識別するためのディープラーニングフレームワークであるCaffeと、ROSでCaffeを呼び出すためのROSパッケージをインストールします。

アプリケーションの作成手順

アプリケーションを作成する手順を下に示します。

ステップ1: イメージ1(ROS + Naoqi SDK)を作成する
ステップ2: イメージ2(ROS + Caffe)をダウンロードする
ステップ3: イメージ1、2をつなげて、識別結果をターミナル上に表示する
ステップ4: 発話生成文ノードをつなげて、Pepperに識別結果をしゃべらせる

まず、ステップ1,2で必要なDockerイメージを作成、またはダウンロードしておきます。次に、ステップ3で、PepperからROS経由で得た画像をCaffeに入力し、その出力結果をターミナル上で確認します。最後に出力結果の中から確信度の最も高いものを選び、その名前をPepperにROSを使ってしゃべらせます。

では、始めていきましょう。

動作確認済み開発環境

Pepper

    
バージョン
Naoqi OS 2.4.2.26

クライアントPC

        
バージョン
Macbook Pro Early 2015(NVidiaのGPUは無し)
Ubuntu 14.04 LTS
Docker 1.8.2

イメージ1

ベースイメージ:osrf/ros:indigo-desktop-full
下表は追加でインストールするもの。

    
バージョン 説明 ソース
Naoqi SDK(C++, Python) 2.4.2.26 NaoqiのSDK本体。 アルデバランのデベロッパコミュニティサイト(ユーザー登録が必要)
naoqi_driver コミットID: 710714022517cedb7db13 6dea890b9fa37485c5b Naoqi SDKを介してPepperの機能をROSで使うためのパッケージ群。様々なセンサデータ取得、移動、発話などがROSから制御可能。 発話機能を使うため、最新版をソースからコンパイルして使う。 https://github.com/ros-naoqi/naoqi_driver
pepper_robot 0.1.7 Pepper専用のROSパッケージ群。内部でnaoqi_driverを呼び出す。Pepperの起動などが可能。apt-getでインストールする。 https://github.com/ros-naoqi/pepper_robot

イメージ2

ベースイメージ:osrf/ros:indigo-desktop-full
下表は追加でインストールするもの。

  
バージョン 説明 ソース
ros_caffe コミットID: 98f76653e0b1f8d256c0e 8fdf4f81b99f1c0b3a2 Caffe本体と、CaffeのROSブリッジ用パッケージを含む。入力画像から識別結果とスコアが取得できる。 https://github.com/ruffsl/ros_caffe

ステップ1: イメージ1(ROS + Naoqi SDK)を作成しよう

PepperをROSで動かすには、Naoqi SDKというAldebaranが提供しているSDKが必要になります。 まずは、AldebaranのDeveloperコミュニティサイトに行き、Naoqi SDK(C++, Python両方)をダウンロードしてください(ユーザー登録必要)。

aldebaran_resource

ここでは、Naoqi SDK(C++)はnaoqi-sdk-2.4.2.26-linux64.tar.gzというファイル名、Naoqi SDK(Python)はpynaoqi-python2.7-2.4.2.26-linux64.tar.gzというファイル名のものをダウンロードしたとします。

次に、下記の内容のDockerfileをコピペし、Dockerfileという名前で保存します。

このDockerfile内の処理を簡単に説明します。まず、2行目で前回使用したROSのIndigoのデスクトップ版をベースイメージとして指定します。5,6行目はapt-getで必要なROSパッケージをインストールします。次に、11-16行目はROSのnaoqi_driverパッケージをソースからコンパイルします。18,19行目でホームディレクトリの下にnaoqi_sdk, pynaoqiというフォルダを作成し、21,22行目でそこにローカルにダウンロードしたNaoqi SDKをそれぞれコピーします。最後に26-28行目で環境変数の設定やROSのセットアップファイルの読み込みを行っています。

次に、ダウンロードしたNaoqi SDK(C++, Python)と、上記のDockerfileを適当な名前の同じフォルダに入れます。

最後に、次のようにコマンドで入力し、イメージ1を作成します。

ビルドが終了したら、指定した名前のDockerイメージができているか確認してください。

イメージ1の動作確認

では、動作確認をしましょう。まずはイメージ1からコンテナを起動します。

次に、起動したコンテナ内で、下記コマンドを実行します。terminal数字と表記しているコマンドは、tmuxなどを使って別々のターミナルから起動してください。

正常に起動すれば、以下のように表示されます。(右図は左図の出力結果の続き)

pepper_bringup_full

これで、ROSでPepperを制御することができるようになりました。次は、取得した画像からCaffeを使って物体を識別するためのイメージを作成してゆきましょう。

ステップ2: イメージ2(ROS + Caffe)をダウンロードしよう

このイメージは、ROS本体、Caffe本体、CaffeのROSブリッジを含みます。このイメージは、既に作っている方がいます。ただし、GPU環境下でCaffeを使う場合のDockerfileしか用意されていません。そこで、筆者の開発環境の都合上により、CPUだけでも動作するように設定ファイルに少し手を加えたDockerイメージを用意しましたので、そちらを使います(こちらからダウンロード可能)。

ちなみに、今回はCaffenetという既に用意されているモデルを使用して画像識別を行います。このモデルのデータセットは1000カテゴリに分けられており、今回のアプリケーションで表示される識別候補も1000カテゴリのどれかになります。

このDockerfileについて簡単に説明します。

まず1行目ですが、ベースイメージはykoga/caffe_cpuという名前のイメージを使用します。これは、ROSのIndigoのデスクトップ版をベースイメージとして、その上にCPUでビルドしたCaffe本体を含むイメージとなります。

次に、ruffslさんのプロジェクトをcloneしてきます。このプロジェクト内に、CaffeのROSブリッジ等が含まれます。

CaffeのROSブリッジを使うためにはROSでビルドを行わなければなりません。ROSではCMakeLists.txtによりパッケージ単位のビルド設定が行われます。このため、このファイルを修正して、CPUのみでビルドするように変更しています。

最後に、ビルドします。

イメージ2の動作確認

Webカメラを使う場合

ROS bagファイルを使う場合

もしWebカメラが無い場合は、事前に録画しておいたbagファイルを使ってテストできます。

結果

Webカメラ、ROS bagファイルどちらを使った場合も下図のような結果になるはずです。 step3-result

Terminal3のように(右図)、識別ラベルとスコアが上位5件まで表示されていることがわかります。カメラ画像とその識別結果から、今回Caffeで使用しているCaffenetの精度を確認してみてください。

以上により、CaffeをROSで動作することが確認できました。

ステップ3: イメージ1と2をつなげて、識別結果を表示しよう

ではいよいよ後半戦です。ここでは、Pepperのカメラ画像からの識別結果を、PCのターミナル上に表示します。

まず、イメージ1を使ってPepperのROSブリッジノードを起動させましょう。ステップ1で動作確認した時のコマンドと全く同じなので、そちらを参照して下さい。ここでは省略します。

次に、イメージ2を使ってCaffeで画像識別させましょう。まずイメージ2からコンテナを起動します。

コンテナ内で、Caffeノードの実行と、識別結果の表示を行います。

結果は、ステップ2の出力結果とほとんど同じです。違うのは、Pepperから得た画像かどうか、ということです。

ステップ4: 発話生成文ノードをつなげて、Pepperに識別結果をしゃべらせよう

ではいよいよ、最後のステップです。このステップでは、識別結果をターミナルに表示するのではなく、Pepperにしゃべらせてみます。

Pepperにしゃべらせるには

まず、Pepperにしゃべらせる方法について説明します。結論から言うと、Pepperにしゃべらせるには、/speechというトピックで文字列を投げればよいです。これは、Pepperノードが、/speechという名前のトピックをSubscribeしていることからわかります。試しに、Pepperに「おはよう」としゃべらせるには、pepper_full.launchを起動した状態で、下記コマンドのようにして、/speechトピックを発行します。

このように、/speechトピックを発行するだけで、/speechトピックがPepperノードに送られます。そのノード内部でNaoqi SDKを介し、Pepperに「おはよう」という発話コマンドが送られ、結果的に「おはよう」としゃべらせることができます。

この例と同じように、Pepperに識別結果をしゃべらせるには、Caffeからの識別結果を受け取り、ノード内部でスコアが一番高いラベルのみを選択し、その文字列を/speechトピックとして発行するようなROSノードを作ればよいということがわかります。(下図参照)

pubsub_speech

発話文生成プログラム

発話文生成プログラムが下記です。ローカルPC側にcreate_speech.pyという名前で、適当な場所に保存しましょう。ここでは、~/create_speech/create_speech.pyとして保存したとします。

また、保存したPythonプログラムは忘れずに実行可能にしておきましょう。

起動

起動前に一つ準備作業を行います。今回は英語で喋らせるので、Pepperを英語モードにしておきます。 http://PepperのIPアドレス にアクセスします。一番右の歯車アイコンの設定ボタンで、言語をEnglishを選択します。元に戻すときも、同じ手順を踏んで日本語を選んでください。

Robot Web Page - Google Chrome_013

では、起動してゆきましょう。最後なので、必要なコマンドすべて下記に表記しています。

まず、コンテナ1を起動します。

コンテナ2も起動しましょう。

結果

結果は下図のようになります。右上のターミナルで表示している文字列(ここではmouse)が、Pepperがしゃべる内容です。Pepperが、"mouse"など/speechトピックの内容をしゃべれば成功です!

step4_result

もし、今回使用したデータセットに無い物体もPepperに識別させたい場合は、自分で集めた画像を学習データとして使い独自の学習モデルをCaffeで構築すれば、実現できます。ぜひ試してみてください。

最後に

今回は、"Caffe"というディープラーニングフレームワークによって、Pepperの目の前にある物体を識別をさせて、識別結果をPepperに喋らせてみるという実践的なロボットアプリケーションを作成しました。

アプリケーションを作成する過程で、ROSやCaffe、Naoqi SDKなどを使いましたが、Dockerを使えば、これらをクライアントPCに直接インストールする必要がなく、コンテナ内部にDockerイメージとして環境ごと閉じ込めることができました。これにより、アプリケーションをスピーディーに開発、実行、共有できることを実感できたのではないでしょうか。

Pepperの一般発売により、日本でもロボットアプリケーション開発をはじめてみようという人が増えてきました。分散処理が得意なROSと、動作環境をパッケージ化できるDockerにより、開発がさらに促進されればと思います。

エンジニア採用中!私たちと一緒に働いてみませんか?