This commit is contained in:
backuppc
2026-01-06 17:35:34 +09:00
parent 649d87cae3
commit 90340f4a7d
39 changed files with 2127 additions and 685 deletions

View File

@@ -78,6 +78,8 @@ namespace AGVNavigationCore.Controls
// 노드 라벨 그리기 (가장 나중 - 선이 텍스트를 가리지 않게)
DrawNodeLabels(g);
DrawLabels(g); // 추가: 텍스트 라벨
}
finally
{
@@ -93,6 +95,12 @@ namespace AGVNavigationCore.Controls
{
DrawSyncScreen(g);
}
//예측문자는 디버깅시에만 표시한다.
if (string.IsNullOrEmpty(PredictMessage) == false && System.Diagnostics.Debugger.IsAttached)
{
g.DrawString(this.PredictMessage, this.Font, Brushes.White, 10, 10);
}
}
private void DrawSyncScreen(Graphics g)

View File

@@ -478,6 +478,17 @@ namespace AGVNavigationCore.Controls
}
}
/// <summary>
/// 상세경로가 설정되어있는가?
/// </summary>
/// <returns></returns>
public bool HasPath()
{
if (_currentPath == null) return false;
if (_currentPath.DetailedPath == null) return false;
return _currentPath.DetailedPath.Any();
}
/// <summary>
/// 모든 경로 목록 (다중 AGV 경로 표시용)
/// </summary>

View File

@@ -19,7 +19,7 @@ namespace AGVNavigationCore.Models
[Description("표시할 텍스트입니다.")]
public string Text { get; set; } = "";
public StationType StationType { get; set; }
public StationType StationType { get; set; }
[Browsable(false)]
public bool CanDocking
@@ -103,7 +103,7 @@ namespace AGVNavigationCore.Models
{
Type = NodeType.Normal;
}
public MapNode(string nodeId, Point position, StationType type) : base(nodeId, position)
{
Type = NodeType.Normal;
@@ -152,6 +152,18 @@ namespace AGVNavigationCore.Models
return $"RFID:{RfidId}(NODE:{Id}): AS:{AliasName} ({Type}) at ({Position.X}, {Position.Y})";
}
/// <summary>
/// RFID(*ID)
/// </summary>
public string ID2
{
get
{
if (HasRfid()) return $"{this.RfidId:0000}(*{this.Id})";
else return $"(*{this.Id})";
}
}
public bool IsNavigationNode()
{
// 이제 MapNode는 항상 내비게이션 노드임 (Label, Image 분리됨)

View File

@@ -40,13 +40,12 @@ namespace AGVNavigationCore.Models
[JsonIgnore]
public bool IsSelected { get; set; } = false;
[Browsable(false)]
[JsonIgnore]
public bool IsHovered { get; set; } = false;
public NodeBase()
{

View File

@@ -83,9 +83,9 @@ namespace AGVNavigationCore.Models
// 에뮬레이터용 추가 속성
public double Angle { get; set; } = 0; // 0 = Right, 90 = Down, 180 = Left, 270 = Up (Standard Math)
// But AGV Direction: Forward usually means "Front of AGV".
// Let's assume Angle is the orientation of the AGV in degrees.
// But AGV Direction: Forward usually means "Front of AGV".
// Let's assume Angle is the orientation of the AGV in degrees.
public bool IsStopMarkOn { get; set; } = false;
#endregion
@@ -143,6 +143,11 @@ namespace AGVNavigationCore.Models
/// </summary>
public AGVPathResult CurrentPath => _currentPath;
public void ClearPath()
{
_currentPath = null;
}
/// <summary>
/// 현재 노드 ID
/// </summary>
@@ -153,6 +158,18 @@ namespace AGVNavigationCore.Models
/// </summary>
public string CurrentNodeId => _currentNode?.Id;
/// <summary>
/// 현재노드의 RFID(id)값을 표시합니다 없는경우 (X)가 표시됩니다
/// </summary>
public string CurrentNodeID2
{
get
{
if (_currentNode == null) return "(X)";
return _currentNode.ID2;
}
}
/// <summary>
/// 이전 위치
/// </summary>
@@ -282,7 +299,7 @@ namespace AGVNavigationCore.Models
if (_currentNode == null) return false;
if (_currentPath == null) return false;
var = _currentPath.DetailedPath.Where(t => t.IsPass == false).OrderBy(t => t.seq).FirstOrDefault();
if ( == null) return false;
if ( == null) return false;
.IsPass = true;
Console.WriteLine($"미완료된처음노드를 true러치합니다");
return true;
@@ -295,6 +312,7 @@ namespace AGVNavigationCore.Models
/// <returns>다음에 수행할 모터/마그넷/속도 명령</returns>
public AGVCommand Predict()
{
// 1. 위치 미확정 상태 (RFID 2개 미만 감지)
if (!_isPositionConfirmed)
{
@@ -311,12 +329,17 @@ namespace AGVNavigationCore.Models
// 2. 위치 확정됨 + 경로 없음 → 정지 (목적지 미설정 상태)
if (_currentPath == null || (_currentPath.DetailedPath?.Count ?? 0) < 1)
{
var curpos = "알수없음";
if (_currentNode != null)
{
curpos = _currentNode.HasRfid() ? $"RFID #{_currentNode.RfidId} (*{_currentNode.Id})" : $"(*{_currentNode.Id})";
}
return new AGVCommand(
MotorCommand.Stop,
MagnetPosition.S,
SpeedLevel.L,
eAGVCommandReason.NoPath,
$"위치 확정 완료 (목적지 미설정) - 현재:{_currentNode?.Id ?? ""}"
$"(목적지 미설정) - 현재={curpos}"
);
}
@@ -325,6 +348,9 @@ namespace AGVNavigationCore.Models
if (_currentPath.DetailedPath.Where(t => t.seq < lastNode.seq && t.IsPass == false).Any() == false)
{
// 마지막 노드에 도착했는지 확인 (현재 노드가 마지막 노드와 같은지)
if (_currentNode != null && _currentNode.Id == lastNode.NodeId)
{
if (lastNode.IsPass) //이미완료되었다.
@@ -334,7 +360,7 @@ namespace AGVNavigationCore.Models
MagnetPosition.S,
SpeedLevel.L,
eAGVCommandReason.Complete,
$"목적지 도착 - 최종:{_currentNode?.Id ?? ""}"
$"목적지 도착 - 최종:{CurrentNodeID2}"
);
}
else
@@ -345,7 +371,7 @@ namespace AGVNavigationCore.Models
MagnetPosition.S,
SpeedLevel.L,
eAGVCommandReason.MarkStop,
$"목적지 도착 전(MarkStop) - 최종:{_currentNode?.Id ?? ""}"
$"목적지 도착 전(MarkStop) - 최종:{CurrentNodeID2}"
);
}
@@ -361,7 +387,7 @@ namespace AGVNavigationCore.Models
MagnetPosition.S,
SpeedLevel.L,
eAGVCommandReason.PathOut,
$"(재탐색요청)경로이탈 현재위치:{_currentNode.Id}"
$"(재탐색요청)경로이탈 현재위치:{CurrentNodeID2}"
);
}
@@ -403,6 +429,18 @@ namespace AGVNavigationCore.Models
#region Public Methods -
/// <summary>
/// 경로가 설정되어있는지?
/// </summary>
/// <returns></returns>
public bool HasPath()
{
if (_currentPath == null) return false;
if (_currentPath.DetailedPath == null) return false;
return _currentPath.DetailedPath.Any();
}
/// <summary>
/// 경로 설정 (실제 AGV 및 시뮬레이터에서 사용)
/// </summary>
@@ -411,6 +449,9 @@ namespace AGVNavigationCore.Models
{
if (path == null)
{
_currentPath = null;
_remainingNodes.Clear();// = null;
_currentNodeIndex = 0;
OnError("경로가 null입니다.");
return;
}
@@ -612,7 +653,7 @@ namespace AGVNavigationCore.Models
PositionChanged?.Invoke(this, (_currentPosition, _currentDirection, _currentNode));
}
#endregion

View File

@@ -322,7 +322,7 @@ namespace AGVNavigationCore.PathFinding.Core
}
return Path?.Select(n => n.Id).ToList() ?? new List<string>();
}
/// <summary>
/// 문자열 표현
/// </summary>

View File

@@ -123,6 +123,8 @@ namespace AGVNavigationCore.PathFinding.Planning
if (RequiresSpecialAction)
result += $" [특수동작:{SpecialActionDescription}]";
if (IsPass) result += "(O)";
return result;
}
}