- Add AGVMapEditor: Visual map editing with drag-and-drop node placement * RFID mapping separation (physical ID ↔ logical node mapping) * A* pathfinding algorithm with AGV directional constraints * JSON map data persistence with structured format * Interactive map canvas with zoom/pan functionality - Add AGVSimulator: Real-time AGV movement simulation * Virtual AGV with state machine (Idle, Moving, Rotating, Docking, Charging, Error) * Path execution and visualization from calculated routes * Real-time position tracking and battery simulation * Integration with map editor data format - Update solution structure and build configuration - Add comprehensive documentation in CLAUDE.md - Implement AGV-specific constraints (forward/backward docking, rotation limits) 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
225 lines
7.1 KiB
C#
225 lines
7.1 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
|
|
namespace AGVMapEditor.Models
|
|
{
|
|
/// <summary>
|
|
/// 맵 노드 정보를 관리하는 클래스
|
|
/// 논리적 노드로서 실제 맵의 위치와 속성을 정의
|
|
/// </summary>
|
|
public class MapNode
|
|
{
|
|
/// <summary>
|
|
/// 논리적 노드 ID (맵 에디터에서 관리하는 고유 ID)
|
|
/// 예: "N001", "N002", "LOADER1", "CHARGER1"
|
|
/// </summary>
|
|
public string NodeId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 노드 표시 이름 (사용자 친화적)
|
|
/// 예: "로더1", "충전기1", "교차점A", "회전지점1"
|
|
/// </summary>
|
|
public string Name { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 맵 상의 위치 좌표 (픽셀 단위)
|
|
/// </summary>
|
|
public Point Position { get; set; } = Point.Empty;
|
|
|
|
/// <summary>
|
|
/// 노드 타입
|
|
/// </summary>
|
|
public NodeType Type { get; set; } = NodeType.Normal;
|
|
|
|
/// <summary>
|
|
/// 도킹 방향 (도킹/충전 노드인 경우만 사용)
|
|
/// </summary>
|
|
public DockingDirection? DockDirection { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// 연결된 노드 ID 목록 (경로 정보)
|
|
/// </summary>
|
|
public List<string> ConnectedNodes { get; set; } = new List<string>();
|
|
|
|
/// <summary>
|
|
/// 회전 가능 여부 (180도 회전 가능한 지점)
|
|
/// </summary>
|
|
public bool CanRotate { get; set; } = false;
|
|
|
|
/// <summary>
|
|
/// 장비 ID (도킹/충전 스테이션인 경우)
|
|
/// 예: "LOADER1", "CLEANER1", "BUFFER1", "CHARGER1"
|
|
/// </summary>
|
|
public string StationId { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 장비 타입 (도킹/충전 스테이션인 경우)
|
|
/// </summary>
|
|
public StationType? StationType { get; set; } = null;
|
|
|
|
/// <summary>
|
|
/// 노드 생성 일자
|
|
/// </summary>
|
|
public DateTime CreatedDate { get; set; } = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// 노드 수정 일자
|
|
/// </summary>
|
|
public DateTime ModifiedDate { get; set; } = DateTime.Now;
|
|
|
|
/// <summary>
|
|
/// 노드 설명 (추가 정보)
|
|
/// </summary>
|
|
public string Description { get; set; } = string.Empty;
|
|
|
|
/// <summary>
|
|
/// 노드 활성화 여부
|
|
/// </summary>
|
|
public bool IsActive { get; set; } = true;
|
|
|
|
/// <summary>
|
|
/// 노드 색상 (맵 에디터 표시용)
|
|
/// </summary>
|
|
public Color DisplayColor { get; set; } = Color.Blue;
|
|
|
|
/// <summary>
|
|
/// 기본 생성자
|
|
/// </summary>
|
|
public MapNode()
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// 매개변수 생성자
|
|
/// </summary>
|
|
/// <param name="nodeId">노드 ID</param>
|
|
/// <param name="name">노드 이름</param>
|
|
/// <param name="position">위치</param>
|
|
/// <param name="type">노드 타입</param>
|
|
public MapNode(string nodeId, string name, Point position, NodeType type)
|
|
{
|
|
NodeId = nodeId;
|
|
Name = name;
|
|
Position = position;
|
|
Type = type;
|
|
CreatedDate = DateTime.Now;
|
|
ModifiedDate = DateTime.Now;
|
|
|
|
// 타입별 기본 색상 설정
|
|
SetDefaultColorByType(type);
|
|
}
|
|
|
|
/// <summary>
|
|
/// 노드 타입에 따른 기본 색상 설정
|
|
/// </summary>
|
|
/// <param name="type">노드 타입</param>
|
|
public void SetDefaultColorByType(NodeType type)
|
|
{
|
|
switch (type)
|
|
{
|
|
case NodeType.Normal:
|
|
DisplayColor = Color.Blue;
|
|
break;
|
|
case NodeType.Rotation:
|
|
DisplayColor = Color.Orange;
|
|
break;
|
|
case NodeType.Docking:
|
|
DisplayColor = Color.Green;
|
|
break;
|
|
case NodeType.Charging:
|
|
DisplayColor = Color.Red;
|
|
break;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 다른 노드와의 연결 추가
|
|
/// </summary>
|
|
/// <param name="nodeId">연결할 노드 ID</param>
|
|
public void AddConnection(string nodeId)
|
|
{
|
|
if (!ConnectedNodes.Contains(nodeId))
|
|
{
|
|
ConnectedNodes.Add(nodeId);
|
|
ModifiedDate = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 다른 노드와의 연결 제거
|
|
/// </summary>
|
|
/// <param name="nodeId">연결 해제할 노드 ID</param>
|
|
public void RemoveConnection(string nodeId)
|
|
{
|
|
if (ConnectedNodes.Remove(nodeId))
|
|
{
|
|
ModifiedDate = DateTime.Now;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 도킹 스테이션 설정
|
|
/// </summary>
|
|
/// <param name="stationId">장비 ID</param>
|
|
/// <param name="stationType">장비 타입</param>
|
|
/// <param name="dockDirection">도킹 방향</param>
|
|
public void SetDockingStation(string stationId, StationType stationType, DockingDirection dockDirection)
|
|
{
|
|
Type = NodeType.Docking;
|
|
StationId = stationId;
|
|
StationType = stationType;
|
|
DockDirection = dockDirection;
|
|
SetDefaultColorByType(NodeType.Docking);
|
|
ModifiedDate = DateTime.Now;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 충전 스테이션 설정
|
|
/// </summary>
|
|
/// <param name="stationId">충전기 ID</param>
|
|
public void SetChargingStation(string stationId)
|
|
{
|
|
Type = NodeType.Charging;
|
|
StationId = stationId;
|
|
StationType = Models.StationType.Charger;
|
|
DockDirection = DockingDirection.Forward; // 충전기는 항상 전진 도킹
|
|
SetDefaultColorByType(NodeType.Charging);
|
|
ModifiedDate = DateTime.Now;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 문자열 표현
|
|
/// </summary>
|
|
public override string ToString()
|
|
{
|
|
return $"{NodeId}: {Name} ({Type}) at ({Position.X}, {Position.Y})";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 노드 복사
|
|
/// </summary>
|
|
/// <returns>복사된 노드</returns>
|
|
public MapNode Clone()
|
|
{
|
|
var clone = new MapNode
|
|
{
|
|
NodeId = NodeId,
|
|
Name = Name,
|
|
Position = Position,
|
|
Type = Type,
|
|
DockDirection = DockDirection,
|
|
ConnectedNodes = new List<string>(ConnectedNodes),
|
|
CanRotate = CanRotate,
|
|
StationId = StationId,
|
|
StationType = StationType,
|
|
CreatedDate = CreatedDate,
|
|
ModifiedDate = ModifiedDate,
|
|
Description = Description,
|
|
IsActive = IsActive,
|
|
DisplayColor = DisplayColor
|
|
};
|
|
return clone;
|
|
}
|
|
}
|
|
} |