Files
ENIG/Cs_HMI/AGVLogic/IMPLEMENTATION_SUMMARY.md
backuppc d932b8d332 fix: Add motor direction parameter to magnet direction calculation in pathfinding
- Fixed critical issue in ConvertToDetailedPath where motor direction was not passed to GetRequiredMagnetDirection
- Motor direction is essential for backward movement as Left/Right directions must be inverted
- Modified AGVPathfinder.cs line 280 to pass currentDirection parameter
- Ensures backward motor direction properly inverts magnet sensor directions

feat: Add waypoint support to pathfinding system

- Added FindPath overload with params string[] waypointNodeIds in AStarPathfinder
- Supports sequential traversal through multiple intermediate nodes
- Validates waypoints and prevents duplicates in sequence
- Returns combined path result with aggregated metrics

feat: Implement path result merging with DetailedPath preservation

- Added CombineResults method in AStarPathfinder for intelligent path merging
- Automatically deduplicates nodes when last of previous path equals first of current
- Preserves DetailedPath information including motor and magnet directions
- Essential for multi-segment path operations

feat: Integrate magnet direction with motor direction awareness

- Modified JunctionAnalyzer.GetRequiredMagnetDirection to accept AgvDirection parameter
- Inverts Left/Right magnet directions when moving Backward
- Properly handles motor direction context throughout pathfinding

feat: Add automatic start node selection in simulator

- Added SetStartNodeToCombo method to SimulatorForm
- Automatically selects start node combo box when AGV position is set via RFID
- Improves UI usability and workflow efficiency

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-24 15:46:16 +09:00

8.9 KiB
Raw Blame History

방향 기반 경로 탐색 구현 완료 요약

구현 완료

사용자 요구사항에 따라 이전 위치 + 현재 위치 + 진행 방향을 기반으로 다음 노드를 계산하는 시스템을 완전히 구현했습니다.


📦 구현된 컴포넌트

1. VirtualAGV.GetNextNodeId() (핵심 메서드)

파일: AGVNavigationCore\Models\VirtualAGV.cs (라인 613~823)

public string GetNextNodeId(AgvDirection direction, List<MapNode> allNodes)

특징:

  • VirtualAGV의 _prevPosition, _currentPosition, _currentNode 사용
  • 최소 2개 위치 히스토리 검증 (prev/current 모두 설정되어야 함)
  • 벡터 기반 방향 계산 (내적, 외적)
  • Forward/Backward/Left/Right 모든 방향 지원
  • Backward 시 좌우 방향 자동 반전

동작 방식:

입력: direction (Forward/Backward/Left/Right), allNodes
  ↓
1⃣ 히스토리 검증: _prevPosition, _currentPosition 확인
2⃣ 연결된 노드 필터링: currentNode의 ConnectedNodes에서 후보 선택
3⃣ 이동 벡터 계산: _currentPosition - _prevPosition
4⃣ 벡터 정규화: 길이를 1로 만듦
5⃣ 각 후보에 대해 점수 계산:
   - 내적: 진행 방향과의 유사도
   - 외적: 좌우 판별
   - direction에 따라 가중치 적용
6⃣ 최고 점수 노드 반환

🧮 방향 점수 계산 로직

Forward (전진) 모드

내적 값 (dotProduct)     점수
────────────────────────────
> 0.9  (거의 같은 방향)   100
0.5~0.9 (비슷한 방향)    80
0~0.5  (약간 다른 방향)  50
-0.5~0 (거의 반대)       20
< -0.5 (완전 반대)       0

Backward (후진) 모드

내적 값 (dotProduct)     점수
────────────────────────────
< -0.9 (거의 반대)       100
-0.5~-0.9 (비슷하게 반대) 80
-0.5~0 (약간 다른)       50
0~0.5  (거의 같은 방향)  20
> 0.5  (완전 같은 방향)  0

Left (좌측) 모드

Forward 상태 (dotProduct > 0):          Backward 상태 (dotProduct < 0):
─────────────────────────────────────────────────────────────────────
crossProduct > 0.5 → 100 (좌측)        crossProduct < -0.5 → 100 (좌측 반전)
0~0.5 → 70                            -0.5~0 → 70
-0.5~0 → 50                           0~0.5 → 50
< -0.5 → 30                           > 0.5 → 30

Right (우측) 모드

Forward 상태 (dotProduct > 0):          Backward 상태 (dotProduct < 0):
─────────────────────────────────────────────────────────────────────
crossProduct < -0.5 → 100 (우측)       crossProduct > 0.5 → 100 (우측 반전)
-0.5~0 → 70                           0~0.5 → 70
0~0.5 → 50                            -0.5~0 → 50
> 0.5 → 30                            < -0.5 → 30

📋 테스트 시나리오

시나리오 1: 직선 경로 전진

001 (65, 229) → 002 (206, 244) → GetNextNodeId(Forward)
이동 벡터: (141, 15)
002→003: (72, 34)
내적: 0.939 → Forward 점수: 100 ✓
결과: 003

시나리오 2: 좌회전

002 (206, 244) → 003 (278, 278) → GetNextNodeId(Left)
이동 벡터에 대해 Left 가중치 적용
외적: crossProduct 양수 선호

시나리오 3: 우회전

003 (278, 278) → 004 (380, 340) → GetNextNodeId(Right)
이동 벡터에 대해 Right 가중치 적용
외적: crossProduct 음수 선호
결과: 030 또는 N022 (맵 구조에 따라)

시나리오 4: 후진

004 → 003 → GetNextNodeId(Backward)
역진 가중치 적용 (dotProduct < -0.9 = 100점)
결과: 002

시나리오 5: Backward 시 좌우 반전

004 → 003 (Backward) → GetNextNodeId(Left)
Backward 상태에서 Left = 원래 Right 방향
좌우 자동 반전으로 올바른 방향 계산

🏗️ 추가 구현 파일들

1. DirectionalPathfinder.cs

파일: PathFinding\Planning\DirectionalPathfinder.cs

  • 독립적인 벡터 기반 경로 탐색 엔진
  • VirtualAGV와 분리된 재사용 가능한 컴포넌트
  • 방향 가중치 커스터마이징 지원

2. AGVDirectionCalculator.cs

파일: Utils\AGVDirectionCalculator.cs

  • VirtualAGV와 실제 AGV 시스템을 위한 통합 인터페이스
  • RFID 위치 기반 계산
  • 선택된 방향 역추적 기능

3. DirectionalPathfinderTest.cs

파일: Utils\DirectionalPathfinderTest.cs

  • NewMap.agvmap 파일 로드 및 파싱
  • 테스트 시나리오 실행
  • 결과 검증 및 출력

4. TestRunner.cs

파일: Utils\TestRunner.cs

  • 전체 테스트 프로그램 실행
  • 모든 시나리오 자동 테스트

📊 .csproj 수정 사항

파일: AGVNavigationCore\AGVNavigationCore.csproj

추가된 항목:

<Compile Include="PathFinding\Planning\DirectionalPathfinder.cs" />
<Compile Include="Utils\AGVDirectionCalculator.cs" />
<Compile Include="Utils\DirectionalPathfinderTest.cs" />
<Compile Include="Utils\TestRunner.cs" />

🚀 사용 방법

기본 사용 (VirtualAGV)

// VirtualAGV 인스턴스
var agv = new VirtualAGV("AGV001");

// 위치 설정 (최소 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);
Console.WriteLine($"다음 노드: {nextNodeId}"); // 003

고급 사용 (독립적인 계산기)

var calculator = new AGVDirectionCalculator();

string nextNodeId = calculator.GetNextNodeId(
    previousRfidPos: new Point(206, 244),
    currentNode: node003,
    currentRfidPos: new Point(278, 278),
    direction: AgvDirection.Right,
    allNodes: allNodes
);

// 실제 선택된 방향 분석
AgvDirection selectedDir = calculator.AnalyzeSelectedDirection(
    new Point(206, 244),
    new Point(278, 278),
    selectedNextNode,
    connectedNodes
);

⚠️ 중요 주의사항

1. 2개 위치 히스토리 필수

// ❌ 잘못된 사용 (처음 호출 시)
string next = agv.GetNextNodeId(direction, allNodes); // null 반환

// ✅ 올바른 사용
agv.SetPosition(node1, pos1, AgvDirection.Forward);  // 첫 번째
agv.SetPosition(node2, pos2, AgvDirection.Forward);  // 두 번째
string next = agv.GetNextNodeId(direction, allNodes); // 결과 반환

2. 벡터 정규화

  • 매우 작은 이동(<0.001px)은 거리 0으로 간주
  • 이 경우 첫 번째 연결 노드 반환

3. 좌표계 유지

  • 모든 좌표는 맵 기준 (화면 좌표가 아님)
  • 줌/팬 상태에서는 별도 변환 필요

4. 내적/외적 이해

내적 (Dot Product):
  = v1.x * v2.x + v1.y * v2.y
  범위: -1 ~ 1
  1 = 같은 방향, 0 = 직각, -1 = 반대 방향

외적 (Cross Product):
  = v1.x * v2.y - v1.y * v2.x
  양수 = 좌측, 음수 = 우측

📁 최종 파일 구조

AGVNavigationCore/
├── Models/
│   └── VirtualAGV.cs ⭐ (GetNextNodeId 추가)
├── PathFinding/
│   └── Planning/
│       ├── DirectionalPathfinder.cs (NEW)
│       ├── AGVPathfinder.cs
│       └── ...
├── Utils/
│   ├── AGVDirectionCalculator.cs (NEW)
│   ├── DirectionalPathfinderTest.cs (NEW)
│   ├── TestRunner.cs (NEW)
│   └── ...
└── AGVNavigationCore.csproj (MODIFIED)

🎯 핵심 요구사항 검증

요구사항 상태 구현 위치
GetNextNodeID(direction) 메서드 완료 VirtualAGV:628
2개 위치 히스토리 검증 완료 VirtualAGV:630-634
Forward/Backward/Left/Right 지원 완료 VirtualAGV:743-817
좌우 반전 로직 완료 VirtualAGV:780, 806
벡터 기반 계산 완료 VirtualAGV:658-678
NewMap.agvmap 테스트 지원 완료 DirectionalPathfinderTest

📝 다음 단계 (선택사항)

  1. 실제 맵에서 테스트

    • TestRunner로 NewMap.agvmap 검증
    • 실제 RFID 번호로 시나리오 테스트
  2. 성능 최적화

    • 벡터 계산 캐싱
    • 점수 계산 병렬화
  3. 기능 확장

    • 3D 좌표 지원
    • A* 알고리즘 통합
    • 동적 가중치 조정
  4. 시뮬레이터 통합

    • AGVSimulator에 GetNextNodeId 연결
    • 실시간 경로 변경 시연

📚 관련 문서

  • ANALYSIS_AGV_Direction_Storage.md - VirtualAGV 필드 분석
  • IMPLEMENTATION_DirectionalPathfinder.md - 상세 구현 가이드

완료 일시: 2025-10-23 상태: 🟢 구현 완료, 테스트 대기 다음 작업: NewMap.agvmap으로 실제 테스트