This commit is contained in:
backuppc
2026-01-07 17:33:17 +09:00
parent 90340f4a7d
commit 9776205364
17 changed files with 186 additions and 104 deletions

View File

@@ -99,8 +99,21 @@ namespace AGVNavigationCore.Controls
//예측문자는 디버깅시에만 표시한다. //예측문자는 디버깅시에만 표시한다.
if (string.IsNullOrEmpty(PredictMessage) == false && System.Diagnostics.Debugger.IsAttached) 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) private void DrawSyncScreen(Graphics g)

View File

@@ -135,6 +135,14 @@ namespace AGVNavigationCore.Controls
private float _syncProgress = 0.0f; private float _syncProgress = 0.0f;
private string _syncDetail = ""; private string _syncDetail = "";
string _alertmesage = "";
bool showalert = false;
public void SetAlertMessage(string m)
{
_alertmesage = m;
showalert = !string.IsNullOrEmpty(m);
}
// 브러쉬 및 펜 // 브러쉬 및 펜
private Brush _normalNodeBrush; private Brush _normalNodeBrush;
private Brush _rotationNodeBrush; private Brush _rotationNodeBrush;
@@ -643,7 +651,7 @@ namespace AGVNavigationCore.Controls
_pathPen = new Pen(Color.Purple, 3); _pathPen = new Pen(Color.Purple, 3);
_agvPen = new Pen(Color.Red, 3); _agvPen = new Pen(Color.Red, 3);
_highlightedConnectionPen = new Pen(Color.Red, 4) { DashStyle = DashStyle.Solid }; _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); // 마크는 흰색 선으로 표시 _markPen = new Pen(Color.White, 3); // 마크는 흰색 선으로 표시
} }

View File

@@ -131,12 +131,15 @@ namespace AGVNavigationCore.PathFinding.Planning
return AGVPathResult.CreateFailure("이동 가능한 노드가 아닙니다", 0, 0); return AGVPathResult.CreateFailure("이동 가능한 노드가 아닙니다", 0, 0);
var tnode = targetNode as MapNode; var tnode = targetNode as MapNode;
//시작노드와 종료노드가 동일위치이고 도킹방향도 맞다면 그대로 OK 한다
if (startNode.Id == targetNode.Id && tnode.DockDirection.MatchAGVDirection(prevDirection)) if (startNode.Id == targetNode.Id && tnode.DockDirection.MatchAGVDirection(prevDirection))
return AGVPathResult.CreateSuccess(new List<MapNode> { startNode, startNode }, new List<AgvDirection>(), 0, 0); return AGVPathResult.CreateSuccess(new List<MapNode> { startNode, startNode }, new List<AgvDirection>(), 0, 0);
//반대방향값 지정
var ReverseDirection = (currentDirection == AgvDirection.Forward ? AgvDirection.Backward : AgvDirection.Forward); var ReverseDirection = (currentDirection == AgvDirection.Forward ? AgvDirection.Backward : AgvDirection.Forward);
//1.목적지까지의 최단거리 경로를 찾는다. //1.목적지까지의 최단거리 경로를 찾는다.(AStar 방식)
var pathResult = _basicPathfinder.FindPathAStar(startNode.Id, targetNode.Id); var pathResult = _basicPathfinder.FindPathAStar(startNode.Id, targetNode.Id);
pathResult.PrevNode = prevNode; pathResult.PrevNode = prevNode;
pathResult.PrevDirection = prevDirection; pathResult.PrevDirection = prevDirection;
@@ -201,9 +204,7 @@ namespace AGVNavigationCore.PathFinding.Planning
} }
if (nextNodeForward != null && pathResult.Path.Count > 1 && if (nextNodeForward != null && pathResult.Path.Count > 1 &&
nextNodeForward.Id == pathResult.Path[1].Id && nextNodeForward.Id == pathResult.Path[1].Id) // ✅ 추가: 현재도 Forward여야 함
tnode.DockDirection == DockingDirection.Forward &&
currentDirection == AgvDirection.Forward) // ✅ 추가: 현재도 Forward여야 함
{ {
if (tnode.DockDirection == DockingDirection.Forward && currentDirection == AgvDirection.Forward || if (tnode.DockDirection == DockingDirection.Forward && currentDirection == AgvDirection.Forward ||
tnode.DockDirection == DockingDirection.Backward && currentDirection == AgvDirection.Backward) tnode.DockDirection == DockingDirection.Backward && currentDirection == AgvDirection.Backward)

View File

@@ -46,94 +46,122 @@ namespace AGVNavigationCore.Utils
System.Diagnostics.Debug.WriteLine($"[DockingValidator] 목적지 노드: {LastNode.Id} 타입:{LastNode.Type} ({(int)LastNode.Type})"); System.Diagnostics.Debug.WriteLine($"[DockingValidator] 목적지 노드: {LastNode.Id} 타입:{LastNode.Type} ({(int)LastNode.Type})");
//detail 경로 이동 예측 검증 ////detail 경로 이동 예측 검증
for (int i = 0; i < pathResult.DetailedPath.Count - 1; i++) //for (int i = 0; i < pathResult.DetailedPath.Count - 1; i++)
{ //{
var curNodeId = pathResult.DetailedPath[i].NodeId; // var curNodeId = pathResult.DetailedPath[i].NodeId;
var nextNodeId = pathResult.DetailedPath[i + 1].NodeId; // var nextNodeId = pathResult.DetailedPath[i + 1].NodeId;
var curNode = mapNodes?.FirstOrDefault(n => n.Id == curNodeId); // var curNode = mapNodes?.FirstOrDefault(n => n.Id == curNodeId);
var nextNode = mapNodes?.FirstOrDefault(n => n.Id == nextNodeId); // var nextNode = mapNodes?.FirstOrDefault(n => n.Id == nextNodeId);
if (curNode != null && nextNode != null) // if (curNode != null && nextNode != null)
{ // {
MapNode prevNode = null; // MapNode prevNode = null;
AgvDirection prevDir = AgvDirection.Stop; // AgvDirection prevDir = AgvDirection.Stop;
if (i == 0) // if (i == 0)
{ // {
prevNode = pathResult.PrevNode; // prevNode = pathResult.PrevNode;
prevDir = pathResult.PrevDirection; // prevDir = pathResult.PrevDirection;
} // }
else // else
{ // {
var prevNodeId = pathResult.DetailedPath[i - 1].NodeId; // var prevNodeId = pathResult.DetailedPath[i - 1].NodeId;
prevNode = mapNodes?.FirstOrDefault(n => n.Id == prevNodeId); // prevNode = mapNodes?.FirstOrDefault(n => n.Id == prevNodeId);
prevDir = pathResult.DetailedPath[i - 1].MotorDirection; // prevDir = pathResult.DetailedPath[i - 1].MotorDirection;
} // }
if (prevNode != null) // if (prevNode != null)
{ // {
// DirectionalHelper를 사용하여 예상되는 다음 노드 확인 // // DirectionalHelper를 사용하여 예상되는 다음 노드 확인
Console.WriteLine( // Console.WriteLine(
$"\n[ValidateDockingDirection] 경로 검증 단계 {i}:"); // $"\n[ValidateDockingDirection] 경로 검증 단계 {i}:");
Console.WriteLine( // Console.WriteLine(
$" 이전→현재→다음: {prevNode.Id}({prevNode.RfidId}) → {curNode.Id}({curNode.RfidId}) → {nextNode.Id}({nextNode.RfidId})"); // $" 이전→현재→다음: {prevNode.Id}({prevNode.RfidId}) → {curNode.Id}({curNode.RfidId}) → {nextNode.Id}({nextNode.RfidId})");
Console.WriteLine( // Console.WriteLine(
$" 현재 노드 위치: ({curNode.Position.X:F1}, {curNode.Position.Y:F1})"); // $" 현재 노드 위치: ({curNode.Position.X:F1}, {curNode.Position.Y:F1})");
Console.WriteLine( // Console.WriteLine(
$" 이전 모터방향: {prevDir}, 현재 모터방향: {pathResult.DetailedPath[i].MotorDirection}"); // $" 이전 모터방향: {prevDir}, 현재 모터방향: {pathResult.DetailedPath[i].MotorDirection}");
Console.WriteLine( // Console.WriteLine(
$" 마그넷방향: {pathResult.DetailedPath[i].MagnetDirection}"); // $" 마그넷방향: {pathResult.DetailedPath[i].MagnetDirection}");
var expectedNextNode = DirectionalHelper.GetNextNodeByDirection( // var expectedNextNode = DirectionalHelper.GetNextNodeByDirection(
curNode, // curNode,
prevNode, // prevNode,
prevDir, // prevDir,
pathResult.DetailedPath[i].MotorDirection, // pathResult.DetailedPath[i].MotorDirection,
pathResult.DetailedPath[i].MagnetDirection, // pathResult.DetailedPath[i].MagnetDirection,
mapNodes // mapNodes
); // );
Console.WriteLine( // var expectedNextNodeL = DirectionalHelper.GetNextNodeByDirection(
$" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.Id ?? "null"}"); // curNode,
Console.WriteLine( // prevNode,
$" [실제] DetailedPath 다음 노드: {nextNode.RfidId}[{nextNode.Id}]"); // prevDir,
// pathResult.DetailedPath[i].MotorDirection,
// PathFinding.Planning.MagnetDirection.Left,
// mapNodes
// );
if (expectedNextNode != null && !expectedNextNode.Id.Equals(nextNode.Id)) // var expectedNextNodeR = DirectionalHelper.GetNextNodeByDirection(
{ // curNode,
string error = // prevNode,
$"[DockingValidator] ⚠️ 경로 방향 불일치" + // prevDir,
$"\n현재={curNode.RfidId}[{curNodeId}] 이전={prevNode.RfidId}[{(prevNode?.Id ?? string.Empty)}] " + // pathResult.DetailedPath[i].MotorDirection,
$"\n예상다음={expectedNextNode.RfidId}[{expectedNextNode.Id}] 실제다음={nextNode.RfidId}[{nextNodeId}]"; // PathFinding.Planning.MagnetDirection.Right,
Console.WriteLine( // mapNodes
$"[ValidateDockingDirection] ❌ 경로 방향 불일치 검출!"); // );
Console.WriteLine(
$" 이동 벡터:"); // var expectedNextNodeS = DirectionalHelper.GetNextNodeByDirection(
Console.WriteLine( // curNode,
$" 이전→현재: ({(curNode.Position.X - prevNode.Position.X):F2}, {(curNode.Position.Y - prevNode.Position.Y):F2})"); // prevNode,
Console.WriteLine( // prevDir,
$" 현재→예상: ({(expectedNextNode.Position.X - curNode.Position.X):F2}, {(expectedNextNode.Position.Y - curNode.Position.Y):F2})"); // pathResult.DetailedPath[i].MotorDirection,
Console.WriteLine( // PathFinding.Planning.MagnetDirection.Straight,
$" 현재→실제: ({(nextNode.Position.X - curNode.Position.X):F2}, {(nextNode.Position.Y - curNode.Position.Y):F2})"); // mapNodes
Console.WriteLine($"[ValidateDockingDirection] 에러메시지: {error}"); // );
return DockingValidationResult.CreateInvalid(
LastNode.Id,
LastNode.Type,
pathResult.DetailedPath[i].MotorDirection,
pathResult.DetailedPath[i].MotorDirection,
error);
} // Console.WriteLine(
else // $" [예상] GetNextNodeByDirection 결과: {expectedNextNode?.Id ?? "null"}");
{ // Console.WriteLine(
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가 아닌 경우) // 도킹이 필요한 노드인지 확인 (DockDirection이 DontCare가 아닌 경우)

View File

@@ -134,6 +134,7 @@ namespace Project
//마지막위치가 아닌 다른 위치에 있으니 버퍼 작업을 할 수없다 //마지막위치가 아닌 다른 위치에 있으니 버퍼 작업을 할 수없다
PUB.XBE.StepBuffer = Device.eDocStep.NotSet; PUB.XBE.StepBuffer = Device.eDocStep.NotSet;
PUB.log.AddE($"목적지가 버퍼이나 노드가 불일치 한다 오류사항"); PUB.log.AddE($"목적지가 버퍼이나 노드가 불일치 한다 오류사항");
PUB._mapCanvas.SetAlertMessage("목적지가 버퍼이나 노드 불일치 오류");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
break; break;

View File

@@ -84,6 +84,7 @@ namespace Project
//5초동안 AGV까 움직이지 않았다면 오류 처리한다. //5초동안 AGV까 움직이지 않았다면 오류 처리한다.
PUB.AGV.AGVMoveStop($"[bufferin] {overtime}초이내 턴 감지 안됨"); PUB.AGV.AGVMoveStop($"[bufferin] {overtime}초이내 턴 감지 안됨");
PUB.log.AddE($"[{funcname}] {overtime}초이내 턴 감지 안됨"); PUB.log.AddE($"[{funcname}] {overtime}초이내 턴 감지 안됨");
PUB._mapCanvas.SetAlertMessage("턴 완료 확인 불가");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }
@@ -129,6 +130,7 @@ namespace Project
{ {
PUB.log.AddE($"[{funcname}] 리프트가 내려가지 않습니다"); PUB.log.AddE($"[{funcname}] 리프트가 내려가지 않습니다");
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP); PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP);
PUB._mapCanvas.SetAlertMessage("리프트가 내려가지 않음");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -162,6 +164,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv속도설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -187,6 +190,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] MARK STOP신호가 확인되지 않습니다"); PUB.log.AddE($"[{funcname}] MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 안됨");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }
@@ -205,6 +209,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV가 멈추지 않아 강제종료 합니다"); PUB.log.AddE($"[{funcname}] AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv가 멈추지 않아 강제 종료");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }

View File

@@ -72,6 +72,7 @@ namespace Project
{ {
PUB.log.AddE($"[{funcname}] 리프트가 동작하지 않습니다"); PUB.log.AddE($"[{funcname}] 리프트가 동작하지 않습니다");
PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP); PUB.AGV.LiftControl(arDev.Narumi.LiftCommand.STP);
PUB._mapCanvas.SetAlertMessage("LIft 동작오류");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -96,6 +97,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도설정실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;

View File

@@ -89,6 +89,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 오류");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -110,6 +111,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 안됨");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }
@@ -128,6 +130,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv 가 멈추지 않아 강제 종료");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }

View File

@@ -42,6 +42,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;

View File

@@ -126,6 +126,7 @@ namespace Project
{ {
PUB.log.AddE($"[{funcname}] AGV속도설정 실패"); PUB.log.AddE($"[{funcname}] AGV속도설정 실패");
PUB.AGV.AGVMoveStop("err"); PUB.AGV.AGVMoveStop("err");
PUB._mapCanvas.SetAlertMessage("agv 속더 설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;

View File

@@ -95,6 +95,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE("AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -115,6 +116,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 불가");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }
@@ -133,6 +135,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv 가 멈추지 않아 강제 종료");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }

View File

@@ -41,6 +41,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv 속도 설정 실패");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;

View File

@@ -90,6 +90,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage("agv속도설정오류");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -112,6 +113,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("MARK STOP신호가 확인되지 않습니다"); PUB.log.AddE("MARK STOP신호가 확인되지 않습니다");
PUB._mapCanvas.SetAlertMessage("mark stop 신호 확인 불가");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }
@@ -130,6 +132,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다"); PUB.log.AddE("AGV가 멈추지 않아 강제종료 합니다");
PUB._mapCanvas.SetAlertMessage("agv 가 멈추지 않아 강제 종료 합니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
return false; return false;
} }

View File

@@ -41,6 +41,7 @@ namespace Project
{ {
PUB.AGV.AGVMoveStop(funcname); PUB.AGV.AGVMoveStop(funcname);
PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다"); PUB.log.AddE($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB._mapCanvas.SetAlertMessage($"[{funcname}] AGV속도설정이 완료되지 않았습니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;

View File

@@ -101,8 +101,7 @@ namespace Project
} }
//경로 생성(경로정보가 없거나 현재노드가 경로에 없는경우) //경로 생성(경로정보가 없거나 현재노드가 경로에 없는경우)
if (PUB._virtualAGV.CurrentPath == null || if (PUB._virtualAGV.HasPath() == false ||
PUB._virtualAGV.CurrentPath.DetailedPath.Any() == false ||
PUB._virtualAGV.CurrentPath.DetailedPath.Where(t => t.NodeId.Equals(currentNode.Id)).Any() == false) PUB._virtualAGV.CurrentPath.DetailedPath.Where(t => t.NodeId.Equals(currentNode.Id)).Any() == false)
{ {
if (PUB.AGV.system1.agv_run) if (PUB.AGV.system1.agv_run)
@@ -112,6 +111,15 @@ namespace Project
} }
var PathResult = CalcPath(PUB._virtualAGV.StartNode, PUB._virtualAGV.TargetNode); var PathResult = CalcPath(PUB._virtualAGV.StartNode, PUB._virtualAGV.TargetNode);
if(PathResult.result !=null &&
PathResult.result.Success == true &&
PathResult.result.DetailedPath.Where(t => t.NodeId == currentNode.Id).Any() == false)
{
PUB._virtualAGV.StartNode = PUB._virtualAGV.CurrentNode;
PathResult = CalcPath(PUB._virtualAGV.StartNode, PUB._virtualAGV.TargetNode);
}
if (PathResult.result == null) if (PathResult.result == null)
{ {
PUB.log.AddE($"경로가 계산되지 않았습니다"); PUB.log.AddE($"경로가 계산되지 않았습니다");
@@ -120,9 +128,10 @@ namespace Project
} }
else else
{ {
//계산은 되었으나 현재위치가 전체 경로 없다면 시작노드를 현재로 변경해야한다.
PUB._mapCanvas.CurrentPath = PathResult.result; PUB._mapCanvas.CurrentPath = PathResult.result;
PUB._virtualAGV.SetPath(PathResult.result); PUB._virtualAGV.SetPath(PathResult.result);
} }
PUB.log.AddI($"경로생성 {PUB._virtualAGV.StartNode.RfidId} -> {PUB._virtualAGV.TargetNode.RfidId}"); PUB.log.AddI($"경로생성 {PUB._virtualAGV.StartNode.RfidId} -> {PUB._virtualAGV.TargetNode.RfidId}");
@@ -136,12 +145,12 @@ namespace Project
PUB.AGV.AGVMoveStop("Path Integrity Fail"); PUB.AGV.AGVMoveStop("Path Integrity Fail");
} }
PUB.log.AddE($"경로 무결성 오류로 인해 경로를 삭제 합니다"); PUB.log.AddE($"경로 무결성 오류로 인해 경로를 삭제 합니다");
Console.WriteLine($"경로 무결성 오류로 인해 경로를 삭제 합니다");
PUB._virtualAGV.SetPath(null); PUB._virtualAGV.SetPath(null);
VAR.I32[eVarInt32.PathValidationError] += 1; VAR.I32[eVarInt32.PathValidationError] += 1;
if (VAR.I32[eVarInt32.PathValidationError] > 50) if (VAR.I32[eVarInt32.PathValidationError] > 50)
{ {
PUB.log.AddE($"연속 경로 무결성 오류로 인해 중지 합니다"); PUB.log.AddE($"연속 경로 무결성 오류로 인해 중지 합니다");
PUB._mapCanvas.SetAlertMessage($"연속 경로 무결성 오류로 인해 중지 합니다");
PUB.sm.SetNewRunStep(ERunStep.ERROR); PUB.sm.SetNewRunStep(ERunStep.ERROR);
} }
return false; return false;
@@ -182,16 +191,6 @@ namespace Project
return false; return false;
} }
var message = $"[다음 행동 예측]\n\n" +
$"모터: {nextAction.Motor}\n" +
$"마그넷: {nextAction.Magnet}\n" +
$"속도: {nextAction.Speed}\n" +
$"이유: {nextAction.Message}\n\n" +
$"---\n" +
$"현재 상태: {PUB._virtualAGV.CurrentState}\n" +
$"현재 방향: {PUB._virtualAGV.CurrentDirection}\n" +
$"위치 확정: {PUB._virtualAGV.IsPositionConfirmed} (RFID {PUB._virtualAGV.DetectedRfidCount}개)\n" +
$"현재 노드: {PUB._virtualAGV.CurrentNodeID2}";
//모터에서 정지를 요청했다 //모터에서 정지를 요청했다
if (nextAction.Motor == AGVNavigationCore.Models.MotorCommand.Stop) if (nextAction.Motor == AGVNavigationCore.Models.MotorCommand.Stop)

View File

@@ -226,12 +226,23 @@ namespace Project
var message = $"[다음 행동 예측]\n\n"; var message = $"[다음 행동 예측]\n\n";
if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false) if (VAR.BOOL[eVarBool.FLAG_AUTORUN] == false)
message += "[수동모드]\n\n"; message += "[X] 수동모드\n";
if (PUB._virtualAGV.TargetNode == null) message += "[X] 목표노드없음\n";
if (PUB._virtualAGV.CurrentNode == null) message += "[X] 현재노드없음\n";
else if (PUB._virtualAGV.HasPath() == false) message += "[X] 경로계산안됨\n";
if (PUB._virtualAGV.PrevNode == null) message += "[X] 이전노드없음\n";
else message += $"이전노드: {PUB._virtualAGV.PrevNode.ID2} : {PUB._virtualAGV.PrevDirection}\n";
message += $"현재노드: {PUB._virtualAGV.CurrentNode.ID2} : {PUB._virtualAGV.CurrentDirection}\n";
message += "-------------\n";
var node = PUB._virtualAGV.CurrentNode; var node = PUB._virtualAGV.CurrentNode;
var curpos = PUB._virtualAGV.CurrentNodeID2; var curpos = PUB._virtualAGV.CurrentNodeID2;
var targetpos = PUB._virtualAGV.TargetNode?.ID2 ?? "(X)"; var targetpos = PUB._virtualAGV.TargetNode?.ID2 ?? "(X)";
var pathdetail = ""; var pathdetail = "";
if (PUB._virtualAGV.CurrentPath != null && PUB._virtualAGV.CurrentPath.DetailedPath.Any()) if (PUB._virtualAGV.CurrentPath != null && PUB._virtualAGV.CurrentPath.DetailedPath.Any())
{ {
@@ -250,13 +261,13 @@ namespace Project
$"마그넷: {nextAction.Magnet}\n" + $"마그넷: {nextAction.Magnet}\n" +
$"속도: {nextAction.Speed}\n" + $"속도: {nextAction.Speed}\n" +
$"이유: {nextAction.Message}\n" + $"이유: {nextAction.Message}\n" +
$"상태머신:{PUB.sm.Step}:{PUB.sm.RunStep}:{PUB.sm.RunStepSeq}\n"+ $"상태머신:{PUB.sm.Step}:{PUB.sm.RunStep}:{PUB.sm.RunStepSeq}\n" +
$"---\n" + $"---\n" +
$"현재 상태: {PUB._virtualAGV.CurrentState}\n" + $"현재 상태: {PUB._virtualAGV.CurrentState}\n" +
$"현재 방향: {PUB._virtualAGV.CurrentDirection}\n" + $"현재 방향: {PUB._virtualAGV.CurrentDirection}\n" +
$"턴: {PUB._virtualAGV.Turn}\n" + $"턴: {PUB._virtualAGV.Turn}\n" +
$"위치 확정: {PUB._virtualAGV.IsPositionConfirmed} (RFID {PUB._virtualAGV.DetectedRfidCount}개)\n" + $"위치 확정: {PUB._virtualAGV.IsPositionConfirmed} (RFID {PUB._virtualAGV.DetectedRfidCount}개)\n" +
$"현재 노드: {curpos}\n" +
$"대상 노드: {targetpos}\n" + $"대상 노드: {targetpos}\n" +
$"상세 경로: {pathdetail}"; $"상세 경로: {pathdetail}";

View File

@@ -437,6 +437,7 @@ namespace Project
PUB.Speak(Lang., addlog: false); PUB.Speak(Lang., addlog: false);
PUB.log.Add($"자동전환 이전스텝:{PUB.sm.RunStep},IDX:{PUB.sm.RunStepSeq}]"); PUB.log.Add($"자동전환 이전스텝:{PUB.sm.RunStep},IDX:{PUB.sm.RunStepSeq}]");
PUB._mapCanvas.SetAlertMessage("START");
} }
else else
{ {