RobotServiceインターフェイス

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

RobotServerサービスをシミュレート

RobotServerサービスのシミュレーションは通常、ロボットを主動制御するために使用されますが、RobotServerを介してロボットを制御することはできません。代わりに、RobotServiceを作成してRobotServerの機能をシミュレートします。RobotServiceがMech-Centerに登録されると、Mech-Vizはロボット実機と同じようにRobotServiceと通信します。

RobotServerサービスのシミュレーションは、次のシーンで使用されます。

  • Eye In Handモードで、Mech-Vision計算用のロボット関節角度を取得するシーン。

  • ロボット実機からの位置姿勢を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に割り当てられます。getJ()はラジアン形式のデータを取得する必要があるため、ここでの単位変換には注意が必要です。

  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()は通常、ロボットの各ブランドが必要とするフォーマットに従ってデータを統合します(通常、通信プロトコルで事前に設定される)。