Mech-Viz 인터페이스
이 부분에서 아래와 같이 Mech-Viz와 관련된 인터페이스를 소개하겠습니다:
Mech-Viz를 시작하기
adapter.py 파일의 Adapter 클래스에서 Mech-Viz를 시작하는 함수가 이미 정의되었으므로 start_viz()를 직접 호출할 수 있습니다. 또한 Mech-Viz를 시작하기 전/후의 작업을 자체적으로 설정하기 위해 프로젝트의 기능에 따라 self.before_start_viz() 和 self.after_start_viz() 내용을 다시 작성할 수 있습니다.
함수 정의
def start_viz(self, in_new_thread=True, timeout=None):
if not self.is_viz_registered():
logging.error("{} has not registered in {}.".format(jk.mech_viz, jk.mech_center))
self.code_signal.emit(ERROR, VIZ_NOT_REGISTERED)
self.viz_finished_signal.emit(True)
self.viz_not_registerd()
return False
if self.is_viz_in_running():
logging.info("{} is already running.".format(jk.mech_viz))
self.code_signal.emit(WARNING, VIZ_IS_RUNNING)
self.viz_finished_signal.emit(False)
self.viz_is_running()
return False
self._read_viz_settings()
if not self.viz_project_dir:
self.msg_signal.emit(ERROR, _translate("messages", "The project of {0} is not registered. Please make sure Autoload Project is selected in {0}.").format(jk.mech_viz))
self.viz_finished_signal.emit(True)
return False
msg = {"simulate": self.is_simulate, "project_dir": self.viz_project_dir}
if self.is_keep_viz_state:
msg["keep_exec_state"] = self.is_keep_viz_state
if self.is_save_executor_data:
msg["save_executor_data"] = self.is_save_executor_data
self.before_start_viz()
self.viz_finished_signal.emit(False)
if in_new_thread:
threading.Thread(target=self.wait_viz_result, args=(msg, timeout)).start()
else:
self.wait_viz_result(msg, timeout)
self.after_start_viz()
return True
start_viz()는 기본적으로 새로운 스레드에서 Mech-Viz의 실행 과정이 완료될 때까지 기다립니다. 이 목적은 Mech-Viz 시작 이외의 다른 작업에 영향을 미치지 않도록 하는 것입니다.
다음으로 스텝의 파라미터 동적 설정을 예시로 self.before_start_viz()를 다시 작성하는 방법에 대해 소개하겠습니다.
def before_start_viz(self):
self.set_move_offset(x, y, z)
Mech-Viz를 시작하기 전에 읽어낸 데이터에 따라 웨이포인트의 X,Y, Z 방향에서의 옵셋을 구성해야 합니다.
Mech-Viz를 정지하기
adapter.py 파일의 Adapter 클래스에서 Mech-Viz를 정지하는 함수가 이미 정의되었으므로 stop_viz()를 직접 호출할 수 있습니다.
함수 정의
def stop_viz(self, timeout=None):
if not self.is_viz_registered():
self.code_signal.emit(WARNING, VIZ_NOT_REGISTERED)
return False
self.call_viz("stop", timeout=timeout)
self.code_signal.emit(INFO, VIZ_STOP_OK)
return True
Mech-Viz를 중지/계속 실행하기
adapter.py 파일의 Adapter 클래스에서 Mech-Viz를 중지/계속 실행하는 함수가 이미 정의되었으며 기능은 Mech-Viz 소프트웨어의 중지 버튼과 동일하여 시뮬레이션할 때만 사용될 수 있습니다.
함수 정의
def pause_viz(self, msg, timeout=None):
if not self.is_viz_registered():
self.code_signal.emit(WARNING, ADAPTER_CANCEL_PAUSE)
return
self.call_viz("switchPauseContinue", msg, timeout)
self.code_signal.emit(INFO, ADAPTER_PAUSE_VIZ if msg.get(
"to_pause") else ADAPTER_CONTINUE_VIZ)
스텝 파라미터를 설정하기
Mech-Viz의 스텝에 대한 동적 파라미터를 설정할 때는 일반적으로 Adapter 클래스의 set_task_property()를 호출하기만 하면됩니다.
함수 정의
def set_task_property(self, msg, timeout=None):
return self.call_viz("setTaskProperties", msg, timeout)
msg는 다양한 스텝에 대해 다른 파라미터를 구성하는 것을 결정합니다.
고정점 이동
Mech-Viz 실행 과정에서 “고정점 이동” 스텝 중 X,Y, Z의 옵셋 값을 조정해야 할 경우, Mech-Viz를 컨토롤하는 메인 프로그램에서 다음과 같은 함수를 작성할 수 있습니다.
예시
def set_move_offset(self, name, x_offset, y_offset, z_offset):
msg = {"name": name,
"values": {"xOffset": x_offset / UNIT_PER_METER,
"yOffset": y_offset / UNIT_PER_METER,
"zOffset": z_offset / UNIT_PER_METER}}
self.set_task_property(msg)
name: “고정점 이동” 스텝의 이름. UNIT_PER_METER=1000, 일반적으로 x_offset, y_offset 및 z_offset 데이터의 단위가 mm이며 Mech-Viz 중의 데이터의 단위가 m일 때 UNIT_PER_METER를 통해 단위를 전환합니다.
다음과 같은 방식으로 set_move_offset() 함수를 호출하면 Mech-Viz의 move_1 스텝의 X, Y, Z 옵셋이 해당 변경 사항이 발생합니다.
self.set_move_offset("move_1", 100, 200, 300)
외부 이동
여러 외부 목표 포즈를 Mech-Viz에 전송하여 계획 및 컨트롤할 필요가 있는 경우 “외부 이동” 스텝을 통해 구현할 수 있습니다. “외부 이동” 스텝은 JPs, TCP, 물체 포즈를 설정하는 데 사용됩니다. 사용법은 다음과 같습니다.
예시
class CustomOuterMoveService(OuterMoveService):
def gather_targets(self, di, jps, flange_pose):
self.add_target(self.move_target_type, [0.189430,-0.455540,0.529460,-0.079367,0.294292,-0.952178,0.021236])
Mech-Viz는 “외부 이동” 스텝까지 실행되면 getMoveTargets()를 호출합니다. 서비스 이름을 통해 서로 다른 외부 이동 스텝을 구분합니다.
def _register_service(self):
self.outer_move_service = CustomOuterMoveService()
self._outer_move_server, port = register_service(outer_move_service, port)
“외부 이동” 스텝 앞에는 피킹 스텝이 있어야 합니다. 그렇지 않으면 "물체를 잡고 있지 않을 때 물체 포즈가 무효합니다!" 오류 알람이 발생합니다 . |
팔레타이징
Mech-Viz 실행 과정에서 다른 팔레타이징 스텝에 따라 다른 파라미터를 설정해야 할 때, 해당 스텝의 이름을 통해 구체적인 스텝을 찾아야 합니다. 프로젝트 편집 영역에서 해당 스텝을 선택하면 Mech-Viz 파라미터 편집 영역에 나타나는 파라미터를 수정할 수 있습니다.
예시
예를 들어 “자체 정의한 파렛트 패턴” 스텝인 경우, 일반적으로 변경해야 하는 파라미터 값은 시작 인덱스*와 *파일 이름(*동적 로딩*을 선택해야 *파렛트 파일 경로*가 나타남)입니다. 따라서 다음과 같은 함수를 메인 프로그램에서 정의할 수 있습니다.
def set_stack_pallet(self, name, startIndex, fileName):
msg = {
"name": name,
"values": {
"startIndex": startIndex,
"fileName": fileName,
}
}
self.set_task_property(msg)
여기서 "startIndex"는 *시작 인덱스*를 나타내고 "fileName"은 *파일 이름*을 나타냅니다. "startIndex" 및 "fileName" 파라미터의 이름은 Mech-Viz에서 정의됩니다.
다음 방법을 사용하여 set_stack_pallet() 함수를 호출합니다.
self.set_stack_pallet("common_pallet_1", 2, "re.json")
“미리 설정된 파렛트 패턴” 스텝의 경우, 일반적으로 변경해야 하는 파라미터 값은 시작 인덱스, 파렛트 패턴, 상자 길이, 상자 너비, 상자 높이, 행 수, 열 수 및 *층 수*입니다. 따라서 다음과 같은 함수를 메인 프로그램에서 정의할 수 있습니다.
def set_stack_pallet(self, name, startIndex, stack_type):
pallet_info = self.box_data_info[stack_type]
"""
pallet_info: Length(mm),Width(mm),Height(mm),pallet type,rows,columns,layers
"""
msg = {
"function": "setTaskProperties",
"name": name,
"values": {
"startIndex": startIndex,
"palletType": pallet_info[3],
"cartonLength": pallet_info[0] / UNIT_PER_METER,
"cartonWidth": pallet_info[1] / UNIT_PER_METER,
"cartonHeight": pallet_info[2] / UNIT_PER_METER,
"cylinderRows": pallet_info[4],
"cylinderCols": pallet_info[5],
"layerNum": pallet_info[6]
}
}
self.set_task_property(msg)
설정해야 할 파라미터가 많은 경우, 일반적으로 파라미터를 Excel 파일에 작성한 다음 Excel 파일에서 데이터를 읽고 self.box_data_info에 기록합니다. 그런 다음 stack_type 값을 사용하여 나중에 참조할 수 있습니다. "startIndex", "palletType", "cartonLength" 등의 이름은 Mech-Viz에서 정해진 것입니다.
자체 정의한 파렛트 패턴 및 미리 설정된 파렛트 패턴 클래스의 msg 값을 비교하면 "values" 값이 다르다는 것을 쉽게 알 수 있습니다. 특정 스텝의 파라미터를 설정해야 하는 경우 해당 파라미터의 이름과 값을 "values"에 추가하기만 하면됩니다. 기타 팔레타이징 스텝의 파라미터 설정에 대해서는 위에서 설명한 예제를 참조하십시오.
메시지 분기
Mech-Viz는 “메시지 분기” 스텝을 실행할 때, 외부 신호(Adapter)가 아웃 포트를 설정할 때까지 계속 기다립니다. “메시지 분기” 스텝에 대해서 다음과 같은 함수를 정의하면 분기를 컨트롤할 수 있습니다.
예시
def set_branch(self, name, area):
time.sleep(1) # The delay of 1s here is to wait for the {product-viz} executor to fully start
try:
info = {"out_port": area, "other_info": []}
msg = {"name": name,
"values": {"info": json.dumps(info)}}
self.set_task_property(msg)
except Exception as e:
logging.exception(e)
여기서 name은 스텝의 이름이고, area는 아웃 포트의 번호이며 왼쪽에서 오른쪽으로 각각0, 1, 2...입니다. 예를 들어 이 스텝은 가장 왼쪽의 아웃 포트를 통해 실행되면 area 값은 0입니다. Mech-Viz를 시작하지 않고 직접 “메시지 분기” 스텝을 호출하면 Mech-Viz에서 “스텝 파라미터를 설정할 때 이그제큐터가 없습니다!”라는 오류 알람이 발생합니다.
카운터
“카운터” 스텝을 사용할 때 일반적으로 카운트 총수와 현재 카운트를 설정해야 합니다. 해당 함수를 정의하는 코드가 다음과 같습니다.
예시
def set_counter_property(self, name, count, curCount):
msg = {"name": name,
"values": {"count": count, "currentCount": curCount}}
self.set_task_property(msg)
해당 함수를 호출하는 예시가 다음과 같습니다.
self.set_counter_property("counter_1", 5, self.success_stack_num)
self.success_stack_num은 성공적으로 적재된 파렛트의 수량을 나타냅니다. 팔레타이징을 수행하는 과정에서 상자가 떨어지고 작업자의 수동 개입으로 Mech-Viz가 정지되면, Mech-Viz 중 "counter_1"로 명명된 카운트 스텝에 "currentCount" 의 값을 저장하지 않습니다. Mech-Viz를 재시작하고 self.success_stack_num을 통해 이 스텝의 현재 카운트 수를 다시 설정할 수 있습니다.
스텝 파라미터를 읽어내기
Mech-Viz를 실행할 때 특정 스텝의 파라미터를 읽어내려면 메인 프로그램에서 다음과 같은 함수를 정의할 수 있습니다.
예시
def read_move_pallet(self, name):
msg = {"name": name,
"properties": ["xOffset","yOffset","zOffset", ]}
return read_task_property(msg)
그 중 "name"을 통해 읽어야 할 스텝의 이름을 찾을 수 있습니다. "properties" 뒤의 목록에 있는 값은 필요에 따라 파라미터 를 추가하거나 제거할 수 있습니다. 이 예시에서는 "xOffset", "yOffset" 및 "zOffset" 값을 읽으므로 이 세 가지 값을 "properties"에 추가하고 다음과 같이 호출합니다.
self.read_move_pallet("move_3")
호출한 후 다음과 같은 결과를 얻었습니다.
{'zOffset': -0.23, 'xOffset': -0.12, 'yOffset': -0.15}
하지만 주의해야 할 것은 Mech-Viz 스텝에서 획득한 파라미터의 일부 값은 계획된 파라미터 값이고 실제 실행 시와 다를 수도 있습니다. 계획 진행 상태는 실행 진행 상태보다 미리 진행됩니다(즉 Mech-Viz는 미래의 이동을 미리 계획할 수도 있음). 여기서는 “팔레타이징” 스텝의 현재 인덱스(curIndex) 파라미터 값을 예로 들어 설명하며, 사용자는 메인 프로그램에서 다음과 같은 함수를 정의할 수 있습니다.
def read_pallet_current_index(self, name):
msg = {"name": name,
"properties": ["curIndex"]}
return read_task_property(msg)
다음과 같이 함수를 호출하여 curIndex의 값을 획득합니다.
self.read_pallet_current_index("common_pallet_1")
호출한 후 다음과 같은 결과를 얻을 수 있습니다.
{'curIndex': 5}
여기서의 5는 현재 계획이 5 라운드를 완료했음을 나타냅니다. 예를 들어 상자 배치 프로젝트의 경우, 5는 계획 진행 상황에서 5 개의 상자를 배치했음을 나타내며, 로봇이 실제로 배치한 상자는 5 개보다 적을 수 있습니다. 따라서 "curIndex"와 같은 파라미터의 값은 실행 시 값이 아니라 계획된 값임을 나타냅니다.
말단장치를 바꾸기
Mech-Viz 말단장치 리스트에서 해당 인덱스를 지정하면 됩니다. Mech-Viz 말단장치 리스트의 인덱스는 위에서 아래로 0, 1, 2, 3 등으로 순서대로 지정됩니다. 범위를 벗어나지 않도록 주의해야 합니다. 구체적인 함수는 아래와 같습니다.
예시
def set_tcp(self, index):
msg = {"function": "setTcp", "index": index}
self.call("executor", msg)
실행 시 전역 속도를 설정하기
Mech-Viz 실행 중에 로봇 실행 속도 백분율을 동적으로 조정해야 하는 경우 다음 함수를 메인 프로그램에 작성할 수 있습니다.
예시
def set_vel(self, vel_scale):
msg = {"function": "setConfig",
"velScale": vel_scale / 100, "accScale": vel_scale / 100}
self.call("executor", msg)
속도를 80%로 설정하면 다음과 같이이 함수를 호출할 수 있습니다.
self.set_vel(80)
이 함수는 Mech-Viz가 시작된 후에만 호출할 수 있습니다. 그렇지 않으면 오류가 발생합니다. 즉,이 모듈의 호출 조건과 “메시지 분기” 스텝이 일치합니다. 따라서 일반적으로 “메시지 분기” 스텝에서 set_vel () 함수를 호출하여 새 스레드에서 set_vel () 함수를 호출하는 것을 피합니다. 다음과 같습니다. |
def set_branch(self, name, area):
time.sleep(1)
if self.box_data_info[int(self.pallet_info)][7] <= 10:
self.set_vel(100)
else:
self.set_vel(80)
try:
info = {"out_port": area, "other_info": []}
msg = {"function": "setTaskProperties",
"name": name,
"values": {"info": json.dumps(info)}}
self.set_task("executor", msg)
except Exception as e:
logging.exception(e)
포인트 클라우드의 충돌 파라미터를 설정하기
포인트 클라우드 충돌 파라미터를 설정하려면 Mech-Viz에 해당하는 인터페이스인 setConfig ()를 사용하면 됩니다. 실행 시 전역 속도 설정 인터페이스와 마찬가지로 설정 정보가 다를뿐입니다. 다음과 같습니다.
예시
msg = {}
msg["function"] = "setConfig"
msg["check_pcl_collision"] = True
msg["collided_point_thre"] = 5000
msg["collide_area_thre"] = 20
msg["pcl_resolution_mm"] = 2
self.call("executor", msg)
Mech-Viz 반환값
Mech-Viz의 반환값 리스트는 다음과 같습니다.
반환값 | 설명 |
---|---|
Finished |
정상적으로 실행되었습니다. 설명: Mech-Viz 프로젝트에서 비전 이동의 오른쪽 분기에 다른 스텝과 연결될 때 Mech-Viz도 정상적으로 반환됩니다. |
Command Stop |
정지 또는 stop_viz () 함수 호출합니다. |
No targets |
비전 포즈가 없음을 나타냅니다. 즉, Mech-Vision이 빈 값을 반환합니다. |
No proper vision poses |
비전 포즈에 도달할 수 없으며 로봇이 현재 인식된 물체의 위치에 도달할 수 없거나 충돌합니다. |
PlanFail |
Mech-Viz 경로 계획 실패. |
SceneCollision |
충돌이 발생합니다. |
Mech-Viz 반환 상황에 대해 Adapter 기본 클래스는 해당 인터페이스 함수를 제공합니다.