RobotService Interface

This section introduces Adapter interfaces related to RobotService, as listed below.

Simulate RobotServer Service

“Simulate RobotServer Service” is usually used in scenarios where the vision system master-controls the robot, but the robot cannot not directly controlled via RobotServer (acting as the master device of the Master-Control communication). In this case, the RobotService interface can be used to simulate a RobotServer and therefore is used to master-control the robot. After RobotService is registered in Mech-Viz, Mech-Viz will interact with RobotService as it interacts with a real robot.

“Simulate RobotServer Service” can be used to:

  • Obtain JPs of the robot for calculation in Mech-Vision (in Eye In Hand scenario);

  • Obtain the pose from the real robot and send it to the RobotService service.

Example

The RobotService object in a child class in Adapter is called as follows.

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])

The RobotService class is shown below.

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

The getJ() function is used to obtain the current JPs for Mech-Viz and Mech-Vision, as shown below. Usually, the current JPs are set by using the setJ() function first and then getJ() will be called.

Example

def getJ(self, *_):
     pose = {"joint_positions": self._jps}
     return pose
  1. In Eye In Hand scenario: write the JPs sent by the robot into 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))

    In this example, “jps” is the JPs sent by the robot, and its value will be assigned to self._jps, which will be called by the getJ() function. Since the getJ() function requires data in radians, please note that unit conversion is required here.

  2. In Eye To Hand scenario: It is not necessary to set the current JPs according to the pose of the real robot. However, a Home position that will not lead to collision needs to be set as the initial pose to simulate the real robot; otherwise, the value will be assigned randomly and an error may occur.

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

getFL

The getFL() function is used to provide the robot flange pose when the robot captures images. Since in Eye In Hand scenario, the calibrated positional relationship is between the flange and camera, but the data finally used is based on the robot base reference frame, the flange pose when the robot captures images is needed.

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

Please note the following details when vision points are provided in Eye In Hand scenario:

  1. If the robot returns an image capturing pose in JPs, you can directly call setJ() in RobotService (the unit is radians) and the function will return [].

  2. If the robot returns a image capture pose in flange pose, then do the following:

    • Make sure that “is_eye_in_hand” is set to true in the extrinsic parameter file “extri_param.json” in the Mech-Vision project;

    • Call setFL() of RobotService (the pose is represented by quaternions and the unit is meters).

moveXs

The RobotService service created using Adapter uses the moveXs() function to receive waypoints in the path planned by Mech-Viz, as shown below.

Function definition

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

“params” passes all the parameters in the Mech-Viz project. All target poses, including targets from Vision Move, Relative Move, etc., can be obtained via params[“moves”]. The returned poses are in JPs by default, and will be passed into “self.targets” for subsequent calls.

Example

Usually, this function is used together with the “notify()” function. When Adapter receives a notify message, it will pass “self.targets” into the function for converting and packing and send it to the robot, as shown below.

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)

When the notify message “started” is received, the targets in the list will be cleared, which aims to avoid duplicate targets caused by unexpected disconnection and restart of Mech-Viz. When the notify message “finished” is received, the target list will be passed into the “pack_move” function, which will consolidate the data and then send the data out.

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)

According to actual on-site needs, you can choose to send all targets planned by Mech-Viz or select several targets to send from the list by index. pack_move() usually consolidates the data according to the specific format required by different robot brands, and the required data format is usually specified in the communication solution.

We Value Your Privacy

We use cookies to provide you with the best possible experience on our website. By continuing to use the site, you acknowledge that you agree to the use of cookies. If you decline, a single cookie will be used to ensure you're not tracked or remembered when you visit this website.