# GetNextNodeId() 구현 - 빠른 참조 가이드 **최종 업데이트**: 2025-10-23 **상태**: 🟢 완료 --- ## 🎯 핵심 정보 ### 구현 메서드 ```csharp public string GetNextNodeId(AgvDirection direction, List allNodes) ``` **위치**: `AGVNavigationCore\Models\VirtualAGV.cs` (라인 628-821) ### 사용 방법 ```csharp // 위치 설정 (최소 2회) agv.SetPosition(node001, new Point(65, 229), AgvDirection.Forward); agv.SetPosition(node002, new Point(206, 244), AgvDirection.Forward); // 다음 노드 조회 string nextNodeId = agv.GetNextNodeId(AgvDirection.Forward, allNodes); // 결과: "N003" ``` --- ## ⚡ 핵심 수정사항 ### Backward 로직 수정 **파일**: `VirtualAGV.cs` (라인 755-767) **변경 전**: ```csharp if (dotProduct < -0.9f) // ❌ 반대 방향 baseScore = 100.0f; ``` **변경 후**: ```csharp if (dotProduct > 0.9f) // ✅ 같은 방향 baseScore = 100.0f; ``` ### 이유 모터 방향(Forward/Backward)은 경로 선택에 영향을 주지 않음 → Forward/Backward 모두 같은 경로 선호 --- ## 🧪 검증 결과 ### 4가지 시나리오 - 모두 패스 ✅ | # | 이동 | 방향 | 결과 | 상태 | |---|-----|------|------|------| | 1 | 001→002 | Forward | N003 | ✅ | | 2 | 001→002 | Backward | N003 | ✅ | | 3 | 002→003 | Forward | N004 | ✅ | | 4 | 002→003 | Backward | N004 | ✅ FIXED | --- ## 📊 기술 개요 ### 벡터 계산 ``` 1. 이동 벡터 = 현재 위치 - 이전 위치 2. 정규화 3. 각 후보와 내적/외적 계산 4. 방향별 점수 결정 5. 최고 점수 노드 반환 ``` ### 점수 기준 ``` Forward/Backward (수정 후 동일): dot > 0.9 → 100점 dot > 0.5 → 80점 dot > 0 → 50점 dot > -0.5 → 20점 else → 0점 ``` --- ## 🔧 관련 파일 ### 핵심 파일 - **VirtualAGV.cs** - GetNextNodeId() 구현 - **MapLoader.cs** - 양방향 연결 자동 설정 - **GetNextNodeIdTest.cs** - 테스트 코드 ### 문서 파일 - **BACKWARD_FIX_SUMMARY_KO.md** - 수정 요약 (한글) - **STATUS_REPORT_FINAL.md** - 최종 보고서 - **BACKWARD_FIX_VERIFICATION.md** - 검증 보고서 --- ## 📝 요구사항 충족 현황 ### 사용자 요청 ✅ Forward/Backward 지원 ✅ Left/Right 지원 ✅ 벡터 기반 계산 ✅ 2-위치 히스토리 필요 ✅ 양방향 연결 자동 설정 ✅ 002→003 Backward → 004 반환 ### 테스트 ✅ 4가지 시나리오 모두 패스 ✅ 사용자 피드백 반영 완료 ✅ 버그 수정 완료 --- ## 💬 주요 개념 ### Forward vs Backward ``` ❌ 틀림: Forward(앞) vs Backward(뒤) - 경로 방향 ✅ 맞음: Forward(정방향) vs Backward(역방향) - 모터 방향 경로 선택은 동일! ``` ### 양방향 연결 ``` 맵 저장: 단방향 (002→003) 메모리: 양방향 (002↔003) 자동 복원됨! ``` --- ## 🚀 사용 시나리오 ### 경로 계산 ```csharp // AGV가 002에서 003으로 이동 (Forward 모터) agv.SetPosition(node002, new Point(206, 244), AgvDirection.Forward); agv.SetPosition(node003, new Point(278, 278), AgvDirection.Forward); // 다음 노드 조회 string nextForward = agv.GetNextNodeId(AgvDirection.Forward, allNodes); // 결과: N004 (경로 계속) string nextBackward = agv.GetNextNodeId(AgvDirection.Backward, allNodes); // 결과: N004 (경로 계속, 모터만 역방향) ``` ### 방향 확인 ```csharp // 이전 모터 방향 AgvDirection prev = agv._currentDirection; // Forward/Backward // 현재 위치 확인 Point current = agv._currentPosition; // 이동 벡터 계산 가능 // 다음 노드 결정 가능 ``` --- ## ⚙️ 내부 동작 ### SetPosition() 호출 시 1. _prevPosition ← _currentPosition 2. _currentPosition ← newPosition 3. _prevNode ← _currentNode 4. _currentNode ← newNode 5. _currentDirection ← direction ### GetNextNodeId() 호출 시 1. 2-위치 히스토리 검증 2. 이동 벡터 계산 3. 정규화 4. 각 후보 노드에 대해: - 벡터 계산 - 정규화 - 내적/외적 계산 - 점수 결정 5. 최고 점수 노드 반환 --- ## 🔍 디버깅 팁 ### 예상과 다른 결과가 나올 때 1. ConnectedNodes 확인 ```csharp var connected = currentNode.ConnectedNodes; // 모든 이웃 노드가 포함되어 있나? ``` 2. 위치 좌표 확인 ```csharp var pos = agv._currentPosition; var prevPos = agv._prevPosition; // 좌표가 올바른가? ``` 3. 벡터 계산 확인 ```csharp var vec = (prevPos.X - currentPos.X, prevPos.Y - currentPos.Y); // 벡터가 맞는 방향인가? ``` --- ## 📚 추가 리소스 **상세 분석**: `GETNEXTNODEID_LOGIC_ANALYSIS.md` **검증 결과**: `BACKWARD_FIX_VERIFICATION.md` **전체 보고서**: `STATUS_REPORT_FINAL.md` --- ## ✅ 체크리스트 프로젝트 통합 시: - [ ] VirtualAGV.cs 확인 (GetNextNodeId 메서드) - [ ] MapLoader.cs 확인 (양방향 연결 설정) - [ ] 테스트 실행 (GetNextNodeIdTest) - [ ] 맵 파일 확인 (NewMap.agvmap) - [ ] 실제 경로 테스트 --- **최종 상태**: 🟢 **준비 완료**