using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace MultiWheelC.TrajectoryPlanning.PathSmoothing; /// 路径平滑的最终不可变结果。 public sealed class PathSmoothingResult { private static readonly IReadOnlyList EmptyPath = new ReadOnlyCollection(new List()); private static readonly IReadOnlyList EmptySegments = new ReadOnlyCollection(new List()); private PathSmoothingResult( PathSmoothingStatus status, SmoothingMethod? method, IReadOnlyList path, IReadOnlyList segments, PathSmoothingDiagnostics diagnostics) { Status = status; Method = method; Path = path; Segments = segments; Diagnostics = diagnostics ?? new PathSmoothingDiagnostics( new PathQualityMetrics(), TimeSpan.Zero, 0, 0d, "No smoothing diagnostics were supplied."); } /// 最终发布状态。 public PathSmoothingStatus Status { get; } /// 成功或回退时的实际(或尝试)平滑方法;失败时为空。 public SmoothingMethod? Method { get; } /// 成功或经过复核的回退路径;其他状态始终为空且不可变。 public IReadOnlyList Path { get; } /// 覆盖 的方向分段;其他状态始终为空且不可变。 public IReadOnlyList Segments { get; } /// 本次平滑的质量和终止诊断;始终非空。 public PathSmoothingDiagnostics Diagnostics { get; } /// 创建已通过所有复核的平滑结果。 public static PathSmoothingResult Success( SmoothingMethod method, IReadOnlyList path, IReadOnlyList segments, PathSmoothingDiagnostics diagnostics) { ValidatePublishedResult(method, path, segments, diagnostics); return new PathSmoothingResult( PathSmoothingStatus.Success, method, CopyReadOnly(path), CopyReadOnly(segments), diagnostics); } /// 创建经过完整复核的原始粗路径回退结果。 public static PathSmoothingResult Fallback( SmoothingMethod attemptedMethod, IReadOnlyList path, IReadOnlyList segments, PathSmoothingDiagnostics diagnostics) { ValidatePublishedResult(attemptedMethod, path, segments, diagnostics); return new PathSmoothingResult( PathSmoothingStatus.FallbackToCoarsePath, attemptedMethod, CopyReadOnly(path), CopyReadOnly(segments), diagnostics); } /// 创建不发布路径的失败、不可行、取消或输入无效结果。 public static PathSmoothingResult Failure(PathSmoothingStatus status, PathSmoothingDiagnostics diagnostics) { if (status == PathSmoothingStatus.Success || status == PathSmoothingStatus.FallbackToCoarsePath) throw new ArgumentException("Use Success or Fallback to publish a path.", nameof(status)); if (!Enum.IsDefined(typeof(PathSmoothingStatus), status)) throw new ArgumentOutOfRangeException(nameof(status)); return new PathSmoothingResult(status, null, EmptyPath, EmptySegments, diagnostics); } private static void ValidatePublishedResult( SmoothingMethod method, IReadOnlyList path, IReadOnlyList segments, PathSmoothingDiagnostics diagnostics) { if (!Enum.IsDefined(typeof(SmoothingMethod), method)) throw new ArgumentOutOfRangeException(nameof(method)); if (path == null || path.Count == 0) throw new ArgumentException("Published smoothing results require a non-empty path.", nameof(path)); if (segments == null || segments.Count == 0) throw new ArgumentException("Published smoothing results require non-empty segments.", nameof(segments)); if (diagnostics == null || diagnostics.Metrics == null || !diagnostics.Metrics.IsFeasible) throw new ArgumentException("Published smoothing results require feasible diagnostics.", nameof(diagnostics)); } private static IReadOnlyList CopyReadOnly(IReadOnlyList source) { var copy = new List(source.Count); for (int index = 0; index < source.Count; index++) copy.Add(source[index]); return new ReadOnlyCollection(copy); } }