servoj()

정의

servoj(pos, vel, acc, time, mod)

기능

비동기 방식의 모션 명령어로 모션 시작과 동시에 다음 명령어를 수행합니다. 모드(mode)를 Override 모드로 설정 시, 연속적으로 전달되는 명령 중 가장 최근의 목표 관절 위치를 최대 속도, 가속도 내에서 추종하는 모션입니다. 모드(mode)를 Queue 모드로 설정하게 되면 이전 명령을 최대 100개까지 기억하고 순차적으로 경로를 추종합니다. Queue 모드로 기록된 경유점이 100개가 되면 다음 경유점에 도달할 때까지 명령어를 리턴하지 않습니다. Queue 모드 중 Override 명령이 입력되면, 이전에 기억한 경유점을 무시하고 가장 최근 목표 관절 위치를 추종합니다.

인수

인수명

자료형

기본값

설명

pos


posj

-

posj 또는

joint angle list

list (float[6])

vel (v)


float

None

최대 속도(모든 축에 동일) 또는

최대 속도(축별 속도) [deg/s]

list (float[6])

acc (a)


float

None

최대 가속도(모든 축에 동일) 또는

최대 가속도(축별 가속도) [deg/s2]

list (float[6])

time (t)

float

None

도달 시간 [sec]

mod

int

DR_SERVO_OVERRIDE

경유점 모드

  • DR_SERVO_OVERRIDE: 마지막 명령 추종

  • DR_SERVO_QUEUE: Queue 모드 (경유점 기록)

알아두기

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

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

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

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

  • P시리즈의 경우, 4축 관련 입력으로 0이 아닌 값을 입력하여도 0으로 처리되며, 별도 알람은 발생하지 않습니다.

주의

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

  • 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
# servoj() 스트리밍 예제
#   J1 을 기준 자세에서 +20 deg 보냈다가 되돌아온다.
#   시작 자세를 절대값으로 고정하지 않으므로 기종에 무관하게 동작한다.
#   실행 전 J1 회전 경로상에 장애물이 없는지 확인한다.

# 스트림 설계값
AXIS   = 0        # 스트리밍할 관절 (0 = J1)
AMP    = 20.0     # 진폭 [deg]
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
#   vel 은 요구 속도의 1.2 배, acc 는 요구 가속도의 2 배로 둔다.
#   vel 을 크게 잡으면 매 지령마다 도달·정지·재출발이 반복되어 진동이 커진다.
V_REQ = 1.5 * AMP / STROKE
A_REQ = 6.0 * AMP / (STROKE * STROKE)
VEL   = 1.2 * V_REQ
ACC   = 2.0 * A_REQ

# 정지 여유 검산 : 최고 속도 지점(u = 0.5)에서
#   남은 거리 >= v * PERIOD + v^2 / (2 * acc)
if V_REQ * PERIOD + (V_REQ * V_REQ) / (2.0 * ACC) > 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_current_posj() 는 실측값이라 추종 오차가 스트림 목표로 되돌아 들어온다.
q0 = get_desired_posj()

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

# 스트림 목표를 미리 계산해 루프 본문의 반복 비용을 일정하게 유지한다.
# 양 끝점 속도가 0 인 곡선을 쓰고 편도마다 정지하여 지령 속도를 연속으로 만든다.
leg_fwd = []
leg_rev = []
for k in range(1, STEPS + 1):
    u = float(k) / float(STEPS)
    s = 3.0 * u * u - 2.0 * u * u * u
    Xf = posj(q0)                             # 복사본 - q0 를 훼손하지 않는다
    Xf[AXIS] = q0[AXIS] + AMP * s             # 0 -> AMP
    leg_fwd.append(Xf)
    Xr = posj(q0)
    Xr[AXIS] = q0[AXIS] + AMP * (1.0 - s)     # AMP -> 0
    leg_rev.append(Xr)

# 스트리밍 : 루프 본문은 servoj() 와 wait() 두 줄뿐이다.
for leg in [leg_fwd, leg_rev]:
    t_begin = get_system_time()
    for Xt in leg:
        servoj(Xt, vel=VEL, acc=ACC)
        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)

관련 명령어