using System; using System.Collections.Generic; using AGVNavigationCore.Models; namespace AGVNavigationCore.PathFinding { /// /// RFID 기반 AGV 경로 계산 결과 /// 실제 현장에서 AGV가 RFID를 기준으로 이동하는 방식에 맞춤 /// public class RfidPathResult { /// /// 경로 찾기 성공 여부 /// public bool Success { get; set; } /// /// RFID 경로 목록 (시작 → 목적지 순서) /// public List RfidPath { get; set; } /// /// AGV 명령어 목록 (이동 방향 시퀀스) /// public List Commands { get; set; } /// /// 총 거리 /// public float TotalDistance { get; set; } /// /// 계산 소요 시간 (밀리초) /// public long CalculationTimeMs { get; set; } /// /// 예상 소요 시간 (초) /// public float EstimatedTimeSeconds { get; set; } /// /// 회전 횟수 /// public int RotationCount { get; set; } /// /// 오류 메시지 (실패시) /// public string ErrorMessage { get; set; } /// /// 기본 생성자 /// public RfidPathResult() { Success = false; RfidPath = new List(); Commands = new List(); TotalDistance = 0; CalculationTimeMs = 0; EstimatedTimeSeconds = 0; RotationCount = 0; ErrorMessage = string.Empty; } /// /// 성공 결과 생성 /// /// RFID 경로 /// AGV 명령어 목록 /// 총 거리 /// 계산 시간 /// 예상 소요 시간 /// 회전 횟수 /// 성공 결과 public static RfidPathResult CreateSuccess( List rfidPath, List commands, float totalDistance, long calculationTimeMs, float estimatedTimeSeconds, int rotationCount) { return new RfidPathResult { Success = true, RfidPath = new List(rfidPath), Commands = new List(commands), TotalDistance = totalDistance, CalculationTimeMs = calculationTimeMs, EstimatedTimeSeconds = estimatedTimeSeconds, RotationCount = rotationCount }; } /// /// 실패 결과 생성 /// /// 오류 메시지 /// 계산 시간 /// 실패 결과 public static RfidPathResult CreateFailure(string errorMessage, long calculationTimeMs) { return new RfidPathResult { Success = false, ErrorMessage = errorMessage, CalculationTimeMs = calculationTimeMs }; } /// /// 명령어 요약 생성 /// /// 명령어 요약 문자열 public string GetCommandSummary() { if (!Success) return "실패"; var summary = new List(); var currentCommand = AgvDirection.Stop; var count = 0; foreach (var command in Commands) { if (command == currentCommand) { count++; } else { if (count > 0) { summary.Add($"{GetCommandText(currentCommand)}×{count}"); } currentCommand = command; count = 1; } } if (count > 0) { summary.Add($"{GetCommandText(currentCommand)}×{count}"); } return string.Join(" → ", summary); } /// /// 명령어 텍스트 반환 /// private string GetCommandText(AgvDirection command) { switch (command) { case AgvDirection.Forward: return "전진"; case AgvDirection.Backward: return "후진"; case AgvDirection.Left: return "좌회전"; case AgvDirection.Right: return "우회전"; case AgvDirection.Stop: return "정지"; default: return command.ToString(); } } /// /// RFID 경로 요약 생성 /// /// RFID 경로 요약 문자열 public string GetRfidPathSummary() { if (!Success || RfidPath.Count == 0) return "경로 없음"; if (RfidPath.Count <= 3) { return string.Join(" → ", RfidPath); } else { return $"{RfidPath[0]} → ... ({RfidPath.Count - 2}개 경유) → {RfidPath[RfidPath.Count - 1]}"; } } /// /// 상세 경로 정보 반환 /// /// 상세 정보 문자열 public string GetDetailedInfo() { if (!Success) { return $"RFID 경로 계산 실패: {ErrorMessage} (계산시간: {CalculationTimeMs}ms)"; } return $"RFID 경로: {RfidPath.Count}개 지점, 거리: {TotalDistance:F1}px, " + $"회전: {RotationCount}회, 예상시간: {EstimatedTimeSeconds:F1}초, " + $"계산시간: {CalculationTimeMs}ms"; } /// /// AGV 운영자용 실행 정보 반환 /// /// 실행 정보 문자열 public string GetExecutionInfo() { if (!Success) return $"실행 불가: {ErrorMessage}"; return $"[실행준비] {GetRfidPathSummary()}\n" + $"[명령어] {GetCommandSummary()}\n" + $"[예상시간] {EstimatedTimeSeconds:F1}초"; } /// /// 문자열 표현 /// public override string ToString() { if (Success) { return $"Success: {RfidPath.Count} RFIDs, {TotalDistance:F1}px, {RotationCount} rotations, {EstimatedTimeSeconds:F1}s"; } else { return $"Failed: {ErrorMessage}"; } } } }