using System; using MultiWheelC.TrajectoryPlanning.Utils; namespace MultiWheelC.TrajectoryPlanning.PathSmoothing.LocalG2; /// 局部 G2 预平滑一次运行使用的已校验不可变选项。 internal sealed class LocalG2OptionsSnapshot { /// 从已配置的请求选项提取并校验一次局部 G2 平滑运行所需的不可变阈值。 /// 包含 的路径平滑配置。 internal LocalG2OptionsSnapshot(PathSmoothingConfiguration configuration) { if (configuration == null) throw new ArgumentNullException(nameof(configuration)); LocalG2QuinticOptions source = configuration.LocalG2Quintic; if (source == null) throw new ArgumentOutOfRangeException(nameof(configuration)); MinimumWindowLengthMeters = source.MinimumWindowLengthMeters; PreferredWindowLengthMeters = source.PreferredWindowLengthMeters; MaximumWindowLengthMeters = source.MaximumWindowLengthMeters; MaximumDeviationMeters = source.MaximumDeviationMeters; AbsoluteCurvatureJumpFloorPerMeter = source.AbsoluteCurvatureJumpFloorPerMeter; CurvatureJumpRatioOfMaximum = source.CurvatureJumpRatioOfMaximum; MinimumPeakGradientImprovementRatio = source.MinimumPeakGradientImprovementRatio; MaximumVariationCostRegressionRatio = source.MaximumVariationCostRegressionRatio; MaximumCandidatesPerRegion = source.MaximumCandidatesPerRegion; if (!NumericGuard.IsPositiveFinite(MinimumWindowLengthMeters)) throw new ArgumentOutOfRangeException(nameof(MinimumWindowLengthMeters)); if (!NumericGuard.IsFinite(PreferredWindowLengthMeters) || PreferredWindowLengthMeters < MinimumWindowLengthMeters) throw new ArgumentOutOfRangeException(nameof(PreferredWindowLengthMeters)); if (!NumericGuard.IsFinite(MaximumWindowLengthMeters) || MaximumWindowLengthMeters < PreferredWindowLengthMeters) throw new ArgumentOutOfRangeException(nameof(MaximumWindowLengthMeters)); if (!NumericGuard.IsPositiveFinite(MaximumDeviationMeters)) throw new ArgumentOutOfRangeException(nameof(MaximumDeviationMeters)); if (!NumericGuard.IsPositiveFinite(AbsoluteCurvatureJumpFloorPerMeter)) throw new ArgumentOutOfRangeException(nameof(AbsoluteCurvatureJumpFloorPerMeter)); if (!NumericGuard.IsFinite(CurvatureJumpRatioOfMaximum) || CurvatureJumpRatioOfMaximum <= 0d || CurvatureJumpRatioOfMaximum > 1d) throw new ArgumentOutOfRangeException(nameof(CurvatureJumpRatioOfMaximum)); if (!NumericGuard.IsFinite(MinimumPeakGradientImprovementRatio) || MinimumPeakGradientImprovementRatio <= 0d || MinimumPeakGradientImprovementRatio >= 1d) { throw new ArgumentOutOfRangeException(nameof(MinimumPeakGradientImprovementRatio)); } if (!NumericGuard.IsFinite(MaximumVariationCostRegressionRatio) || MaximumVariationCostRegressionRatio < 0d) throw new ArgumentOutOfRangeException(nameof(MaximumVariationCostRegressionRatio)); if (MaximumCandidatesPerRegion < 1) throw new ArgumentOutOfRangeException(nameof(MaximumCandidatesPerRegion)); } internal double MinimumWindowLengthMeters { get; } internal double PreferredWindowLengthMeters { get; } internal double MaximumWindowLengthMeters { get; } internal double MaximumDeviationMeters { get; } internal double AbsoluteCurvatureJumpFloorPerMeter { get; } internal double CurvatureJumpRatioOfMaximum { get; } internal double MinimumPeakGradientImprovementRatio { get; } internal double MaximumVariationCostRegressionRatio { get; } internal int MaximumCandidatesPerRegion { get; } }