TOP > HSR 音声操作

HSR 音声操作

概要

このチュートリアルでは、HSRの頭部マイクに向かって「Move your head.」と音声入力したときに、HSRが首を上方向に動かした後、左右に首振りをするサンプルを作成します。

実行結果

HSRロボット実機へのrospeexのインストール

HSRの頭部マイクからの入力を取得するため、HSRロボット実機にrospeexをインストールします。
HSRに関する詳しい操作は、HSRマニュアルを確認してください。
  1. HSRのマニュアルに従って、HSRロボット実機に開発用ユーザを追加します。

  2. HSRロボット実機に開発用ユーザでログインします。

  3. rospeexのインストール(推奨)の手順に従って、HSRロボット実機にrospeexをインストールします。

サンプル用ROSパッケージの作成

ROSパッケージの作成

始める前に本サンプルプロジェクト用に新しいROSパッケージを作成します。
次のコマンドによってワークスペース内に rospeex_if に依存した hsr_demo という名前のROSパッケージを作成します。

$ cd ~/%YOUR_CATKIN_WORKSPACE_HOME%/src
$ catkin_create_pkg hsr_demo rospeex_if

roscd の前に新しく作ったROSパッケージをビルドします。

$ cd ~/%YOUR_CATKIN_WORKSPACE_HOME%
$ catkin_make_isolated

ディレクトリの作成

次に scripts / launch という新しいディレクトリを hsr_demo パッケージの中に作ります。

$ source ~/%YOUR_CATKIN_WORKSPACE_HOME%/devel_isolated/setup.bash
$ roscd hsr_demo
$ mkdir scripts launch

ソースコード

scripts ディレクトリ内に hsr_demo.py というファイルを作成してエディタで開き、以下のソースコードを記述してください。

* 以下のコードでは、google音声認識APIエンジンを使用しています。
  google音声認識APIエンジンの使用には、別途 API KEYが必要です。

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import rospy
import re
import time

# importing rospeex library
from rospeex_if import ROSpeexInterface
# importing HSR library
import hsrb_interface


class HSRControlDemo(object):
    """ HSR Control Demo class """
    def __init__(self):
        """ Initializer """
        self._interface = None
        self._robot = None
        self.whole_body = None

    def sr_response(self, message):
        """ speech recognition response callback
        @param message: recognize result (e.g. Move your head.)
        @type  message: str
        """
        # extract a body-part name from an utterance
        rospy.loginfo('result_received : %f', time.time())
        PATTERN_LIST=['Move your','move your']
        rospy.loginfo('you said: %s' % message)
        for pattern in PATTERN_LIST:
            parts = re.compile(pattern + ' (?P<part>.*)').search(message)
            if parts:
                target = parts.group('part')
                if re.search('head', target):
                    self.move_head()
                else:
                    rospy.loginfo('%s is not defined.' % target)
                break

    def move_head(self):
        """ move HSR head joint """
        text = u'I\'m moving my head.'
        self._interface.say(text, 'en', 'nict')

        try:
            self.whole_body.move_to_joint_positions({'arm_lift_joint': 0.1})
            self.whole_body.move_to_joint_positions({'head_pan_joint': -0.5, 'head_tilt_joint': 0.0})
            self.whole_body.move_to_joint_positions({'head_pan_joint': 0.5, 'head_tilt_joint': 0.0})
            self.whole_body.move_to_neutral()
        except:
            rospy.logerr('Failed to joint control.')
        
    def run(self):
        """ run ros node """
        # initialize hsr
        self._robot = hsrb_interface.Robot()
        # whole body controller
        self.whole_body = self._robot.get('whole_body')
        # initialize hsr pose
        self.whole_body.move_to_neutral()
        self.whole_body.move_to_joint_positions({'arm_lift_joint': 0.1})

        # initialize rospeex
        self._interface = ROSpeexInterface()
        self._interface.init()
        self._interface.register_sr_response(self.sr_response)
        self._interface.set_spi_config(language='en', engine='google')

        rospy.spin()

if __name__ == '__main__':
    try:
        node = HSRControlDemo()
        node.run()
    except rospy.ROSInterruptException:
        pass

作成したソースコードを実行可能な状態に変更します。

$ roscd hsr_demo
$ chmod +x scripts/hsr_demo.py

ソースコードの解説

import rospy
import re
import time

# importing rospeex library
from rospeex_if import ROSpeexInterface
# importing HSR library
import hsrb_interface

必要なライブラリをインポートします。ROSpeexInterfaceがrospeexを制御するためのクライアントライブラリ、hsrb_interfaceがHSRを制御するためのクライアントライブラリです。

        """ run ros node """
        # initialize hsr
        self._robot = hsrb_interface.Robot()
        # whole body controller
        self.whole_body = self._robot.get('whole_body')

HSR制御用インタフェースを初期化します(* ROSノードの初期化が含まれます。)

        # initialize hsr pose
        self.whole_body.move_to_neutral()
        self.whole_body.move_to_joint_positions({'arm_lift_joint': 0.1})

HSRの腕を初期姿勢に変更し、アームの直動軸を上方向に移動します。

        # initialize rospeex
        self._interface = ROSpeexInterface()
        self._interface.init()

rospeexインタフェースを初期化します。

        self._interface.register_sr_response(self.sr_response)

音声認識完了時に呼び出されるコーバック関数を登録します。

        self._interface.set_spi_config(language='en', engine='google')

波形モニタから入力される音声情報をどのように処理するかを設定します。 本サンプルコードでは、発話言語を英語(en)、音声認識エンジンをgoogleとしています。

* google音声認識APIエンジンの使用には、別途 API KEYが必要です。

    def sr_response(self, message):
        """ speech recognition response callback
        @param message: recognize result (e.g. Move your head.)
        @type  message: str
        """
        # extract a body-part name from an utterance
        rospy.loginfo('result_received : %f', time.time())
        PATTERN_LIST=['Move your','move your']
        rospy.loginfo('you said: %s' % message)
        for pattern in PATTERN_LIST:
            parts = re.compile(pattern + ' (?P<part>.*)').search(message)

音声認識結果を受け取り、”Move your”または”move your”が発話内容に含まれていた場合、後に続く認識結果を評価します。

            if parts:
                target = parts.group('part')
                if re.search('head', target):
                    self.move_head()
                else:
                    rospy.loginfo('%s is not defined.' % target)
                break

“Move your” または “move your” の後に”head” が含まれていた場合、HSRの首のアクチュエータを動作させながら、固定メッセージを発話します。

    def move_head(self):
        """ move HSR head joint """
        text = u'I\'m moving my head.'
        self._interface.say(text, 'en', 'nict')

        try:
            self.whole_body.move_to_joint_positions({'arm_lift_joint': 0.1})
            self.whole_body.move_to_joint_positions({'head_pan_joint': -0.5, 'head_tilt_joint': 0.0})
            self.whole_body.move_to_joint_positions({'head_pan_joint': 0.5, 'head_tilt_joint': 0.0})
            self.whole_body.move_to_neutral()
        except:
            rospy.logerr('Failed to joint control.')

HSR動作の実装です。

launchファイル

launch ディレクトリ内に hsr_demo.launch というファイルを作成してエディタで開き、以下のソースコードを記述してください。

<launch>
  <include file="$(find rospeex_launch)/launch/rospeex_browser.launch" />
  <node name="hsr_demo" pkg="hsr_demo" type="hsr_demo.py" output="screen" />
</launch>

launchファイルの解説

   <include file="$(find rospeex_launch)/launch/rospeex_browser.launch" />

includeタグ により、rospeexで用いる音声認識、音声合成に必要な全てのノードを起動します。

  <node name="hsr_demo" pkg="hsr_demo" type="hsr_demo.py" output="screen" />

nodeタグ により、作成した hsr_demo.py を起動します。

プログラムの起動

  1. HSRの起動手順に従って、HSRを起動します。

  2. 端末を開き、サンプルを起動します。

    * サンプルを起動すると、グリッパが前を向いた基本姿勢になるようHSRのアームが動作します。
      そのため次の点に気をつけてください。

    1. ハンドが開くため、手にものを持たせない。
    2. ロボットが動くため、まわりのスペースが十分に空いたところで起動する。

        $ source ~/%YOUR_CATKIN_WORKSPACE_HOME%/devel_isolated/setup.bash
        $ roslaunch hsr_demo hsr_demo.launch
        
  3. Mozilla Firefoxで ブラウザ版波形モニタサイト にアクセスします。
  4. 以下のようなマイクを共有するかを問い合わせるダイアログが表示されるので、[Microphone to share] を [PrimeSense Device Analog Stereo] に設定し、[Share Selected Device]ボタンを押下します。
  5. ブラウザ版波形モニタとrospeexを接続するために、[rospeex machine IP] に 127.0.0.1 を入力してください。
  6. アイコンが「Connected」状態に変化すれば接続完了です。

操作

マイクに「Move your head.」と言ってください。正常に認識された場合、「I’m moving my head.」と発話し、HSRが首を上方向に動かした後、左右に首振りをします。