はじめに
ROS2で音声ファイルを再生する方法を紹介する。
動作確認環境
- ROS2 Foxy
- audio_commonパッケージ
- バイナリパッケージは提供されていない (2024.12.17時点)
-
https://github.com/ros-drivers/audio_common/commit/06c280a798596db952538772918e8c7d44a6e5a8
- ハッシュ
06c280a798596db952538772918e8c7d44a6e5a8
- ハッシュ
方法
audio_commonパッケージ(ros2ブランチ)を使う。audio_commonパッケージは、音声再生、録音などの音声に関連する機能が実装されている。内部では、GStreamerを利用している。
インストール
audio_commonパッケージ(ros2ブランチ)は、バイナリパッケージは提供されていない(2024.12.17時点)のでビルドする必要がある。
ROS2がインストールしてある環境で、以下のコマンドを実行してビルドする。
例:ワークスペースが~/ros2_ws
の場合
cd ~/ros2_ws/src
git clone https://github.com/ros-drivers/audio_common
git checkout ros2
cd ~/ros2_ws
sudo apt update
rosdep install --from-paths src --ignore-src -r -y
colcon build --symlink-install --packages-up-to sound_play
使い方
soundplay_node
を起動して、音声ファイルの情報を付与したトピック(/robotsound)を受信させて音声を鳴らす。soundplay_node
の仕様は、ROS1と同様である。詳細はROS1のsoundplay_nodeのドキュメントを参照。
音声再生用のノードの起動
ros2 launch sound_play soundplay_node.launch.xml
起動時に設定できるノードパラメータは以下の通りである。
パラメータ | 概要 | デフォルト | 備考 |
---|---|---|---|
loop_rate | 連続再生の周期(Hz) | 100 | 参考 |
device | 再生デバイス | 'default' | 参考 |
default_voice | 再生音声 | 'default_voice' | 参考 |
再生デバイスを指定する場合は、以下のようにする。
ros2 launch sound_play soundplay_node.launch.xml device:=hw:1,0
デバイスの指定方法は、ALSAと同じになる。詳細は、以前書いた「Ubuntuで音声ファイルを再生する方法」を参照。
音声ファイルの再生
再生したい音声ファイル情報を持ったトピックをpublishすることで音声ファイルを再生させることができる。soundplay_nodeは、/robot_sound
トピック(型:SoundRequest)をsubscribeするので、このトピックをターミナルや別ノードからpublishすることで音声再生できる。
音声ファイル再生時のトピックに設定する変数は以下のようにする。
トピック変数 | 型 | 概要 | 設定値 | 備考 |
---|---|---|---|---|
sound | int8 | 音源のタイプ | -2(PLAY_FILE) | |
command | int8 | 再生方法 | 0(PLAY_ONCE) | |
volume | float | 音量 (0.0-1.0) | 1.0 | 1.0を超えても設定は可能、音量も10.0までは上がった |
arg | string | 音声ファイルのパス (.wav or .ogg) | test.wav | OGG/WAVファイルの指定が可能 |
arg2 | string | 音声ファイルが置かれているパッケージ名 | '' | 指定しない場合は、空文字('')とする |
トピックをPublishし続けている間は、音声が再生される。以下に、コマンドの例を示す。
例:一度のみ、音声ファイル(test.wav)を再生する場合
ros2 topic pub -1 /robotsound sound_play/msg/SoundRequest "{sound: -2, command: 1, volume: 1.0, arg: 'test.wav', arg2: ''}"
- arg2を指定しない場合は、空文字として、音声ファイルは実行ファイルの直下に置く、または、絶対パスを指定する
音声ファイル再生の際の注意点
- command
- PLAY_STOP(0): 効かない(2024/9/2時点)
- PLAY_START(2): リピートは可能だが停止できない(2024/9/2時点)
- PLAY_ALL かつ PLAY_STOPだと、全て停止に実装されている
- https://github.com/ros-drivers/audio_common/blob/06c280a798596db952538772918e8c7d44a6e5a8/sound_play/scripts/soundplay_node.py#L435-L437
"{sound: -1, command: 0, volume: 1.0, arg: '', arg2: ''}"
- PLAY_ONCE(1): 問題なく動作(2024/9/2時点)
- 複数回、Publishすると継続できる
- トピックのPublishをやめると停止できる
- PLAY_STOP(0): 効かない(2024/9/2時点)
- arg2
- パッケージの場所を指定することが可能
- 設定されると、音声ファイルの参照パスが、{package_directory}/arg となる
- 空文字('')を設定する
- 設定しないと、
None
となり、パッケージ検索の際に例外で落ちるので必ず空文字を指定する
- 設定しないと、
まとめ
ROS2で音声ファイルを再生する方法を紹介した。音声ファイルの情報を付与したトピックをpublishすることで簡単に音声再生させることができた。
参考
トラブルシューティング
Can't open sound device.See http://wiki.ros.org/sound_play/Troubleshooting
上記のエラーがROSログで表示される。
原因不明、調査中 (2024/9/9)。音声自体は再生できているので問題はなさそう。
付録
soundplay_nodeの詳細
- https://github.com/ros-drivers/audio_common/blob/06c280a798596db952538772918e8c7d44a6e5a8/sound_play/scripts/soundplay_node.py#L82
- GStreamerのplaybin
定義済み音声の再生
ros2 run sound_play playbuiltin.py <ID>
例: ID=1の場合
ros2 run sound_play playbuiltin.py 1
- 指定可能なID
# Sounds int8 BACKINGUP = 1 int8 NEEDS_UNPLUGGING = 2 int8 NEEDS_PLUGGING = 3 int8 NEEDS_UNPLUGGING_BADLY = 4 int8 NEEDS_PLUGGING_BADLY = 5
audio_commonのROS2 Humbleでの動作
ROS2 Humbleでは、別ブランチが必要(参考)。別の機会に動作確認予定。