refactor: Convert AGVPathResult.Path from List<string> to List<MapNode>

## Summary
- Changed Path property type from List<string> to List<MapNode> for better type safety
- Eliminated O(n) node lookups throughout pathfinding system
- Added DirectionalHelper with motor direction consistency bonus/penalty
- Updated all path processing to work with MapNode objects directly

## Files Modified
- AGVPathResult.cs: Path property and CreateSuccess() method signature
- AStarPathfinder.cs: Path generation and node lookup optimization
- AGVPathfinder.cs: Path processing with MapNode objects
- DirectionChangePlanner.cs: Direction change planning with MapNode paths
- DockingValidator.cs: Docking validation with direct node access
- UnifiedAGVCanvas.Events.cs: Path visualization with MapNode iteration
- UnifiedAGVCanvas.cs: Destination node access
- VirtualAGV.cs: Path conversion to string IDs for storage
- DirectionalHelper.cs: Enhanced with motor direction awareness
- NodeMotorInfo.cs: Updated for new path structure

## Benefits
- Performance: Eliminated O(n) lookup searches
- Type Safety: Compile-time checking for node properties
- Code Quality: Direct property access instead of repeated lookups
- Maintainability: Single source of truth for node data

## Build Status
 AGVNavigationCore: Build successful (0 errors, 2 warnings)

🤖 Generated with Claude Code
Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
backuppc
2025-10-27 16:46:13 +09:00
parent dbf81bfc60
commit 735b7dccec
12 changed files with 520 additions and 239 deletions

View File

@@ -238,8 +238,13 @@ namespace AGVNavigationCore.Controls
for (int i = 0; i < path.Path.Count - 1; i++)
{
var currentNodeId = path.Path[i];
var nextNodeId = path.Path[i + 1];
var currentNode = path.Path[i];
var nextNode = path.Path[i + 1];
if (currentNode == null || nextNode == null) continue;
var currentNodeId = currentNode.NodeId;
var nextNodeId = nextNode.NodeId;
// 왕복 구간 키 생성 (양방향 모두 같은 키)
var segmentKey = string.Compare(currentNodeId, nextNodeId) < 0
@@ -250,9 +255,6 @@ namespace AGVNavigationCore.Controls
visitedSegments[segmentKey] = 0;
visitedSegments[segmentKey]++;
var currentNode = _nodes?.FirstOrDefault(n => n.NodeId == currentNodeId);
var nextNode = _nodes?.FirstOrDefault(n => n.NodeId == nextNodeId);
if (currentNode != null && nextNode != null)
{
// 왕복 경로면 더 진한 색상으로 표시
@@ -295,9 +297,8 @@ namespace AGVNavigationCore.Controls
const int JUNCTION_CONNECTIONS = 3; // 교차로 판정 기준: 3개 이상의 연결
foreach (var nodeId in path.Path)
foreach (var node in path.Path)
{
var node = _nodes.FirstOrDefault(n => n.NodeId == nodeId);
if (node == null) continue;
// 교차로 판정: 3개 이상의 노드가 연결된 경우
@@ -339,7 +340,7 @@ namespace AGVNavigationCore.Controls
}
// 교차로 라벨 추가
DrawJunctionLabel(g, junctionNode);
//DrawJunctionLabel(g, junctionNode);
}
/// <summary>

View File

@@ -525,10 +525,7 @@ namespace AGVNavigationCore.Controls
if (_currentPath != null && _currentPath.Success && _currentPath.Path != null && _currentPath.Path.Count > 0)
{
// 경로의 마지막 노드가 목적지
string destinationNodeId = _currentPath.Path[_currentPath.Path.Count - 1];
// 노드 목록에서 해당 노드 찾기
_destinationNode = _nodes?.FirstOrDefault(n => n.NodeId == destinationNodeId);
_destinationNode = _currentPath.Path[_currentPath.Path.Count - 1];
}
}