fix: preserve raw path smoothing baselines

This commit is contained in:
梁薄云
2026-07-30 08:42:14 +08:00
parent 09953ab1f1
commit 20215defdd
5 changed files with 197 additions and 149 deletions
@@ -13,7 +13,6 @@ public sealed class PathSmoothingComparisonService
{
private readonly PathSmoothingService _smoothingService = new PathSmoothingService();
private readonly PathSmoothingPreprocessor _preprocessor = new PathSmoothingPreprocessor();
private readonly PathGeometryAnalyzer _analyzer = new PathGeometryAnalyzer();
private readonly SmoothedPathValidator _validator = new SmoothedPathValidator();
/// <summary>比较所有请求方法;一个方法的失败不会阻止其他方法,取消会停止后续启动。</summary>
@@ -137,31 +136,23 @@ public sealed class PathSmoothingComparisonService
if (!_preprocessor.TryPrepare(smoothingRequest, out PreparedPath preparedPath, out reason))
return FailedBaseline(PathSmoothingStatus.InvalidInput, reason, out reason);
if (!_analyzer.TryAnalyze(preparedPath.Segments, configuration.OutputSpacingMeters, out PathGeometryAnalysis analysis, out reason))
return FailedBaseline(PathSmoothingStatus.InvalidInput, reason, out reason);
if (!_validator.TryValidate(
analysis.Path,
analysis.Segments,
if (!RawPathBaselineBuilder.TryCreate(
smoothingRequest,
preparedPath,
smoothingRequest.Map,
smoothingRequest.Vehicle,
_validator,
configuration.MaximumCollisionCheckStepMeters,
out IReadOnlyList<SmoothedPathPoint> safePath,
out double minimumClearanceMeters,
out RawPathBaseline rawPath,
out reason))
{
return FailedBaseline(PathSmoothingStatus.InvalidInput, reason, out reason);
}
PathQualityMetrics metrics = CreateMetrics(analysis, minimumClearanceMeters);
string digest = StableGeometryDigest.Compute(PathSmoothingStatus.Success, null, safePath, analysis.Segments);
string digest = StableGeometryDigest.Compute(PathSmoothingStatus.Success, null, rawPath.Path, rawPath.Segments);
return PathSmoothingComparisonEntry.CreateRawPathBaseline(
PathSmoothingStatus.Success,
metrics,
rawPath.Metrics,
digest,
string.Empty,
safePath,
analysis.Segments);
rawPath.Path,
rawPath.Segments);
}
private static PathSmoothingComparisonEntry FailedBaseline(
@@ -199,22 +190,6 @@ public sealed class PathSmoothingComparisonService
configuration);
}
private static PathQualityMetrics CreateMetrics(PathGeometryAnalysis analysis, double minimumClearanceMeters)
{
return new PathQualityMetrics(
true,
analysis.PathLengthMeters,
analysis.MaximumAbsoluteVehicleCurvaturePerMeter,
analysis.RootMeanSquareVehicleCurvaturePerMeter,
analysis.TotalAbsoluteCurvatureVariationPerMeter,
analysis.CurvatureVariationEnergy,
minimumClearanceMeters,
0d,
0d,
0d,
0d);
}
private static PathQualityMetrics NormalizeMetrics(
PathQualityMetrics candidate,
PathQualityMetrics raw)
@@ -16,7 +16,6 @@ public sealed class PathSmoothingService
{
private readonly PathSmoothingPreprocessor _preprocessor = new PathSmoothingPreprocessor();
private readonly SmoothingAlgorithmRunner _runner = new SmoothingAlgorithmRunner();
private readonly PathGeometryAnalyzer _analyzer = new PathGeometryAnalyzer();
private readonly SmoothedPathValidator _validator = new SmoothedPathValidator();
private readonly IPathSmoother _bSpline = new CubicBSplineSmoother();
private readonly IPathSmoother _bezier = new LocalCubicBezierSmoother();
@@ -37,15 +36,11 @@ public sealed class PathSmoothingService
if (!_preprocessor.TryPrepare(request, out PreparedPath preparedPath, out reason))
return Failure(PathSmoothingStatus.InvalidInput, stopwatch, 0, 0d, reason);
if (!TryAnalyzeAndValidate(
if (!RawPathBaselineBuilder.TryCreate(
request,
preparedPath,
preparedPath.Segments,
configuration,
false,
cancellationToken,
out _,
out _,
_validator,
configuration.MaximumCollisionCheckStepMeters,
out _,
out reason))
{
@@ -136,64 +131,20 @@ public sealed class PathSmoothingService
if (!_preprocessor.TryPrepare(request, out PreparedPath revalidatedPath, out reason)) return false;
cancellationToken.ThrowIfCancellationRequested();
return TryAnalyzeAndValidate(
request,
revalidatedPath,
ToFallbackSegments(revalidatedPath),
configuration,
true,
cancellationToken,
out fallbackPath,
out fallbackSegments,
out fallbackMetrics,
out reason);
}
private bool TryAnalyzeAndValidate(
PathSmoothingRequest request,
PreparedPath originalPath,
IReadOnlyList<PreparedDirectionSegment> candidateSegments,
PathSmoothingConfiguration configuration,
bool useFallbackSource,
CancellationToken cancellationToken,
out IReadOnlyList<SmoothedPathPoint> safePath,
out IReadOnlyList<SmoothedPathSegment> safeSegments,
out PathQualityMetrics metrics,
out string reason)
{
safePath = null;
safeSegments = null;
metrics = null;
reason = string.Empty;
if (!_analyzer.TryAnalyze(
candidateSegments,
configuration.OutputSpacingMeters,
out PathGeometryAnalysis analysis,
out reason))
{
return false;
}
IReadOnlyList<SmoothedPathPoint> pathForValidation = useFallbackSource
? ToFallbackPoints(analysis.Path)
: analysis.Path;
cancellationToken.ThrowIfCancellationRequested();
if (!_validator.TryValidate(
pathForValidation,
analysis.Segments,
originalPath,
request.Map,
request.Vehicle,
if (!RawPathBaselineBuilder.TryCreate(
request,
revalidatedPath,
_validator,
configuration.MaximumCollisionCheckStepMeters,
out safePath,
out double minimumClearanceMeters,
out RawPathBaseline rawPath,
out reason))
{
return false;
}
safeSegments = analysis.Segments;
metrics = CreateMetrics(analysis, minimumClearanceMeters);
fallbackPath = ToFallbackPoints(rawPath.Path);
fallbackSegments = rawPath.Segments;
fallbackMetrics = rawPath.Metrics;
return true;
}
@@ -268,36 +219,6 @@ public sealed class PathSmoothingService
return NumericGuard.IsFinite(thresholdRadians) && thresholdRadians > 0d && thresholdRadians <= Math.PI;
}
private static IReadOnlyList<PreparedDirectionSegment> ToFallbackSegments(PreparedPath path)
{
var segments = new List<PreparedDirectionSegment>(path.Segments.Count);
for (int segmentIndex = 0; segmentIndex < path.Segments.Count; segmentIndex++)
{
PreparedDirectionSegment segment = path.Segments[segmentIndex];
var points = new List<SmoothingPoint2D>(segment.Points.Count);
for (int pointIndex = 0; pointIndex < segment.Points.Count; pointIndex++)
{
SmoothingPoint2D point = segment.Points[pointIndex];
points.Add(new SmoothingPoint2D(
point.X,
point.Y,
point.ArcLength,
point.Heading,
point.UnwrappedHeading,
point.BodyClearance,
point.IsGearSwitchPoint,
SmoothedPathPointSource.CoarsePathFallback));
}
segments.Add(new PreparedDirectionSegment(
segment.SegmentIndex,
segment.Direction,
points,
segment.StartsAtGearSwitch,
segment.EndsAtGearSwitch));
}
return segments;
}
private static IReadOnlyList<SmoothedPathPoint> ToFallbackPoints(IReadOnlyList<SmoothedPathPoint> path)
{
var points = new List<SmoothedPathPoint>(path.Count);
@@ -320,22 +241,6 @@ public sealed class PathSmoothingService
return points;
}
private static PathQualityMetrics CreateMetrics(PathGeometryAnalysis analysis, double minimumClearanceMeters)
{
return new PathQualityMetrics(
true,
analysis.PathLengthMeters,
analysis.MaximumAbsoluteVehicleCurvaturePerMeter,
analysis.RootMeanSquareVehicleCurvaturePerMeter,
analysis.TotalAbsoluteCurvatureVariationPerMeter,
analysis.CurvatureVariationEnergy,
minimumClearanceMeters,
0d,
0d,
0d,
0d);
}
private static int GetRetryCount(IReadOnlyList<double> attemptedStrengths)
{
return attemptedStrengths == null || attemptedStrengths.Count == 0 ? 0 : attemptedStrengths.Count - 1;