1. はじめに
本稿では、ROS を使ったプログラムでMG400を実際に動かす方法をご案内します。ここでは、例としてPythonを使って書いたプログラムをご紹介します。
WindowsにROSをインストールする方法は、以前の記事をご参照ください。
[MG400] WindowsのWSL2にROSをインストールし、MG400をrviz上で動かす方法
2. 環境
以下の環境にて、この手順が有効であることを確認しています。
OS: Windows 10 (64bit)
WSL2: Ubuntu-20.04
ROS: Noetic
3. 手順
3.1 MG400_ROS パッケージのインストール
ROSでMG400の実機を動かすためには、弊社のMG400_ROSのパッケージを使用する必要があります。
以前の記事でDobot社のMG400_ROS のパッケージをインストールしていた場合は競合してしまうため、以前のパッケージを削除するか、新しいワークスペースを作りそこに新たなパッケージをダウンロードしてください。
(1) ワークスペースにソースコードを展開する。
$ cd ~/catkin_ws/src
$ git clone https://github.com/TechShare-inc/MG400_ROS.git
(2) ビルドする。
$ cd ~/catkin_ws
$ catkin_make
(3) 環境設定をする。
$ echo "source ~/catkin_ws/devel/setup.bash" >> ~/.bashrc
$ source ~/.bashrc
3.2 プログラムを書く
(1) ファイルを作成し、ノードを実行可能にする。ここでは、sample.py にプログラムを書いていきます。
$ cd ~/catkin_ws/src/MG400_ROS/mg400_bringup/
$ mkdir scripts
$ touch scripts/sample.py
$ chmod +x scripts/sample.py
(2) Pythonでプログラムを書く
ROSでMG400を操作するために、MG400_ROS/mg400_bringup/srv、/msg 内のファイルで定義されているさまざまなサービスおよびトピックを利用することができます。ここで利用するサービスは以下の通りです。
・MovJ(引数 – float64 x y z r、戻り値 – int32 res): 与えた直交座標系の点まで動かす。成功したら 0 を返す。
・EnableRobot(引数 – なし、戻り値 – int32 res): ロボットを有効化させる。
・DisableRobot(引数 – なし、戻り値 – int32 res): ロボットを無効化させる。
・ClearError(引数 – なし、戻り値 – int32 res): エラーを取り除く。
各サービスの情報を表示させたい場合、ターミナルで以下のコマンドを実行します。
$ rosservice info <サービス名>
たとえば、サービス名にmg400_bringup/srv/MovJ を入れると、
$ rosservice info mg400_bringup/srv/MovJ
Node: /mg400_bringup
URI: rosrpc://VortexNote-03:50085
Type: mg400_bringup/MovJ
Args: x y z r
サービスの引数、戻り値を確認したい場合は、以下を実行します。
$ rossrv show <サービスの型>
たとえば、
$ rossrv show mg400_bringup/MovJ
float64 x
float64 y
float64 z
float64 r
---
int32 res
各サービスの説明は、Dobot社のTCP-IP Protocolをご参照ください (英語)。サービスの種類や引数などは異なる場合があります。
sample.py には、MG400が3点を移動するサイクルが10回繰り返されるプログラムを書きます。サービス MovJ を利用して指定した点へMG400を動かしています。前の動きが完了してから次の動きのリクエストを送るため、トピック RobotStatus を購読し、ロボットのステータスに応じて待つか次の動きに進むかを判断しています。
ロボットの動作を変更するためには move() 関数内を変更します。wait() や sleep() 関数等を使用して各動作を反映させます。
#!/usr/bin/env python
import rospy
from mg400_bringup.srv import *
from mg400_bringup.msg import RobotStatus
class Move:
def __init__(self):
# 新しいノードを作る
rospy.init_node('MG400_work')
# MG400 のステータスを格納する変数
self.status = 0
# 使用するサービスを呼ぶハンドラー
self.enable = rospy.ServiceProxy('mg400_bringup/srv/EnableRobot', EnableRobot)
self.moveJ = rospy.ServiceProxy('mg400_bringup/srv/MovJ', MovJ)
self.disable = rospy.ServiceProxy('mg400_bringup/srv/DisableRobot', DisableRobot)
self.clear_error = rospy.ServiceProxy('mg400_bringup/srv/ClearError', ClearError)
# RobotStatusトピックを購読
rospy.Subscriber("mg400_bringup/msg/RobotStatus", RobotStatus, self.robotStatus_callback)
self.rate = rospy.Rate(20)
# 指定の時間スリープさせる
def sleep(self, duration):
now = rospy.Time().now()
while now + rospy.Duration(duration) > rospy.Time().now():
self.rate.sleep()
# エラーが発生した際に、リスタートをするか選択させる
def restart(self):
answer = input("Error detected. Do you want to continue? [y/N]: ").lower()
self.sleep(2)
self.disable()
self.clear_error()
if answer in ['y', 'yes']:
self.enable()
self.sleep(2)
elif answer in ['n', 'no']:
self.sleep(2)
self.disable()
sys.exit(1) # プログラムを終了される
# 購読したトピックのメッセージで変数をアップデートする
def robotStatus_callback(self, robot_status):
"""
1: "ROBOT_MODE_INIT",
2: "ROBOT_MODE_BRAKE_OPEN",
3: "",
4: "ROBOT_MODE_DISABLED",
5: "ROBOT_MODE_ENABLE",
6: "ROBOT_MODE_BACKDRIVE",
7: "ROBOT_MODE_RUNNING",
8: "ROBOT_MODE_RECORDING",
9: "ROBOT_MODE_ERROR",
10: "ROBOT_MODE_PAUSE",
11: "ROBOT_MODE_JOG"
"""
self.status = robot_status.robot_status
# 前の動きが止まるまで待つ
def wait(self):
if self.status == 9: # エラーのときは restart()を呼ぶ
self.restart()
self.sleep(0.5)
while self.status !=5:
if self.status == 9:
self.restart()
break
self.rate.sleep()
# ロボットを動かす
def move(self):
# 指定のサービスが使えるようになるまで待機
rospy.wait_for_service('mg400_bringup/srv/EnableRobot')
try:
self.enable()
self.wait()
self.sleep(1)
for _ in range(10): # 10サイクル繰り返す
self.moveJ(280, 165, -60, 30)
self.wait()
self.moveJ(275, -170, -30, -30)
self.wait()
self.moveJ(220, -35, 48, -10)
self.wait()
self.disable()
except rospy.ServiceException as e:
print("Service call failed: %s"%e)
if __name__ == "__main__":
print("MG400 sample start")
mv = Move()
mv.move()
rospy.spin()
3.3 プログラムを実行する
(1) MG400 の LAN1とPCをケーブルで繋げ、電源を入れる。
(2) PC のイーサネットのIPアドレスを固定する。「[MG400, M1Pro] DobotStudioPro セットアップ方法」の 3-2. IPアドレスの固定をご参照ください。
(3) MG400のIPアドレスを指定しながら mg400_bringup パッケージを起動する。
$ roslaunch mg400_bringup mg400_bringup.launch robot_ip:=192.168.1.6
(4) 別のターミナルで、
$ rosrun mg400_bringup sample.py
3.4 うまく動作しない場合
- プログラムを実行してもMG400が動かない
解決方法:mg400_bringupを起動させながら、別ターミナルで
$ rosservice call /mg400_bringup/srv/ResetRobot
を呼んだ後、再度プログラムを実行する。他にも、サービスをターミナルから直接呼ぶには「rosservice call <サービス名>」コマンドが使用できる。
- エラーでLEDライトが赤くなり停止する
解決方法:
MovJ などで指定した座標が可動域外でないか確認する。一時的なエラーの場合は、
$ rosservice call /mg400_bringup/srv/ClearError
でエラーを取り除き、再度プログラムを実行する。
繰り返しエラーが起こるならば、DobotStudio Pro をつなぎながらエラーが発生するプログラムを実行し、エラー内容を確認してください。DobotStudioPro セットアップ方法はこちら。
- 「
/usr/bin/env: 'python\r': No such file or directory
」と表示される
解決方法:改行コードを「LF」に変更する。
変更しても「/usr/bin/env: 'python': No such file or directory
」と出る場合は、「python -V
」でpython 3がインストールされていることを確認してから、実行するファイルの最上部にある「#!/usr/bin/env python
」を「#!/usr/bin/env python3
」に変更する。
3.5 プログラムの実行結果
今回作成したsample.py を実行させると、MG400が以下のように動くのが確認できます。
本稿では、ROSを利用したPythonのプログラムでMG400の実機を動かす方法をご紹介しました。
ご不明点等ございましたら、お気軽にdobot@techshare.co.jpまでお問い合わせください。