前回はROSの基本的な概要と特徴について触れました。今回は、ROSの基本的な概念である「ノード」、「トピック」、「サービス」について概念だけでなく、実際にサンプルコードを動かしながら詳しく見ていきましょう。これらの概念の理解はROSを用いた開発の基本となります。
まずはWindows上にROSの環境を構築していきます。
1.VirtualBoxにUbuntuをインストール
Windows上にROSの環境を構築するために、VirtualBoxを使用します。VirtualBoxはWindows上に仮想マシンを構築し、仮想マシンの中で別のOSを稼働させることができるアプリケーションです。ROSはUbuntuというOSで動作するので、この仮想マシンでUbuntuを動かし、その中でROSを動かすように環境構築していきます。
1.1 VirtualBoxのインストール
本記事ではWindows 11を使用していきます。
まずはVirtualBoxを公式サイトからダウンロードします。ダウンロードページのWindows版のものをクリックしてダウンロードします。
ダウンロードしたインストーラをクリックし、インストールを進めます。基本的には設定画面の「Next/Yes」をクリックしていき、最後に「Install」をクリックしてインストールを開始します。
インストールが完了すると再起動するように促されるので、PCの再起動を行います。
再起動したらVirtualBoxを立ち上げます。立ち上げると以下のような画面が表示されます。
1.2 VirtualBoxの仮想マシン上にUbuntuをインストール
VirtualBoxの仮想マシン上にUbuntuをインストールしていきます。VirtualBoxを立ち上げた画面から「新規」のボタンをクリックします。
最初の設定画面で、以下のように設定します。タイプを「Linux」にバージョンを「Ubuntu20.04」にします。
次に仮想マシン上で使用するメモリとCPUのコア数の割り当てを行います。これらのリソースを多く割り当てることで仮想マシンの性能が上がりますが、ホスト側(Windows)のリソースが減少するので、適当なところで設定を行います。
次に仮想ハードディスクの容量を設定します。こちらもUbuntuとROSをインストールすることを考慮し、数十GB程度は割り当てておきます。
最後完了を押して、仮想マシンの設定は終わりです。
以下の画面から仮想マシンの「起動」をクリックし仮想マシンを立ち上げます。
起動すると以下のようにインストールDVDのマウントを求められるので、こちらのサイトからUbuntu20.04のインストーラのイメージ(64-bit PC (AMD64) desktop image)をダウンロードします。
ダウンロード完了したら、インストールDVDのイメージにダウンロードしたファイルを指定し、「マウントとブートのリトライ」をクリックします。
しばらくすると、仮想マシン上にUbuntuのインストーラ画面が表示されます。「Install Ubuntu」をクリックし、次に進みます。
キーボードを日本語設定にし、次の画面に進んでいきます。基本的にデフォルトの設定にしつつ、「Instal now」をクリックします。
Ubuntuでのユーザ名とパスワードを設定します。「Continue」をクリックするとUbuntuのインストールが開始されます。
インストールが完了すると仮想マシンの再起動を求められるので、再起動を行います。
インストールメディアのアンマウントを求められますが、そのまま「Enter」を押します。
仮想マシンの再起動でUbuntuのログイン画面が出るので、設定したパスワードでログインします。
1.3 仮想マシンのUbuntuにROSをインストール
Ubuntuにログイン出来たら、ターミナルを立ち上げます。ターミナルは以下の画像の左下の赤で囲んだところをクリックし、検索窓が出るので、「teminal」と入力し、terminalアプリをクリックします。
ターミナル上でROSのインストールを行っていきます。ROS1の最新バージョンであるnoeticをインストールします。公式ページに従って、ターミナル上で以下のコマンドを順番に入力してください。
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
$ sudo apt install curl
$ curl -s https://raw.githubusercontent.com/ros/rosdistro/master/ros.asc | sudo apt-key add -
$ sudo apt update
$ sudo apt install ros-noetic-desktop-full
実際にターミナルを立ち上げている様子は以下のようになります。
インストール完了後、以下を実行します。
$ echo "source /opt/ros/noetic/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
これでROSのセットアップは完了です。ROSがちゃんとインストールされているか調べるために、roscoreというプログラムを実行させてみます。
このような出力が得られればOKです。実行が確認できたらCtrl+Cでプログラムを落としてください。
2.ノード、トピック、サービスについて
ここでは、ROSの基本概念となるノード、トピック、サービスについて説明します。
2.1. ノードとは?
ROSでは、プログラムの単位を「ノード」と呼びます。ノードは、ROSネットワーク内で動作する独立したプロセスであり、特定のタスクを担当します。例えば、センサーデータの読み取り、データの処理、アクチュエータの制御など、各ノードは一つの機能に特化した設計がされることになります。
2.2. トピックとは?
トピックは、ノード間でのメッセージの通信チャネルです。ノードはトピックを介してメッセージをパブリッシュ(送信)またはサブスクライブ(受信)することができます。一つのトピックには、複数のパブリッシャやサブスクライバが存在できます。
以下にパブリッシャとサブスクライバの関係を絵にしたものを載せます。ここではNode1がパブリッシャとなりメッセージをNode2、Node3、 Node4に送信しています。Node2、Node3、Node4がサブスクライバに相当します。
2.3. サービスとは?
サービスは、ノード間での同期通信を可能にする概念で、一つのノードから別のノードに対して、リクエストを送り、それに対するレスポンスを受け取ります。サービスは、リクエスト/レスポンスのペアで定義され、一つのサービスに対しては一つのサーバーと、一つまたは複数のクライアントが存在します。
以下にサーバーとクライアントの関係を図にしたものを載せます。ここではNode1がサーバーとなりクライアントであるNode2からリクエストを受け取り、何らかの処理を実行した後、レスポンスをNode2に返します。
3.ROSノードを作ってみる
ROSの基本概念が分かったところで、実際にパブリッシャとサブスクライバのノードをPythonを使用して作成してみます。
Ubuntu内で適当な作業フォルダ(今回はworkとします)を作成し、ここにプログラムのファイルとなるtalker.pyとlistener.pyを作成していきます。作業フォルダを以下のコマンドで作成して下さい。
$ mkdir work
$ cd work
nanoというエディタを使ってコードの作成を行っていきます。以下のコマンドでnanoエディタを立ち上げて下さい。
$ nano talker.py
エディタが立ち上がったら、以下のコードを入力してください。
import rospy
from std_msgs.msg import String
rospy.init_node('talker')
pub = rospy.Publisher('chatter', String, queue_size=10)
r = rospy.Rate(1)
while not rospy.is_shutdown():
str = 'hello world!'
pub.publish(str)
r.sleep()
実際の入力画面は以下のようになっていると思います。
入力が完了したらCtr+xと入力し、Shift+Y→Enterと入力することでファイルが保存されます。
同様にlistener.pyも作成します。
$ nano listener.py
エディタ上で以下のコードを入力し、保存してください。
import rospy
from std_msgs.msg import String
def callback(data):
print('Message from talker:', data.data)
rospy.init_node('listener')
rospy.Subscriber('chatter', String, callback)
rospy.spin()
これでパブリッシャとサブスクライバ、2つのノードのプログラムが完成しました。
これらのプログラムの動作を簡単に説明します。
talker.pyはパブリッシャのノードのプロブラムになります。ROSの初期化の後、’chatter’という名前のメッセージでサブスクライバにデータを送信することを宣言しています。while文の中で、’chatter’に’hello world!’という実際のメッセージのデータを1秒毎に送信するという処理を行っています。
一方、listener.pyはこの’chatter’メッセージを受け取るサブスクライバのノードとなっており、メッセージを受け取った際にcallback関数が呼ばれ、メッセージの内容をプリントするようになっています。
つまり、パブリッシャから1秒毎に送られる’hello world!’というメッセージがサブスクライバ側でprintされるという動作になります。
それでは、実際にこれらを立ち上げて実際の動作を見ていきます。動作確認を行うためにターミナルのウィンドウを3つ立ち上げてください。
それぞれのウィンドウで以下を順番に実行していきます。
ウィンドウ1
$ roscore
ウィンドウ2
$ cd work
$ python3 talker.py
ウィンドウ3
$ cd work
$ python3 listener.py
最初に立ち上げたroscoreというプログラムはROSを動かすためのベースとなるプログラムで、ROSを動かす際には必ず立ち上げる必要があるものです。トピックやサービスの登録もroscoreを通して行われます。
これらの実行に成功すると、ウィンドウ3に1秒おきに”Message from talker: hello world!”という文字が流れてくるようになります。listener.pyがtalker.pyからのメッセージを受け取って処理しているのが分かります。
4.まとめ
ROSの基本概念について説明し、WindowsにVirtualBOXをインストールし、仮想マシン上のUbuntuでROS環境の構築を行いました。簡単なROSノードのプログラムを作成し、パブリッシャとサブスクライバによる通信のやり取りを見てきました。
実際の動きを見ることで、なんとなくROSがどのようなものか理解できたのではないでしょうか?次回からはロボットで必須となるセンサとの接続をROSを使って行っていきます。まずは、身近なセンサとしてPC内蔵のカメラもしくはWebカメラを用いて、ROSでカメラ画像の描画を行っていきたいと思います。
コメント