環境
この記事は以下の環境で動いています。
項目 | 値 |
---|---|
CPU | Core i5-8250U |
Ubuntu | 16.04 |
ROS | Kinetic |
Gazebo | 7.0.0 |
python | 2.7.12 |
インストールについてはROS講座02 インストールを参照してください。
またこの記事のプログラムはgithubにアップロードされています。ROS講座11 gitリポジトリを参照してください。
概要
前回にrosbridge_serverを立てて、ブラウザのjavascriptからアクセスする例を紹介しました。今回はroslibpy
を使ってrosbridge_serverに接続するclientをpythonで作ります。
インストール
pipの問題
今回はroslibpyをインストールするのにpipを使います。pip(というよりもpython)の困ったこととしてインストールするディレクトリが様々で、混ざるとかなり面倒なことになります。例えば
- システム領域(
/usr/local/lib/python2.7/
)
aptでpipを取得した場合・sudo pip
で取得した場合 - ユーザー領域(
~/.local/lib/python2.7/
)
pip --user
で入れた場合
これにより以下のコマンドを実行すると環境が汚れてpipでエラーが起きます
sudo apt install python-pip
pip install --upgrade pip
aptとpipを併用すると問題が多いのでaptを使用せずにインストールするのが良いです。上記を行ってしまった時の対処法として以下のコマンドでpipをすべてアンインストールできます。
sudo python -m pip uninstall pip
sudo apt autoremove python-pip
実行すべきコマンド
以下を実行するとroslibpyがインストールできます。
curl -kL https://bootstrap.pypa.io/get-pip.py | sudo python
sudo pip install roslibpy
sudo pip install service_identity
ソースコード
#!/usr/bin/env python
# -*- coding:utf8 -*-
import time
from roslibpy import Message, Ros, Topic
import time
class rosbridge_client:
def __init__(self):
self.ros_client = Ros('127.0.0.1', 9090)
print("wait for server")
self.publisher = Topic(self.ros_client, '/cmd_vel', 'geometry_msgs/Twist')
self.listener = Topic(self.ros_client, '/odom', 'nav_msgs/Odometry')
self.listener.subscribe(self.callback)
self.ros_client.on_ready(self.start_thread, run_in_thread=True)
self.ros_client.run_forever()
def callback(self, message):
x = message["pose"]["pose"]["position"]["x"]
y = message["pose"]["pose"]["position"]["y"]
print(x, y)
def start_thread(self):
while True:
if self.ros_client.is_connected:
self.publisher.publish(Message({
'linear': {
'x': 0.5,
'y': 0,
'z': 0
},
'angular': {
'x': 0,
'y': 0,
'z': 0.5
}
}))
else:
print("Disconnect")
break
time.sleep(1.0)
if __name__ == '__main__':
rosbridge_client()
-
self.ros_client = Ros('127.0.0.1', 9090)
でrosbridge_serverへの接続を設定します。 -
self.ros_client.is_connected
でrosbridge_serverに接続しているかを判定します。- 切れていても
self.ros_client.connect()
で再接続を試みます。
- 切れていても
-
Message()
でメッセージをjsonで記述してself.publisher.publish()
でpublishします。 -
self.listener.subscribe(self.callback)
でsubscribeした時のcallbackを登録します。callback関数の引数で受信メッセージを渡せれて、x = message["pose"]["pose"]["position"]["x"]
のようにアクセスします。 -
self.ros_client.on_ready(self.start_thread, run_in_thread=True)
でスレッドを生成できます。
実行
roslaunch web_lecture web_if.launch
roscd web_lecture/scripts && rospy_client.py`で実行できます。
ユースケース
rosbridgeは本来rosがインストールされていないシステムからrosにアクセスするためのツールです。しかし、この疎結合のシステムを使うと下記の図のようにマルチマスターのシステムを組むこともできます。