Skip to content

Python IndyDCP 클라이언트

Python IndyDCP 클라이언트IndyDCP Protocol을 기반으로 Indy에게 명령을 인가하고, 데이터를 송수신 할 수 있는 Python 모듈입니다. 본 장에서는 이에 대한 기본 사용법 및 명령어 리스트들을 제공합니다.

설치

Python IndyDCP 클라이언트는 Python이 설치된 컴퓨터에서 실행 가능하며, 모듈 파일과 예제 노트북 파일은 아래 링크를 클릭하여 다운받을 수 있습니다.

indy_utils/indydcp_client.py 는 Python 모듈 소스 파일이며 indydcp_examples.ipynb 는 IndyDCP 사용 예제와 이에 대한 상세 내용이 기술된 주피터 노트북 파일입니다. 그리고 indy_utils/indy_program_maker.pyindy_program_example.ipynb 는 다음 장에서 사용 될 Program maker 모듈 파일과 예제 노트북 파일입니다. 첨부 된 주피터 노트북에는 각 셀에 대한 설명이 포함되어 있어 주피터 노트북만으로도 기본 예제들에 대한 학습이 가능합니다.

기본 사용법

Python IndyDCP 클라이언트는 아래와 같이 indydcp_client.py 모듈을 임포트 하면 바로 사용할 수 있습니다. 이 때에 클라이언트를 구현할 PC는 로봇과 동일한 네트워크로 구성되어 있어야 합니다.

1
2
3
4
5
from indy_utils import indydcp_client as client

robot_ip = "192.168.0.2"    # 예시 STEP IP 주소
robot_name = "NRMK-Indy7"   # IndyRP2의 경우 "NRMK-IndyRP2"
indy = client.IndyDCPClient(robot_ip, robot_name) # indy 객체 생성

아래 connect(), disconnect() 함수를 이용하여 로봇에 연결하고 해당 연결을 해제할 수 있습니다. IndyDCP 클라이언트를 이용한 프로그램의 시작과 끝에 두 함수를 각각 추가하여, 로봇 연결 및 프로그램 구동 후 로봇과의 연결을 정상적으로 해제해주어야 합니다.

1
2
indy.connect() # 로봇 연결
indy.disconnect() # 연결 해제

indydcp_client.py 모듈에는 IndyDCP의 모든 명령어 함수들이 구현된 IndyDCPClient 클래스가 구현되어 있으며 이를 사용하기 위해 클래스의 객체 (indy) 를 생성합니다. 객체 생성 시 robot_ip (인디 컨트롤박스의 IP 주소) 와 robot_name (인디7의 경우 "NRMK-Indy7" 문자열) 을 인자로 넣어주어야 합니다. indy 객체가 정상적으로 생성되었다면 아래의 여러 예시들이 정상 동작하게 됩니다.

로봇 상태 요청 명령

indy 객체를 이용하여 모든 명령어 함수를 사용할 수 있습니다. 예를 들어 로봇의 상태를 받아 출력하고 싶으면 아래 명령어를 사용할 수 있습니다.

1
2
3
4
5
6
indy.connect()

status = indy.get_robot_status()
print(status)

indy.disconnect()

이와 같은 로봇 상태 명령어 요청은 현재의 로봇 상태에 따라 True 또는 False 값을 아래와 같이 딕셔너리로 반환합니다.

1
{'ready': 1, 'emergency': 0, 'collision': 0, 'error': 0, 'busy': 0, 'movedone': 0, 'home': 0, 'zero': 0, 'resetting': 0, 'teaching': 0, 'direct_teaching': 0}

로봇 관절 각도 및 작업 공간 위치 획득 명령

관절 공간에서의 각도와 작업 공간에서의 위치 및 방향을 획득하는 방법은 아래와 같습니다.

1
2
3
4
indy.connect()

joint_pos = indy.get_joint_pos() # [q1, q2, q3, q4, q5, q6]
task_pos = indy.get_task_pos()   # [x, y, z, u, v, w]

여기서 관절 각도 (q1-q6) 의 단위는 degree 이며 작업 공간의 위치 (x, y, z) 단위는 meter, 작업 공간의 방향각 단위 (u, v, w)는 degree 입니다. 여기서 방향각 u, v, w 는 각각 x, y, z 축을 기준으로 회전한 각도를 나타냅니다.

아래와 같이 관절 및 작업 공간의 속도와 각 관절 토크 값 또한 읽어올 수 있습니다.

1
2
3
4
5
print(indy.get_joint_vel())
print(indy.get_task_vel())
print(indy.get_control_torque())

indy.disconnect()

작업 공간에서의 위치에 해당하는 관절 공간의 위치는 다음 명령어를 통해서 획득 할 수 있습니다. 해당 명령을 수행하기 위하여 두가지 정보가 필요합니다. 관절공간위치를 알고 싶은 작업공간위치 정보와 계산의 시작점이 되는 관절공간위치입니다. 특이자세를 시작점으로 입력하거나, 시작 위치에서 목표 위치까지의 이동경로에 특이자세가 들어갈 경우, 계산에 실패합니다. 계산이 실패한 경우 명령어의 반환값은 [0, 0, 0, 0, 0, 0] 입니다.

Warning

반환값에 [0, 0, 0, 0, 0, 0] 가 들어갈 수 있습니다. 반환값을 목시로 확인하지 않고 joint move 명령어를 실행할 경우 로봇이 예상하지 않은 방향으로 움직일 수 있습니다.

1
2
3
print(indy.get_inv_kin(task_pos = [0.5, -0.2, 0.3, 180, -10, 180], init_q = [0, -20, -90, 0, -60, 0]))

indy.disconnect()

로봇 모션 명령

로봇 연결 후, 아래 명령어를 통해 로봇을 홈 위치와 제로 위치로 이동시킬 수 있습니다.

1
indy.connect()
1
indy.go_home()
1
indy.go_zero()

그리고 조인트 무브와 태스크 무브를 아래와 같이 직접 좌표 값을 입력하여 모션을 실행할 수 있습니다.

1
2
j_pos1 = [0, -20, -90, 0, -60, 0] # degree
indy.joint_move_to(j_pos1)
1
2
t_pos1 = [0.5, -0.2, 0.3, 180, -10, 180]
indy.task_move_to(t_pos1)
1
indy.disconnect()

위 명령은 단일 경유점에 대한 모션 명령이며, 여러 경유점과 툴 명령어 등 복잡한 로직에 대한 로봇 프로그래밍은 Program maker를 참고하시기 바랍니다.

기본 프로그램 제어 명령

Conty 를 통해 사전에 작성되고 등록 된 기본 프로그램 (default program)을 불러오고 실행할 수 있습니다. 기본 프로그램은 1번부터 10번까지의 인덱스를 가지며 인덱스를 통해 기본 프로그램을 불러오고 실행할 수 있습니다. 아래는 기본 프로그램 1번을 불러와 이를 실행하는 예제입니다.

1
2
3
4
5
indy.connect()
indy.set_default_program(1)
print("Current default program index: ", indy.get_default_program_idx())
print("Start the loaded default program")
indy.start_default_program()
1
indy.disconnect()

IndyDCP 클라이언트 명령어 함수 리스트

Python 모듈에 포함된 명령어 함수 리스트는 아래 에 모두 요약되어 있습니다1. 에서는 indy 객체가 가지고 있는 명령어 함수와 입출력 타입이 표기되어 있으며, 모든 함수의 입력과 출력은 단일 값일 때는 bool, int 또는 double 이며, 여러 값일 때는 list 입니다. 그 외 비고란에서 참고사항을 확인할 수 있습니다.

C++을 포함하여 MATLABLabview 인터페이스 또한 모두 IndyDCP 프로토콜을 이용한 클라이언트 예제이기 때문에 함수명과 입출력은 차이가 있을지라도 기능 및 사용법은 완전히 동일합니다. 따라서 다른 인터페이스 예제를 사용하더라도 아래 표를 참고하여 사용할 수 있습니다.

Warning

비고 란에 Warning! 이 표기되어 있는 명령어는 로봇이 실제 움직임을 수행하는 명령어 함수들 입니다. Conty 를 이용하여 작업 교시를 할 때에는 로봇을 목표 위치로 JOG 또는 직접 교시로 이동 시킨 후에 해당 위치를 경유점으로 등록할 수 있지만, IndyDCP 이용시 사용자가 직접 타겟 위치 (관절 각도, 작업 공간 위치) 를 입력해야 합니다. 이 때문에 좌표를 잘못 입력하거나, 단위를 착각하거나, 명령어를 잘못 입력하는 등의 사용자 실수로 인해 로봇이 의도하지 않은 위치로 이동할 수 있으며, 이로 인해 로봇이 장애물과 충돌하여 파손될 수도 있습니다. 이러한 실수 발생 시 로봇을 즉시 정지 시키기 위해 비상 정지 버튼을 옆에 두고 로봇을 실행하길 권장드립니다.

Function Parameters 비고
Joint servo commands
stop_emergency() - -
reset_robot() - -
set_servo(arr) arr (list): length DOF ex) arr = [1, 1, 1, 1, 1, 0]
set_brake(arr) arr (list): length DOF ex) arr = [1, 1, 1, 1, 0, 0]
Warning!
브레이크 해제 시 중력에 의해 로봇 링크 바닥으로 처짐 주의
Motion commands
stop_motion() - -
execute_move(cmd_name) cmd_name (string): command name Warning!
Conty 의 기본 프로그램에 등록된 무브 블록 실행
ex) cmd_name = "j_move1"
go_home() - -
go_zero() - -
joint_move_to(q) q (list): absolute joint angles [deg] ex) q=[0, -20, -90, 0, -60, 0]
Warning!
실행 시 타겟 위치로 이동 명령 수행
joint_move_by(q) q (list): relative joint angles [deg] ex) q=[0, 0, 0, 0, 0, 20]
6번 관절만 20도 회전
Warning!
실행 시 타겟 위치로 이동 명령 수행
task_move_to(p) p (list): absolute task-space pose [m, deg] ex) p=[0.5, -0.2, 0.3, 180, -10, 180]
Warning!
실행 시 타겟 위치로 이동 명령 수행
task_move_by(p) p (list): relative task-space pose [m, deg] ex) p=[0, 0, -0.1, 0, 0, 0]
-z축 방향으로 0.1m 이동
Warning!
실행 시 타겟 위치로 이동 명령 수행
Default program and current program control
start_current_program() - -
pause_current_program() - -
resume_current_program() - -
stop_current_program() - -
start_default_program() - Warning!
등록 된 기본 프로그램 실행
set_default_program(idx) idx (int): default program index -
idx=get_default_program_idx() idx (int): default program index -
Robot state
res=get_robot_status() res (bool): {'ready', 'emergency', 'collision', 'error', 'busy', 'movedone', 'home', 'zero', 'resetting', 'teaching', 'direct_teaching'} -
res=get_program_state() res (bool): {'running', 'pause'} -
res=is_conty_connected() res (bool): True or False -
Direct teaching mode
direct_teaching(mode) mode (bool): True or False -
Waypoint move
push_back_joint_waypoint(q) q (list): absolute joint angles -
pop_back_joint_waypoint() - -
clear_joint_waypoints() - -
execute_joint_waypoints( policy, resume_time) policy (int): collision policy
resume_time (double): resume time (sec)
Warning!
등록 된 경유점 모션 실행
policy = 0 : 충돌 시 정지
1 : resume_time(초) 후 충돌 상태 해제
2 : resume_time(초) 후 충돌 상태 해제 및 역순 모션 실행
3 : 충돌 감지 없음
push_back_task_waypoint(p) p (list): absolute task-space pose -
pop_back_task_waypoint() - -
clear_task_waypoints() - -
execute_task_waypoints( policy, resume_time ) policy (int): collision policy
resume_time (double): resume time (sec)
Warning!
등록 된 경유점 모션 실행
policy = 0 : 충돌 시 정지
1 : resume_time(초) 후 충돌 상태 해제
2 : resume_time(초) 후 충돌 상태 해제 및 역순 모션 실행
3 : 충돌 감지 없음
Set properties
set_default_tcp(tcp) tcp (list): tool center point (pose) ex) tcp=[0, 0, 0.1, 0, 0, 0]
TCP 위치가 z축으로 0.1m 일 때
reset_default_tcp() - -
set_tcp_comp(tcp) tcp (list): offset from default TCP -
reset_tcp_compensation() - -
set_reference_frame(ref) ref (list): reference frame -
reset_reference_frame() - -
set_collision_level(level) level (int): 1-5 level -
set_joint_vel_level(level) level (int): 1-9 level -
set_task_vel_level(level) level (int): 1-9 level -
set_joint_waypoint_time(wp_time) wp_time (double): 0.5-4 sec -
set_task_waypoint_time(wp_time) wp_time (double): 0.5-4 sec -
set_task_base(mode) mode (int): 0=reference body, 1=end-effector tool tip -
set_joint_blend_radius(radius) radius (int): 3-27 deg -
set_task_blend_radius(radius) radius (double): 0.02-0.2 m -
Get properties
tcp=get_default_tcp() tcp (list): current TCP -
tcp=get_tcp_comp() tcp (list): current TCP offset -
ref=get_reference_frame() ref (list): current reference frame -
level=get_collision_level() level (int): current collision level -
level=get_joint_vel_level() level (int): current joint speed level -
level=get_task_vel_level() level (int): current task speed level -
time=get_joint_waypoint_time() time (double): current joint waypoint time -
time=get_task_waypoint_time() time (double): current task waypoint time -
mode=get_task_base() mode (int): current task-move base mode -
radius=get_joint_blend_radius() radius (double): current joint blend radius -
radius=get_task_blend_radius() radius (double): current task blend radius -
time=get_robot_running_time() time (double): Total execution time after resetting robot -
cmode=get_cmode() cmode (int): control mode -
servo, brake
=get_servo_state()
servo (list): servo state
brake (list): brake state
-
Robot data and information
j_pos=get_joint_pos() j_pos (list): current joint angles -
j_vel=get_joint_vel() j_vel (list): current joint velocities -
t_pos=get_task_pos() t_pos (list): current task-space pose -
t_vel=get_task_vel() t_vel (list): current task-space velocity -
j_tor=get_control_torque() j_tor (list): current torques applied to joints -
j_pos=get_inv_kin(target_t_pos, init_j_pos) j_pos (list): result of inverse kinematics
target_t_pos (list): target task-space pose
init_j_pos (list): initial joint angles
계산 실패시 [0, 0, 0, 0, 0, 0] 반환
err, err_idx, err_val
=get_last_emergency_info()
err (int): error code
err_idx (list): error index
err_val (list): error value
-
Digital I/O and Analog I/O
val=get_di() val (list): list of 32 channel digital input -
set_do(idx, val) idx (int): 0-31 channel
val (int): 0 or 1
-
val=get_do() val (list): 32 channels -
val=get_ai(idx) val (int): analog input value 0-10000 (0-10V)
idx (int): index of analog input channel
-
set_ao(idx, val) idx (int): index of analog output channel
val (int): analog output value (0-10000)
-
val=get_ao(idx) idx (int): 0-1 channel
val (int): 0-10000
-
set_endtool_do(type, val) type (int): type of end tool
val (int): 0 or 1
0: NPN, 1: PNP, 2: Not use, 3: eModi
val=get_endtool_do(type) type (int): type of end tool
val (int): 0 or 1
0: NPN, 1: PNP, 2: Not use, 3: eModi
F/T sensor interface
val=get_robot_ft_raw() val (list): [Fx, Fy, Fz, Tx, Ty, Tz] 앤드툴포트에 연결된 F/T 센서의 raw 값
val=get_robot_ft() val (list): [Fx, Fy, Fz, Tx, Ty, Tz] 앤드툴포트에 연결된 F/T 센서의 베이스 좌표계에 대한 좌표변환 값
val=get_cb_ft_raw() val (list): [Fx, Fy, Fz, Tx, Ty, Tz] CB CAN포트에 연결된 F/T 센서의 raw 값
val=get_cb_ft() val (list): [Fx, Fy, Fz, Tx, Ty, Tz] CB CAN포트에 연결된 F/T 센서의 베이스좌표계에 대한 좌표변환 값
Direct variables
val
=read_direct_variable(dv_type, dv_addr)
val (int): value of direct variable
dv_type (int): type of direct variable
dv_addr (int): address of direct variable
-
val=read_direct_variables(dv_type, dv_addr, dv_len) val (list): value list to be assigned
dv_type (int): type of direct variable
dv_addr (int): address of direct variable
dv_len (int): length of direct variables to be read
-
write_direct_variable(dv_type, dv_addr, val) addr (int): address of direct variable
val (int): value of direct variable
type (int): type of direct variable
-
write_direct_variables(dv_type, dv_addr, dv_len, val) dv_type (int): type of direct variable
dv_addr (int): address of direct variable
dv_len (int): length of direct variables to be written
val (list): value list to be assigned
-

Table 1. Python IndyDCP 클라이언트 명령어 함수 리스트

Extended IndyDCP 명령어 함수 리스트

확장된 IndyDCP (Extended IndyDCP) 명령어 리스트는 아래 표와 같습니다. External trajectory move 커맨드를 통해 사용자가 작성한 모션 트라젝토리를 로봇에게 전달하여 해당 모션을 수행하게 할 수 있습니다. 외부 트라젝토리를 로봇에게 전달하는 네 가지 명령어 함수가 제공됩니다. 메모리에 있는 트라젝토리 데이터를 바이너리 또는 텍스트 형태로 전달하는 방법 (move_ext_traj_bin, move_ext_traj_txt) 과 바이너리 또는 텍스트 형태로 저장된 파일을 읽어서 명령을 수행하도록 하는 방법 (move_ext_traj_bin_file, move_ext_traj_txt_file) 입니다. 파일을 읽도록 할 때에는 파일 이름을 전달하며 이 때 파일은 STEP 에 있어야 합니다. 반면 메모리의 데이터를 전달할 때에는 클라이언트 PC 에서 전체 트라젝토리 데이터를 TCP/IP 통신으로 전송합니다.

Function Parameters 비고
move_ext_traj_bin(traj_type, traj_freq, dat_size, traj_data) traj_type (int): type 1=joint move, type 2=task move
traj_freq (int): control frequency of trajectory
dat_size (int): size of data
traj_data (list): binary data
-
move_ext_traj_txt(traj_type, traj_freq, dat_size, traj_data) traj_type (int): type 1=joint move, type 2=task move
traj_freq (int): control frequency of trajectory
dat_size (int): size of data
traj_data (list): binary data
-
move_ext_traj_bin_file(file_name) file_name (string): name of file saved in STEP -
move_ext_traj_txt_file(file_name) file_name (string): name of file saved in STEP -

Table 2. Python Extended IndyDCP 클라이언트 명령어 함수 리스트


  1. 모듈 내에 있는 모든 명령어 함수들은 IndyDCP 프로토콜의 명령어 리스트를 참고하여 작성된 것이므로 각 함수에 대한 설명은 IndyDCP 프로토콜의 명령어 리스트를 참고하셔도 됩니다. 

  2. 로봇 관절 개수 (Indy7=6, IndyRP2 여유자유도 옵션=7)