using System; using MultiWheelC.TrajectoryPlanning.Utils; namespace MultiWheelC.TrajectoryPlanning.PathSmoothing.Algorithms; /// 供单次平滑算法运行使用的、已校验的不可变方法选项快照。 internal sealed class SmoothingOptionsSnapshot { internal SmoothingOptionsSnapshot(PathSmoothingConfiguration configuration) { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); CubicBSplineEndpointTangentScale = configuration.CubicBSpline.EndpointTangentScale; BezierCornerHeadingThresholdRadians = configuration.LocalCubicBezier.CornerHeadingThresholdRadians; BezierMaximumWindowLengthMeters = configuration.LocalCubicBezier.MaximumWindowLengthMeters; BezierHandleLengthRatio = configuration.LocalCubicBezier.HandleLengthRatio; QuinticKnotSpacingMeters = configuration.PiecewiseQuintic.KnotSpacingMeters; QuinticMinimumKnotSpacingMeters = configuration.PiecewiseQuintic.MinimumKnotSpacingMeters; ValidatePositiveFinite(CubicBSplineEndpointTangentScale, nameof(CubicBSplineEndpointTangentScale)); if (!NumericGuard.IsFinite(BezierCornerHeadingThresholdRadians) || BezierCornerHeadingThresholdRadians <= 0d || BezierCornerHeadingThresholdRadians > Math.PI) { throw new ArgumentOutOfRangeException(nameof(BezierCornerHeadingThresholdRadians)); } ValidatePositiveFinite(BezierMaximumWindowLengthMeters, nameof(BezierMaximumWindowLengthMeters)); ValidatePositiveFinite(BezierHandleLengthRatio, nameof(BezierHandleLengthRatio)); ValidatePositiveFinite(QuinticKnotSpacingMeters, nameof(QuinticKnotSpacingMeters)); ValidatePositiveFinite(QuinticMinimumKnotSpacingMeters, nameof(QuinticMinimumKnotSpacingMeters)); if (QuinticKnotSpacingMeters < QuinticMinimumKnotSpacingMeters) throw new ArgumentOutOfRangeException(nameof(QuinticKnotSpacingMeters)); } internal double CubicBSplineEndpointTangentScale { get; } internal double BezierCornerHeadingThresholdRadians { get; } internal double BezierMaximumWindowLengthMeters { get; } internal double BezierHandleLengthRatio { get; } internal double QuinticKnotSpacingMeters { get; } internal double QuinticMinimumKnotSpacingMeters { get; } private static void ValidatePositiveFinite(double value, string name) { if (!NumericGuard.IsPositiveFinite(value)) throw new ArgumentOutOfRangeException(name); } }