enhance: Display RFID values in path UI and improve AGV lift direction visualization

- Replace NodeID with RFID values in path display for better field mapping
- Add ComboBoxItem<T> class for {rfid} - [{node}] format in combo boxes
- Implement GetRfidByNodeId helper method for NodeID to RFID conversion
- Enhanced UpdatePathDebugInfo to show both RFID and NodeID information
- Improved path visualization with RFID-based route display
- Users can now easily match displayed paths with physical RFID tags

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ChiKyun Kim
2025-09-12 15:36:01 +09:00
parent de0e39e030
commit 1add9ed59a
9 changed files with 1626 additions and 98 deletions

View File

@@ -59,6 +59,7 @@ namespace AGVSimulator.Models
private List<string> _remainingNodes;
private int _currentNodeIndex;
private string _currentNodeId;
private string _targetNodeId;
// 이동 관련
private System.Windows.Forms.Timer _moveTimer;
@@ -67,6 +68,9 @@ namespace AGVSimulator.Models
private Point _moveTargetPosition;
private float _moveProgress;
// 도킹 관련
private DockingDirection _dockingDirection;
// 시뮬레이션 설정
private readonly float _moveSpeed = 50.0f; // 픽셀/초
private readonly float _rotationSpeed = 90.0f; // 도/초
@@ -114,13 +118,23 @@ namespace AGVSimulator.Models
/// <summary>
/// 목표 위치
/// </summary>
public Point TargetPosition => _targetPosition;
public Point? TargetPosition => _targetPosition;
/// <summary>
/// 배터리 레벨 (시뮬레이션)
/// </summary>
public float BatteryLevel { get; set; } = 100.0f;
/// <summary>
/// 목표 노드 ID
/// </summary>
public string TargetNodeId => _targetNodeId;
/// <summary>
/// 도킹 방향
/// </summary>
public DockingDirection DockingDirection => _dockingDirection;
#endregion
#region Constructor
@@ -138,6 +152,9 @@ namespace AGVSimulator.Models
_currentDirection = startDirection;
_currentState = AGVState.Idle;
_currentSpeed = 0;
_dockingDirection = DockingDirection.Forward; // 기본값: 전진 도킹
_currentNodeId = string.Empty;
_targetNodeId = string.Empty;
InitializeTimer();
}
@@ -175,13 +192,27 @@ namespace AGVSimulator.Models
_remainingNodes = new List<string>(path.Path);
_currentNodeIndex = 0;
// 시작 노드 위치로 이동
// 시작 노드와 목표 노드 설정
if (_remainingNodes.Count > 0)
{
var startNode = mapNodes.FirstOrDefault(n => n.NodeId == _remainingNodes[0]);
if (startNode != null)
{
_currentNodeId = startNode.NodeId;
// 목표 노드 설정 (경로의 마지막 노드)
if (_remainingNodes.Count > 1)
{
_targetNodeId = _remainingNodes[_remainingNodes.Count - 1];
var targetNode = mapNodes.FirstOrDefault(n => n.NodeId == _targetNodeId);
// 목표 노드의 타입에 따라 도킹 방향 결정
if (targetNode != null)
{
_dockingDirection = GetDockingDirection(targetNode.Type);
}
}
StartMovement();
}
else
@@ -245,6 +276,35 @@ namespace AGVSimulator.Models
SetState(AGVState.Idle);
}
/// <summary>
/// AGV 방향 직접 설정 (시뮬레이터용)
/// </summary>
/// <param name="direction">설정할 방향</param>
public void SetDirection(AgvDirection direction)
{
_currentDirection = direction;
}
/// <summary>
/// AGV 위치 직접 설정 (시뮬레이터용)
/// 이전 위치를 TargetPosition으로 저장하여 리프트 방향 계산이 가능하도록 함
/// </summary>
/// <param name="newPosition">새로운 위치</param>
public void SetPosition(Point newPosition)
{
// 현재 위치를 이전 위치로 저장 (리프트 방향 계산용)
if (_currentPosition != Point.Empty)
{
_targetPosition = _currentPosition;
}
// 새로운 위치 설정
_currentPosition = newPosition;
// 위치 변경 이벤트 발생
PositionChanged?.Invoke(this, _currentPosition);
}
/// <summary>
/// 충전 시작 (시뮬레이션)
/// </summary>
@@ -449,6 +509,19 @@ namespace AGVSimulator.Models
}
}
private DockingDirection GetDockingDirection(NodeType nodeType)
{
switch (nodeType)
{
case NodeType.Charging:
return DockingDirection.Forward; // 충전기: 전진 도킹
case NodeType.Docking:
return DockingDirection.Backward; // 장비 (로더, 클리너, 오프로더, 버퍼): 후진 도킹
default:
return DockingDirection.Forward; // 기본값: 전진
}
}
private void OnError(string message)
{
SetState(AGVState.Error);