Files
ParkingRobot/ClumsyPilot/ParkrobTrajplanner/CoarsePath/Contracts/PlanningResult.cs
T

68 lines
3.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
namespace MultiWheelC.TrajectoryPlanning.CoarsePath;
/// <summary>
/// 一次粗路径规划的最终不可变结果。
/// 只有 <see cref="Status"/> 为 <see cref="PlanningStatus.Success"/> 时才携带非空路径与方向分段;其他状态始终返回空只读集合。
/// </summary>
public sealed class PlanningResult
{
private static readonly IReadOnlyList<CoarsePathPoint> EmptyPath = new ReadOnlyCollection<CoarsePathPoint>(new List<CoarsePathPoint>());
private static readonly IReadOnlyList<PathSegment> EmptySegments = new ReadOnlyCollection<PathSegment>(new List<PathSegment>());
private PlanningResult(PlanningStatus status, PlanningDiagnostics diagnostics, IReadOnlyList<CoarsePathPoint> path, IReadOnlyList<PathSegment> segments)
{
Status = status;
Diagnostics = diagnostics ?? new PlanningDiagnostics(terminationReason: "未提供诊断信息。");
Path = path;
Segments = segments;
}
/// <summary>规划最终状态;只有 <see cref="PlanningStatus.Success"/> 可以发布路径。</summary>
public PlanningStatus Status { get; }
/// <summary>节点、耗时、路径长度、净空和终止原因统计;始终非空。</summary>
public PlanningDiagnostics Diagnostics { get; }
/// <summary>成功时的稠密粗路径;失败时为不可修改的空集合。</summary>
public IReadOnlyList<CoarsePathPoint> Path { get; }
/// <summary>成功时覆盖 <see cref="Path"/> 的包含式方向分段;失败时为不可修改的空集合。</summary>
public IReadOnlyList<PathSegment> Segments { get; }
/// <summary>
/// 创建成功结果。
/// 参数:path 与 segments 必须均为非空;diagnostics 为本次规划的统计快照。参数不符合要求时抛出 <see cref="ArgumentException"/>,防止以成功状态发布不完整路径。
/// </summary>
public static PlanningResult Success(IReadOnlyList<CoarsePathPoint> path, IReadOnlyList<PathSegment> 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));
}
/// <summary>
/// 创建失败、取消或资源受限结果。
/// 参数:status 不能为 <see cref="PlanningStatus.Success"/>diagnostics 会原样保留。返回结果的路径与分段始终为空只读集合。
/// </summary>
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<T> CopyReadOnly<T>(IReadOnlyList<T> source)
{
var copy = new List<T>(source.Count);
for (int index = 0; index < source.Count; index++)
copy.Add(source[index]);
return new ReadOnlyCollection<T>(copy);
}
}