3.5 안전한 텔레오퍼레이션 루프
3.5.1 안전 계층
안전은 하나의 if 문이 아니라 독립적인 방어층으로 구성한다.
| 계층 | 검사 | 실패 시 동작 |
|---|---|---|
| 입력 무결성 | 이름, 길이, NaN/Inf, 타임스탬프 | 프레임 폐기 |
| 캘리브레이션 | 장치 ID, 버전, 관절 순서 | 제어 시작 거부 |
| 위치 제한 | 관절별 soft limit | clamp 및 경고 |
| 속도 제한 | 프레임 간 최대 변화 | slew-rate 제한 |
| 통신 워치독 | 마지막 유효 명령의 나이 | hold 또는 torque off |
| 데드맨 스위치 | 조작자 지속 입력 | hold |
| 독립 하드웨어 | 전원 차단/E-stop | 모터 전력 차단 |
code/safe_teleop_core.py는 하드웨어와 분리된 순수 Python 예제다. JointSafetyFilter가 이름 기반 재정렬, 위치 clamp, 속도 제한, timeout을 적용한다. --dry-run과 같은 단계 없이 실물 송신 함수를 연결하지 않는다.
3.5.2 주기와 지연
목표 제어 주기가 50 Hz라면 한 주기는 20 ms다. 전체 지연은 대략
이다. 평균뿐 아니라 최악 지연과 jitter를 기록해야 한다. 다음 원칙을 적용한다.
- 단조 시계(monotonic clock)로 timeout을 판단한다.
- 수신 메시지의 ROS time과 로컬 수신 시각을 모두 기록한다.
- 늦은 명령을 한꺼번에 재생하지 않고 가장 최신 유효 상태만 사용한다.
- 통신 실패 후 자동 재개하지 말고 재정렬/재승인을 요구한다.