servol()

기능

비동기 방식의 모션 명령어로 모션 시작과 동시에 다음 명령어를 수행합니다. 연속적으로 전달되는 명령 중 가장 최근의 목표 위치를 설정한 속도, 가속도 내에서 추종하는 모션입니다.

인수

인수명

자료형

기본값

설명

pos

posx

-

posx 또는

position list

list (float[6])

vel (v)

float

None

최대 속도[mm/s] 또는

최대 속도[mm/s], 최대 속도[deg/s]

list (float[2])

acc (a)

float

None

최대 가속도[mm/s2] 또는

최대 가속도[mm/s2], 최대 가속도[deg/s2]

list (float[2])

time (t)

float

None

도달 시간 [sec]

알아두기

  • 단축 인수를 지원합니다. (v:vel, a:acc, t:time)

  • vel이 None인 경우, _global_velx가 적용됩니다. (_global_velx 초기값은 0이며, set_velx에 의해 설정 가능)

  • acc이 None인 경우, _global_accx가 적용됩니다. (_global_accx 초기값은 0이며, set_accx에 의해 설정 가능)

  • time이 입렵된 경우 최대 속도/가속도 조건에 의해 도달 시간을 지킬 수 없는 경우 자동 조정하고 알림 메시지를 띄웁니다.

주의

  • 속도 슬라이드바의 작동 속도 조절 기능과 연동되지 않습니다.

  • singularity 처리 옵션 중 DR_VAR_VEL 옵션과 연동되지 않습니다. DR_VAR_VEL 옵션으로 설정 시 자동으로 DR_AVOID옵션으로 변경하고 알림 메시지를 띄웁니다.

  • 힘/강성 제어 명령어와 연동되지 않습니다.

  • check_motion(), change_operation_speed() 명령어와 연동되지 않습니다.

  • Safety Zone의 감속률 설정과 연동되지 않습니다.

리턴

설명

0

성공

음수값

오류

예외

예외

설명

DR_Error (DR_ERROR_TYPE)

인수들의 데이터형 오류 시

DR_Error (DR_ERROR_VALUE)

인수의 값이 유효하지 않을 시

DR_Error (DR_ERROR_RUNTIME)

C Extension 모듈 에러 발생 시

DR_Error (DR_ERROR_STOP)

프로그램 강제 종료 시

예제

Python
# servol() 스트리밍 예제
#   기준 자세의 TCP 를 Base +Z 로 50 mm 올렸다가 되돌아온다.
#   시작 좌표를 절대값으로 고정하지 않으므로 기종에 무관하게 동작한다.
#   자세(회전)를 바꾸지 않아 4축 기종에서도 성립한다.
#   실행 전 TCP 위쪽 50 mm 에 장애물이 없는지 확인한다.

# 스트림 설계값
AMP    = 50.0     # 이동량 [mm], Base +Z
STROKE = 2.0      # 편도 시간 [sec]
PERIOD = 0.05     # 목표 갱신 주기 [sec]
STEPS  = 40       # 편도 스텝 수 ( = STROKE / PERIOD )

# 파라미터 산출
#   smoothstep s(u) = 3u^2 - 2u^3 은 최대 미분값 1.5, 최대 2차 미분값 6 이다.
#     요구 속도   = 1.5 * AMP / STROKE
#     요구 가속도 = 6.0 * AMP / STROKE^2
V_REQ   = 1.5 * AMP / STROKE
A_REQ   = 6.0 * AMP / (STROKE * STROKE)
VEL_LIN = 1.2 * V_REQ          # 선속도 [mm/s]
ACC_LIN = 2.0 * A_REQ          # 선가속도 [mm/s^2]

# vel/acc 는 [선속도, 각속도] / [선가속도, 각가속도] 2 원소이다.
# 회전 성분에 병진 값을 그대로 복사하면 안 된다. 자세를 함께 스트리밍하는
# 경우에도 각속도는 20 deg/s 수준을 넘기지 않는 것이 좋다.
VEL_ANG = 20.0                 # 각속도 [deg/s]
ACC_ANG = 100.0                # 각가속도 [deg/s^2]

# 정지 여유 검산 : 최고 속도 지점(u = 0.5)에서
#   남은 거리 >= v * PERIOD + v^2 / (2 * acc)
if V_REQ * PERIOD + (V_REQ * V_REQ) / (2.0 * ACC_LIN) > AMP / 2.0:
    tp_log("정지 여유 부족 - AMP 또는 STROKE 를 늘려야 한다")

# 기준 자세로 이동
set_velj(30)
set_accj(60)
movej(posj(0, 0, 90, 0, 90, 0), vel=30, acc=60)
mwait(0)

# 시작 좌표는 지령값으로 한 번만 확보한다. get_desired_posx() 는 posx 를 반환한다.
# (get_current_posx() 는 (posx, sol) 튜플을 반환하므로 받는 형태가 다르다.)
# 실측값을 기준점으로 쓰면 IK 수렴 잔차가 자세 목표로 들어가 증폭된다.
# 반복 실행 시에도 루프 안에서 다시 읽지 않는다.
p0 = get_desired_posx()

# 실행라인 표시를 끄면 줄당 오버헤드가 없어져 실주기가 지정값에 근접한다.
drl_report_line(OFF)

# 스트림 목표를 미리 계산해 루프 본문의 반복 비용을 일정하게 유지한다.
# 양 끝점 속도가 0 인 곡선을 쓰고 편도마다 정지하여 지령 속도를 연속으로 만든다.
leg_up = []
leg_dn = []
for k in range(1, STEPS + 1):
    u = float(k) / float(STEPS)
    s = 3.0 * u * u - 2.0 * u * u * u
    Xu = posx(p0)                         # 복사본 - ori_type/sol/turn 승계
    Xu[2] = p0[2] + AMP * s               # Base Z 만 변경, 0 -> AMP
    leg_up.append(Xu)
    Xd = posx(p0)
    Xd[2] = p0[2] + AMP * (1.0 - s)       # AMP -> 0
    leg_dn.append(Xd)

# 스트리밍 : 루프 본문은 servol() 과 wait() 두 줄뿐이다.
for leg in [leg_up, leg_dn]:
    t_begin = get_system_time()
    for Xt in leg:
        servol(Xt, vel=[VEL_LIN, VEL_ANG], acc=[ACC_LIN, ACC_ANG])
        wait(PERIOD)
    t_finish = get_system_time()
    mwait(0)          # 정지 완료 대기. 고정 시간 wait() 로 대신하지 않는다.
    t_span = t_finish - t_begin
    tp_log("실주기 " + str(round(t_span / STEPS, 4)) + " s (지정 " + str(PERIOD) + " s)")

drl_report_line(ON)

관련 명령어