using System.Collections.Generic;
using System.Collections.ObjectModel;
using MultiWheelC.TrajectoryPlanning.CoarsePath;
using MultiWheelC.TrajectoryPlanning.Mapping;
namespace MultiWheelC.TrajectoryPlanning.PathSmoothing;
///
/// 一次路径平滑所需的不可变输入快照。
/// 粗路径、方向段、车辆和配置均在构造时复制;地图保留为调用方已冻结的 快照。
///
public sealed class PathSmoothingRequest
{
private readonly VehicleParameters _vehicle;
private readonly PathSmoothingConfiguration _configuration;
///
/// 创建路径平滑请求,并防御性复制可变的路径、分段、车辆和配置输入。
///
/// 按起点到终点顺序排列的粗路径点集合;位置与弧长单位为 m,航向单位为 rad。
/// 与 对应的前进/倒车包含式方向分段集合。
/// 用于完整车体碰撞与净空复核的已准备不可变规划地图快照。
/// 车辆长宽、安全余量和曲率约束;长度单位为 m,曲率单位为 1/m。
/// 本次平滑的采样、净空、曲率和 Local G2 配置;构造后不会与调用方共享可变实例。
public PathSmoothingRequest(
IReadOnlyList coarsePath,
IReadOnlyList segments,
PlanningGridMap map,
VehicleParameters vehicle,
PathSmoothingConfiguration configuration)
{
CoarsePath = CopyReadOnly(coarsePath);
Segments = CopyReadOnly(segments);
Map = map;
_vehicle = CopyVehicle(vehicle);
_configuration = CopyConfiguration(configuration);
}
/// 原始粗路径的只读快照,按起点到终点顺序排列;位置与弧长单位为 m,航向单位为 rad。
public IReadOnlyList CoarsePath { get; }
/// 原始粗路径方向分段的只读快照;每段标识连续前进或倒车区间。
public IReadOnlyList Segments { get; }
/// 用于平滑后完整车体碰撞和净空复核的已冻结规划栅格地图快照。
public PlanningGridMap Map { get; }
/// 车辆几何与最大曲率约束的不可变快照副本。
public VehicleParameters Vehicle => CopyVehicle(_vehicle);
/// 本次平滑配置的不可变快照副本。
public PathSmoothingConfiguration Configuration => CopyConfiguration(_configuration);
private static IReadOnlyList CopyReadOnly(IReadOnlyList source)
{
var copy = new List(source == null ? 0 : source.Count);
if (source != null)
{
for (int index = 0; index < source.Count; index++)
copy.Add(source[index]);
}
return new ReadOnlyCollection(copy);
}
private static VehicleParameters CopyVehicle(VehicleParameters source)
{
if (source == null) return null;
return new VehicleParameters
{
LengthMeters = source.LengthMeters,
WidthMeters = source.WidthMeters,
SafetyMarginMeters = source.SafetyMarginMeters,
MaximumCurvaturePerMeter = source.MaximumCurvaturePerMeter,
MinimumTurningRadiusMeters = source.MinimumTurningRadiusMeters,
};
}
private static PathSmoothingConfiguration CopyConfiguration(PathSmoothingConfiguration source)
{
if (source == null) return null;
var copy = new PathSmoothingConfiguration
{
OutputSpacingMeters = source.OutputSpacingMeters,
MaximumCollisionCheckStepMeters = source.MaximumCollisionCheckStepMeters,
MinimumClearanceReserveMeters = source.MinimumClearanceReserveMeters,
CurvatureLimitRadiusToleranceMeters = source.CurvatureLimitRadiusToleranceMeters,
};
copy.LocalG2Quintic.MinimumWindowLengthMeters = source.LocalG2Quintic.MinimumWindowLengthMeters;
copy.LocalG2Quintic.PreferredWindowLengthMeters = source.LocalG2Quintic.PreferredWindowLengthMeters;
copy.LocalG2Quintic.MaximumWindowLengthMeters = source.LocalG2Quintic.MaximumWindowLengthMeters;
copy.LocalG2Quintic.MaximumDeviationMeters = source.LocalG2Quintic.MaximumDeviationMeters;
copy.LocalG2Quintic.AbsoluteCurvatureJumpFloorPerMeter = source.LocalG2Quintic.AbsoluteCurvatureJumpFloorPerMeter;
copy.LocalG2Quintic.CurvatureJumpRatioOfMaximum = source.LocalG2Quintic.CurvatureJumpRatioOfMaximum;
copy.LocalG2Quintic.MinimumPeakGradientImprovementRatio = source.LocalG2Quintic.MinimumPeakGradientImprovementRatio;
copy.LocalG2Quintic.MaximumVariationCostRegressionRatio = source.LocalG2Quintic.MaximumVariationCostRegressionRatio;
copy.LocalG2Quintic.MaximumCandidatesPerRegion = source.LocalG2Quintic.MaximumCandidatesPerRegion;
return copy;
}
}