|
注記:このページで説明する内容は、2017年に実施したロボットの操作に関する説明です。2022年では、Ubuntu Mate のバージョンは20.04 LTS にアップグレードされており、16.04 バージョンは5年前のものです。ただ、Ubuntu Mate 20.04 LTS を利用する場合でも、手順は同じです。
ROS(Robot Operating System)はOpen Source Robotics Foundationによって開発されたロボット・フレームワークです。ROSは様々なロボットを操作するための汎用ミドルウエアですが、サポートしているOSは主にLinuxなので、コンピュータのOSとしてLinux Ubuntuをインストールすることが便利です。Raspberry Pi Robot(例えば、RT/RaspberryPI Mouseなど)の操作をROSを用いて実行するためには、Raspberry PiへLinux Ubuntuをインストールする必要があります。ここでは、Raspberry Pi 3 Model B に Ubuntu Mate 16.04 LTS をインストールしました。
はじめに、Ubuntu Mate 16.04 LTS をインストールする手順を説明します。Ubuntu Mate 20.04LTS のインストールについての説明は、 Ubuntu Mate 20.04 でROSを活用を参照してください。ここで使用するリモートPCは Macです。
次に、ROSのインストール手順を説明します。最新ROSバージョンは ROS Noetic Ninjemys ですが、Ubuntu 16.04 をサポートするROSのバージョンは Kinetic Kame です。ここでは、Raspberry Pi 3 に Ros-Kinetci Kame をインストールしました。
使用するRasPiはRaspberry Pi 3(Model B) です。その構成と機能は以下の通りです。
Raspberry Piを作動させるためには、電源用USB-microBケーブル、モニター(TV)との接続用 HDMIケーブル、USB接続のキーボードとマウスが必要です。Raspberry Piにはハードディスクが内蔵されていないので、microSDカードにOSをインストールして用います。16GBあるいは32GBのmicroSDを用意してください。microSDカードはそれほど高価ではないので新しい物を用意したほうが無難です。
Last updated: 2022.3.5
Ubuntu Mateのダウンロードとインストール |
microSDカードにインストールするイメージファイルをダウンロードする必要があります。Raspberry Pi用のイメージファイルをUbuntu Mateの公式サイト
からダウンロードする。xz形式で圧縮されているので、解凍する必要があります。unix系OSではxzコマンドを使います。ダウンロードしたファイル名を確認して、以下のコマンドを入力してください。
$ brew install xz $ xz -d Downloads/ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz
解凍されてimgファイルになっています。
microSDを挿す前に
$ diskutil list
と入力して、その後でmicroSDを挿して、(Linuxでは、コマンドはlsblk を使用してください)
$ diskutil list
と同じコマンドを入力します。この結果、例えば、/dev/disk2 (external, physical)が増えている時、これがmicroSDであることがわかります。できるなら新しいmicroSDを使用して下さい。使用するmicroSDに古いOS等が残っている場合(新品のmicroSDの時はフォーマットする必要はありません)、SD Associationが配布しているSDフォマッター4.0でFAT32にフォーマットする必要があります。 SD Association’s websiteから SD Formatter 4.0 をダウンロードします。SD Formatterを起動して、 この/dev/disk2/ を指定して、フォーマットします。
イメージファイルをbalenaEtcherを使用して、microSD に書き込むみます。「Flash from」 でubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img を選択して、書き込みのtarget を miocroSD にして、 Flash (書き込みの実行)します。書き込みは15分程度で終了します。
書き込みが終わったら、ejectしてmicroSDの準備完了です。
以下の手順でインストールをおこないます。
microSDをRaspiに挿入して、起動すると、インストール画面が表示されます。
しばらく時間が経過すると、設定の画面が表示されます。言語を日本語、タイムゾーンをtokyo、キーボードを日本語にし、WiFiの設定をします。login 名にubuntuと入力して、パスワードもubuntuと入力する。次に、passwordを聞いてくるので、最初にubuntuと入力します。その後、好きなパスワードに変更する。
インストールは1時間以上かかります。気長に待ちましょう。ログインに成功すると、コマンド入力を要求する状態のプロンプトが表示されます。
まず、aptのパッケージリストを更新してアップグレードしておきます。少々時間がかかります。Ubuntu OS の取扱説明はLinux OS 入門のページを参照ください
$ sudo apt update $ sudo apt upgrade
デフォルトでは、Vimエディターがインストールされていますが、Vimの操作は初心者には煩雑なので、より取り扱いやすいエディタをインストールします。好みのエディターのインストールを行う。例えば、
$ sudo apt-get install nano
と入力して、nano をインストールします。
リモートPCからSSH接続でRaspberry PiにログインするためにラズパイのIPアドレスを調べます。
$ ip addr show
というコマンドを使います。
... inet 192.168.2.7/24 ...
のようなアドレスが表示されます。このとき、PCのTerminalから
$ ssh ubuntu@192.168.2.7
とコマンドを入力します。この後、パスワードが要求されるので、入力すれば接続できます。
作業を終了するためには
$ sudo shutdown -h now
と入力して、コンピュータの電源を切って、終了します。デスクトップ画面のメニューからもshutdownをクリックできます。
と入力して、ラズパイと接続します。以後、PCからのリモート操作となります。
ROSのインストールと起動 |
ROS(Robot Operating System)をLinux Ubuntu上でインストールする手順を説明します。OSとしてUbuntu Mate 16.04がインストールされているラズパイへのROSのインストールについて説明します。ただし、ROS Melodic Moreniaのインストールでは OS としてUbuntu 18.04 が必要とされます。また、ROS Noetic Ninjemysのインストールでは、Ubuntu 20.04がインストールされていることが前提とされますので、ご注意ください。
リモートPCのデスクトップでブラウザを開いて、 http://wiki.ros.org に行って[getting started]のページ行くと、「distribution list」がありますので、ROS Kinetic Kameの「download」のページに行きます。次に、「select your platform」のページでubuntuを選択します。すると、「Ubuntu install of ROS Kinetic」のページに移行するので、そこに説明されている通りの手順でインストールする。ROS Melodic Morenia インストールするときは、ROS Melodic Morenia の download をクリックします。
注意書きに、ROS Kinetic ONLY supports Wily (Ubuntu 15.10), Xenial (Ubuntu 16.04) and Jessie (Debian 8) for debian packages.という記述があります。なお、ROS Melodic Morenia は Ubuntu Artful (17.10), Bionic (18.04 LTS) and Debian Stretchをサポートしています。
以下、ROS Kinetic Kame のインストールの手順を説明します。Ubuntu install of ROS Kinetic の手順通りに、Terminal上にコピペして実行してください。ROS Melodic Morenia や ROS Noetic Ninjemys のインストールもほぼ同様の手順になります。(デスクトップのGUI操作でインストールはできません。)
まず、リモートPCのターミナルからラズパイのUbuntuにssh接続して、ログインします。「packages.ros.org.」からのソフトを受け入れるためにセットアップします(長いですが全部でコマンド1行文です)。以下のコマンドを入力します。
$ sudo sh -c 'echo "deb http://packages.ros.org/ros/ubuntu $(lsb_release -sc) main" > /etc/apt/sources.list.d/ros-latest.list'
以下のコマンドでキーをセットアップする。(全部でコマンド1行文です)
$ sudo apt-key adv --keyserver hkp://ha.pool.sks-keyservers.net:80 --recv-key 421C365BD9FF1F717815A3895523BAEEB01FA116
インストールするにあたって、始めに、Debian package indexをアップデートする。
$ sudo apt-get update
次のコマンドでDesktop-Fullをインストールする。GUIを含めた基本セットをインストールしたい場合は、ros-kinetic-desktop-fullを選択して、インストールしてください。(GUIを用いたシミュレーションをしない場合は、ros-kinetic-desktopでも十分ですが、disktop-fullをインストール方が無難でしょう。
$ sudo apt-get install ros-kinetic-desktop-full
ROSを使用する前に、rosdepを初期化し、アップデートする必要があります。
$ sudo rosdep init $ rosdep update
ROS環境変数を設定するために、
$ echo "source /opt/ros/kinetic/setup.bash" >> ~/.bashrc $ source ~/.bashrc
と入力して、bashファイルをシェルに組み込む。更に、PythonのROSパッケージなどを組み込むために
$ sudo apt-get install python-rosinstall python-rosinstall-generator python-wstool build-essential
とコマンドを入力する。これで、一応のインストールは終了します。インストールが成功していれば、
$ roscore
とコマンド入力すると、ROSの本体が作動します。以下の通りに、ROSが起動されたことが表示されます。
------------------------------------------------------------------------------------------------------------------------------- ubuntu@Raspi:~$ roscore ... logging to /home/ubuntu/.ros/log/eee38daa-f417-11e7-bd6e-b827eb3b9c1b/roslaunch-Raspi-1782.log Checking log directory for disk usage. This may take awhile. Press Ctrl-C to interrupt Done checking log file disk usage. Usage is <1GB. started roslaunch server http://localhost:44753/ ros_comm version 1.12.7 SUMMARY ======== PARAMETERS * /rosdistro: kinetic * /rosversion: 1.12.7 NODES auto-starting new master process[master]: started with pid [1794] ROS_MASTER_URI=http://localhost:11311/ setting /run_id to eee38daa-f417-11e7-bd6e-b827eb3b9c1b process[rosout-1]: started with pid [1809] started core service [/rosout] -------------------------------------------------------------------------------------------------------------------------------
ROSの終了は「Ctrl」キーを押しながら「c」キーを押します。詳細は、この説明を読んでください。このページにあるコマンドをコピペする方がベターかもしれません。ROSの使い方ガイドは、このサイトの説明を参照してください。
ROSの構造の初歩的説明 |
最初に、ROSの構造について初歩的な説明をします。複数のノード(プログラム)の間を通信で結合させる通信ライブラリがROSの中心部分です。ノードはロボットを構成する各器官に対応していると理解します。各ノードの送信と受信はTopicという回線チャネルを介して行われます。Topicにデータを送る(publishする)ノードをpublisher、データを受信するノードをsubscriberと言います。Topicが使用可能なデータ(messages)の型は規格化されていて、それに対応するライブラリがあります。
ROSにはPythonの様々なモジュールが内蔵されているので、各ノードの作成やmessageの送・受信の仕方などは主にPythonのプログラムで書かれます。ロボットをブラウザ上で操作するためのWebページを作成する必要があるので、htmlファイルとそれに付随したjavascriptファイル、CSSファイルが活用されます。ロボットのデバイス・ドライバーをインストールするためには、C++で書かれたプログラムでシェルに組み込む必要もあります。
ROSのプログラムを書く前に、kinetic-desktop-fullをインストールした場合、Turtlesimという亀を用いたシミュレーションをしてみましょう。まず、ラズパイのデスクトップでTerminalを3つ立ち上げます。(PCにインストールしたROSで行うときは、当該PCのデスクトップでTerminalを3つ立ち上げます)一つ目で、
$ roscore
と入力して、ROS Masterを立ち上げます。二つ目のTerminalで
$ rosrun turtlesim turtlesim_node
と入力します。画面に亀アイコンが表示されています。これは亀をロボットとして使ったシミュレータです。次に、残ったTerminalで
$ rosrun turtlesim turtle_teleop_key
と入力します。今回立ち上げた「turtlesim_node」と「turtle_teleop_key」はROSの中に作られた二つのノードで、このノード間で通信をさせます。Topicという名称のチャンネルを介して通信します。turtle_teleop_keyを打ったTerminalにおける上下左右(↑↓)のキーを押すと、下の写真のように亀アイコンがその通りに移動します。
亀ロボットの操作
各ノード間の通信を可視化してみましょう。4つ目のTerminalを立ち上げて、
$ rqt_graph
と入力する。各ノード間の通信の様子が伺えます。ROSにおける各ノード間の通信の仕方が理解できたと思います。ROSには、ここで見たTopic通信以外に、service、actionというデータ通信の方法もあります。複雑なデータの送受信については実際のロボットを使用する必要がありますが、ROSにはgazeboというロボット・シミュレーションも用意されています。以下の写真がそうです。
Gazeboによるロボット・シミュレーション
ROSのプログラミング入門 |
ロボットに一連の動作をさせるためのプログラム群を納める作業スペースをcatkinワークスペースと言います。ROSを使用するにあたって最初にすることはこのcatkinワークスペースを作成することです。正確に言い換えると、例えば「catkin_ws」というわかりやすい名称のディレクトリを作成することです。このディレクトリの中にコードや設定ファイルを納めると、ロボットを動かす時に必要なもの一式が「catkin_make」というコマンド一つで生成できます。詳しい説明はhttp://wiki.ros.org/ROS/Tutorialsを参照してください。そこからのコピペがベターかもしれません。
以下のコマンドを入力して、作業用のワークスペースを作成します。
$ mkdir -p ~/catkin_ws/src $ cd ~/catkin_ws/src $ catkin-init-workspace $ cd ~/catkin_ws/ $ catkin_make
このコマンド「catkin_make」はC言語のビルド・システムのmakeに対応していて、C++でのコードのコンパイルに関係する仕事をしてます。この結果、「source」ディレクトリの中に「CMakeLists.txt」が作成され、「catkin_ws」ディレクトリの下に「devel」と「build」という名称の二つのディレクトリが生成されます。いくつかの「setup.*sh」ファイルも生成されます。
このワークスペース関連の設定をシェルに読み込ませるために、
$ source ~/catkin_ws/devel/setup.bash
と入力する必要があります。ラズパイを立ち上げたときに毎回、この読み込みの入力をすることは煩雑です。この設定を自動的に起動するためには.bashrcファイルを修正する必要があります。そこで、
$ sudo nano ~/.bashrc
と.bashrcファイルを開いて、
source /opt/ros/kinetic/setup.bash
の行を
source ~/catkin_ws/devel/setup.bash
と書き換えます。
$ echo $ROS_PACKAGE_PATH
と打って、Terminalの標示からcatkin_ws/srcへのパスが確認できれば成功です。
ロボットに一連の動作をさせるための自作のプログラム・ファイル作成した時、これらを一つのパッケージにしてROSのワークスペース(catkin_ws)にビルドする必要があります。このパッケージ名がros_testとするとき、以下のようなコマンド入力が必要です。
$ cd ~/catkin_ws/src $ catkin_create_pkg ros_test std_msgs rospy roscpp
ここでのcatkin_create_pkgはパッケージの雛形を作ることを指示します。Terminalには
Created file ros_test/CMakeLists.txt Created file ros_test/package.xml Created folder ros_test/include/ros_test Created folder ros_test/src Successfully created files in /home/koichi/catkin_ws/src/ros_test. Please adjust the values in package.xml.
と表示されます。CMakeLists.txtはROSのcmakeというビルド・システムの設定ファイルです。package.xmlはROSのパッケージ管理システムが利用するファイルです。このファイルの中にはこのパッケージが利用するモジュール(rospy、roscpp、std_msgsなど)の依存関係が書かれています。ここまで来たら一度catkin_wsに戻って、catkin_makeする必要があります。
$ cd ~/catkin_ws $ catkin_make
このコマンドを実行すると、
Base path: /home/koichi/catkin_ws Source space: /home/koichi/catkin_ws/src Build space: /home/koichi/catkin_ws/build Devel space: /home/koichi/catkin_ws/devel Install space: /home/koichi/catkin_ws/install #### #### Running command: "make cmake_check_build_system" in "/home/koichi/catkin_ws/build" #### -- Using CATKIN_DEVEL_PREFIX: /home/koichi/catkin_ws/devel -- Using CMAKE_PREFIX_PATH: /home/koichi/catkin_ws/devel;/opt/ros/kinetic -- This workspace overlays: /home/koichi/catkin_ws/devel;/opt/ros/kinetic -- Using PYTHON_EXECUTABLE: /usr/bin/python -- Using Debian Python package layout -- Using empy: /usr/bin/empy -- Using CATKIN_ENABLE_TESTING: ON -- Call enable_testing() -- Using CATKIN_TEST_RESULTS_DIR: /home/koichi/catkin_ws/build/test_results -- Found gtest sources under '/usr/src/gtest': gtests will be built -- Using Python nosetests: /usr/bin/nosetests-2.7 -- catkin 0.7.8 -- BUILD_SHARED_LIBS is on -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- ~~ traversing 4 packages in topological order: -- ~~ - beginner_tutorials -- ~~ - raspimouse_ros -- ~~ - ros_start -- ~~ - ros_test -- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -- +++ processing catkin package: 'beginner_tutorials' -- ==> add_subdirectory(beginner_tutorials) -- +++ processing catkin package: 'raspimouse_ros' -- ==> add_subdirectory(raspimouse_ros) -- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy -- Generating .msg files for action raspimouse_ros/Music /home/koichi/catkin_ws/src/raspimouse_ros/action/Music.action -- raspimouse_ros: 10 messages, 2 services -- +++ processing catkin package: 'ros_start' -- ==> add_subdirectory(ros_start) -- Using these message generators: gencpp;geneus;genlisp;gennodejs;genpy -- Generating .msg files for action ros_start/GoUntilBumper /home/koichi/catkin_ws/src/ros_start/action/GoUntilBumper.action -- ros_start: 7 messages, 1 services -- +++ processing catkin package: 'ros_test' -- ==> add_subdirectory(ros_test) -- Configuring done -- Generating done -- Build files have been written to: /home/koichi/catkin_ws/build #### #### Running command: "make -j2 -l2" in "/home/koichi/catkin_ws/build" #### --------------- 以下略 -------------
と表示されます。これで、自作のパッケージがROSで利用できるようになります。ROSの中のディレクトリを探すとき、cdの代わりにroscdを使います。以下のコマンドでパッケージが構成されていることを確認しましょう。
$ roscd ros_test $ ls
ロボットを動かすための一連のプログラムをこのパッケージに書き込んでいくことになります。以下にパッケージ内容のリストの実例を示します。
koichi@Raspi-Ubuntu:~/catkin_ws/src/raspimouse_ros$ tree . ├── action │ └── Music.action ├── CMakeLists.txt ├── LICENSE ├── misc │ ├── keikyu.bash │ └── keikyu_stop.bash ├── msg │ ├── LightSensorValues.msg │ ├── MotorFreqs.msg │ └── Switches.msg ├── package.xml ├── raspimouse.launch ├── raspimouse_ns.launch ├── README.md ├── scripts │ ├── check_driver_io.py │ ├── rtbuzzer.py │ ├── rtlightsensors.py │ ├── rtmotor.py │ └── rtswitches.py ├── srv │ ├── PutMotorFreqs.srv │ └── SwitchMotors.srv └── test ├── lightsensors_output ├── switches_output ├── travis_prepare.bash └── travis_test.bash 6 directories, 23 files
この実例は小型移動ロボットRaspberry Pi Mouse(RT社製造)を操作するための入門パッケージです。パッケージの内容は上田隆一氏(『RaspberryPiで学ぶROSロボット入門』日経BP)によって提供されたものです。現段階で必要な部分はscriptsの部分に対応するプログラムです。action、misc、srv、testのディレクトリにあるプログラムは無視しましょう。
上記に見られるscriptsに対応する部分を簡単な例で書いてみましょう。トピックへのメッセージの送信(発行)者と受信者のそれぞれのプログラムをPythonで書きます。送信者のノード名をsender、受信者のノード名をreceiverとしましょう。したがって、scriptsディレクトリにsender.pyとreceiver.pyという名前のファイルを作成します。
$ roscd ros_test $ mkdir scripts $ cd scripts $ vi sender.py
でファイルsender.pyを新しく開いて、Pythonスクリプトを記述します。エディターはnanoでもgeditでも好きな方を使ってください。以下のコードを入力してください。
#!/usr/bin/env python
import rospy
from std_msgs.msg import String
rospy.init_node('sender')
pub = rospy.Publisher('test', String, queue_size=10)
rate = rospy.Rate(10)
while not rospy.is_shutdown():
hello_str = String()
hello_str.data = "is successful. %s" % rospy.get_time()
pub.publish(hello_str)
rate.sleep()
第1行目の「#!/usr/bin/env python」はPythonで実行ファイルを作成するときのお決まりでです。第2行目でモジュール「rospy」をインポートしています。「rospy」はPythonからROSを使用するためのPythonモジュールです。第3行目の「from std_msgs.msg import String」はメッセージで送受信するデータの型を、ここでは、文字列なのでstringという型をインポートしています。rospy.init_node(...)はクオーテーションマーク内の「sender」というノードを立ち上げ、初期化をしています。rospy.Publisher('test', String, queue_size=10)は、文字列型のデータをtestという名称のトピックとして発信することを意味します。queue_size=10はバッファのサイズが10の値を持つという意味です。rate = rospy.Rate(10)は1秒間に10回の割合でプログラムを実行するというインスタンスを作成しています。while not rospy.is_shutdown():はプログラムが「ctrl+c」の入力で終了するまで無限ループで続くことを意味します。hello_str = String()は文字列のインスタンスhello_strを作成しています。hello_str.data = ".."は文字列".."をhello_strのdataというメンバー変数に書き込んでいます。%は文字列演算子で、後に続く%以下の変数値を代入することです。pub.publish(hello_str)はメッセージとしてhello_strを送信しています。rate.sleep()はインスタンスrateの機能を使って、1秒間に10回プログラムが実行されるように、作動を休みます。
同じく、
$ vi receiver.py
と打って、以下のような内容のreceiver.pyを作成してください。
#/!usr/bin/env python
import rospy
from std_msgs.msg import String
def callback(message):
rospy.loginfo("This test %s", message.data)
rospy.init_node('receiver')
sub = rospy.Subscriber('test', String, callback)
rospy.spin()
これで、scriptsディレクトリに2つのプログラムが作成できました。この2つのノード間で通信を行うことになります。通信のトピック名を'test'としてあります。rospy.init_node('receiver')はreceverというノードを立ち上げます。rospy.Subscriber('test', String, callback)は、トピックtestを受信して、callback関数で定義された動作をすることを意味します。rospy.spin() は無限ループで受信を待つことを意味します。ここでは、Terminalに「This test is successful.」と表示する動作になっています。
スクリプトを実行可能な状態にするために
$ chmod +x sender.py receiver.py
と打ちます。各ノード間の通信を実行させるために、3つのターミナルを立ち上げます。一つ目で、roscoreを入力して、二つ目で
$ rosrun ros_test sender.py
3つ目のターミナルで
$ rosrun ros_test receiver.py
と入力します。すると、このターミナルに通信結果のデータが表示されます。
3つのターミナルを立ち上げるのが面倒となるので、一つのターミナルで処理したいときはlaunchファイルを作成します。まずlaunchディレクトリを作成して、そこにlaunchファイルを作ります。
$ roscd ros_test $ mkdir launch $ cd launch $ vi test.launch
とファイルを新しく開いて、以下のコードを入力します。
<launch>
<node package="ros_test" name="sender" type="sender.py"/>
<node package="ros_test" name="receiver" type="receiver.py"/>
</launch>
このファイルの文法はxmlです。このファイルを実行するためには
$ roslaunch ros_test test.launch
と一つのコマンドを入力すれば済みます。ROSが自動的に起動します。この場合、各ノードの動作は見れませんが、別のターミナルで$rostopic echo /testとコマンドを入力すると動作状況が表示できます。また、$rostopic listと入力するとトピックの情報が見れます。ノードが正しく作動していることを確認するためには、$rosnode listと入力します。topicの送受信の設定に関する詳しい情報は、wiki.ros.org/rospy_tutorials/Tutorials/WritingPublisherSubscriberにあります。
以上でROSの初歩的なプログラミングの仕方は理解できたでしょう。Pythonコードを実行するときエラーがでることがよくありますが、これはPythonのPATHの設定に原因があります。ROSが使用しているPythonのバージョンは2.7です。Raspberry Pi以外で、例えば、ubuntu PCにROSをインストールして利用して、ROS以外のPython(anacondaなど)を使用しているケースではPythonPATHの衝突が起こりますので要注意です。
「service」を用いたノード間通信 |
トピックを介した通信はメッセージを送受するノードが互いに待つことはなく、非同期で動作します。サービスを利用すると、相手のノードの処理を待ち、その結果を受け取ることができます。サービスを実装するプログラムを作成します。ロボットのモーターの「on/off」など、一度しか送信しない指令で、「on」になったことを知りたいときには、「service」を利用します。使用できるサービスの型については、
$ rossrv list
と入力すると表示されます。サービスのサーバーとクライアントの二つのノードを立ち上げるコードを作成します。 以下の通り、スクリプトを作成してください。
#!/usr/bin/env python import rospy from std_srvs.srv import Empty from std_srvs.srv import EmptyResponse def handle_service(req): rospy.loginfo('called!') return EmptyResponse() def service_server(): rospy.init_node('service_server') s = rospy.Service('call_me', Empty, handle_service) print "Ready to serve." rospy.spin() if __name__ == "__main__": service_server()
このファイルをservice_server.pyとして/ros_test/scriptsディレクトリに保存してください。if __name__ == "__main__": はこれ以下がメインプログラムであることを意味します。実行ファイルとして使う場合の、お定まりの書き方だと思ってください。from std_srvs.srv import Empty と from std_srvs.srv import EmptyResponse はサービスの型パッケージstd_srvs.srv からEmpty及びEmptyResponse を利用することを宣言しています。関数service_server で'service_server'という名前のノードを立ち上げ、サービスの名前を'call_me'とするとなっています。サービスの型はEmptyで、コールバック関数はhandle_serviceとなっています。
以下のファイルを作成して、service_client.pyという名前でscriptsディレクトリに保存してくだい。
#!/usr/bin/env python import rospy from std_srvs.srv import Empty def service_client(): rospy.loginfo('waiting service') rospy.wait_for_service('call_me') try: service = rospy.ServiceProxy('call_me', Empty) response = service() except rospy.ServiceException, e: print "Service call failed: %s" % e if __name__ == "__main__": service_client()
最初のdefで関数service_clientを作成します。rospy.wait_for_service('call_me')はメッセージの'call_me'を受信を待ちます。 service = rospy.ServiceProxy('call_me', Empty)はメッセージ'call_me'を、Empty型で受信するserviceProxyを立ち上げて、それをservice(service clientにして)という変数に入れます。service()の内容物をresponseに返します。プログラムが読み込まれると、if __name__ == "__main__":以下にあるservice_client()が実行されます。
3つのターミナルを開いてください。一つ目のターミナルで、roscoreを起動して、2番目のターミナルで
$ roscd ros_test/scripts $ chmod +x service_server.py service_client.py $ rosrun ros_test service_server.py
と打ちます。続いて、残りのターミナルから、
$ rosrun ros_test service_client.py
と入力します。サーバー側のターミナルに、結果が表示されます。