"feat:Enable-hover-highlight-and-refactor"
This commit is contained in:
@@ -76,7 +76,7 @@ namespace AGVNavigationCore.Utils
|
||||
List<MapNode> candidateNodes = new List<MapNode>();
|
||||
if (prevDirection == direction)
|
||||
{
|
||||
candidateNodes = connectedMapNodes.Where(n => n.NodeId != prevNode.NodeId).ToList();
|
||||
candidateNodes = connectedMapNodes.Where(n => n.Id != prevNode.Id).ToList();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -112,9 +112,9 @@ namespace AGVNavigationCore.Utils
|
||||
Console.WriteLine(
|
||||
$"\n[GetNextNodeByDirection] ========== 다음 노드 선택 시작 ==========");
|
||||
Console.WriteLine(
|
||||
$" 현재노드: {currentNode.RfidId}[{currentNode.NodeId}]({currentNode.Position.X:F1}, {currentNode.Position.Y:F1})");
|
||||
$" 현재노드: {currentNode.RfidId}[{currentNode.Id}]({currentNode.Position.X:F1}, {currentNode.Position.Y:F1})");
|
||||
Console.WriteLine(
|
||||
$" 이전노드: {prevNode.RfidId}[{prevNode.NodeId}]({prevNode.Position.X:F1}, {prevNode.Position.Y:F1})");
|
||||
$" 이전노드: {prevNode.RfidId}[{prevNode.Id}]({prevNode.Position.X:F1}, {prevNode.Position.Y:F1})");
|
||||
Console.WriteLine(
|
||||
$" 이동벡터: ({movementVector.X:F2}, {movementVector.Y:F2}) → 정규화: ({normalizedMovement.X:F3}, {normalizedMovement.Y:F3})");
|
||||
Console.WriteLine(
|
||||
@@ -159,7 +159,7 @@ namespace AGVNavigationCore.Utils
|
||||
}
|
||||
|
||||
Console.WriteLine(
|
||||
$"\n [후보] {candidate.RfidId}[{candidate.NodeId}]({candidate.Position.X:F1}, {candidate.Position.Y:F1})");
|
||||
$"\n [후보] {candidate.RfidId}[{candidate.Id}]({candidate.Position.X:F1}, {candidate.Position.Y:F1})");
|
||||
Console.WriteLine(
|
||||
$" 벡터: ({toNextVector.X:F2}, {toNextVector.Y:F2}), 길이: {toNextLength:F2}");
|
||||
Console.WriteLine(
|
||||
@@ -204,7 +204,7 @@ namespace AGVNavigationCore.Utils
|
||||
}
|
||||
|
||||
Console.WriteLine(
|
||||
$"\n 최종선택: {bestNode?.RfidId ?? "null"}[{bestNode?.NodeId ?? "null"}] (점수: {bestScore:F4})");
|
||||
$"\n 최종선택: {bestNode?.RfidId ?? "null"}[{bestNode?.Id ?? "null"}] (점수: {bestScore:F4})");
|
||||
Console.WriteLine(
|
||||
$"[GetNextNodeByDirection] ========== 다음 노드 선택 종료 ==========\n");
|
||||
|
||||
@@ -445,15 +445,15 @@ namespace AGVNavigationCore.Utils
|
||||
// 선택 이유 생성
|
||||
if (prevMotorDirection.HasValue && direction == prevMotorDirection)
|
||||
{
|
||||
reason = $"모터 방향 일관성 유지 ({direction}) → {candidate.NodeId}";
|
||||
reason = $"모터 방향 일관성 유지 ({direction}) → {candidate.Id}";
|
||||
}
|
||||
else if (prevMotorDirection.HasValue)
|
||||
{
|
||||
reason = $"모터 방향 변경 ({prevMotorDirection} → {direction}) → {candidate.NodeId}";
|
||||
reason = $"모터 방향 변경 ({prevMotorDirection} → {direction}) → {candidate.Id}";
|
||||
}
|
||||
else
|
||||
{
|
||||
reason = $"방향 기반 선택 ({direction}) → {candidate.NodeId}";
|
||||
reason = $"방향 기반 선택 ({direction}) → {candidate.Id}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -90,8 +90,8 @@ namespace AGVNavigationCore.Utils
|
||||
return;
|
||||
}
|
||||
|
||||
Console.WriteLine($"이전 노드: {previousNode.NodeId} (RFID: {previousNode.RfidId}) - 위치: {previousNode.Position}");
|
||||
Console.WriteLine($"현재 노드: {currentNode.NodeId} (RFID: {currentNode.RfidId}) - 위치: {currentNode.Position}");
|
||||
Console.WriteLine($"이전 노드: {previousNode.Id} (RFID: {previousNode.RfidId}) - 위치: {previousNode.Position}");
|
||||
Console.WriteLine($"현재 노드: {currentNode.Id} (RFID: {currentNode.RfidId}) - 위치: {currentNode.Position}");
|
||||
Console.WriteLine($"이동 벡터: ({currentNode.Position.X - previousNode.Position.X}, " +
|
||||
$"{currentNode.Position.Y - previousNode.Position.Y})");
|
||||
|
||||
@@ -111,10 +111,10 @@ namespace AGVNavigationCore.Utils
|
||||
}
|
||||
|
||||
// 다음 노드 정보 출력
|
||||
var nextNode = _allNodes.FirstOrDefault(n => n.NodeId == nextNodeId);
|
||||
var nextNode = _allNodes.FirstOrDefault(n => n.Id == nextNodeId);
|
||||
if (nextNode != null)
|
||||
{
|
||||
Console.WriteLine($"✓ 다음 노드: {nextNode.NodeId} (RFID: {nextNode.RfidId}) - 위치: {nextNode.Position}");
|
||||
Console.WriteLine($"✓ 다음 노드: {nextNode.Id} (RFID: {nextNode.RfidId}) - 위치: {nextNode.Position}");
|
||||
Console.WriteLine($" ├─ 노드 타입: {GetNodeTypeName(nextNode.Type)}");
|
||||
Console.WriteLine($" └─ 연결된 노드: {string.Join(", ", nextNode.ConnectedNodes)}");
|
||||
}
|
||||
@@ -132,7 +132,7 @@ namespace AGVNavigationCore.Utils
|
||||
Console.WriteLine("\n========== 모든 노드 정보 ==========");
|
||||
foreach (var node in _allNodes.OrderBy(n => n.RfidId))
|
||||
{
|
||||
Console.WriteLine($"{node.RfidId:D3} → {node.NodeId} ({GetNodeTypeName(node.Type)})");
|
||||
Console.WriteLine($"{node.RfidId:D3} → {node.Id} ({GetNodeTypeName(node.Type)})");
|
||||
Console.WriteLine($" 위치: {node.Position}, 연결: {string.Join(", ", node.ConnectedNodes)}");
|
||||
}
|
||||
}
|
||||
@@ -149,8 +149,9 @@ namespace AGVNavigationCore.Utils
|
||||
}
|
||||
|
||||
Console.WriteLine($"\n========== RFID {rfidId} 상세 정보 ==========");
|
||||
Console.WriteLine($"노드 ID: {node.NodeId}");
|
||||
Console.WriteLine($"이름: {node.Name}");
|
||||
Console.WriteLine($"노드 ID: {node.Id}");
|
||||
Console.WriteLine($"RFID: {node.RfidId}");
|
||||
Console.WriteLine($"ALIAS: {node.AliasName}");
|
||||
Console.WriteLine($"위치: {node.Position}");
|
||||
Console.WriteLine($"타입: {GetNodeTypeName(node.Type)}");
|
||||
Console.WriteLine($"TurnLeft/Right/교차로 : {(node.CanTurnLeft ? "O":"X")}/{(node.CanTurnRight ? "O" : "X")}/{(node.DisableCross ? "X" : "O")}");
|
||||
@@ -165,7 +166,7 @@ namespace AGVNavigationCore.Utils
|
||||
{
|
||||
foreach (var connectedId in node.ConnectedNodes)
|
||||
{
|
||||
var connectedNode = _allNodes.FirstOrDefault(n => n.NodeId == connectedId);
|
||||
var connectedNode = _allNodes.FirstOrDefault(n => n.Id == connectedId);
|
||||
if (connectedNode != null)
|
||||
{
|
||||
Console.WriteLine($" → {connectedId} (RFID: {connectedNode.RfidId}) - 위치: {connectedNode.Position}");
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace AGVNavigationCore.Utils
|
||||
return DockingValidationResult.CreateNotRequired();
|
||||
}
|
||||
if (pathResult.DetailedPath.Any() == false && pathResult.Path.Any() && pathResult.Path.Count == 2 &&
|
||||
pathResult.Path[0].NodeId == pathResult.Path[1].NodeId)
|
||||
pathResult.Path[0].Id == pathResult.Path[1].Id)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 도킹 검증 불필요: 동일포인트");
|
||||
return DockingValidationResult.CreateNotRequired();
|
||||
@@ -44,7 +44,7 @@ namespace AGVNavigationCore.Utils
|
||||
return DockingValidationResult.CreateNotRequired();
|
||||
}
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 목적지 노드: {LastNode.NodeId} 타입:{LastNode.Type} ({(int)LastNode.Type})");
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 목적지 노드: {LastNode.Id} 타입:{LastNode.Type} ({(int)LastNode.Type})");
|
||||
|
||||
//detail 경로 이동 예측 검증
|
||||
for (int i = 0; i < pathResult.DetailedPath.Count - 1; i++)
|
||||
@@ -52,8 +52,8 @@ namespace AGVNavigationCore.Utils
|
||||
var curNodeId = pathResult.DetailedPath[i].NodeId;
|
||||
var nextNodeId = pathResult.DetailedPath[i + 1].NodeId;
|
||||
|
||||
var curNode = mapNodes?.FirstOrDefault(n => n.NodeId == curNodeId);
|
||||
var nextNode = mapNodes?.FirstOrDefault(n => n.NodeId == nextNodeId);
|
||||
var curNode = mapNodes?.FirstOrDefault(n => n.Id == curNodeId);
|
||||
var nextNode = mapNodes?.FirstOrDefault(n => n.Id == nextNodeId);
|
||||
|
||||
if (curNode != null && nextNode != null)
|
||||
{
|
||||
@@ -67,7 +67,7 @@ namespace AGVNavigationCore.Utils
|
||||
else
|
||||
{
|
||||
var prevNodeId = pathResult.DetailedPath[i - 1].NodeId;
|
||||
prevNode = mapNodes?.FirstOrDefault(n => n.NodeId == prevNodeId);
|
||||
prevNode = mapNodes?.FirstOrDefault(n => n.Id == prevNodeId);
|
||||
prevDir = pathResult.DetailedPath[i - 1].MotorDirection;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,7 @@ namespace AGVNavigationCore.Utils
|
||||
Console.WriteLine(
|
||||
$"\n[ValidateDockingDirection] 경로 검증 단계 {i}:");
|
||||
Console.WriteLine(
|
||||
$" 이전→현재→다음: {prevNode.NodeId}({prevNode.RfidId}) → {curNode.NodeId}({curNode.RfidId}) → {nextNode.NodeId}({nextNode.RfidId})");
|
||||
$" 이전→현재→다음: {prevNode.Id}({prevNode.RfidId}) → {curNode.Id}({curNode.RfidId}) → {nextNode.Id}({nextNode.RfidId})");
|
||||
Console.WriteLine(
|
||||
$" 현재 노드 위치: ({curNode.Position.X:F1}, {curNode.Position.Y:F1})");
|
||||
Console.WriteLine(
|
||||
@@ -96,16 +96,16 @@ namespace AGVNavigationCore.Utils
|
||||
);
|
||||
|
||||
Console.WriteLine(
|
||||
$" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.NodeId ?? "null"}");
|
||||
$" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.Id ?? "null"}");
|
||||
Console.WriteLine(
|
||||
$" [실제] DetailedPath 다음 노드: {nextNode.RfidId}[{nextNode.NodeId}]");
|
||||
$" [실제] DetailedPath 다음 노드: {nextNode.RfidId}[{nextNode.Id}]");
|
||||
|
||||
if (expectedNextNode != null && !expectedNextNode.NodeId.Equals(nextNode.NodeId))
|
||||
if (expectedNextNode != null && !expectedNextNode.Id.Equals(nextNode.Id))
|
||||
{
|
||||
string error =
|
||||
$"[DockingValidator] ⚠️ 경로 방향 불일치" +
|
||||
$"\n현재={curNode.RfidId}[{curNodeId}] 이전={prevNode.RfidId}[{(prevNode?.NodeId ?? string.Empty)}] " +
|
||||
$"\n예상다음={expectedNextNode.RfidId}[{expectedNextNode.NodeId}] 실제다음={nextNode.RfidId}[{nextNodeId}]";
|
||||
$"\n현재={curNode.RfidId}[{curNodeId}] 이전={prevNode.RfidId}[{(prevNode?.Id ?? string.Empty)}] " +
|
||||
$"\n예상다음={expectedNextNode.RfidId}[{expectedNextNode.Id}] 실제다음={nextNode.RfidId}[{nextNodeId}]";
|
||||
Console.WriteLine(
|
||||
$"[ValidateDockingDirection] ❌ 경로 방향 불일치 검출!");
|
||||
Console.WriteLine(
|
||||
@@ -118,7 +118,7 @@ namespace AGVNavigationCore.Utils
|
||||
$" 현재→실제: ({(nextNode.Position.X - curNode.Position.X):F2}, {(nextNode.Position.Y - curNode.Position.Y):F2})");
|
||||
Console.WriteLine($"[ValidateDockingDirection] 에러메시지: {error}");
|
||||
return DockingValidationResult.CreateInvalid(
|
||||
LastNode.NodeId,
|
||||
LastNode.Id,
|
||||
LastNode.Type,
|
||||
pathResult.DetailedPath[i].MotorDirection,
|
||||
pathResult.DetailedPath[i].MotorDirection,
|
||||
@@ -150,12 +150,12 @@ namespace AGVNavigationCore.Utils
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 필요한 도킹 방향: {requiredDirection}");
|
||||
|
||||
var LastNodeInfo = pathResult.DetailedPath.Last();
|
||||
if (LastNodeInfo.NodeId != LastNode.NodeId)
|
||||
if (LastNodeInfo.NodeId != LastNode.Id)
|
||||
{
|
||||
string error = $"마지막 노드의 도킹방향과 경로정보의 노드ID 불일치: 필요={LastNode.NodeId}, 계산됨={LastNodeInfo.NodeId }";
|
||||
string error = $"마지막 노드의 도킹방향과 경로정보의 노드ID 불일치: 필요={LastNode.Id}, 계산됨={LastNodeInfo.NodeId }";
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] ❌ 도킹 검증 실패: {error}");
|
||||
return DockingValidationResult.CreateInvalid(
|
||||
LastNode.NodeId,
|
||||
LastNode.Id,
|
||||
LastNode.Type,
|
||||
requiredDirection,
|
||||
LastNodeInfo.MotorDirection,
|
||||
@@ -167,7 +167,7 @@ namespace AGVNavigationCore.Utils
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] ✅ 도킹 검증 성공");
|
||||
return DockingValidationResult.CreateValid(
|
||||
LastNode.NodeId,
|
||||
LastNode.Id,
|
||||
LastNode.Type,
|
||||
requiredDirection,
|
||||
LastNodeInfo.MotorDirection);
|
||||
@@ -177,7 +177,7 @@ namespace AGVNavigationCore.Utils
|
||||
string error = $"도킹 방향 불일치: 필요={GetDirectionText(requiredDirection)}, 계산됨={GetDirectionText(LastNodeInfo.MotorDirection)}";
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] ❌ 도킹 검증 실패: {error}");
|
||||
return DockingValidationResult.CreateInvalid(
|
||||
LastNode.NodeId,
|
||||
LastNode.Id,
|
||||
LastNode.Type,
|
||||
requiredDirection,
|
||||
LastNodeInfo.MotorDirection,
|
||||
@@ -264,7 +264,7 @@ namespace AGVNavigationCore.Utils
|
||||
var deltaY = lastNode.Position.Y - secondLastNode.Position.Y;
|
||||
var distance = Math.Sqrt(deltaX * deltaX + deltaY * deltaY);
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[CalculateFinalDirection] 마지막 구간: {secondLastNode.NodeId} → {lastNode.NodeId}, 벡터: ({deltaX}, {deltaY}), 거리: {distance:F2}");
|
||||
System.Diagnostics.Debug.WriteLine($"[CalculateFinalDirection] 마지막 구간: {secondLastNode.Id} → {lastNode.Id}, 벡터: ({deltaX}, {deltaY}), 거리: {distance:F2}");
|
||||
|
||||
// 이동 거리가 매우 작으면 현재 방향 유지
|
||||
if (distance < 1.0)
|
||||
|
||||
@@ -28,10 +28,10 @@ namespace AGVNavigationCore.Utils
|
||||
Console.WriteLine("================================================\n");
|
||||
|
||||
// 테스트 노드 생성
|
||||
var node001 = new MapNode { NodeId = "N001", RfidId = "001", Position = new Point(65, 229), ConnectedNodes = new List<string> { "N002" } };
|
||||
var node002 = new MapNode { NodeId = "N002", RfidId = "002", Position = new Point(206, 244), ConnectedNodes = new List<string> { "N001", "N003" } };
|
||||
var node003 = new MapNode { NodeId = "N003", RfidId = "003", Position = new Point(278, 278), ConnectedNodes = new List<string> { "N002", "N004" } };
|
||||
var node004 = new MapNode { NodeId = "N004", RfidId = "004", Position = new Point(380, 340), ConnectedNodes = new List<string> { "N003", "N022", "N031" } };
|
||||
var node001 = new MapNode { Id = "N001", RfidId = "001", Position = new Point(65, 229), ConnectedNodes = new List<string> { "N002" } };
|
||||
var node002 = new MapNode { Id = "N002", RfidId = "002", Position = new Point(206, 244), ConnectedNodes = new List<string> { "N001", "N003" } };
|
||||
var node003 = new MapNode { Id = "N003", RfidId = "003", Position = new Point(278, 278), ConnectedNodes = new List<string> { "N002", "N004" } };
|
||||
var node004 = new MapNode { Id = "N004", RfidId = "004", Position = new Point(380, 340), ConnectedNodes = new List<string> { "N003", "N022", "N031" } };
|
||||
|
||||
var allNodes = new List<MapNode> { node001, node002, node003, node004 };
|
||||
|
||||
@@ -115,7 +115,7 @@ namespace AGVNavigationCore.Utils
|
||||
|
||||
Console.WriteLine($"설명: {description}");
|
||||
Console.WriteLine($"이전 위치: {prevPos} (RFID: {allNodes.First(n => n.Position == prevPos)?.RfidId ?? "?"})");
|
||||
Console.WriteLine($"현재 노드: {currentNode.NodeId} (RFID: {currentNode.RfidId}) - 위치: {currentNode.Position}");
|
||||
Console.WriteLine($"현재 노드: {currentNode.Id} (RFID: {currentNode.RfidId}) - 위치: {currentNode.Position}");
|
||||
Console.WriteLine($"현재 모터 방향: {motorDir}");
|
||||
Console.WriteLine($"요청 방향: {direction}");
|
||||
|
||||
@@ -128,32 +128,32 @@ namespace AGVNavigationCore.Utils
|
||||
Console.WriteLine($"이동 벡터: ({movementVector.X}, {movementVector.Y})");
|
||||
|
||||
// 각 후보 노드에 대한 점수 계산
|
||||
Console.WriteLine($"\n현재 노드({currentNode.NodeId})의 ConnectedNodes: {string.Join(", ", currentNode.ConnectedNodes)}");
|
||||
Console.WriteLine($"\n현재 노드({currentNode.Id})의 ConnectedNodes: {string.Join(", ", currentNode.ConnectedNodes)}");
|
||||
Console.WriteLine($"가능한 다음 노드들:");
|
||||
|
||||
var candidateNodes = allNodes.Where(n =>
|
||||
currentNode.ConnectedNodes.Contains(n.NodeId) && n.NodeId != currentNode.NodeId
|
||||
currentNode.ConnectedNodes.Contains(n.Id) && n.Id != currentNode.Id
|
||||
).ToList();
|
||||
|
||||
foreach (var candidate in candidateNodes)
|
||||
{
|
||||
var score = CalculateScoreAndPrint(movementVector, currentNode.Position, candidate, direction);
|
||||
string isExpected = (candidate.NodeId == expectedNextNode.NodeId) ? " ← 예상 노드" : "";
|
||||
Console.WriteLine($" {candidate.NodeId} (RFID: {candidate.RfidId}) - 위치: {candidate.Position} - 점수: {score:F1}{isExpected}");
|
||||
string isExpected = (candidate.Id == expectedNextNode.Id) ? " ← 예상 노드" : "";
|
||||
Console.WriteLine($" {candidate.Id} (RFID: {candidate.RfidId}) - 위치: {candidate.Position} - 점수: {score:F1}{isExpected}");
|
||||
}
|
||||
|
||||
// 최고 점수 노드 선택
|
||||
var bestCandidate = GetBestCandidate(movementVector, currentNode.Position, candidateNodes, direction);
|
||||
|
||||
Console.WriteLine($"\n✓ 선택된 노드: {bestCandidate.NodeId} (RFID: {bestCandidate.RfidId})");
|
||||
Console.WriteLine($"\n✓ 선택된 노드: {bestCandidate.Id} (RFID: {bestCandidate.RfidId})");
|
||||
|
||||
if (bestCandidate.NodeId == expectedNextNode.NodeId)
|
||||
if (bestCandidate.Id == expectedNextNode.Id)
|
||||
{
|
||||
Console.WriteLine($"✅ 정답! ({expectedNodeIdStr})");
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine($"❌ 오답! 예상: {expectedNextNode.NodeId}, 실제: {bestCandidate.NodeId}");
|
||||
Console.WriteLine($"❌ 오답! 예상: {expectedNextNode.Id}, 실제: {bestCandidate.Id}");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,14 +63,14 @@ namespace AGVNavigationCore.Utils
|
||||
// 이전 노드 제외 (되돌아가는 방향 제외)
|
||||
if (previousNode != null)
|
||||
{
|
||||
nextNodes = nextNodes.Where(n => n.NodeId != previousNode.NodeId).ToList();
|
||||
nextNodes = nextNodes.Where(n => n.Id != previousNode.Id).ToList();
|
||||
}
|
||||
|
||||
if (nextNodes.Count == 1)
|
||||
{
|
||||
// 직선 경로: 다음 노드 방향으로 예측
|
||||
targetPosition = nextNodes.First().Position;
|
||||
calculationMethod = $"전진 경로 예측 ({currentNode.NodeId}→{nextNodes.First().NodeId})";
|
||||
calculationMethod = $"전진 경로 예측 ({currentNode.Id}→{nextNodes.First().Id})";
|
||||
}
|
||||
else if (nextNodes.Count > 1)
|
||||
{
|
||||
@@ -268,7 +268,7 @@ namespace AGVNavigationCore.Utils
|
||||
|
||||
foreach (var nodeId in currentNode.ConnectedNodes)
|
||||
{
|
||||
var connectedNode = mapNodes.FirstOrDefault(n => n.NodeId == nodeId);
|
||||
var connectedNode = mapNodes.FirstOrDefault(n => n.Id == nodeId);
|
||||
if (connectedNode != null)
|
||||
{
|
||||
connectedNodes.Add(connectedNode);
|
||||
|
||||
Reference in New Issue
Block a user