..
This commit is contained in:
@@ -99,8 +99,21 @@ namespace AGVNavigationCore.Controls
|
||||
//예측문자는 디버깅시에만 표시한다.
|
||||
if (string.IsNullOrEmpty(PredictMessage) == false && System.Diagnostics.Debugger.IsAttached)
|
||||
{
|
||||
g.DrawString(this.PredictMessage, this.Font, Brushes.White, 10, 10);
|
||||
g.DrawString(this.PredictMessage, this.Font, Brushes.White, 10, 100);
|
||||
}
|
||||
DrawAlertMessage(g);
|
||||
|
||||
}
|
||||
|
||||
void DrawAlertMessage(Graphics g)
|
||||
{
|
||||
if (showalert == false) return;
|
||||
|
||||
//상단에 경고 메세지를 추가한다
|
||||
if (String.IsNullOrEmpty(this._alertmesage)) return;
|
||||
|
||||
|
||||
g.DrawString(this._alertmesage, this.Font, Brushes.Gold, 10, 10);
|
||||
}
|
||||
|
||||
private void DrawSyncScreen(Graphics g)
|
||||
|
||||
@@ -135,6 +135,14 @@ namespace AGVNavigationCore.Controls
|
||||
private float _syncProgress = 0.0f;
|
||||
private string _syncDetail = "";
|
||||
|
||||
string _alertmesage = "";
|
||||
bool showalert = false;
|
||||
public void SetAlertMessage(string m)
|
||||
{
|
||||
_alertmesage = m;
|
||||
showalert = !string.IsNullOrEmpty(m);
|
||||
}
|
||||
|
||||
// 브러쉬 및 펜
|
||||
private Brush _normalNodeBrush;
|
||||
private Brush _rotationNodeBrush;
|
||||
@@ -643,7 +651,7 @@ namespace AGVNavigationCore.Controls
|
||||
_pathPen = new Pen(Color.Purple, 3);
|
||||
_agvPen = new Pen(Color.Red, 3);
|
||||
_highlightedConnectionPen = new Pen(Color.Red, 4) { DashStyle = DashStyle.Solid };
|
||||
_magnetPen = new Pen(Color.FromArgb(100,Color.LightSkyBlue), 15) { DashStyle = DashStyle.Solid };
|
||||
_magnetPen = new Pen(Color.FromArgb(100, Color.LightSkyBlue), 15) { DashStyle = DashStyle.Solid };
|
||||
_markPen = new Pen(Color.White, 3); // 마크는 흰색 선으로 표시
|
||||
}
|
||||
|
||||
|
||||
@@ -131,12 +131,15 @@ namespace AGVNavigationCore.PathFinding.Planning
|
||||
return AGVPathResult.CreateFailure("이동 가능한 노드가 아닙니다", 0, 0);
|
||||
|
||||
var tnode = targetNode as MapNode;
|
||||
|
||||
//시작노드와 종료노드가 동일위치이고 도킹방향도 맞다면 그대로 OK 한다
|
||||
if (startNode.Id == targetNode.Id && tnode.DockDirection.MatchAGVDirection(prevDirection))
|
||||
return AGVPathResult.CreateSuccess(new List<MapNode> { startNode, startNode }, new List<AgvDirection>(), 0, 0);
|
||||
|
||||
//반대방향값 지정
|
||||
var ReverseDirection = (currentDirection == AgvDirection.Forward ? AgvDirection.Backward : AgvDirection.Forward);
|
||||
|
||||
//1.목적지까지의 최단거리 경로를 찾는다.
|
||||
//1.목적지까지의 최단거리 경로를 찾는다.(AStar 방식)
|
||||
var pathResult = _basicPathfinder.FindPathAStar(startNode.Id, targetNode.Id);
|
||||
pathResult.PrevNode = prevNode;
|
||||
pathResult.PrevDirection = prevDirection;
|
||||
@@ -201,9 +204,7 @@ namespace AGVNavigationCore.PathFinding.Planning
|
||||
}
|
||||
|
||||
if (nextNodeForward != null && pathResult.Path.Count > 1 &&
|
||||
nextNodeForward.Id == pathResult.Path[1].Id &&
|
||||
tnode.DockDirection == DockingDirection.Forward &&
|
||||
currentDirection == AgvDirection.Forward) // ✅ 추가: 현재도 Forward여야 함
|
||||
nextNodeForward.Id == pathResult.Path[1].Id) // ✅ 추가: 현재도 Forward여야 함
|
||||
{
|
||||
if (tnode.DockDirection == DockingDirection.Forward && currentDirection == AgvDirection.Forward ||
|
||||
tnode.DockDirection == DockingDirection.Backward && currentDirection == AgvDirection.Backward)
|
||||
|
||||
@@ -46,94 +46,122 @@ namespace AGVNavigationCore.Utils
|
||||
|
||||
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 목적지 노드: {LastNode.Id} 타입:{LastNode.Type} ({(int)LastNode.Type})");
|
||||
|
||||
//detail 경로 이동 예측 검증
|
||||
for (int i = 0; i < pathResult.DetailedPath.Count - 1; i++)
|
||||
{
|
||||
var curNodeId = pathResult.DetailedPath[i].NodeId;
|
||||
var nextNodeId = pathResult.DetailedPath[i + 1].NodeId;
|
||||
////detail 경로 이동 예측 검증
|
||||
//for (int i = 0; i < pathResult.DetailedPath.Count - 1; i++)
|
||||
//{
|
||||
// var curNodeId = pathResult.DetailedPath[i].NodeId;
|
||||
// var nextNodeId = pathResult.DetailedPath[i + 1].NodeId;
|
||||
|
||||
var curNode = mapNodes?.FirstOrDefault(n => n.Id == curNodeId);
|
||||
var nextNode = mapNodes?.FirstOrDefault(n => n.Id == nextNodeId);
|
||||
// var curNode = mapNodes?.FirstOrDefault(n => n.Id == curNodeId);
|
||||
// var nextNode = mapNodes?.FirstOrDefault(n => n.Id == nextNodeId);
|
||||
|
||||
if (curNode != null && nextNode != null)
|
||||
{
|
||||
MapNode prevNode = null;
|
||||
AgvDirection prevDir = AgvDirection.Stop;
|
||||
if (i == 0)
|
||||
{
|
||||
prevNode = pathResult.PrevNode;
|
||||
prevDir = pathResult.PrevDirection;
|
||||
}
|
||||
else
|
||||
{
|
||||
var prevNodeId = pathResult.DetailedPath[i - 1].NodeId;
|
||||
prevNode = mapNodes?.FirstOrDefault(n => n.Id == prevNodeId);
|
||||
prevDir = pathResult.DetailedPath[i - 1].MotorDirection;
|
||||
}
|
||||
// if (curNode != null && nextNode != null)
|
||||
// {
|
||||
// MapNode prevNode = null;
|
||||
// AgvDirection prevDir = AgvDirection.Stop;
|
||||
// if (i == 0)
|
||||
// {
|
||||
// prevNode = pathResult.PrevNode;
|
||||
// prevDir = pathResult.PrevDirection;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// var prevNodeId = pathResult.DetailedPath[i - 1].NodeId;
|
||||
// prevNode = mapNodes?.FirstOrDefault(n => n.Id == prevNodeId);
|
||||
// prevDir = pathResult.DetailedPath[i - 1].MotorDirection;
|
||||
// }
|
||||
|
||||
|
||||
if (prevNode != null)
|
||||
{
|
||||
// DirectionalHelper를 사용하여 예상되는 다음 노드 확인
|
||||
Console.WriteLine(
|
||||
$"\n[ValidateDockingDirection] 경로 검증 단계 {i}:");
|
||||
Console.WriteLine(
|
||||
$" 이전→현재→다음: {prevNode.Id}({prevNode.RfidId}) → {curNode.Id}({curNode.RfidId}) → {nextNode.Id}({nextNode.RfidId})");
|
||||
Console.WriteLine(
|
||||
$" 현재 노드 위치: ({curNode.Position.X:F1}, {curNode.Position.Y:F1})");
|
||||
Console.WriteLine(
|
||||
$" 이전 모터방향: {prevDir}, 현재 모터방향: {pathResult.DetailedPath[i].MotorDirection}");
|
||||
Console.WriteLine(
|
||||
$" 마그넷방향: {pathResult.DetailedPath[i].MagnetDirection}");
|
||||
// if (prevNode != null)
|
||||
// {
|
||||
// // DirectionalHelper를 사용하여 예상되는 다음 노드 확인
|
||||
// Console.WriteLine(
|
||||
// $"\n[ValidateDockingDirection] 경로 검증 단계 {i}:");
|
||||
// Console.WriteLine(
|
||||
// $" 이전→현재→다음: {prevNode.Id}({prevNode.RfidId}) → {curNode.Id}({curNode.RfidId}) → {nextNode.Id}({nextNode.RfidId})");
|
||||
// Console.WriteLine(
|
||||
// $" 현재 노드 위치: ({curNode.Position.X:F1}, {curNode.Position.Y:F1})");
|
||||
// Console.WriteLine(
|
||||
// $" 이전 모터방향: {prevDir}, 현재 모터방향: {pathResult.DetailedPath[i].MotorDirection}");
|
||||
// Console.WriteLine(
|
||||
// $" 마그넷방향: {pathResult.DetailedPath[i].MagnetDirection}");
|
||||
|
||||
var expectedNextNode = DirectionalHelper.GetNextNodeByDirection(
|
||||
curNode,
|
||||
prevNode,
|
||||
prevDir,
|
||||
pathResult.DetailedPath[i].MotorDirection,
|
||||
pathResult.DetailedPath[i].MagnetDirection,
|
||||
mapNodes
|
||||
);
|
||||
// var expectedNextNode = DirectionalHelper.GetNextNodeByDirection(
|
||||
// curNode,
|
||||
// prevNode,
|
||||
// prevDir,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// pathResult.DetailedPath[i].MagnetDirection,
|
||||
// mapNodes
|
||||
// );
|
||||
|
||||
Console.WriteLine(
|
||||
$" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.Id ?? "null"}");
|
||||
Console.WriteLine(
|
||||
$" [실제] DetailedPath 다음 노드: {nextNode.RfidId}[{nextNode.Id}]");
|
||||
// var expectedNextNodeL = DirectionalHelper.GetNextNodeByDirection(
|
||||
// curNode,
|
||||
// prevNode,
|
||||
// prevDir,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// PathFinding.Planning.MagnetDirection.Left,
|
||||
// mapNodes
|
||||
// );
|
||||
|
||||
if (expectedNextNode != null && !expectedNextNode.Id.Equals(nextNode.Id))
|
||||
{
|
||||
string error =
|
||||
$"[DockingValidator] ⚠️ 경로 방향 불일치" +
|
||||
$"\n현재={curNode.RfidId}[{curNodeId}] 이전={prevNode.RfidId}[{(prevNode?.Id ?? string.Empty)}] " +
|
||||
$"\n예상다음={expectedNextNode.RfidId}[{expectedNextNode.Id}] 실제다음={nextNode.RfidId}[{nextNodeId}]";
|
||||
Console.WriteLine(
|
||||
$"[ValidateDockingDirection] ❌ 경로 방향 불일치 검출!");
|
||||
Console.WriteLine(
|
||||
$" 이동 벡터:");
|
||||
Console.WriteLine(
|
||||
$" 이전→현재: ({(curNode.Position.X - prevNode.Position.X):F2}, {(curNode.Position.Y - prevNode.Position.Y):F2})");
|
||||
Console.WriteLine(
|
||||
$" 현재→예상: ({(expectedNextNode.Position.X - curNode.Position.X):F2}, {(expectedNextNode.Position.Y - curNode.Position.Y):F2})");
|
||||
Console.WriteLine(
|
||||
$" 현재→실제: ({(nextNode.Position.X - curNode.Position.X):F2}, {(nextNode.Position.Y - curNode.Position.Y):F2})");
|
||||
Console.WriteLine($"[ValidateDockingDirection] 에러메시지: {error}");
|
||||
return DockingValidationResult.CreateInvalid(
|
||||
LastNode.Id,
|
||||
LastNode.Type,
|
||||
pathResult.DetailedPath[i].MotorDirection,
|
||||
pathResult.DetailedPath[i].MotorDirection,
|
||||
error);
|
||||
// var expectedNextNodeR = DirectionalHelper.GetNextNodeByDirection(
|
||||
// curNode,
|
||||
// prevNode,
|
||||
// prevDir,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// PathFinding.Planning.MagnetDirection.Right,
|
||||
// mapNodes
|
||||
// );
|
||||
|
||||
// var expectedNextNodeS = DirectionalHelper.GetNextNodeByDirection(
|
||||
// curNode,
|
||||
// prevNode,
|
||||
// prevDir,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// PathFinding.Planning.MagnetDirection.Straight,
|
||||
// mapNodes
|
||||
// );
|
||||
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Console.WriteLine(
|
||||
$" ✅ 경로 방향 일치!");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Console.WriteLine(
|
||||
// $" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.Id ?? "null"}");
|
||||
// Console.WriteLine(
|
||||
// $" [실제] DetailedPath 다음 노드: {nextNode.RfidId}[{nextNode.Id}]");
|
||||
|
||||
// if (expectedNextNode != null && !expectedNextNode.Id.Equals(nextNode.Id))
|
||||
// {
|
||||
// string error =
|
||||
// $"[DockingValidator] ⚠️ 경로 방향 불일치" +
|
||||
// $"\n현재={curNode.RfidId}[{curNodeId}] 이전={prevNode.RfidId}[{(prevNode?.Id ?? string.Empty)}] " +
|
||||
// $"\n예상다음={expectedNextNode.RfidId}[{expectedNextNode.Id}] 실제다음={nextNode.RfidId}[{nextNodeId}]";
|
||||
// Console.WriteLine(
|
||||
// $"[ValidateDockingDirection] ❌ 경로 방향 불일치 검출!");
|
||||
// Console.WriteLine(
|
||||
// $" 이동 벡터:");
|
||||
// Console.WriteLine(
|
||||
// $" 이전→현재: ({(curNode.Position.X - prevNode.Position.X):F2}, {(curNode.Position.Y - prevNode.Position.Y):F2})");
|
||||
// Console.WriteLine(
|
||||
// $" 현재→예상: ({(expectedNextNode.Position.X - curNode.Position.X):F2}, {(expectedNextNode.Position.Y - curNode.Position.Y):F2})");
|
||||
// Console.WriteLine(
|
||||
// $" 현재→실제: ({(nextNode.Position.X - curNode.Position.X):F2}, {(nextNode.Position.Y - curNode.Position.Y):F2})");
|
||||
// Console.WriteLine($"[ValidateDockingDirection] 에러메시지: {error}");
|
||||
// return DockingValidationResult.CreateInvalid(
|
||||
// LastNode.Id,
|
||||
// LastNode.Type,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// pathResult.DetailedPath[i].MotorDirection,
|
||||
// error);
|
||||
|
||||
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// Console.WriteLine(
|
||||
// $" ✅ 경로 방향 일치!");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
||||
|
||||
// 도킹이 필요한 노드인지 확인 (DockDirection이 DontCare가 아닌 경우)
|
||||
|
||||
Reference in New Issue
Block a user