[ロボ実験記録] Dobot magicianをpythonで動かす(公式API ver)

Dobot magicianをシリアル通信で制御する野良ライブラリを使っていたのですが、なぜか初期化に失敗することがあまりにも多かった※ので、公式のAPIを使うことにしました。
※シリアル通信の応答が何も帰ってこないことが多かったです

ドライバのインストール

Windowsなどではdobotとの接続にドライバが必要な可能性があります。

universal driverあたりを入れておけば大丈夫でした

DLLのダウンロード

公式サイトからダウンロードします。会員登録が必要です。

Dobot Demoをダウンロードします

Dobot Demoをダウンロード

rar形式で圧縮されているので、7zipなどで解凍します。
今回使うのは、
Dobot Demo V2.3-en\demo-magician-python-64-master.zip\demo-magician-python-64-master
の中身のファイル群です。32bitの方は、32-masterを使います。

ライブラリのセットアップ

Pythonのプロジェクトフォルダの中に、DobotDriverというフォルダを作り、コピーします。

こんな感じです。DobotWrapper.pyは後で定義します

DobotDllType.pyを少しいじります。
591行付近、
./DobotDLL.dll →"DobotDriver/DobotDll.dll" という感じです。

ラッパークラスの作成

元のAPIは設定項目が多すぎて少し使いにくいので、ラッパークラスを同フォルダ内に作って入れておきます。
(エンドエフェクタ周りのコードも少し入ってますが、微調整していません。後日、解説予定?)

DobotWrapper.py

from .DobotDllType import *
import time


class DobotWrapper:
    def __init__(self, COM="COM3"):
        self.COM = COM
        self.simulated = False

    def initiate(self, end_effector_type="cup"):
        self.api = load()

        # connect
        state = ConnectDobot(self.api, self.COM, 115200)[0]
        if not state == DobotConnect.DobotConnect_NoError:
            print("could not connect to DOBOT")

        # settings
        SetCmdTimeout(self.api, 3000)
        SetQueuedCmdClear(self.api)
        SetQueuedCmdStartExec(self.api)
        device = "DOBOT Magician"
        SetDeviceName(self.api, device)

        SetJOGJointParams(self.api, 50, 50, 50, 50, 50, 50, 50, 50, True)
        SetJOGCoordinateParams(
            self.api, 50, 50, 50, 50, 50, 50, 50, 50, True)
        SetJOGCommonParams(self.api, 100, 100, True)
        SetPTPJointParams(self.api, 100, 100, 100, 100,
                          100, 100, 100, 100, True)
        SetPTPCoordinateParams(self.api, 100, 100, 100, 100, True)
        SetPTPJumpParams(self.api, 20, 100, True)
        SetPTPCommonParams(self.api, 30, 30, True)
        SetHOMEParams(self.api, 200, 0, 0, 0, True)

        if end_effector_type in ["cup", "gripper"]:
            SetEndEffectorParams(self.api, 59.7, 0, 0, 0)
        elif end_effector_type in ["pen"]:
            SetEndEffectorParams(self.api, 61.0, 0, 0, 0)
        else:
            raise ValueError("invalid end effector type")

        # set home
        self.set_home()

    def set_home(self):
        SetHOMECmdEx(self.api, 0, True)

    def reset_alarm(self):
        ClearAllAlarmsState(self.api)

    def move_arm(self, x, y, z, w):
        self._check_xy(x, y)
        if not self.simulated:
            SetPTPCmdEx(self.api, PTPMode.PTPMOVJXYZMode, x, y, z, w, True)

    def get_position(self):
        return GetPose(self.api)[:4]

    def _check_xy(self, x, y):
        r = (x**2+y**2)**0.5

        if r < 115 or r > 320:
            raise ValueError(
                f"invalid position! (x^2+y^2)^0.5 ={r} should be 115~320. x={x} y={y}")

    def cup(self, mode=True):
        if mode:
            SetEndEffectorSuctionCup(self.api, True, True)
        else:
            SetEndEffectorSuctionCup(self.api, False, True)
        # SetEndEffectorGripper(self.api, 0, True)

    def grip(self, grip=True, sleep=0.5):
        if grip:
            SetEndEffectorGripper(self.api, True, True)
        else:
            SetEndEffectorGripper(self.api, True, False)
            time.sleep(sleep)
            SetEndEffectorGripper(self.api, False, False)

利用

Dobotの初期化
initiateを実行すると、諸々が初期化されます。
座標補正のため、ホーミングと呼ばれる動作もします(明後日の方向にアームが動きます)。

from DobotDriver.DobotWrapper import DobotWrapper
dobot=DobotWrapper("COM3")
dobot.initiate()

アームの移動

x,y,z,rを設定するだけです

dobot.move_arm(170, 10,-20 ,0,)

座標の取得
x,y,z,rが返ってきます

dobot.get_position()

TODO
x,y,zの可動域を軽く設定しており、それを外れるとエラーが返ってくるようになっています。ただ、可動域の定義が完璧ではないので、注意。

変なところにアーム座標を設定して、アラームが出た時は、reset_alarmします

dobot.reset_alarm()


いいなと思ったら応援しよう!