3.7.0 3.6.0 3.5.0 3.4.0 3.3.0 3.2.2 3.2.1 3.2.0 Korean English Chinese Czech Dutch French German Hungarian Italian Japanese Polish Portuguese Spanish
3.7.0 3.6.0 3.5.0 3.4.0 3.3.0 3.2.2 3.2.1 3.2.0 Korean English Chinese Czech Dutch French German Hungarian Italian Japanese Polish Portuguese Spanish

alter_motion()

정의

alter_motion(pos)

기능

입력 인자 pos에 해당하는 양만큼 경로 수정을 진행합니다.

주의

  • alter_motion()은 사용자 thread 내에서만 동작합니다.

  • alter_motion()은 posx의 orientation type이 None인 경우, DR_FIX_XYZ로 설정됩니다.

  • n 을 권장 범위로 맞춰도 가속도 리플은 구조적으로 남습니다. 크기는 보정의 최대 속도에 비례하므로, 소음이 문제인 경우 진폭 또는 주파수를 낮추십시오.

  • 증분량 모드(DR_DVEL)에서는 제어기가 Tn선착순 1 건만 받아들이므로 그 뒤에 도착한 증분이 알람 없이 버려질 수 있습니다. 폐루프로 구성해 누락분이 다음 측정에서 보정되도록 하십시오.

알아두기

  • alter_motion()은 enable_alter_motion()을 통해 경로보정기능이 활성화된 경우에만 유효합니다.

  • enable_alter_motion의 설정 값 limit_dPOS, limit_dPOS_per에 따라 경로 수정량은 조정될 수 있습니다.

  • alter_motion()은 SW 버전 V3.4부터 pos를 posx()로 입력하면 다양한 Orientation type을 지원하며, list(float[6]) 형식으로 입력하는 경우, Fixed XYZ로 동작합니다.

  • n × 10ms 는 실측한 최대 공급 주기 이상이어야 합니다. 산정 방법은 아래 사용 조건을 참고하십시오.

인수

인수명

자료형

기본값

설명

pos

list (float[6])

posx

-

position list

posx (if ori_type is None, then ori_type is DR_FIX_XYZ)

사용 조건

동작 원리

경로 수정은 보정 1 건마다 정지 → 정지 궤적을 경로 생성 주기 Tn = n × 10ms 로 계획하는 방식으로 동작합니다. 진행 중인 궤적은 새 보정이 도착해도 중단되지 않고, 다음 궤적이 현재 궤적의 감속 구간에서 이어받아 합산됩니다. 제어기는 Tn 당 보정을 한 건만 받아들입니다. 새 궤적이 시작할 때 열린 수용 창은 가장 먼저 도착한 한 건을 받은 즉시 닫히므로, 같은 Tn 안에 2 건이 들어오면 뒤에 온 값(더 최신 보정)이 알람 없이 버려집니다. 최신값으로 덮어쓰는 방식이 아닙니다.

따라서 n 은 이 함수가 보정을 실제로 전달할 수 있는 주기에 맞춰 정해야 합니다. 그 주기는 보정 계산 · 호출 비용 · thread 경합이 모두 더해진 값이므로 실측한 최대값을 쓰십시오. Tn 이 그 값보다 짧으면 보정이 멈춰 선 채 대기하는 구간이 매 주기 생겨 진동 · 소음이 납니다. 증분량 모드(DR_DVEL)는 n 을 하한에 가능한 한 붙여 잡고, 간헐적으로 누락되는 증분을 보정할 수 있도록 폐루프로 구성하십시오. 어려우면 누적량 모드를 쓰십시오.

공급 주기 실측과 n 산정의 상세한 절차는 enable_alter_motion() 페이지의 사용 조건을 참고하십시오.

예외

예외

설명

DR_Error (DR_ERROR_TYPE)

인수들의 데이터형 오류 시

DR_Error (DR_ERROR_VALUE)

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

DR_Error (DR_ERROR_RUNTIME)

C Extension 모듈 에러 발생 시

DR_Error (DR_ERROR_STOP)

프로그램 강제 종료 시

예제

Python
# ---------------------------------------------------------------
# 실시간 경로 보정
#   예제1 누적량 모드(DR_DPOS) - 절대 오프셋을 아는 경우
#   예제2 증분량 모드(DR_DVEL) - 외부 센서로 남은 오차를 재는 경우
# ---------------------------------------------------------------
drl_report_line(0)    # 보정 주기를 코드량과 무관하게 만듭니다

DT      = 0.05        # 공급 주기 기준값 [sec]. 실제 주기는 이보다 큽니다
AMP     = 5.0         # 예제1 보정 진폭 [mm]
FREQ    = 0.25        # 예제1 보정 주파수 [Hz]
GAIN    = 0.5         # 예제2 보정 이득 (0 < GAIN <= 1)
LAT_MAX = 0.25        # 예제1 허용 보정 지연 [sec]. 지연 = 약 2 x n x 10ms
LIM_POS = [50, 90]    # limit_dPOS     : 누적 보정 한계 [mm, deg]
LIM_INC = [10, 10]    # limit_dPOS_per : 1 주기 증분 한계 [mm, deg]

g_mode  = 0           # 0 = 누적량 / 1 = 증분량
g_gain  = 0.0         # 보정 배율. 0 이면 보정이 걸리지 않습니다
g_t0    = 0.0
g_calls = 0
g_prev  = 0.0
g_max   = 0.0         # 실측 공급 주기의 최대값 [sec]

def read_path_error():
    # 외부 센서(비전 등)가 측정한 "현재 남은 경로 오차" [mm] 를 반환하도록
    # 교체하십시오. 보정이 반영된 뒤의 잔여 오차여야 합니다.
    return 0.0

# thread_run(loop=True) 는 함수가 반환할 때마다 다시 호출하므로 함수 안에
# while 루프를 두지 않습니다. while 을 두면 thread_stop 이 걸리지 않습니다.
def alter_thread():
    global g_calls, g_prev, g_max
    if g_mode == 0:
        var_y = g_gain * AMP * sin(6.28318 * FREQ * (time.time() - g_t0))
        alter_motion(posx(0, var_y, 0, 0, 0, 0))       # 지금 있어야 할 오프셋
    else:
        var_e = g_gain * GAIN * read_path_error()
        alter_motion(posx(0, var_e, 0, 0, 0, 0))       # 남은 오차의 일부만큼 더
    # 호출 간격을 매 주기 재서 최대값을 남깁니다.
    var_now = time.time()
    if g_prev > 0.0:
        if var_now - g_prev > g_max:
            g_max = var_now - g_prev
    g_prev  = var_now
    g_calls = g_calls + 1
    wait(DT)

# 기저 모션 양단 자세 - 측정값(get_current_posx)이 아니라 지령값을 씁니다.
# 측정 자세에는 추종 잔차가 섞여 있어 목표로 되돌려 쓰면 오차가 누적됩니다.
movej(posj(30, 45, 45, 0, 90, 0), vel=60, acc=60)
X1 = get_desired_posx(DR_BASE)
movej(posj(-30, 45, 45, 0, 90, 0), vel=60, acc=60)
X2 = get_desired_posx(DR_BASE)

# --- 공급 주기 실측 -------------------------------------------
# 실제로 쓸 모션과 thread 구성 그대로 한 번 돌립니다.
# g_gain = 0.0 이라 보정량은 0 이지만 계산과 호출은 그대로 일어나므로,
# 로봇 궤적은 변하지 않으면서 실사용과 같은 부하로 측정됩니다.
movel(X1, vel=30, acc=60)
mwait(0)
enable_alter_motion(n=20, mode=DR_DPOS, ref=DR_BASE,
                    limit_dPOS=LIM_POS, limit_dPOS_per=LIM_INC)
g_mode  = 0
g_gain  = 0.0
g_calls = 0
g_prev  = 0.0
g_max   = 0.0
g_t0    = time.time()
th_id   = thread_run(alter_thread, loop=True)

movel(X2, vel=30, acc=60)

thread_stop(th_id)
disable_alter_motion()

var_supply = DT                                # 실측 실패 시 대비값
if g_calls > 5:
    var_supply = g_max                         # 최대 공급 주기 [sec] - n 산정 기준
tp_log("supply max = {0} ms".format(int(var_supply * 100000) / 100.0))

# 하한 : 최대 공급 주기 / 10ms 를 올림한 값
N_MIN = int(var_supply * 100)
if var_supply * 100 > N_MIN:
    N_MIN = N_MIN + 1
if N_MIN < 1:
    N_MIN = 1

# --- 예제 1. 누적량 모드 (DR_DPOS) ----------------------------
# 매 전송이 완결된 오프셋입니다. 제어기가 한 건을 받지 못해도 다음 전송이
# 그대로 복구하므로 손실이 없습니다.
# 지연 예산이 허용하는 최대로 잡습니다.
N_DPOS = int(LAT_MAX * 100 / 2)
if N_DPOS < N_MIN:
    N_DPOS = N_MIN                             # 하한이 우선입니다

movel(X1, vel=30, acc=60)
mwait(0)                                       # 정지 상태에서 보정 시작
enable_alter_motion(n=N_DPOS, mode=DR_DPOS, ref=DR_BASE,
                    limit_dPOS=LIM_POS, limit_dPOS_per=LIM_INC)
g_mode = 0
g_gain = 1.0
g_t0   = time.time()
th_id  = thread_run(alter_thread, loop=True)

movel(X2, vel=30, acc=60)                      # 보정이 중첩된 기저 모션

# 종료 순서 : 보정 정지 -> thread_stop -> disable_alter_motion
# 비활성화 후에도 thread 가 살아 있으면 alter_motion() 호출이 남아 에러가 납니다.
g_gain = 0.0
thread_stop(th_id)
disable_alter_motion()

# --- 예제 2. 증분량 모드 (DR_DVEL) ----------------------------
# 센서가 남은 오차를 계속 재는 폐루프에서만 쓰십시오. 제어기가 받지 못한
# 증분은 되돌아오지 않지만, 폐루프면 다음 측정에서 자동으로 재시도됩니다.
# n 은 하한에 붙여 잡습니다. 간헐적으로 누락되는 증분은 폐루프가 다음
# 측정에서 보정합니다.
# read_path_error() 가 폐루프가 아니라면 이 예제 대신 예제 1 을 쓰십시오.
N_DVEL = N_MIN

movel(X1, vel=30, acc=60)
mwait(0)
enable_alter_motion(n=N_DVEL, mode=DR_DVEL, ref=DR_BASE,
                    limit_dPOS=LIM_POS, limit_dPOS_per=LIM_INC)
g_mode = 1
g_gain = 1.0
g_t0   = time.time()
th_id  = thread_run(alter_thread, loop=True)

movel(X2, vel=30, acc=60)                      # 센서 보정이 중첩된 기저 모션

g_gain = 0.0
thread_stop(th_id)
disable_alter_motion()

관련 명령어

Keyword

alter / motion / alter_