ROS(Robot Operating System)
ですが、Raspberry Pi(ラズパイ)やArduinoと組み合わせて手軽に試すことができます。OSとついていますが、実際にはRaspbianやUbuntu Mate上で動作するミドルウェアと言えます。
前回はPub/Subを簡単に試してみましたが、今回はサーボモータを動かす実験をしてみます。
プログラミング言語としてPythonを用いますので、C言語のようにコンパイルもいらず、手軽に試せることでしょう。
OSはUbuntu Mateで
ROSをRaspbianにインストールするドキュメントもあるのですが、試してみた限りでは最後の起動で失敗してしまいました。そのため、前回と同様に今回もUbuntu Mate 18.04を使っています。特に問題はないと思いますが、ライブラリのバージョンなどが多少異なる可能性があります。Raspbianの場合、ROSを一つずつコンパイルしないといけないですが、Ubuntu Mateの場合はパッケージ管理から簡単にインストールできるのも大きな利点です。
ROSインストールから初期セットアップまでは下記コマンドになります。詳しくは前回の記事を参考にしてください。
$ sudo apt-get update $ sudo apt-get upgrade -y $ sudo add-apt-repository universe $ sudo add-apt-repository multiverse $ sudo add-apt-repository restricted $ 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-key adv --keyserver 'hkp://keyserver.ubuntu.com:80' --recv-key C1CF6E31E6BADE8868B172B4F42ED6FBAB17C654 $ sudo apt-get -y update $ sudo apt-get -y upgrade $ sudo dpkg -i --force-all /var/cache/apt/archives/linux-firmware-raspi2_1.20190215-0ubuntu0.18.04.1_armhf.deb $ sudo apt-get upgrade $ sudo apt install ros-melodic-desktop-full -y $ sudo rosdep init $ rosdep update $ echo "source /opt/ros/melodic/setup.bash" >> ~/.bashrc $ source ~/.bashrc $ sudo apt-get -y install python-rosinstall $ mkdir -p ~/catkin_ws/src $ cd ~/catkin_ws/src $ catkin_init_workspace $ cd ~/catkin_ws $ catkin_make $ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc $ source ~/.bashrc $ roscore
パッケージを作成する
今回もまずPub/Subの仕組みを作りますので、ja/ROS/Tutorials/WritingPublisherSubscriber(python) – ROS Wikiに沿って進めていきます。まずパッケージを作ります。パッケージの作り方についてはja/ROS/Tutorials/CreatingPackage – ROS Wikiを参考にします。
$ cd ~/catkin_ws/src $ catkin_create_pkg beginner_tutorials std_msgs rospy roscpp $ roscd beginner_tutorials
Pythonスクリプト用のディレクトリを作成
Pythonスクリプトを格納するディレクトリを作成します。
$ mkdir scripts $ cd scripts
スクリプトを配置する
テンプレートになるスクリプトをダウンロードします。
$ wget https://raw.github.com/ros/ros_tutorials/indigo-devel/rospy_tutorials/001_talker_listener/talker.py $ chmod +x talker.py $ wget https://raw.github.com/ros/ros_tutorials/indigo-devel/rospy_tutorials/001_talker_listener/listener.py $ chmod +x listener.py
コードを見ると分かりますが、talker.py
が現在時刻を発信(Publish)し、listener.py
がその発信を購読しているという仕組みです。
ビルドする
このコードを確実にデプロイするため、 catkin_make
を実行します。
$ cd ~/catkin_ws $ catkin_make
実行する
では試しに実行してみます。まず購読側を実行します。
$ rosrun beginner_tutorials listener.py
次に発信側を実行します。
$ rosrun beginner_tutorials talker.py
そして、購読側のログに以下のように流れれば問題ありません。
[ INFO] 1251943144.400553000: Received [Hello there! This is message [1]] [ INFO] 1251943144.600712000: Received [Hello there! This is message [2]]
サーボモータのコードに変更する
では続いてこのtalker.py
、listener.py
をサーボモータを動かすコードに変えてみたいと思います。talker.pyからサーボモータの値を送信し、listener.py
はその値にモータを動かすという仕組みです。
pigpiodのインストール
サーボモータを動かす際にはGPIOを使いますので、pigpiodをインストールします。
$ sudo apt-get install pigpio python-pigpio python3-pigpio -y $ sudo systemctl enable pigpiod $ sudo systemctl start pigpiod
Publish側のコード
Publish(発信)側のコードです。サーボモータの動作範囲である 500〜2500 の値を100ずつ増加させたり、逆に減らしたりします。発信できるのは文字列のみなので、str関数を使って数字を文字列にしています。
#!/usr/bin/env python import rospy from std_msgs.msg import String def talker(): pub = rospy.Publisher('chatter', String, queue_size=10) rospy.init_node('talker', anonymous=True) rate = rospy.Rate(10) # 10hz i = 500 plus = True while not rospy.is_shutdown(): msg = str(i) rospy.loginfo(msg) pub.publish(msg) rate.sleep() if plus: i += 100 else: i -= 100 if i == 2500: plus = False if i == 500: plus = True if __name__ == '__main__': try: talker() except rospy.ROSInterruptException: pass
Subscribe側のコード
Subscribe(購読)側のコードです。こちらは送られてきた文字列を数字にして、その値をサーボモータに適用しているだけです。サーボモータはGPIOの23番ピンを使っています。
#!/usr/bin/env python import rospy import pigpio from std_msgs.msg import String SERVO_PIN = 23 pi = pigpio.pi() def callback(data): rospy.loginfo(rospy.get_caller_id() + 'I heard %s', data.data) p_width = int(data.data) pi.set_servo_pulsewidth(SERVO_PIN, p_width) def listener(): rospy.init_node('listener', anonymous=True) rospy.Subscriber('chatter', String, callback) rospy.spin() if __name__ == '__main__': listener()
デモ
実際に動かしているところです。
このようにROSのPub/Subを使うことで、モジュールの独立性が高まったり、複数のモジュールを同時に操作できるようになります。発信側ではサーボモータの数字を指定するだけで、pigpioを読み込む必要もありません。
まとめ
ROSを使えばセンサーに依存したコードを排除したり、再利用性の高いノードを開発できるようになります。コールバックやPub/Subを使った方式なので、値や状態変化によって動作するロボットを開発するのが簡単になるでしょう。ぜひRaspberry Piと一緒に試してみてください。
]]>