# 프로젝트 요약 (AGVMapEditor, AGVNavigationCore, AGVSimulator) ## 📊 프로젝트 개요 3개의 주요 프로젝트가 **AGVNavigationCore** 라이브러리를 공유하며 연동되는 구조입니다. ``` ┌─────────────────────────────────────────────────────────────┐ │ AGVNavigationCore (공유 라이브러리) │ ├─────────────────────────────────────────────────────────────┤ │ • Models: MapNode, MapLoader, Enums, IMovableAGV, VirtualAGV │ • Controls: UnifiedAGVCanvas (통합 UI 렌더링) │ • PathFinding: A*, AGVPathfinder, DirectionChangePlanner └─────────────────────────────────────────────────────────────┘ ▲ ▲ ▲ │ 참조 │ 참조 │ 참조 │ │ │ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │ AGVMapEditor │ │ AGVSimulator │ │ AGV4 (미사용) │ (맵 편집) │ │ (시뮬레이션) │ │ (메인앱) └──────────────┘ └──────────────┘ └──────────────┘ ``` --- ## 🎯 각 프로젝트의 기능 ### 1️⃣ **AGVMapEditor** (맵 편집 도구) **목적**: AGV 맵 데이터를 시각적으로 생성/편집 #### 제공 기능 | 기능 | 설명 | |------|------| | **노드 생성** | 맵 상에 AGV 네비게이션 노드 추가 | | **노드 편집** | 노드 이름, RFID, 타입, 도킹방향 설정 | | **노드 이동** | 드래그로 노드 위치 변경 (그리드 스냅 지원) | | **연결 관리** | 노드 간 경로 연결 생성/삭제 | | **노드 삭제** | 선택된 노드 제거 | | **라벨 추가** | 맵에 텍스트 라벨 추가 | | **이미지 추가** | 맵에 배경 이미지 추가 | | **맵 저장/로드** | JSON 형식 맵 파일 저장/로드 | #### 기술 구성 ``` MainForm (WinForms) └─ UnifiedAGVCanvas (UI 렌더링) ├─ MapNode 목록 관리 ├─ 편집 모드 (Select, Move, AddNode, Connect, Delete, DeleteConnection, AddLabel, AddImage) └─ MapLoader 사용 (JSON 저장/로드) ``` #### 주요 UI 요소 - **메뉴바**: File (Open/Save), Edit, View - **툴바**: 편집 모드 전환 버튼 (선택, 이동, 노드추가, 연결, 삭제, 라벨, 이미지) - **속성 패널**: 선택된 노드 정보 표시/편집 - **캔버스**: 맵 시각화 및 편집 --- ### 2️⃣ **AGVNavigationCore** (경로 계산 엔진 라이브러리) **목적**: AGV 경로 계산 및 네비게이션 핵심 로직 제공 #### 제공 기능 | 영역 | 모듈 | 기능 | |------|------|------| | **Models** | MapNode | AGV 네비게이션 노드 데이터 | | | MapLoader | 맵 파일 로드/저장 | | | IMovableAGV | AGV 동작 인터페이스 | | | VirtualAGV | 가상 AGV 시뮬레이션 로직 ⚠️ **미완성** | | **Controls** | UnifiedAGVCanvas | 맵 렌더링/편집/모니터링 UI | | **PathFinding** | AStarPathfinder | 기본 A* 경로 탐색 | | | AGVPathfinder | AGV 제약 고려 경로 계산 ⚠️ **미완성** | | | DirectionChangePlanner | 방향 전환 경로 계획 ⚠️ **미완성** | #### 핵심 기능 (구현 상태) ``` ✅ 완성 ├─ MapNode 데이터 모델 ├─ MapLoader (파일 I/O) ├─ UnifiedAGVCanvas (UI 렌더링/편집) └─ AStarPathfinder (기본 경로 탐색) ❌ 미완성 (개발 대상) ├─ VirtualAGV.ExecutePath() - 경로 실행 ├─ VirtualAGV.Update() - 프레임 업데이트 ├─ AGVPathfinder 핵심 로직 - 경로 상세화, 마그넷 방향 계산 └─ DirectionChangePlanner - 4단계 방향 전환 알고리즘 ``` #### 기술 구성 ``` AGVNavigationCore (Class Library) ├── Models/ │ ├── MapNode.cs │ ├── MapLoader.cs │ ├── VirtualAGV.cs (← 경로 추적 미완성) │ ├── IMovableAGV.cs │ └── Enums.cs ├── Controls/ │ ├── UnifiedAGVCanvas.cs (메인 UI) │ ├── UnifiedAGVCanvas.Designer.cs │ ├── UnifiedAGVCanvas.Events.cs │ ├── UnifiedAGVCanvas.Mouse.cs (← 줌 기능) │ ├── UnifiedAGVCanvas.Rendering.cs │ └── UnifiedAGVCanvas.Utilities.cs ├── PathFinding/ │ ├── Core/ │ │ ├── AStarPathfinder.cs ✅ │ │ ├── PathNode.cs │ │ └── AGVPathResult.cs │ ├── Planning/ │ │ ├── AGVPathfinder.cs (❌ 미완성) │ │ ├── DirectionChangePlanner.cs (❌ 미완성) │ │ └── NodeMotorInfo.cs │ ├── Analysis/ │ │ └── JunctionAnalyzer.cs │ └── Validation/ │ ├── PathValidationResult.cs │ └── DockingValidationResult.cs └── Utils/ └── LiftCalculator.cs ``` --- ### 3️⃣ **AGVSimulator** (AGV 시뮬레이터) **목적**: AGV 경로 계산 및 동작을 시각적으로 검증 #### 제공 기능 | 기능 | 설명 | |------|------| | **맵 로드** | 저장된 맵 파일 로드 | | **AGV 시뮬레이션** | 가상 AGV 생성 및 경로 따라 이동 | | **경로 계산** | 시작점/목적지 선택 후 경로 자동 계산 | | **경로 시각화** | 계산된 경로 맵에 표시 | | **실시간 상태 모니터링** | AGV 위치, 방향, 상태 실시간 표시 | | **도킹 검증** | AGV 도킹 방향 검증 | #### 기술 구성 ``` SimulatorForm (WinForms) ├─ UnifiedAGVCanvas (맵 렌더링) ├─ VirtualAGV 리스트 (가상 AGV들) ├─ MapLoader (맵 파일 로드) ├─ AGVPathfinder (경로 계산) └─ 시뮬레이션 타이머 (매 프레임 AGV 업데이트) ``` #### 주요 UI 요소 - **메뉴바**: File (Open Map) - **경로 제어 그룹**: 시작RFID, 목적지RFID, 타겟계산 버튼 - **시뮬레이션 제어**: 시작, 일시정지, 정지 버튼 - **캔버스**: 맵 + AGV + 경로 시각화 --- ## 🎨 UnifiedAGVCanvas (통합 UI 컨트롤) **위치**: `AGVNavigationCore/Controls/UnifiedAGVCanvas.cs` (4개 파일) ### 핵심 기능 | 기능 | 설명 | |------|------| | **맵 렌더링** | 노드, 연결선, 그리드, AGV, 경로 표시 | | **편집 기능** | 노드 추가/이동/삭제, 연결 관리 (AGVMapEditor) | | **모니터링** | 실시간 AGV 상태 표시 (AGVSimulator) | | **줌/팬** | 마우스 휠 줌, 좌클릭 드래그 팬 | | **선택/호버** | 노드 선택, 호버 표시 | | **경로 시각화** | 계산된 경로를 색상으로 표시 | ### 모드 및 상태 ```csharp // CanvasMode Edit // 편집 모드 (맵 에디터) // EditMode (Edit 모드에서만 적용) Select // 노드 선택 Move // 노드 이동 AddNode // 노드 추가 Connect // 연결 생성 Delete // 노드/연결 삭제 DeleteConnection // 연결 삭제 AddLabel // 라벨 추가 AddImage // 이미지 추가 ``` --- ## 🖱️ 줌/팬 기능 (현재 상태) ### 현재 구현 ```csharp // UnifiedAGVCanvas.Mouse.cs : 171-188 private void UnifiedAGVCanvas_MouseWheel(object sender, MouseEventArgs e) { // 줌 처리 var mouseWorldPoint = ScreenToWorld(e.Location); var oldZoom = _zoomFactor; if (e.Delta > 0) _zoomFactor = Math.Min(_zoomFactor * 1.2f, 5.0f); // 확대 (1.2배) else _zoomFactor = Math.Max(_zoomFactor / 1.2f, 0.1f); // 축소 (1.2배) // 마우스 위치를 중심으로 줌 var zoomRatio = _zoomFactor / oldZoom; _panOffset.X = (int)(e.X - (e.X - _panOffset.X) * zoomRatio); _panOffset.Y = (int)(e.Y - (e.Y - _panOffset.Y) * zoomRatio); Invalidate(); } ``` ### 문제점 및 개선 사항 #### ⚠️ 현재 문제 1. **줌 계산 로직**: 수식이 복잡하고 정확하지 않을 수 있음 2. **좌표계 혼동**: 스크린 좌표와 월드 좌표 변환이 일관성 없음 3. **매끄러움**: 줌 비율 계산에서 부자연스러운 동작 가능 #### ✅ 개선 방안 마우스 커서 위치를 기준점으로 하는 스무스한 줌을 구현: ```csharp private void UnifiedAGVCanvas_MouseWheel(object sender, MouseEventArgs e) { // 현재 마우스 위치를 월드 좌표로 변환 var mouseWorldBefore = ScreenToWorld(e.Location); float oldZoom = _zoomFactor; // 줌 팩터 계산 (휠 델타 기반) if (e.Delta > 0) _zoomFactor = Math.Min(_zoomFactor * 1.15f, 5.0f); // 확대 (부드러움) else _zoomFactor = Math.Max(_zoomFactor / 1.15f, 0.1f); // 축소 (부드러움) // 마우스 위치가 같은 월드 좌표를 가리키도록 팬 오프셋 조정 var mouseWorldAfter = ScreenToWorld(e.Location); _panOffset.X += (int)((mouseWorldBefore.X - mouseWorldAfter.X) * _zoomFactor); _panOffset.Y += (int)((mouseWorldBefore.Y - mouseWorldAfter.Y) * _zoomFactor); Invalidate(); } ``` #### 주요 개선점 1. **더 부드러운 줌**: 1.2배 → 1.15배로 조정 2. **명확한 로직**: 마우스 위치 기준으로 명시적으로 계산 3. **정확한 좌표 변환**: ScreenToWorld() 사용으로 일관성 보장 4. **자연스러운 동작**: 마우스 아래의 점이 같은 위치를 가리킴 --- ## 📂 파일 구조 (48개 C# 파일) ### AGVMapEditor (10개 파일) ``` AGVMapEditor/ ├── Forms/ │ ├── MainForm.cs (메인 폼, 편집 로직) │ └── MainForm.Designer.cs (UI 디자인) ├── Models/ │ ├── EditorSettings.cs (에디터 설정) │ ├── MapImage.cs (맵 이미지 데이터) │ ├── MapLabel.cs (맵 라벨 데이터) │ └── NodePropertyWrapper.cs (노드 속성 래퍼) ├── Program.cs (진입점) └── Properties/ └── AssemblyInfo.cs (어셈블리 정보) ``` ### AGVNavigationCore (30개 파일) ``` AGVNavigationCore/ ├── Models/ (8개) │ ├── MapNode.cs, MapLoader.cs, VirtualAGV.cs, IMovableAGV.cs, etc. ├── Controls/ (6개) │ ├── UnifiedAGVCanvas.cs, UnifiedAGVCanvas.Designer.cs, etc. ├── PathFinding/ (13개) │ ├── Core/ (AStarPathfinder, PathNode, AGVPathResult) │ ├── Planning/ (AGVPathfinder, DirectionChangePlanner, etc.) │ ├── Analysis/ (JunctionAnalyzer) │ └── Validation/ (PathValidationResult, DockingValidationResult) └── Utils/ (3개) ├── LiftCalculator.cs, DockingValidator.cs, etc. ``` ### AGVSimulator (8개 파일) ``` AGVSimulator/ ├── Forms/ │ ├── SimulatorForm.cs (시뮬레이터 메인 폼) │ └── SimulatorForm.Designer.cs ├── Models/ │ └── (VirtualAGV는 AGVNavigationCore에서 참조) ├── Program.cs └── Properties/ └── AssemblyInfo.cs ``` --- ## 🔄 데이터 흐름 ### 맵 편집 → 저장 흐름 ``` AGVMapEditor.MainForm ↓ UnifiedAGVCanvas (편집 모드) ↓ MapLoader.SaveMapToFile() ↓ NewMap.agvmap (JSON 파일) ``` ### 맵 로드 → 시뮬레이션 흐름 ``` NewMap.agvmap (JSON 파일) ↓ MapLoader.LoadMapFromFile() ↓ AGVSimulator.SimulatorForm ↓ UnifiedAGVCanvas (모니터링 모드) ↓ VirtualAGV (경로 실행) ⚠️ 미완성 ``` --- ## ⚠️ 현재 미완성 부분 ### 🔴 우선순위 높음 1. **VirtualAGV.ExecutePath()** - 경로 실행 로직 2. **VirtualAGV.Update()** - 매 프레임 위치 업데이트 3. **AGVPathfinder 핵심** - 경로 상세화, 마그넷 방향 계산 ### 🟡 우선순위 중간 4. **DirectionChangePlanner** - 4단계 방향 전환 알고리즘 5. **UnifiedAGVCanvas 줌 개선** - 마우스 기준 스무스 줌 --- ## 📝 참고 문서 - `CLAUDE.md` - 개발 가이드 및 AGV 하드웨어 설명 - `CHANGELOG.md` - 변경 로그 - `Data/NewMap.agvmap` - 실제 맵 데이터 샘플