Major improvements to AGV navigation system: • Consolidated RFID management into MapNode, removing duplicate RfidMapping class • Enhanced MapNode with RFID metadata fields (RfidStatus, RfidDescription) • Added automatic bidirectional connection generation in pathfinding algorithms • Updated all components to use unified MapNode-based RFID system • Added command line argument support for AGVMapEditor auto-loading files • Fixed pathfinding failures by ensuring proper node connectivity Technical changes: - Removed RfidMapping class and dependencies across all projects - Updated AStarPathfinder with EnsureBidirectionalConnections() method - Modified MapLoader to use AssignAutoRfidIds() for RFID automation - Enhanced UnifiedAGVCanvas, SimulatorForm, and MainForm for MapNode integration - Improved data consistency and reduced memory footprint 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
144 lines
4.6 KiB
C#
144 lines
4.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace AGVNavigationCore.Models
|
|
{
|
|
/// <summary>
|
|
/// AGV 맵 파일 로딩/저장을 위한 공용 유틸리티 클래스
|
|
/// AGVMapEditor와 AGVSimulator에서 공통으로 사용
|
|
/// </summary>
|
|
public static class MapLoader
|
|
{
|
|
/// <summary>
|
|
/// 맵 파일 로딩 결과
|
|
/// </summary>
|
|
public class MapLoadResult
|
|
{
|
|
public bool Success { get; set; }
|
|
public List<MapNode> Nodes { get; set; } = new List<MapNode>();
|
|
public string ErrorMessage { get; set; } = string.Empty;
|
|
public string Version { get; set; } = string.Empty;
|
|
public DateTime CreatedDate { get; set; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// 맵 파일 저장용 데이터 구조
|
|
/// </summary>
|
|
public class MapFileData
|
|
{
|
|
public List<MapNode> Nodes { get; set; } = new List<MapNode>();
|
|
public DateTime CreatedDate { get; set; }
|
|
public string Version { get; set; } = "1.0";
|
|
}
|
|
|
|
/// <summary>
|
|
/// 맵 파일을 로드하여 노드를 반환
|
|
/// </summary>
|
|
/// <param name="filePath">맵 파일 경로</param>
|
|
/// <returns>로딩 결과</returns>
|
|
public static MapLoadResult LoadMapFromFile(string filePath)
|
|
{
|
|
var result = new MapLoadResult();
|
|
|
|
try
|
|
{
|
|
if (!File.Exists(filePath))
|
|
{
|
|
result.ErrorMessage = $"파일을 찾을 수 없습니다: {filePath}";
|
|
return result;
|
|
}
|
|
|
|
var json = File.ReadAllText(filePath);
|
|
var mapData = JsonConvert.DeserializeObject<MapFileData>(json);
|
|
|
|
if (mapData != null)
|
|
{
|
|
result.Nodes = mapData.Nodes ?? new List<MapNode>();
|
|
result.Version = mapData.Version ?? "1.0";
|
|
result.CreatedDate = mapData.CreatedDate;
|
|
|
|
// 이미지 노드들의 이미지 로드
|
|
LoadImageNodes(result.Nodes);
|
|
|
|
result.Success = true;
|
|
}
|
|
else
|
|
{
|
|
result.ErrorMessage = "맵 데이터 파싱에 실패했습니다.";
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
result.ErrorMessage = $"맵 파일 로딩 중 오류 발생: {ex.Message}";
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
/// <summary>
|
|
/// 맵 데이터를 파일로 저장
|
|
/// </summary>
|
|
/// <param name="filePath">저장할 파일 경로</param>
|
|
/// <param name="nodes">맵 노드 목록</param>
|
|
/// <returns>저장 성공 여부</returns>
|
|
public static bool SaveMapToFile(string filePath, List<MapNode> nodes)
|
|
{
|
|
try
|
|
{
|
|
var mapData = new MapFileData
|
|
{
|
|
Nodes = nodes,
|
|
CreatedDate = DateTime.Now,
|
|
Version = "1.0"
|
|
};
|
|
|
|
var json = JsonConvert.SerializeObject(mapData, Formatting.Indented);
|
|
File.WriteAllText(filePath, json);
|
|
|
|
return true;
|
|
}
|
|
catch (Exception)
|
|
{
|
|
return false;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 이미지 노드들의 이미지 로드
|
|
/// </summary>
|
|
/// <param name="nodes">노드 목록</param>
|
|
private static void LoadImageNodes(List<MapNode> nodes)
|
|
{
|
|
foreach (var node in nodes)
|
|
{
|
|
if (node.Type == NodeType.Image)
|
|
{
|
|
node.LoadImage();
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// MapNode 목록에서 RFID가 없는 노드들에 자동으로 RFID ID를 할당합니다.
|
|
/// </summary>
|
|
/// <param name="mapNodes">맵 노드 목록</param>
|
|
public static void AssignAutoRfidIds(List<MapNode> mapNodes)
|
|
{
|
|
foreach (var node in mapNodes)
|
|
{
|
|
// 네비게이션 가능한 노드이면서 RFID가 없는 경우에만 자동 할당
|
|
if (node.IsNavigationNode() && !node.HasRfid())
|
|
{
|
|
// 기본 RFID ID 생성 (N001 -> 001)
|
|
var rfidId = node.NodeId.Replace("N", "").PadLeft(3, '0');
|
|
|
|
node.SetRfidInfo(rfidId, "", "정상");
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
} |