RobotService 인터페이스
이 부분에서 아래와 같이 RobotService와 관련된 인터페이스를 소개하겠습니다.
RobotServer 시뮬레이션 서비스
RobotServer 서비스 시뮬레이션은 일반적으로 로봇을 마스터 컨트롤하는 데 사용되지만 RobotServer를 통해 로봇을 제어할 수 없고 RobotService를 생성하여 RobotServer를 시뮬레이션합니다. 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
-
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는 로봇이 보내는 관절 각도 데이터이며, 이를 self._jps에 할당하여 getJ()에서 호출됩니다. getJ()는 라디안 형식의 데이터를 획득해야 하므로 여기서 단위 변환에 유의해야 합니다.
-
Eye To Hand: 로봇의 현재 관절 각도에 따라 설정할 필요는 없지만 실제 로봇 상태를 시뮬레이션하려면 안전한 웨이포인트를 원점 위치(보통 Home 포인트)로 설정해야 합니다. 그렇지 않으면 임의의 숫자가 할당되어 오류가 발생하기 쉽습니다.
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 방식을 통해 포즈를 제공할 때 다음과 같은 사항을 주의해야 합니다:
-
로봇이 이미지를 캡처했을 때의 JPs를 반환하면 RobotService에서 직접 setJ()함수(단위: 라디안)를 호출하면 됩니다. 이 함수는 []를 반환할 것입니다.
-
로봇이 플랜지 포즈를 반환하면 다음과 같이 처리하십시오:
-
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 실행 오류로 인해 중단되어 이동 전/후 두 개의 웨이포인트가 서로 겹치는 것을 방지하기 위해 웨이포인트 리스트를 지워야 합니다. "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() 함수는 각 로봇 브랜드가 필요한 데이터 포맷에 따라 데이터를 정리합니다(일반적으로 통신 프로토콜에서 미리 설정됨).