前回は、Arduino + ESCで動かしていたRoverの足回りを、Raspberry PiとL298Nを使うROS 2構成へ移行した。
今回はその続きとして、Roverにモニターを追加し、走行中に顔の表情を表示できるようにした。単に映像を出すだけでなく、PC側のキーボード操作からROS 2トピックを送って、Raspberry Pi側で表情を切り替える構成にしている。
走行と表情を別々に操作するのではなく、いつもの走行キーに表情キーを追加した。Rover Botらしさが少し出てきた気がする。
今回できるようになったこと
- モニターに通常顔・笑顔・困り顔を表示する。
- 一定間隔でまばたきする。
- PCのキーボードから、走行指令と表情指令を同時に送る。
- モータ制御と顔表示を、Raspberry Pi上の別ROS 2プロセスとして動かす。
表情は、将来的にWindows側のLLMクライアントなどからも使えるよう、画面専用のキー処理ではなくROS 2トピックで受け取る形にした。
構成
PC側はROS 2 Jazzy、Raspberry Pi側はROS 2 Humbleのままである。前回と同様、PCからWi-Fi LAN経由でRaspberry PiへROS 2メッセージを送る。
PC(ROS 2 Jazzy)
rover_operator / integrated_teleop
├─ /cmd_vel_raw ─> cmd_vel_limiter ─> /cmd_vel
└─ /face_expression
│
│ Wi-Fi LAN
▼
Raspberry Pi(ROS 2 Humble)
rover_base rover_face
/cmd_vel ─> L298N ─> DCモータ /face_expression ─> モニター
走行系は前回作成した rover_base が担当する。今回追加したのは、顔を表示するための rover_face パッケージと、走行・表情をまとめて送るPC側の integrated_teleop である。
表情表示の仕組み
rover_face は std_msgs/msg/String 型の /face_expression を購読する。現在受け付ける文字列は次の3種類だけに絞った。
| メッセージ | 表示 |
|---|---|
happy | 笑顔 |
neutral | 通常顔 |
worried | 困り顔 |
Raspberry PiではOpenCVで目の形を描画し、Linuxのフレームバッファ /dev/fb0 に直接書き込む。解像度は現在 480 x 320、描画は30fpsで行っている。通常は3.5秒ごとに、閉じる・少し閉じたままにする・開く、という短いまばたきアニメーションを入れた。
画面描画には専用の仮想端末(現在はVT2)を使う。顔表示プロセスのログを画面へ出さないようにし、終了時にはグラフィックスモードを解除して、起動前のテキストコンソールへ戻すようにしている。
モータ制御と同じプロセスにしなかったのは、顔表示がフレームバッファと仮想端末を扱うためである。表示側の起動・停止や画面関連のトラブルが、走行制御へ影響しにくい構成を優先した。
キーボード操作を一本化
PC側の integrated_teleop は、従来のキーボード走行操作に表情キーを追加したノードである。走行指令は /cmd_vel_raw へ送り、既存の cmd_vel_limiter が速度上限をかけて /cmd_vel としてRaspberry Piへ送る。表情は同時に /face_expression へpublishする。
| キー | 動作 |
|---|---|
u / i / o、j / k / l、m / , / . | 走行操作(k は停止) |
q / z、w / x、e / c | 走行速度の調整 |
a | 笑顔(happy) |
s | 通常顔(neutral) |
d | 困り顔(worried) |
表情を変えた後も、同じ操作画面でそのまま走行操作を続けられる。画面表示だけが止まった場合でも、モータ制御ノードは別プロセスなので、切り分けしやすい。
起動手順
PCとRaspberry Piは同じネットワークに接続し、すべての端末で同じ ROS_DOMAIN_ID を使う。現在は 30 にしている。
初回だけ、それぞれのワークスペースでビルドする。
Raspberry Pi側
cd ~/raspi_rover_ws
source /opt/ros/humble/setup.bash
colcon build --symlink-install
通常はRaspberry Piでターミナルを2本使う。まず、前回からあるモータ制御を起動する。
cd ~/raspi_rover_ws
source /opt/ros/humble/setup.bash
source install/setup.bash
export ROS_DOMAIN_ID=30
ros2 launch rover_base l298n_rover.launch.py
別のターミナルで、顔表示を起動する。フレームバッファと仮想端末を扱うため、顔表示には管理者権限が必要になる。
cd ~/raspi_rover_ws
export ROS_DOMAIN_ID=30
sudo -E bash -c '
source /opt/ros/humble/setup.bash
source /home/tkazu/raspi_rover_ws/install/setup.bash
exec ros2 launch rover_face face_display.launch.py
'
PC側
初回だけ、ワークスペースでビルドする。
cd ~/pc_rover_ws
source /opt/ros/jazzy/setup.bash
colcon build --symlink-install
PCでは統合キーボード操作を起動する。
cd ~/pc_rover_ws
source /opt/ros/jazzy/setup.bash
source install/setup.bash
export ROS_DOMAIN_ID=30
ros2 launch rover_operator teleop_rover.launch.py
起動時に開く xterm にフォーカスを置き、a、s、d を押すと表情が切り替わる。走行はこれまでと同じキーで操作できる。
今後
今回はキーボードから表情を切り替えるところまでにした。表情の入口を /face_expression に統一したので、次はWindows側のLLMクライアントや状態監視ノードから同じトピックをpublishし、会話や走行状態に合わせてRoverの表情を変えることもできそうである。
足回りがROS 2で動き、画面にも反応が出るようになった。次はセンサ情報や会話機能とつなげて、Rover自身が周囲の状況を表情で伝えられるようにしていきたい。
