Jetbot+ROS+Python3環境構築
この記事について
この記事ではJetbotのOSイメージにROSをインストールしPython3でROSのスクリプトを記述する方法について説明する。Jetbotのイメージで提供されているPythonのライブラリはPython3で記載されている。しかし、公式ではROSはPython2系対応のみだ。そのためJetbotのライブラリを利用してJetbot向けのROSのパッケージを作ることができない。 そこでROSのパッケージ開発(rospyなどを使った開発)のみPython3で行えるようにした。今回はROSのシステムはPython2.7で動作する。実際は以下のように ROS全てをPython3で動くようソースからビルドするのが望ましいだろう。
手順
1. ROSのインストール
ROSのインストールは公式ページに従って進める。今回ROSのバージョンはMelodicをインストールした。またros-melodic-desktop
を利用した。Jetson nano及びJetbotの場合、OSはUbuntu 18.04 がインストールされている。
roscore, rosrunが実行できる状態まで持っていく。またpython2系でimport rospy
ができるところまで確認する。
2. Python3向け準備
ROSコマンドやPYTHONPATHはROSインストール時にインストールされるPython2.7をさしている。ROSのPythonライブラリであるrospyやsensor_msgsなどはPython3系でそのまま動くようになっている。そこで、Python3からPython2.7のdist-packageにインストールされているROSライブラリを参照できるようにする。
2. Python3からrospyを使えるようにする。
基本的にはPyhotn3のパスにPyhton2.7のdist-packageのパスが追加できればいい(と信じている)rospkgというパッケージをインストールするとこれが実現できる。何らかの副作用だと思うが深くは追っていない。
sudo pip3 install rospkg catkin_pkg
パッケージのインストール後、Python3でrospy, sensor_megsがインポートできるようになる。
3. vision_opencvのインストール
この状態でOpenCVとROSのブリッジライブラリcv_bridge
ライブラリを利用するとエラーが発生する。cv_bridge
で利用しているネイティブライブラリがPython2系向けにコンパイルされているためだ。そこで、cv_bridge自体をPython3系向けにコンパイルし直す必要がある。手順は以下のページを参考にした。一部パスがx86向けなので、ARM向けに修正した。
How to setup ROS with Python 3 - Omri Ben-Bassat - Medium
- python3系向けにビルドするための準備
mkdir ~/catkin_build_ws && cd ~/catkin_build_ws catkin config -DPYTHON_EXECUTABLE=/usr/bin/python3 -DPYTHON_INCLUDE_DIR=/usr/include/python3.6m -DPYTHON_LIBRARY=/usr/lib/aarch64-linux-gnu/libpython3.6m.so catkin config --install
mkdir src cd src git clone -b melodic https://github.com/ros-perception/vision_opencv.git
cd ~/catkin_build_ws catkin build cv_bridge source install/setup.bash --extend
これで、Python3でROSパッケージを書く準備が整った。
4. スクリプトの書き方と実行方法
rosのワークスペースで新しいパッケージを作成する。ワークスペースはパスさえ通っていれば先ほどのワークスペースと違うものでも大丈夫。 パッケージ内にscriptsフォルダを作成し、次のファイルを作成する。
- camera.py
#!/usr/bin/env python3 import yaml import rospy from sensor_msgs.msg import Image from cv_bridge import CvBridge, CvBridgeError from jetbot import Camera from sensor_msgs.msg import CameraInfo NODE_NAME = 'jetbot_camera_node' IMAGE_TOPIC = 'jetbot/image_raw' class JetbotCamera: def __init__(self, width=640, height=480, calib_file=''): self.calib_file = calib_file self.camera = Camera(width=width,height=height) self.publisher = rospy.Publisher(IMAGE_TOPIC, Image, queue_size=1) self.bridge = CvBridge() def start(self): rospy.init_node(NODE_NAME) self.camera.observe(self.image_proc, names='value') self.camera.start() rospy.spin() def image_proc(self, change): image_value = change['new'] cv2_image = self.bridge.cv2_to_imgmsg(image_value, 'bgr8') self.publisher.publish(cv2_image) if __name__ == '__main__': jetbot_camera = JetbotCamera() jetbot_camera.start() pass
ファイル先頭に#!/usr/bin/env python3
を記載する。またファイルのパーミッションを755に設定し、実行ファイルにする。その後以下のコマンドで実行する。
roscore #別ターミナルに切り替え rosrun ros_package-name camera.py
そうするとjetbot/image_rawというトピックが設定される。rosのimage_viewで画像を表示させてみる。
rosrun image_view image_veiw image:=jetbot/image_raw
まとめ
jetbot用に車輪のコントロールと画像を受信するrosパッケージを作ってみた。広角カメラのカメラパラメータも一緒に入ってる。 時間があるときにちょくちょくメンテする予定。