using System; using System.Collections.Generic; using System.Collections.ObjectModel; namespace MultiWheelC.TrajectoryPlanning.CoarsePath; /// /// 一次粗路径规划的最终不可变结果。 /// 只有 时才携带非空路径与方向分段;其他状态始终返回空只读集合。 /// public sealed class PlanningResult { private static readonly IReadOnlyList EmptyPath = new ReadOnlyCollection(new List()); private static readonly IReadOnlyList EmptySegments = new ReadOnlyCollection(new List()); private PlanningResult(PlanningStatus status, PlanningDiagnostics diagnostics, IReadOnlyList path, IReadOnlyList segments) { Status = status; Diagnostics = diagnostics ?? new PlanningDiagnostics(terminationReason: "未提供诊断信息。"); Path = path; Segments = segments; } /// 规划最终状态;只有 可以发布路径。 public PlanningStatus Status { get; } /// 节点、耗时、路径长度、净空和终止原因统计;始终非空。 public PlanningDiagnostics Diagnostics { get; } /// 成功时的稠密粗路径;失败时为不可修改的空集合。 public IReadOnlyList Path { get; } /// 成功时覆盖 的包含式方向分段;失败时为不可修改的空集合。 public IReadOnlyList Segments { get; } /// /// 创建成功结果。 /// 参数:path 与 segments 必须均为非空;diagnostics 为本次规划的统计快照。参数不符合要求时抛出 ,防止以成功状态发布不完整路径。 /// public static PlanningResult Success(IReadOnlyList path, IReadOnlyList segments, PlanningDiagnostics diagnostics) { if (path == null || path.Count == 0) throw new ArgumentException("Successful planning results require a non-empty path.", nameof(path)); if (segments == null || segments.Count == 0) throw new ArgumentException("Successful planning results require non-empty segments.", nameof(segments)); return new PlanningResult(PlanningStatus.Success, diagnostics, CopyReadOnly(path), CopyReadOnly(segments)); } /// /// 创建失败、取消或资源受限结果。 /// 参数:status 不能为 ;diagnostics 会原样保留。返回结果的路径与分段始终为空只读集合。 /// public static PlanningResult Failure(PlanningStatus status, PlanningDiagnostics diagnostics) { if (status == PlanningStatus.Success) throw new ArgumentException("Use Success to create a successful planning result.", nameof(status)); return new PlanningResult(status, diagnostics, EmptyPath, EmptySegments); } 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); } }