Use when adding, extending, or debugging Waypoint Teaching & Playback: saving robot poses as waypoints, sequencing them, playing/looping sequences, exporting/importing JSON, coroutine-based runner engine, or teaching UI integration.
아래 요청에서 사용:
웨이포인트 저장/재생티칭 플레이백시퀀스 재생/루프/정지포즈 익스포트/임포트웨이포인트 러너 디버깅Teaching UI 확장Assets/Scripts/App/Fairino/WaypointStore.cs — 데이터 모델 + JSON 영속Assets/Scripts/App/Fairino/WaypointCycleRunner.cs — 코루틴 재생 엔진Assets/Scripts/App/Fairino/PresetTransitionAnimator.cs — 보간 애니메이터 (Runner가 의존)Assets/Scripts/UI/FairinoJointControlPanel.cs — Teaching 섹션 UIAssets/Scripts/App/Fairino/RobotControlSceneCoordinator.cs — 통합 핸들러WaypointStore (데이터)
Waypoint { name, jointsDeg[6], tcpMm[6], moveType, speedPreset, dwellSec }
WaypointSequence { name, created, waypoints[] }
Save/Load/Delete/Duplicate/Rename/Export/Import
↕
WaypointCycleRunner (엔진, MonoBehaviour)
PlayOnce / PlayLoop / Stop
코루틴 기반 순차 실행
PresetTransitionAnimator로 3D 보간
↕
JointControlPanel (UI)
Teaching 섹션: Save Point / Play / Loop / Stop / Undo / Export / Import / Clear All
8개 이벤트로 Coordinator에 위임
↕
RobotControlSceneCoordinator (통합)
이벤트 바인딩, FK TCP 계산, Runner↔3D 미러 연결
StopCoroutine(activeCoroutine)는 중첩 코루틴(AnimateToWaypoint)을 정지하지 않음. 반드시 StopAllCoroutines()로 전체 정지.presetAnimator.OnTransitionComplete에 구독하는 핸들러를 activeCompleteHandler 필드에 저장하고, Stop 시 CleanupCompleteHandler()로 확실히 해제.yield return 이후 if (State != RunState.Running) yield break; 추가. Stop 응답 지연 방지.waypoints.Length == 0 체크 → break. 빠지면 yield 없는 무한 루프로 Unity 프리즈.yield return null 추가. UI 이벤트(Stop 버튼) 처리 기회 보장.private double[] lastCompletedAngles;
// RunSequence 시작 시 초기화
lastCompletedAngles = null;
// AnimateToWaypoint에서 이전 완료 위치를 시작점으로 사용
var fromAngles = lastCompletedAngles ?? GetCurrentAnglesFromAnimator();
presetAnimator.StartTransition(fromAngles, wp.jointsDeg, duration);
// 완료 후 기억
lastCompletedAngles = (double[])wp.jointsDeg.Clone();
// 반드시 Runner 정지 선행 → 데이터 삭제 → 트레일 정리 → UI 초기화
waypointRunner?.Stop();
WaypointStore.ClearWaypoints(currentSequence);
eeTrailRenderer?.Clear();
displacementArrow?.Clear();
jointControlPanel?.SetTeachingState(false);
{
"name": "Pick-and-Place-A",
"created": "2026-03-15T14:30:00+09:00",
"waypoints": [
{
"name": "W1",
"jointsDeg": [10, -30, 15, -45, -80, 0],
"tcpMm": [320.1, 150.3, 480.5, 0.0, -90.0, 0.0],
"moveType": "MoveJ",
"speedPreset": "medium",
"dwellSec": 0.0
}
]
}
Application.persistentDataPath/waypoints/{name}.json| 이벤트 | 트리거 | Coordinator 핸들러 |
|---|---|---|
| OnSaveWaypointRequested | Save Point 클릭 | 현재 포즈+TCP+속도 저장 |
| OnPlayRequested | ▶ Play 클릭 | PlayOnce 실행 |
| OnLoopRequested | ⟳ Loop 클릭 | PlayLoop 실행 |
| OnTeachStopRequested | ■ Stop 클릭 | Runner.Stop + UI 초기화 |
| OnExportRequested | Export 클릭 | WaypointStore.Save |
| OnImportRequested | Import 클릭 | WaypointStore.Load |
| OnUndoLastRequested | Undo 클릭 | RemoveLast |
| OnClearAllRequested | Clear All 클릭 | Stop→Clear→Trail→UI |
StopCoroutine(activeCoroutine) 단독 사용 금지 → 반드시 StopAllCoroutines()OnSequenceComplete를 do-while 내부에서 호출 금지presetAnimator.OnFrameUpdated 구독 금지 → Coordinator 직접 구독과 중복GetCurrentAnglesFromAnimator()를 매 웨이포인트 시작점으로 사용 금지 → lastCompletedAngles 패턴 사용persistentDataPath/waypoints/ JSON 파일 생성 확인## Waypoint Teaching 변경 요약
- 변경 파일: {파일 목록}
- 추가/수정 기능: {기능 설명}
- 코루틴 안전 체크: StopAllCoroutines ✓ / 핸들러 해제 ✓ / 빈 시퀀스 감지 ✓
- 테스트: {Validation 체크리스트 결과}