6.4 안전 배포 감독기

그림 6-2. Dry-run에서 정상 운전까지 단계적 승격

6.4.1 승격 상태

단계모터속도작업공간통과 기준 예시
0. OFFLINE분리-로그 재생NaN 0건, schema/단위 확인
1. DRY_RUN미명령계산만전체를 검사경계 위반률 0, latency 예산 충족
2. LOW_SPEED활성10~20%보수적 박스무부하 20회, E-stop 시험
3. BOUNDED활성30~50%실제 과업 일부단일 물체 20회, 충돌 0
4. NOMINAL활성승인값승인 작업공간조건별 평가 및 운영 승인

승격은 단방향 자동 증가가 아니다. 다음 사건은 즉시 HOLD 또는 FAULT로 강등한다.

  • 워치독 timeout 또는 deadline 연속 위반
  • NaN/Inf, 관절 이름/차원 불일치
  • 작업공간/관절 한계 위반
  • E-stop, 모터 오류, 카메라 입력 손실
  • 정책/캘리브레이션/URDF 해시 변경

FAULT에서 자동 재개하지 않는다. 원인 기록, 작업공간 확인, 자세 재정렬, 사람 승인 후 낮은 단계부터 다시 시작한다.

6.4.2 작업공간 Bounding Box

베이스 프레임에서 엔드이펙터 위치 p=(x,y,z)p=(x,y,z)가

pmin≤p≤pmaxp_{min}\le p\le p_{max}

를 만족해야 한다. 축 정렬 박스는 구현이 쉽지만 장애물과 로봇 자체 충돌을 표현하지 못한다. 따라서 최소한 다음을 결합한다.

  • 관절 soft limit
  • 엔드이펙터 bounding box
  • 테이블 아래 zz 금지
  • 최대 관절 변화/속도
  • self-collision/환경 collision 검사
  • gripper payload와 접근 방향 규칙

정책의 Cartesian target을 단순 clamp하면 방향이 바뀌거나 표면을 따라 미끄러질 수 있다. 큰 위반은 clamp보다 거부와 HOLD가 안전하다.

작업공간 검사는 반드시 어느 좌표계의 값인지와 함께 수행한다. PoseStamped의 frame_id가 base_link와 다르면 숫자만 base 좌표로 재표기해서는 안 된다. 이 장의 교육용 guard는 보수적으로 동일 base_link frame만 허용한다. 다른 frame을 지원하려면 TF2로 메시지 timestamp 시점의 transform을 조회하고, transform timeout/extrapolation은 latched FAULT로 처리한다.

6.4.3 워치독과 생명주기

워치독은 “마지막 메시지가 왔는가”뿐 아니라 current/target의 source timestamp, 수신 시각, 추론 완료, 명령 송신, Follower 상태 피드백을 각각 본다. 서로 다른 timeout 원인을 하나의 stale로 합치지 않는다. position뿐 아니라 quaternion의 finite와 norm도 검증한다.

ROS 2 노드는 구성되지 않은 상태, inactive, active, error를 구분하는 managed lifecycle을 사용할 수 있다. 그러나 lifecycle state 자체가 안전 기능의 인증을 뜻하지 않는다. 실제 토크 차단은 드라이버와 하드웨어 계약으로 검증해야 한다.

code/safety_supervisor.py는 하드웨어 비종속 상태 머신이고 code/ros2_ws/.../workspace_guard.py는 교육용 ROS 2 노드다.

잠깐 점검 — 안전 감독기는 언제 멈춰야 하는가

  1. 목표가 작업공간 경계를 크게 벗어났을 때 경계값으로 clamp하는 것보다 HOLD가 나은 이유는 무엇인가?
  2. 정책이나 캘리브레이션 파일의 hash가 바뀌면 이전 승격 상태를 그대로 유지해도 되는가?

확인 포인트: 큰 위반을 clamp하면 의도와 다른 경로를 만들 수 있으므로 명령을 거부하고 원인을 확인한다. 정책·캘리브레이션 변경은 검증했던 시스템 계약을 바꾸므로 낮은 단계에서 다시 승인해야 한다.

이 장의 예제 코드·설정 파일 (10)

이 장의 자가 점검·가상실습