[ロボ実験記録] ロボットアームDobot MG400をpythonで動かす(TCP-IP通信)
はじめに
ロボットアームDobot MG400をpythonで動かす試行錯誤のメモです。
以下の記事の続きです。
MG400を制御する手段
軽くネットを調べた感じ、23/12/15時点で4つほど選択肢がありました。
公式のDobot Studio Proを使う
GUIまたはlua言語
ネットに転がっているROS2ライブラリを使う
Robot operation system (ROS)のセットアップが必要
公式のSDKを読み解いて動かす
TCP-IPプロトコルで動くようです
TCP-IPプロトコルを動かすラッパーライブラリを使う
GUI/Lua言語では拡張性に課題があります。一方、ROSは下手に触ると火傷します。
そのため、Pythonだけで動かせるインターフェースを今回はつかいます。いろいろと探したところ、TCP-IPのラッパーライブラリがあったので、それを試すことにします。
dobotの設定変更
ラッパーライブラリを使う前に、dobotの設定の変更が必要でした。
(ここに詰まりました)
ソフトウェアの設定画面上で、「TCP/IP..」を選んで、適用後、このソフトからは接続解除しておく必要があります。
これをしないと、通信時の戻り値がすべて-1になり、何もうごきません。
ライブラリの使用
ライブラリのセットアップ
git cloneでOK
git clone https://github.com/Dobot-Arm/TCP-IP-4Axis-Python.git
dobot_api.pyが肝となるファイルです。適当に環境変数のパスなどに追加して、これを読み込める状態にしておきます。
実際のロボット操作の例はPythonExample.pyに記載があります。
dobotの初期化
from dobot_api import DobotApiDashboard, DobotApi, DobotApiMove, MyType
from time import sleep
import numpy as np
def connect_robot(ip="192.168.1.6"):
try:
dashboard_port = 29999
move_port = 30003
feedback_port = 30004
print("Attempting to establish connection...")
dashboard = DobotApiDashboard(ip, dashboard_port)
move = DobotApiMove(ip, move_port)
feed = DobotApi(ip, feedback_port)
print("Connection successful!")
return dashboard, move, feed
except Exception as e:
print("Connection failed :(")
raise e
#初期化: dobotのipは環境に応じて変更
dashboard, move, feed = connect_robot(ip="192.168.11.40")
enable
dashboard.EnableRobot()
うまく実行できると、'0,{},EnableRobot();'というレスポンスが帰ってきます。
終了するときは
dashboard.DisableRobot()
です。
アームを動かす
move.RelMovL(-10,0,0,0) #相対座標でx-=10とする例
アームを動かして、動かし終わるまで待つ
Sync系の関数を呼び出すと、動作が終わるまで(多分)待ってくれる模様です。
move.RelMovL(0,10,10,0)
#move.SyncAll()
print("fin")
現在の座標を取得する
dashboard.GetPose()
(ジョイント角の倍は、GetAngle)
現在の座標を取得して、そこから少し移動する
GetPoseとMovLをつかいます。
GetPoseの返り値がただの文字列なので、floatに変換するcodeも必要です。
def extract_values(response):
# レスポンスから中括弧内の値を抽出する
start = response.find('{') + 1
end = response.find('}')
values_str = response[start:end]
# 文字列を数値のリストに変換
values = [float(val) for val in values_str.split(',')]
return values
response=dashboard.GetPose()
pose=extract_values(response)
#yを-10する例
move.MovL(pose[0],pose[1]-10,pose[2],pose[3])
移動スピードの変更
dashboard.SpeedL(1) #範囲は1-100の整数の模様
エラー番号の取得
dashboard.GetErrorID()
おかしな座標を設定すると17、接触センサが起動したときは-2でした。
エラーからの復旧
dashboard.ClearError()
dashboard.Continue()
動作の様子
1218追記: 状態の取得
feedインスタンスを使うと、アームの位置etcを高速で取得できます。
以下は、1 secごとにアームの状態を取得し、更新があったパラメータを表示するコードです。
from dobot_api import MyType
import time
def get_buffer():
data = bytes()
hasRead = 0
while hasRead < 1440:
temp = feed.socket_dobot.recv(1440 - hasRead)
if len(temp) > 0:
hasRead += len(temp)
data += temp
feedInfo = np.frombuffer(data, dtype=MyType)
return feedInfo
#if hex(feedInfo['test_value'][0]) == '0x123456789abcdef':
# print(feedInfo['EnableStatus'][0]) # 出力机器使能状态
previous_data=None
while True:
data=feedInfo=get_buffer()
current_data = np.frombuffer(data, dtype=MyType)
# 前回のデータと比較して変更がある場合のみ表示
print("---------------")
if previous_data is not None:
for field in MyType.names:
#if current_data[field] != previous_data[field]:
if not np.array_equal(current_data[field], previous_data[field]):
print(f"Changed: {field} ")
# 現在のデータを保存
previous_data = current_data.copy()
time.sleep(1)
力がかかったときに変化するパラメータを探したのですが、特に見つかりませんでした。まじめな触覚センサは、CRシリーズじゃないと難しい印象です。