using System;
using System.Collections.Generic;
using System.Linq;
using AGVNavigationCore.Models;
namespace AGVNavigationCore.PathFinding
{
///
/// AGV 경로 계산 결과 (방향성 및 명령어 포함)
///
public class AGVPathResult
{
///
/// 경로 찾기 성공 여부
///
public bool Success { get; set; }
///
/// 경로 노드 ID 목록 (시작 → 목적지 순서)
///
public List Path { get; set; }
///
/// AGV 명령어 목록 (이동 방향 시퀀스)
///
public List Commands { get; set; }
///
/// 노드별 모터방향 정보 목록
///
public List NodeMotorInfos { 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 AGVPathResult()
{
Success = false;
Path = new List();
Commands = new List();
NodeMotorInfos = new List();
TotalDistance = 0;
CalculationTimeMs = 0;
EstimatedTimeSeconds = 0;
RotationCount = 0;
ErrorMessage = string.Empty;
}
///
/// 성공 결과 생성
///
/// 경로
/// AGV 명령어 목록
/// 총 거리
/// 계산 시간
/// 성공 결과
public static AGVPathResult CreateSuccess(List path, List commands, float totalDistance, long calculationTimeMs)
{
var result = new AGVPathResult
{
Success = true,
Path = new List(path),
Commands = new List(commands),
TotalDistance = totalDistance,
CalculationTimeMs = calculationTimeMs
};
result.CalculateMetrics();
return result;
}
///
/// 성공 결과 생성 (노드별 모터방향 정보 포함)
///
/// 경로
/// AGV 명령어 목록
/// 노드별 모터방향 정보
/// 총 거리
/// 계산 시간
/// 성공 결과
public static AGVPathResult CreateSuccess(List path, List commands, List nodeMotorInfos, float totalDistance, long calculationTimeMs)
{
var result = new AGVPathResult
{
Success = true,
Path = new List(path),
Commands = new List(commands),
NodeMotorInfos = new List(nodeMotorInfos),
TotalDistance = totalDistance,
CalculationTimeMs = calculationTimeMs
};
result.CalculateMetrics();
return result;
}
///
/// 실패 결과 생성
///
/// 오류 메시지
/// 계산 시간
/// 실패 결과
public static AGVPathResult CreateFailure(string errorMessage, long calculationTimeMs)
{
return new AGVPathResult
{
Success = false,
ErrorMessage = errorMessage,
CalculationTimeMs = calculationTimeMs
};
}
///
/// 경로 메트릭 계산
///
private void CalculateMetrics()
{
RotationCount = CountRotations();
EstimatedTimeSeconds = CalculateEstimatedTime();
}
///
/// 회전 횟수 계산
///
private int CountRotations()
{
int count = 0;
foreach (var command in Commands)
{
if (command == AgvDirection.Left || command == AgvDirection.Right)
{
count++;
}
}
return count;
}
///
/// 예상 소요 시간 계산
///
/// AGV 속도 (픽셀/초, 기본값: 100)
/// 회전 시간 (초, 기본값: 3)
/// 예상 소요 시간 (초)
private float CalculateEstimatedTime(float agvSpeed = 100.0f, float rotationTime = 3.0f)
{
float moveTime = TotalDistance / agvSpeed;
float totalRotationTime = RotationCount * rotationTime;
return moveTime + totalRotationTime;
}
///
/// 명령어 요약 생성
///
/// 명령어 요약 문자열
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();
}
}
///
/// 상세 경로 정보 반환
///
/// 상세 정보 문자열
public string GetDetailedInfo()
{
if (!Success)
{
return $"경로 계산 실패: {ErrorMessage} (계산시간: {CalculationTimeMs}ms)";
}
return $"경로: {Path.Count}개 노드, 거리: {TotalDistance:F1}px, " +
$"회전: {RotationCount}회, 예상시간: {EstimatedTimeSeconds:F1}초, " +
$"계산시간: {CalculationTimeMs}ms";
}
///
/// PathResult로 변환 (호환성을 위해)
///
/// PathResult 객체
public PathResult ToPathResult()
{
if (Success)
{
return PathResult.CreateSuccess(Path, TotalDistance, CalculationTimeMs, 0);
}
else
{
return PathResult.CreateFailure(ErrorMessage, CalculationTimeMs, 0);
}
}
///
/// 문자열 표현
///
public override string ToString()
{
if (Success)
{
return $"Success: {Path.Count} nodes, {TotalDistance:F1}px, {RotationCount} rotations, {EstimatedTimeSeconds:F1}s";
}
else
{
return $"Failed: {ErrorMessage}";
}
}
}
}