2026-07-30 16:12:06 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Collections.ObjectModel;
|
|
|
|
|
|
|
|
|
|
namespace MultiWheelC.TrajectoryPlanning.PathSmoothing;
|
|
|
|
|
|
|
|
|
|
/// <summary>单个局部 G2 平滑区域的不可变发布报告。</summary>
|
|
|
|
|
public sealed class PathSmoothingRegionReport
|
|
|
|
|
{
|
2026-08-04 14:17:56 +08:00
|
|
|
/// <summary>创建单个局部 G2 区域的不可变处理报告。</summary>
|
|
|
|
|
/// <param name="segmentIndex">所属方向段的从零开始索引。</param>
|
|
|
|
|
/// <param name="startArcLengthMeters">区域在完整路径上的起始弧长,单位 m。</param>
|
|
|
|
|
/// <param name="endArcLengthMeters">区域在完整路径上的结束弧长,单位 m。</param>
|
|
|
|
|
/// <param name="curvatureJumpsPerMeter">触发该区域的曲率跳变只读副本,单位 1/m。</param>
|
|
|
|
|
/// <param name="plannedWindowLengthMeters">规划窗口长度,单位 m。</param>
|
|
|
|
|
/// <param name="actualWindowLengthMeters">实际参与平滑的窗口长度,单位 m。</param>
|
|
|
|
|
/// <param name="leftWindowLengthMeters">锚点左侧窗口长度,单位 m。</param>
|
|
|
|
|
/// <param name="rightWindowLengthMeters">锚点右侧窗口长度,单位 m。</param>
|
|
|
|
|
/// <param name="candidateCount">已评估候选数量。</param>
|
|
|
|
|
/// <param name="selectedCandidateIndex">改进时选中候选索引;未改进时结果固定为 -1。</param>
|
|
|
|
|
/// <param name="status">区域是替换为改进候选还是保留原始几何。</param>
|
|
|
|
|
/// <param name="failureReason">未替换原始几何时的稳定拒绝原因。</param>
|
|
|
|
|
/// <param name="rawPeakCurvatureDerivativePerSquareMeter">原始峰值曲率导数,单位 1/m²。</param>
|
|
|
|
|
/// <param name="resultPeakCurvatureDerivativePerSquareMeter">结果峰值曲率导数,单位 1/m²。</param>
|
|
|
|
|
/// <param name="rawCurvatureVariationCost">原始曲率变化代价。</param>
|
|
|
|
|
/// <param name="resultCurvatureVariationCost">结果曲率变化代价。</param>
|
|
|
|
|
/// <param name="maximumDeviationMeters">候选相对原始路径最大偏移,单位 m。</param>
|
|
|
|
|
/// <param name="minimumBodyClearanceMeters">扩大车体最小保守净空,单位 m。</param>
|
|
|
|
|
/// <param name="maximumAbsoluteVehicleCurvaturePerMeter">绝对车辆曲率峰值,单位 1/m。</param>
|
2026-07-30 16:12:06 +08:00
|
|
|
public PathSmoothingRegionReport(
|
|
|
|
|
int segmentIndex,
|
|
|
|
|
double startArcLengthMeters,
|
|
|
|
|
double endArcLengthMeters,
|
|
|
|
|
IReadOnlyList<double> curvatureJumpsPerMeter,
|
|
|
|
|
double plannedWindowLengthMeters,
|
|
|
|
|
double actualWindowLengthMeters,
|
|
|
|
|
double leftWindowLengthMeters,
|
|
|
|
|
double rightWindowLengthMeters,
|
|
|
|
|
int candidateCount,
|
|
|
|
|
int selectedCandidateIndex,
|
|
|
|
|
PathSmoothingRegionStatus status,
|
|
|
|
|
PathSmoothingRegionFailureReason failureReason,
|
|
|
|
|
double rawPeakCurvatureDerivativePerSquareMeter,
|
|
|
|
|
double resultPeakCurvatureDerivativePerSquareMeter,
|
|
|
|
|
double rawCurvatureVariationCost,
|
|
|
|
|
double resultCurvatureVariationCost,
|
|
|
|
|
double maximumDeviationMeters,
|
|
|
|
|
double minimumBodyClearanceMeters,
|
|
|
|
|
double maximumAbsoluteVehicleCurvaturePerMeter)
|
|
|
|
|
{
|
|
|
|
|
SegmentIndex = segmentIndex;
|
|
|
|
|
StartArcLengthMeters = startArcLengthMeters;
|
|
|
|
|
EndArcLengthMeters = endArcLengthMeters;
|
|
|
|
|
CurvatureJumpsPerMeter = CopyReadOnly(curvatureJumpsPerMeter);
|
|
|
|
|
PlannedWindowLengthMeters = plannedWindowLengthMeters;
|
|
|
|
|
ActualWindowLengthMeters = actualWindowLengthMeters;
|
|
|
|
|
LeftWindowLengthMeters = leftWindowLengthMeters;
|
|
|
|
|
RightWindowLengthMeters = rightWindowLengthMeters;
|
|
|
|
|
CandidateCount = candidateCount;
|
|
|
|
|
SelectedCandidateIndex = status == PathSmoothingRegionStatus.Improved
|
|
|
|
|
? selectedCandidateIndex
|
|
|
|
|
: -1;
|
|
|
|
|
Status = status;
|
|
|
|
|
FailureReason = failureReason;
|
|
|
|
|
RawPeakCurvatureDerivativePerSquareMeter = rawPeakCurvatureDerivativePerSquareMeter;
|
|
|
|
|
ResultPeakCurvatureDerivativePerSquareMeter = resultPeakCurvatureDerivativePerSquareMeter;
|
|
|
|
|
RawCurvatureVariationCost = rawCurvatureVariationCost;
|
|
|
|
|
ResultCurvatureVariationCost = resultCurvatureVariationCost;
|
|
|
|
|
MaximumDeviationMeters = maximumDeviationMeters;
|
|
|
|
|
MinimumBodyClearanceMeters = minimumBodyClearanceMeters;
|
|
|
|
|
MaximumAbsoluteVehicleCurvaturePerMeter = maximumAbsoluteVehicleCurvaturePerMeter;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public int SegmentIndex { get; }
|
|
|
|
|
public double StartArcLengthMeters { get; }
|
|
|
|
|
public double EndArcLengthMeters { get; }
|
|
|
|
|
public IReadOnlyList<double> CurvatureJumpsPerMeter { get; }
|
|
|
|
|
public double PlannedWindowLengthMeters { get; }
|
|
|
|
|
public double ActualWindowLengthMeters { get; }
|
|
|
|
|
public double LeftWindowLengthMeters { get; }
|
|
|
|
|
public double RightWindowLengthMeters { get; }
|
|
|
|
|
public int CandidateCount { get; }
|
|
|
|
|
public int SelectedCandidateIndex { get; }
|
|
|
|
|
public PathSmoothingRegionStatus Status { get; }
|
|
|
|
|
public PathSmoothingRegionFailureReason FailureReason { get; }
|
|
|
|
|
public double RawPeakCurvatureDerivativePerSquareMeter { get; }
|
|
|
|
|
public double ResultPeakCurvatureDerivativePerSquareMeter { get; }
|
|
|
|
|
public double RawCurvatureVariationCost { get; }
|
|
|
|
|
public double ResultCurvatureVariationCost { get; }
|
|
|
|
|
public double MaximumDeviationMeters { get; }
|
|
|
|
|
public double MinimumBodyClearanceMeters { get; }
|
|
|
|
|
public double MaximumAbsoluteVehicleCurvaturePerMeter { get; }
|
|
|
|
|
|
|
|
|
|
private static IReadOnlyList<double> CopyReadOnly(IReadOnlyList<double> source)
|
|
|
|
|
{
|
|
|
|
|
var copy = new List<double>(source == null ? 0 : source.Count);
|
|
|
|
|
if (source != null)
|
|
|
|
|
{
|
|
|
|
|
for (int index = 0; index < source.Count; index++)
|
|
|
|
|
copy.Add(source[index]);
|
|
|
|
|
}
|
|
|
|
|
return new ReadOnlyCollection<double>(copy);
|
|
|
|
|
}
|
|
|
|
|
}
|