본문으로 건너뛰기

정지·안전

로봇이 멈추는 경로는 여러 개고, 각각 즉시성과 복구 방법, 자동 복귀 여부가 다릅니다. 이 페이지는 클라이언트가 정지를 요청하고 관측하고 복구하는 방법과, 이 스택이 무엇을 보장하지 않는지를 다룹니다.

정지의 종류​

정지발동로봇 동작복구
궤적 취소실행 중인 goal 을 cancel활성 궤적 컨트롤러의 취소 동작을 따름필요 없음 — TRAJECTORY 유지
브레이크 정지plem/set_mode(BRAKED) 또는 plem/control_command 의 protective_stop감속 구간 없이 브레이크 체결 시퀀스 시작다시 set_mode
보호정지(P-STOP)스택이 자동 트립 (아래 원인 표)토크 차단 + 브레이크 체결수동 — 아래 복구 절차
명령 정체 홀드제어 스택 내부의 명령 갱신이 100 ms 를 초과해 끊긴 채 로봇이 이동 중현재 자세를 능동 유지 (브레이크 아님)자동 — 명령이 다시 흐르면 해제

BRAKED 요청은 감속(STOPPING)을 거치지 않습니다. 브레이크는 다른 스레드의 협조 없이 듣는 최후 수단이기 때문입니다. 감속 구간을 거치는 것은 TRAJECTORY 에서 FREEDRIVE 로 넘어갈 때뿐이고, 그 감속이 2초 안에 끝나지 않으면 스택이 브레이크를 체결해 BRAKED 로 떨어뜨립니다(요청하신 목표 모드로 가지 않습니다).

robot_mode 가 BRAKED 로 바뀐 것은 체결 시퀀스를 시작했다는 뜻이지 물리적 정지가 끝났다는 뜻이 아닙니다. 실제 체결은 필드버스 계층에서 여러 사이클에 걸쳐 진행됩니다. joint_states 의 속도로 로봇이 멎었는지는 보실 수 있습니다.

브레이크 상태를 구독할 토픽은 없습니다. 관절별 브레이크를 직접 여닫는 plem/set_joint_brake 액션이 상태를 함께 돌려주지만, 그 값은 드라이브 상태 전환이 끝났다는 소프트웨어 표시이지 물리 접점 확인이 아닙니다.

경고
set_joint_brake 로 브레이크를 풀지 마세요

유지보수용 직접 인터페이스라 모드도 컨트롤러도 준비하지 않습니다. BRAKED 상태에서 해제 goal 을 보내시면 제어 루프가 0 토크를 쓰는 동안 하중을 지지하던 브레이크가 풀립니다. 정상 운전 전환은 plem/set_mode 로 하세요.

모드 전환 규약​

plem/set_mode 액션은 cancel 요청을 거부하고, 이미 그 모드면 goal 자체를 거부합니다. 다른 모드 전환이 진행 중일 때 TRAJECTORY·FREEDRIVE goal 은 거부되지만 BRAKED 는 수락되어 그 전환을 끊습니다 — 끊긴 goal 은 "preempted by BRAKED" 로 abort 되고, 그 goal 이 켜던 컨트롤러도 BRAKED 가 내리려 시도합니다. 이미 끝나 가던 goal 은 abort 대신 SUCCEEDED 로 끝날 수 있고, BRAKED goal 자신의 컨트롤러 정리는 끊기지 않습니다 — 아래처럼 액션 결과가 아니라 robot_mode 로 판정하세요. BRAKED 는 다른 제어 주체가 점유 중이어도 수락되지만, TRAJECTORY 와 FREEDRIVE 진입은 텔레옵 레인이 활성이면 거부됩니다.

BRAKED 전환은 모드를 바꾼 뒤 모션 컨트롤러 비활성화를 시도하는데, 그 단계가 실패해도 goal 은 성공으로 끝납니다. 컨트롤러까지 확인하셔야 하면 controller_manager/list_controllers 를 보세요.

plem/control_command 의 release_brake 와 free_drive 는 액션 서버를 거치지 않고 하위 모드·브레이크 전환만 수행합니다. 목표 모드에 맞는 컨트롤러 전환도, 텔레옵 점유 검사도 하지 않습니다. 궤적 실행이나 freedrive 를 실제로 쓸 목적이라면 plem/set_mode 를 쓰세요.

물리 비상정지에 대해 PLEM 소프트웨어는 발동 경로도 관측 경로도 갖지 않습니다. 비상정지의 동작과 복구는 로봇 안전 매뉴얼을 따르며, 클라이언트가 이를 다른 정지와 구분해 처리하도록 설계하지 않았습니다.

실행 중이던 궤적은 어떻게 되나​

BRAKED 나 P-STOP 이면 하드웨어 계층이 궤적 컨트롤러의 명령을 무시하고 측정된 현재 위치로 덮어씁니다. 로봇은 멈춥니다.

반면 실행 중이던 FollowJointTrajectory goal 의 종료 처리는 경우에 따라 다릅니다. 명시적인 BRAKED 전환은 모션 컨트롤러 비활성화를 시도하고(위 규약대로 실패해도 성공으로 끝날 수 있습니다), 자동 트립된 P-STOP 은 모드 전환 서버를 우회하므로 컨트롤러가 활성인 채로 남습니다. 어느 쪽이든 goal 이 어떤 결과로 끝나는지는 이 스택이 정하지 않습니다.

그래서 액션 결과만으로 정지를 판정하시면 안 됩니다. 안전 상태 판정은 status_broadcaster/robot_mode 와 status_broadcaster/safety_mode 구독으로 병행하세요.

그리퍼는 함께 멈추지 않습니다

그리퍼는 팔의 모드·안전 상태와 연동되지 않는 독립 액션 서버입니다. 팔의 BRAKED 나 P-STOP 은 진행 중인 그리퍼 goal 을 취소하지 않습니다. 협조 정지가 필요하면 그리퍼 goal 도 별도로 cancel 하세요. cancel 의 정지 명령은 그리퍼 액션 서버가 다음에 상태를 확인할 때 나갑니다 — 보통 0.1 초 안팎, 길게는 약 0.3 초 뒤입니다.

명령 정체 홀드​

로봇이 움직이는 중에 제어 스택 내부의 명령 갱신이 100 ms 를 초과해 끊기면, 스택이 현재 자세를 목표로 고정해 능동 유지합니다. 토크를 끊으면 중력으로 팔이 처지기 때문입니다. 보호정지가 아니며, 명령이 다시 흐르면 자동으로 풀립니다.

이 홀드가 지키는 것은 제어 스택 자신의 이상입니다. 외부 클라이언트가 죽는 것은 이 조건을 만들지 않습니다. 하드웨어 인터페이스가 매 주기 실시간 계층으로 명령을 내려보내며 타임스탬프를 갱신하기 때문입니다.

클라이언트가 사라지면 로봇이 알아서 멈춘다고 가정하지 마세요. 진행 중인 모션을 중단해야 하면 goal 을 cancel 하거나 BRAKED 를 요청하는 쪽이 애플리케이션의 책임입니다.

홀드는 한 번 진입하면 명령이 다시 신선해질 때까지 유지되고(로봇이 그 사이 멈춰도 자동으로 풀리지 않습니다), FREEDRIVE 중에는 적용되지 않습니다. 손으로 안내하는 중에 고정 목표를 향한 토크가 걸리면 조작자의 손과 겨루게 되기 때문입니다.

보호정지(P-STOP)​

P-STOP 은 스택이 스스로 트립하는 정지입니다. 걸리면 로봇 모드가 BRAKED 로 강제되고 자동으로 복원되지 않습니다. safety_mode 구독이 유일하게 신뢰할 수 있는 감지 수단입니다.

발동 원인은 하나가 아니고 safety_mode 값만으로는 구분되지 않습니다. 모든 P-STOP 은 rt_events 에 공통 PROTECTIVE_STOP 을 남기고, 원인별 이벤트가 있으면 그 위에 더해집니다.

원인전용 이벤트
관절 위치·속도 한계 위반 (URDF 파생)없음
작업영역 하한 위반WORKSPACE_LIMIT_EE · WORKSPACE_LIMIT_ELBOW (해석 실패 시 없음)
외력 과부하 (아래 절)DISTURBANCE_OVERLOAD
수신한 목표 값에 NaN·무한대TARGET_COMMAND_INVALID
산출 토크가 유효하지 않음TORQUE_OUTPUT_INVALID
EtherCAT 워킹카운터 이상이 지속WKC_MISMATCH
실시간 계층으로 가는 토크 명령 정체TORQUE_COMMAND_STALE
제어 사이클 예산 초과 (예산을 설정한 기기에서만)CONTROLLER_BUDGET_EXCEEDED
운전 중(브레이크 해제 상태) 축이 운전 허용 상태(Operation enabled)를 벗어남 — 드라이브 고장 등OPERATION_ENABLED_LOST (0x61 — error_code = 그 축의 statusword)
운전 중 축이 선언된 운전 모드를 벗어남MODE_OF_OPERATION_MISMATCH (0x5F)

전용 이벤트가 없는 두 경우(관절 한계 위반, 작업영역 해석 실패)는 공통 이벤트만 보입니다. 현재 joint_states 를 URDF 한계와 대조하면 위치가 걸렸는지 정도는 짐작하실 수 있지만, 속도 위반이나 해석 실패는 사후에 확정할 수 없습니다.

반대로 WKC_MISMATCH 는 정지 없이도 발생합니다. P-STOP 은 이상이 지속돼야 걸리기 때문입니다. 이벤트와 정지는 별개이므로 정지 여부는 safety_mode 로 판정하시고, 해제 판정도 마찬가지입니다(PROTECTIVE_STOP_CLEAR 는 해제 경로에 따라 발행되지 않습니다).

복구 절차​

P-STOP 중에는 BRAKED 와 FREEDRIVE 로만 전환하실 수 있습니다. 이 상태에서 set_mode(TRAJECTORY) 나 release_brake 를 보내시면 거부됩니다.

  1. safety_mode 로 P-STOP 을 확인하고 rt_events 로 원인을 식별하세요.
  2. 텔레옵 레인이 활성이면 먼저 내리세요. 활성인 동안은 plem/set_mode 의 FREEDRIVE·TRAJECTORY 진입이 거부돼 이후 단계가 막힙니다. 자동 트립된 P-STOP 은 모드 전환 서버를 우회하므로 레인이 그대로 남아 있을 수 있고, 이미 BRAKED 라서 BRAKED 재요청으로는 내릴 수 없습니다(동일 모드 거부). 판정 기준은 명령 전송 여부가 아니라 teleop_controller 의 활성 상태이므로, 송신을 멈추는 것만으로는 부족합니다. 레인 소유자가 그 컨트롤러를 비활성화하고 inactive 를 확인해야 합니다. control_command 의 free_drive 는 이 검사를 우회하지만, 레인 정리를 건너뛰는 우회로로 쓰지 마세요.
  3. 원인을 제거하세요. 로봇이 한계나 장애물에 걸려 있으면 FREEDRIVE 로 전환해 손으로 안전한 자세로 빼내세요.
  4. 정지를 해제하세요. plem/control_command 의 reset_error 를 보내시거나, 3단계에서 FREEDRIVE 를 쓰셨다면 BRAKED 로 돌아오는 것만으로 해제됩니다(안전한 자세를 확인했다는 조작자 확인으로 취급합니다).
  5. safety_mode 가 NORMAL 로 돌아오는지 확인하세요. 서비스 응답 성공은 복구를 뜻하지 않습니다. 원인이 남아 있으면 다음 제어 사이클에 다시 래치됩니다.
  6. plem/set_mode 로 운전 모드에 재진입하세요. reset_error 는 로봇 모드를 바꾸지 않습니다. 오류 표시가 사라졌는데 로봇이 멈춰 있으면 BRAKED 로 돌아온 것을 확인한 뒤 목표 모드를 다시 고르세요.

드라이브 고장 초기화​

reset_error 는 보낼 때마다 드라이브 고장 초기화(fault reset)를 새로 요청하고, 소프트웨어 보호정지의 해제도 요청합니다. 관절 한계 위반처럼 원인이 남아 있으면 보호정지 해제는 거부되고(rt_events 에 보호정지 이벤트가 error_code 1 로 남습니다) P-STOP 이 유지됩니다. 요청이 실제로 드라이브에 쓰였는지는 축마다 rt_events 의 SERVO_FAULT_RESET_RESULT(0x60)로 보실 수 있습니다 — 쓰였는지, 그 축이 고장 상태가 아니어서 버려졌는지, statusword 를 해석하지 못해 버려졌는지를 알려 줍니다. 버려진 요청은 PLEM 이 다시 보내지 않으니 필요하면 새로 요청하세요. 이 이벤트도 유실될 수 있으므로, 없다는 것을 아무 일도 없었다는 증거로 쓰지 마세요.

브레이크 체결·해제 시퀀스 도중 축이 고장 나면 로봇 모델에 따라 다릅니다.

  • Neuromeka: 고장 난 축을 자동으로 초기화하지 않습니다. 시퀀스는 그 축에서 멈춰 있으니, 고장 원인을 해결한 뒤 reset_error 를 보내세요.
  • Huayan Elfin: 고장이 이어지는 동안 약 200 ms 마다, 고장 한 번에 최대 25 회 자동으로 초기화를 요청합니다. 요청마다 SERVO_FAULT_RESET(0x58), 횟수를 다 쓰면 SERVO_FAULT_RESET_EXHAUSTED(0x59)가 남습니다. 둘 다 드라이브가 실제로 초기화됐다는 증거는 아닙니다.

풀리지 않는 드라이브와 정지 보류​

드라이브가 퀵스톱(Quick stop active)처럼 PLEM 이 다음 단계로 진행시키지 못하는 상태에 머물면, 그 축의 브레이크 시퀀스는 거기서 멈춥니다. 퀵스톱 같은 상태의 축을 푸는 명령은 이 릴리스에 없고, 그 경우의 복구 절차도 검증되지 않았습니다. 드라이브 고장(Fault)은 이와 다릅니다 — 원인을 해결한 뒤 위의 reset_error 로 초기화합니다. rt_events 의 BRAKE_SEQUENCE_STALLED(0x5C — error_code = 그 축의 statusword, value = 도달하지 못한 단계)가 어느 축이 진행하지 못했는지 알려 줍니다. 진행하지 못했다는 사실만 말하며 원인은 말하지 않습니다.

브레이크 그룹을 선언한 모델(현재 Huayan Elfin)은 로봇 스택을 끌 때 로봇을 BRAKED 로 바꾸고, 모든 브레이크 그룹의 체결이 확인될 때까지 종료를 보류합니다. 그동안 체결을 계속 다시 요청하며, 그때마다 로그에 brake engage UNCONFIRMED — shutdown HELD 와 축별 statusword 를 남깁니다. 두 번째 종료 신호(SIGINT·SIGTERM 을 합쳐 셉니다)를 받으면 확인 없이 진행하는데, plem·ros2 launch 로 끌 때는 launch 가 잠시 뒤 보내는 SIGTERM 이 그 두 번째 신호가 되므로 보류는 운영자를 기다려 주지 않습니다. Neuromeka 로봇은 이 보류 없이 내려갑니다. 체결이 확인되지 않은 브레이크는 열려 있는 것으로 보고 다루세요.

스택을 끄기 전에 정지를 직접 확인하세요

어느 모델이든 스택을 끄기 전에 로봇이 실제로 멈췄는지 눈으로 확인하고, 드라이브가 풀리지 않는 축이 있으면 팔을 받친 뒤 끄세요. 소프트웨어가 체결을 확인하지 못한 축은 물리 브레이크 상태도 확인되지 않은 것입니다.

모드 수락 게이트의 release 거부​

브레이크 release 요청(plem/set_mode 의 TRAJECTORY·FREEDRIVE 진입, control_command 의 release_brake)이 다른 허가(모션 모드·admission·P-STOP/pending)를 통과했더라도, 요청한 브레이크 그룹의 모든 축이 그 사이클에 선언된 운전 모드로 수락된 상태(초기화됨 · 인식되는 statusword · 0x6061 == 선언)이고 그 축의 EtherCAT 슬레이브가 OP 여야(마스터가 보고하는 슬레이브 상태 — 재구성 대기 없음) enable 시퀀스가 시작됩니다. 한 축이라도 미수락이면 요청 전체가 폐기되고(보류 없음) 실패 축마다 rt_events 에 발행을 시도합니다 — 슬레이브가 OP 가 아니면 SLAVE_NOT_OPERATIONAL(0x62 — error_code = 슬레이브의 AL 상태(0 은 오프라인 또는 조회 실패), value = 링 위치. 기동 직후면 슬레이브가 아직 OP 로 가는 중일 수 있으니 잠시 뒤 다시 요청하고, 아니면 커널 로그(sudo dmesg | grep -i ethercat)의 AL status code 나 거부된 startup SDO 를 보세요), 그 밖에는 MODE_OF_OPERATION_MISMATCH(0x5F — error_code = 그 축의 statusword, value = 0x6061 표시값. 관측값이지 원인 판정이 아닙니다). 다른 허가에 막힌 요청은 종전대로 이벤트 없이 폐기됩니다. 준비 거부 자체는 P-STOP 을 새로 요청하지 않습니다 — 기존 정지나 별도 이탈이 없으면 safety_mode 는 NORMAL 을 유지하며, 현재 정지 여부는 언제나 safety_mode 로 확인합니다.

  • 모드 전환 성공은 해제를 뜻하지 않습니다. plem/set_mode 는 로봇 모드가 바뀐 시점에 성공하므로 robot_mode 가 TRAJECTORY·FREEDRIVE 여도 브레이크는 체결된 채일 수 있습니다. rt_events 의 0x5F·0x62 는 미수락 진단의 단서입니다 — 이벤트는 유실될 수 있으므로 그것이 없다는 것을 수락이나 해제의 확인으로 쓰지 마세요(브레이크 상태 토픽도 없습니다).
  • 수락이 회복돼도 자동으로 해제되지 않습니다. 폐기된 요청은 되살아나지 않고 reset_error 도 다시 게시하지 않습니다. 새 요청을 보내세요. 같은 모드 goal 은 거부되므로 BRAKED 로 돌아온 것을 확인한 뒤 목표 모드를 명시적으로 다시 고릅니다 — TUI 는 TRAJECTORY r · FREEDRIVE f, 펜던트는 BRAKED 선택 뒤 원하는 모드 버튼. 기존 P-STOP 이 남아 있으면 먼저 위 「복구 절차」로 원인을 제거하고 정지를 해제하세요 — 펜던트는 P-STOP 중 FREEDRIVE 만 활성이라 BRAKED 로 되돌아올 수 없으므로 복구 버튼(reset_error)을 씁니다. safety_mode 가 NORMAL 인 것을 확인한 뒤 이 절로 돌아오세요. reset_error 는 로봇 모드를 바꾸지 않으므로 BRAKED 가 아니면 먼저 BRAKED 로 전환·확인한 뒤 목표 모드를 다시 고릅니다(이미 BRAKED 면 목표 모드 선택부터). 이 모드 선택 절차에서 거부됐던 release 를 다시 게시하는 것은 목표 모드 재선택입니다 — 복구 중 FREEDRIVE 진입이 거부됐다면 로봇 모드는 이미 FREEDRIVE 라서 같은 모드를 다시 골라도 goal 이 거부됩니다.
  • 운전 중(OPERATION_ENABLED) 이탈은 다릅니다. 이때는 P-STOP 을 요청하고 다음 브레이크 스텝에서 전 축 체결 시퀀스를 시작·계속합니다 — 체결 완료나 물리 폐쇄를 보장하지는 않습니다(위 「정지의 종류」의 BRAKED 한계와 같습니다). 위 복구 절차를 따르세요. 두 경우가 같은 0x5F 로 남으므로 정지 여부는 safety_mode 로 가릅니다.

Teaching Pendant 하단 로봇 제어 바의 ↻ (P-STOP 복구) 버튼이 내려보내는 것이 이 reset_error 입니다. 클라이언트가 직접 구현하셔도 같은 경로입니다.

여러 대를 운용하신다면 한 대의 P-STOP 이 다른 로봇을 멈추지 않습니다. 협조 정지는 애플리케이션 책임입니다.

외력 과부하 가드​

모션 중 관절에 걸리는 외력 토크를 추정해, 그 관절의 예산을 200 ms 이상 지속적으로 넘으면 P-STOP 을 겁니다(짧은 스파이크는 트립하지 않습니다). 예산은 URDF 의 effort 와 velocity 한계에서 파생되며 속도에 비례해 커집니다. 정지 상태에서 가장 엄격합니다. 설정 파라미터나 on/off 스위치는 없습니다.

적용 범위에 두 가지 제약이 있습니다. 관측기를 가진 제어기(기본값 ADRC)에서만 판정이 성립하고, 토크 제어가 실제로 돈 사이클에서만 판정합니다. BRAKED·FREEDRIVE 와 이미 걸린 P-STOP 에서는 판정하지 않습니다. 반대로 제어 중이라면 팔이 멈춰 있어도 판정합니다.

인증된 협동안전 기능이 아닙니다

이 가드는 전류에서 유도한 추정이라 마찰과 모델 오차가 실제 접촉과 섞여 들어갑니다. 기계 보호가 목적이며, ISO 10218 급 force/power 제한은 로봇 안전 컨트롤러의 책임입니다.

계획 시점 검사의 한계​

PlanTrajectory 가 하는 검사는 계획 시점의 것뿐입니다 — 관절 한계와 Pilz 의 자기충돌·정적 객체 검증. 작업영역 상자 검사는 없습니다(실행 중 연속 감시도, 안전등급 기능도 아닙니다). 작업영역을 물리적으로 벗어나지 못하게 하는 것은 로봇 안전 컨트롤러나 외부 안전 PLC 의 몫입니다.

직접 작성해 follow_joint_trajectory 로 보내신 궤적은 이 게이트를 전부 우회하며, 실행 성공이 목표 도달을 뜻하지도 않습니다. 두 계약 모두 ROS 2 통합의 클라이언트 규약에 있습니다.