はじめに
ロボットに高度な行動を行わせようとすると,
自ずと複数のタスクを組み合わせて制御する必要が出てます.
例えば,
ある物体をこちらまで持ってくるためには,
その物体を探して,
その場所まで,安全に移動し,
その物体をアームで掴んで,
そして再び元の場所に戻ってくる.
などのタスクを正確なタイミングで組み合わせなくてはなりません.
このように複雑なタスクを複数組み合わせる場合,
それぞれの行動を行うためのプログラム,
つまり,ROSで言うところのノードの起動や停止を
ロボット自身が周りの環境や自分の状態を認識しながら制御する必要があります.
そこで,今回ROSを使用したロボットソフトウェアプラットフォームにおいて,
Pythonスクリプトを使用して,
他のノードを起動したり,停止させる方法について説明したいと思います.
SubprocessによるROSノード起動
今回の方法では,ノードの制御に
Python のデフォルトモジュールである
Subprocess モジュールを使用します.[1]
この Subprocess モジュールは,
Python スクリプトの中で
様々なプログラムを起動するためのモジュールであり,
自動的にマルチプロセスで様々なプログラムを起動することができます.
この Subprocess モジュールを使用するためには,
Python スクリプト内で,
from subprocess import *
と記述すれば良いです.
続いて,
起動する対象のノードが
自動的に役目を終えるとプロセスを終了するプログラムの場合
(例えば,Bag File Serverなど),
以下のように Call 関数という関数を利用すると便利です..
call([’rosrun’,’fakelocalization’,’fakelocalization.py’])
このCall 関数では,
引数に通常通りノードを起動する時に
ターミナルに入力する文字列をカンマ区切りで入力すると,
そのプログラムを起動し,
そのプログラムが正常に終了すると,
Call関数から処理が抜けるという仕様になっています.
一方,
ノードが自動的に終了しない,
または Call 関数の場合,
呼び出したノードの処理が終わるまでは,
他のスクリプトの処理を行うことができないため,
あるノードを起動しながら,
他のスクリプト処理を行いたい場合には,
以下のような Popen 関数を利用して,ノードを起動すると便利です.
p=Popen([’rosrun’,’infant_ddf’,’infant_ddf_fab.py’])
この Popen 関数は,
起動したノードをマルチプロセスで起動したまま,
次の処理を行います.
従って,これらのcall関数とPopen関数を使用すれば,
Pythonスクリプト内において,
好きなタイミングで単一,または複数のノードを起動することができるのです.
rosnodeモジュールによる他のノード起動チェック
rosnodeというnode専用のpythonモジュールを使うことで、
指定したノード名のノードが立ち上がっているかを
簡単のチェックすることができます。
import rosnode isNodeAlive=rosnode.rosnode_ping("/mrpc_interface",max_count=1,verbose=False)
ノードが立ち上がっているかは、返り値のboolで判断できます。
引数のmax_countはpingを送る回数なので、
ノードが立ち上がっているかを確認したい場合は、
max_count=1で良いと思います。