RobotServiceインターフェース

本節では、RobotServiceを使用するインターフェースについて説明します。次のインターフェースが含まれています。

モックRobotServerサービス

モックRobotServerサービスは通常、Vizティーチングの場合に使用されますが、ロボットをRobotServerを介して制御することはできず、その代わりにRobotServerの役割を模擬するためにRobotServiceを作成します。RobotServiceがMech-Centerに登録された後、Mech-Vizはロボット実機と同様の方法で「RobotService」と情報のやり取りを行います。

モックRobotServerサービスは、以下の場合に使用されます。

  • Mech-Visionに計算されるロボットの関節角度を取得する場合(Eye In Hand)。

  • ロボット実機から位置姿勢を取得し、それをRobotServiceサービスに転送する場合。

サンプル

以下は、Adapterの子クラス内での呼び出し方法の例です。

def _register_service(self):
       """
       register_service
       :return:
       """
       if self.robot_service:
           return

       self.robot_service = RobotService(self)
       other_info = {'robot_type': self.robot_service.service_name}
       self.server, _ = register_service(self.hub_caller, self.robot_service, other_info)

       self.robot_service.setJ([0.0, 0.0, 0.0, 0.0, 0.0, 0.0])

以下は、RobotServiceクラスの例です。

class RobotService(JsonService):
    service_type = "robot"
    service_name = "robot"
    jps = [0, 0, 0, 0, 0, 0]
    pose = [0, 0, 0, 1, 0, 0, 0]

    def getJ(self, *_):
        return {"joint_positions": self.jps}

    def setJ(self, jps):
        logging.info("setJ:{}".format(jps))
        self.jps = jps

    def getL(self, *_):
        return {"tcp_pose": self.pose}

    def getFL(self, *_):
        return {"flange_pose": self.pose}

    def setL(self, pose):
        logging.info("setL:{}".format(pose))
        self.pose = pose

    def moveXs(self, params, _):
        pass

    def stop(self, *_):
        pass

    def setTcp(self, *_):
        pass

    def setDigitalOut(self, params, _):
        pass

    def getDigitalIn(self, *_):
        pass

    def switchPauseContinue(self, *_):
        pass

getJ

getJ()は、Mech-VizおよびMech-Visionで現在の関節角度を取得するために使用されます。通常の場合、関節角度を設定するためにはsetJ()を使用し、その後getJ()を呼び出すことが一般的です。以下に例を示します。

サンプル

def getJ(self, *_):
     pose = {"joint_positions": self._jps}
     return pose
  1. Eye In Hand:ロボットから送信された関節角度をsetJ()に書き込みます。

    def setJ(self, jps):
      assert len(jps) = 6
      for i in range(6):
          jps[i] = deg2rad(float(jps[i]))
      self._jps = jps
      logging.info("SetJ:{}".format(self._jps))

    その中、jpsはロボットから送信された関節角度データで、getJ()によって呼び出されるようにself._jpsに割り当てられます。関節角度データを取得する際に、適切な単位変換を行ってラジアン形式のデータを取得する必要があります。

  2. Eye to Handの場合、現在のロボットの関節角度に基づいて目標点を設定する必要はありませんが、ロボット実機の状態をシミュレーションする場合、安全な目標点を設定する必要があります(通常は初期位置)。そうしないと、ランダムな値が割り当てられてしまい、エラーが発生しやすくなります。

    def getJ(self, *_):
         return {"joint_positions": [1.246689,-0.525868,-0.789761,-1.330814, 0.922581, 4.364021]}

getFL

getFL()は、ロボットの画像撮影時におけるフランジ位置姿勢を提供するために使用されます。Eye In Hand方式では、フランジとカメラの位置関係をキャリブレーションしますが、最終的に使用するデータは基準座標系であるため、画像撮影時のロボットのフランジ位置姿勢が必要です。

def getFL(self, *_):
    return {"flange_pose": self.pose}

Eye In Hand方式でビジョンポイントを提供する際には、以下の点に注意する必要があります。

  1. ロボットが画像撮影時の関節角度(JPs)を返す場合、RobotServiceでsetJ()を直接呼び出すことができます(ラジアン単位)。この関数は[]を返します。

  2. ロボットがフランジ位置姿勢を返す場合、次の操作を行う必要があります。

    • Mech-Visionプロジェクトの「extri_param.json」外部パラメータファイルの「is_eye_in_hand」がtrueに設定されていることを確認します。

    • RobotServiceのsetFL()を呼び出します(メートル単位、四元数形式の位置姿勢)。

moveXs

Adapterによって作成されたRobotServiceサービスは、moveXs()を使用して、Mech-Vizによって計画された経路点データを受け取ります。以下に例を示します。

関数定義

def moveXs(self, params, _):
     with self.lock:
         for move in params["moves"]:
             self.targets.append(move)
     return {"finished": True}

その中で、paramsはMech-Vizプロジェクトのすべてのパラメータが渡されており、params[“moves”]を使用すると、ビジョン移動や相対移動を含むすべての移動点の位置姿勢情報を取得できます。位置姿勢情報はデフォルトで関節角度の形式で返されます。その位置姿勢をself.targetsに渡すことで、後続の呼び出しで使用できるようになります。

サンプル

通常、この関数は通知と共に使用されます。Adapterが通知メッセージを受信した場合、self.targetsを関数に送信して変換し、パッケージ化してロボットに送信します。以下に例を示します。

def notify(self, request, _):
    msg = request["notify_message"]
    logging.info("{} notify message:{}".format(self.service_name, msg))
    if msg = "started":
        with self.lock:
            self.move_targets.clear()
    elif msg = "finished":
        with self.lock:
            targets = self.move_targets[:]
            self.move_targets.clear()
        self.send_moves(targets)

通知メッセージが「started」の場合、目標点リストをクリアします(Mech-Vizのエラー中断により、前後の2つの移動点が重なってしまうのを防ぐため)。通知メッセージが「finished」の場合、目標点リストをpack_move関数に渡します(データ統合送信のため)。

def pack_move(self, move_param):
     move_list = []
     for i, move in enumerate(move_param):
         target = move["target"]
         move_list.append(target)
     logging.info("move list num:{}".format(len(move_list)))
     logging.info("move list:{}".format(*move_list))
     motion_cmd = pack('>24f', *move_list)
     self.send(motion_cmd)

現場の要件に応じて、Mech-Vizのすべての移動点を送信するか、indexに従っていくつかの点を選択して送信することができます。pack_move()は通常、ロボットの各ブランドが必要とするフォーマットに従ってデータを統合します(通常、通信プロトコルで事前に設定される)。