はじめに
本記事はABEJA Advent Calendar 2022 1本目の記事です。
こんにちは、メカやロボットが大好きな栗林です。本日ご紹介するのは清掃ロボットの制御システムをRaspberry Piから操作する方法についてです!
過去の記事など tech-blog.abeja.asia
※ 例によって、本記事でおこなっている清掃ロボットの分解・改造はくれぐれも自己責任でお願いします。本記事内容を参考に生じた不具合・損害について、当方は責任を負いかねます。
※ 間違っても私のように買ったばっかり&愛用している機体で試さない方がよさそうです。
清掃ロボットとは
そもそも清掃ロボットとは、人間の代わりに清掃作業をおこなってくれるロボットです。近年さまざまなロボットが登場しており、一般消費者向けだけでなく、オフィスやホテルなどの施設向けのものまで存在します。
清掃の方法としては吸い込みによるものだけでなく拭き掃除まで行えるものもあります。
最近のロボットはずぼらな人間よりもはるかに念入りに、決まった時間に必ず掃除を執行してくれます。技術者視点ではその制御システムやアルゴリズムに関心するとともに、とても利口なペットを飼っているかのような感覚になります。
そんな清掃ロボットの性能を大きく左右するのが清掃能力(吸い込み能力・ごみ容量)と、制御システム(自己位置推定や走行アルゴリズムなど)です。 どちらも重要なのですが制御システムは掃除の範囲と効率に影響し、こちらが不十分であるとそもそも移動が行えないため致命的です。
制御システムについて、一般的には自機が部屋のどの位置にいるかを把握し、どのような経路で移動したらもっとも早く、移動距離を短く、部屋の隅々まで清掃できるかの問題設定が行われます。そのため清掃ロボットにはカメラ・LIDAR・Wi-Fi・衝突センサ・超音波センサなどが複数とりつけられ、それらのセンサ情報を統合することによって制御されています。
ことの発端
私はこの夏ごろに清掃ロボットを購入して以来、ほぼ毎日掃除を任せています。いままで15分ほどかかっていた掃除の作業を、Siri経由で指示するだけで私がどこにいても完了する状態になったため非常に便利に感じていました。
そんなある日、社内で清掃ロボットをおすすめする内容を投稿したところこんな返信がありました。
昨今の機種では年々清掃アルゴリズムが改善されているはずですが、昔のモデルであったり下位モデルの場合は自分が思う通りに掃除してくれないケースがあります。
そして私自身でも「コーヒーの粉をこぼしてしまったから、”ここ”だけ掃除してくれたら良いのに」と思うことがあります。
つまり清掃ロボットは定期的に全ての場所を清掃することは得意ですが、突発的に特定の一ヶ所を掃除するという従来の掃除機にできたことができないという弱点があることに気がつきました。
ゴール
そこで今回は清掃ロボットをコントローラーによって制御し、ピンポイントでも清掃を行えるように改良を施したいと思います。
もちろん、毎日お世話になっている標準の清掃機能を損いたくはないため、任意のタイミングで切り替えが行える必要もあります。
どのようにしたら解決できそうか
はじめに考えたのは、どのレイヤーでロボットの制御に介入を行うかという点です。
1. サーボモーターの操作
2. 制御システムの操作
3. 外部向けインターフェースの操作
1はサーボモーターのPWM信号に対する介入です。移動すなわちタイヤ制御を行えさえすれば任意の操作ができるため、PWM信号をマイコンなどから与えることでも可能そうです。
2は制御システムであるROS(Robot Operating System)への介入です。ROSとはロボット開発のために必要なライブラリとツール群を含むオープンソースの統合的なソフトウェアプラットフォームです。具体的には通信、ツール群(設定・起動・監視・ログ・停止などの機能)、機能群(移動・センシング)が提供されており、清掃ロボットでもこれを利用しているケースであればシリアル通信などからアクセスが可能です。
3は清掃ロボットをAlexaやSiriなどから指示するショートカット機能の操作です。
結論から言うと2の手法を選択しました。1については、PWM信号を入力するためにはモジュール化された移動機能群を分解しなければならず難易度が高いことがわかりました。また3については「直進」「回転」などの移動単体では機能提供がされていませんでした。そこで、2の方法を選択しROSをRaspberry Pi側で構築しシリアル信号を経由して清掃ロボットを操作することにします。
実験準備
市販の清掃ロボットの一部ではiRobot社などが仕様を公開しており、公式にこれらに接続できる機種も存在しています。
今回はRaspberry PiにROSを導入し、シリアル通信によって操作を行います。
機材一覧
- 清掃ロボット
- Raspberry Pi 4(RAM 8GB以上が好ましい)
- モバイルバッテリー(Raspberry Pi 4用電源)
- シリアル通信用ケーブル(ジャンパワイヤ等で自作する)
Raspberry Piのセットアップ
ROSが動作できるRaspberry Piを準備します。Raspberry Pi ImagerによるOSイメージの準備やRaspberry Piの初期設定については詳細を記すと長くなるため省略しています。
ubuntu-18.04.5-preinstalled-server-arm64+raspi4.img.xz
をダウンロード- Raspberry Pi imagerでOS書き込みを行い、起動
- パッケージ群のアップデートおよびインストール
ROSのインストール
Raspberry PiにROS(CLI版)のインストールを行います。
# GPGキーの追加 $ sudo apt update && sudo apt install curl gnupg2 lsb-release $ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add - # ソースリストの更新 $ sudo sh -c 'echo "deb [arch=$(dpkg --print-architecture)] http://packages.ros.org/ros2/ubuntu $(lsb_release -cs) main" > /etc/apt/sources.list.d/ros2-latest.list' # aptリポジトリの更新 $ sudo apt update # ROS Command-line toolsのインストール $ rosinstall_generator ros_comm --rosdistro indigo --deps --wet-only --exclude roslisp --tar > indigo-ros_comm-wet.rosinstall $ wstool init src indigo-ros_comm-wet.rosinstall $ rosdep install --from-paths src --ignore-src --rosdistro indigo -y -r --os=debian:jessie $ sudo ./src/catkin/bin/catkin_make_isolated --install -DCMAKE_BUILD_TYPE=Release --install-space /opt/ros/indigo
ハードウェア(清掃ロボット)への接続
ここでは基盤部分分解工程については記載しませんが、シリアル通信にてRaspberry Piとロボット側基盤を接続します。
などとサクッと一行で書いていますが、実際は恐る恐る分解しました。 というのも私の所持している機種が新しいためか、改造や分解に関する情報はネットの海になかなか存在しなかったからです。 過去の製品に関しては公式に公開されている仕様書もあったため、それらと見比べながら通信用のポートを探しました。
基盤上にシリアル通信用TX、RXおよびGNDがあるのでこちらにRaspberry PiのIOポートと接続します。
以上が行えたら動作確認を行います。
ROSの操作
ROSではnodeと呼ばれるプログラムの最小単位が定義されており、node同士が通信を行うことで目的のシステムを形成します。また、node間でやりとりするデータをtopicと定義しており、これらを用いることでRaspberry Piからロボットへと動作命令を送ることができます。 ロボット制御では複数のnodeを扱うため、launchファイルに起動するnodeやそのパラメーターを保存しておき、一括で起動する方法が用意されています。
$ roslaunch robot_test robot_test.launch
robot_testパッケージ(ディレクトリ)内にrobot_test.launchファイルを作成しておきます。
# .launch sample <launch> <node pkg="clean_robot_ros" type="clean_robot_ros" name="clean_robot_ros"> <param name="port" value="/dev/serial/by-id/usb-Driver-i00" /> <param name="param_file" value="/home/$(env USER)/params/$(env PARAMS)" /> </node> <node pkg="clean_robot_ros" type="clean_robot_ros" name="clean_robot_ros" output="screen"> </node> </launch>
ROSにおけるデータの送受信方式は大きく分けて、topicとserviceの二つが存在します。
topic
- 単方向のメッセージの送受信
- 非同期通信
- 継続的なメッセージの送受信が可能
- topicを提供するpublisherとtopicを利用するsubscriberが存在
service
- 双方向のメッセージの要求と応答
- 同期式通信のため、要求があったときのみデータを送受信
- 1度限りのメッセージ送信
- 要求があった時に応答するサービスサーバーと応答を受信するサービスクライアントが存在
今回はRaspberry Pi側から命令を送るためのrostopic pub
の使用例を表示しますが、ロボット側からの送信も確認が行えます。
$ rostopic pub [topic] [msg_type] [args] # usage $ rostopic pub /command_velocity geometry_msgs/Twist -r 60 -- '[2, 0, 0]' '[0, 0.5, 0]'
-r 60
: 60Hzでの送信。
/command_velocity
: 配信するトピックの名称
/geometry_msgs/Twist
: 配信時の実行内容
geometry_msgs/Twistは3要素からなる2つのベクトルを持つ
linear value [x, y, z] = [2, 0, 0]
angular value [x, y, z] = [0, 0.5, 0]
結果
実際に通信を行いながら、Raspberry Piキーボードで動作させてみます。 先ほどのrostopicのパラメーターを矢印キーから変更できるように設定し任意に動けるようにしてみます。
操作量はキーボード上から決定ができるため、任意の値を出力値として設定しています。
まとめ
Raspberry Piを用いて遠隔操作も可能な機能を清掃ロボットに付け加えてみました。これで仮にコーヒーの粉をこぼしてしまってもすぐに対応ができるでしょう! 今回はあくまで操作のみを行いましたが、オリジナルの清掃アルゴリズムを搭載することもシリアル通信経由で可能になるはずです。
この分解を行っている1週間程度の間、私の部屋の床が汚くなる一方だったのですがこの原因は謎に包まれたままです...
ABEJAについて
株式会社ABEJAでは共に働く仲間を募集しています! AIだけでなく、ロボットや分解好きな方もぜひこちらの採用ページからエントリーください。