test: add path smoothing scenarios and fixtures
This commit is contained in:
@@ -0,0 +1,15 @@
|
||||
param(
|
||||
[string]$AssemblyPath = (Join-Path $PSScriptRoot '..\bin\Debug\netstandard2.0\ClumsyPilot.dll'),
|
||||
[string]$OutputPath = (Join-Path $PSScriptRoot '..\ParkrobTrajplanner\PathSmoothing\Test\Fixtures\path-smoothing-fixtures.json'),
|
||||
[switch]$Overwrite
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$newtonsoftPath = Join-Path $env:USERPROFILE '.nuget\packages\newtonsoft.json\13.0.4\lib\netstandard2.0\Newtonsoft.Json.dll'
|
||||
if (Test-Path -LiteralPath $newtonsoftPath) { [Reflection.Assembly]::LoadFrom($newtonsoftPath) | Out-Null }
|
||||
$assembly = [Reflection.Assembly]::LoadFrom((Resolve-Path $AssemblyPath))
|
||||
$type = $assembly.GetType('MultiWheelC.TrajectoryPlanning.PathSmoothing.Test.SmoothingFixtureGenerator', $true)
|
||||
$method = $type.GetMethod('Generate', [Type[]]@([string], [bool]))
|
||||
if ($null -eq $method) { throw 'SmoothingFixtureGenerator.Generate(string, bool) is missing.' }
|
||||
$method.Invoke($null, @([IO.Path]::GetFullPath($OutputPath), [bool]$Overwrite))
|
||||
Write-Output "Path smoothing fixtures generated: $OutputPath"
|
||||
@@ -0,0 +1,119 @@
|
||||
param(
|
||||
[string]$AssemblyPath = (Join-Path $PSScriptRoot '..\bin\Debug\netstandard2.0\ClumsyPilot.dll'),
|
||||
[string]$FixturePath = (Join-Path $PSScriptRoot '..\ParkrobTrajplanner\PathSmoothing\Test\Fixtures\path-smoothing-fixtures.json'))
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$newtonsoftPath = Join-Path $env:USERPROFILE '.nuget\packages\newtonsoft.json\13.0.4\lib\netstandard2.0\Newtonsoft.Json.dll'
|
||||
if (Test-Path -LiteralPath $newtonsoftPath) { [Reflection.Assembly]::LoadFrom($newtonsoftPath) | Out-Null }
|
||||
$assembly = [Reflection.Assembly]::LoadFrom((Resolve-Path $AssemblyPath))
|
||||
|
||||
function Assert-True($Actual, [string]$Message) { if (-not $Actual) { throw $Message } }
|
||||
function Assert-Equal($Expected, $Actual, [string]$Message) {
|
||||
if ($Expected -ne $Actual) { throw "$Message Expected=$Expected Actual=$Actual" }
|
||||
}
|
||||
function Assert-ThrowsMatching([scriptblock]$Action, [string]$ExpectedPattern, [string]$Message) {
|
||||
try {
|
||||
& $Action
|
||||
}
|
||||
catch {
|
||||
$exception = $_.Exception
|
||||
while ($null -ne $exception.InnerException) { $exception = $exception.InnerException }
|
||||
if ($exception.Message -match $ExpectedPattern) { return }
|
||||
throw "$Message ExpectedPattern=$ExpectedPattern Actual=$($exception.Message)"
|
||||
}
|
||||
throw "$Message Expected an exception."
|
||||
}
|
||||
function Get-RequiredType([string]$Name) { return $assembly.GetType($Name, $true) }
|
||||
|
||||
$root = 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Test.'
|
||||
$comparison = 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Comparison.'
|
||||
$loaderType = Get-RequiredType ($root + 'SmoothingScenarioFixtureLoader')
|
||||
$factoryType = Get-RequiredType ($root + 'SmoothingScenarioFactory')
|
||||
$fixtureType = Get-RequiredType ($root + 'SmoothingScenarioFixture')
|
||||
$comparisonRequestType = Get-RequiredType ($comparison + 'PathSmoothingComparisonRequest')
|
||||
$preprocessorType = Get-RequiredType 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Processing.PathSmoothingPreprocessor'
|
||||
|
||||
$loadMethod = $loaderType.GetMethod('LoadAndVerify', [Type[]]@([string]))
|
||||
Assert-True ($null -ne $loadMethod) 'Fixture loader must expose LoadAndVerify(string).'
|
||||
$fixtureRequestsMethod = $factoryType.GetMethod('CreateFixtureRequests', [Type[]]@([string]))
|
||||
Assert-True ($null -ne $fixtureRequestsMethod) 'Scenario factory must expose CreateFixtureRequests(string).'
|
||||
$generateMethod = $assembly.GetType($root + 'SmoothingFixtureGenerator', $true).GetMethod('Generate', [Type[]]@([string], [bool]))
|
||||
Assert-True ($null -ne $generateMethod) 'Fixture generator must expose Generate(string, bool).'
|
||||
$tryPrepareMethod = $preprocessorType.GetMethod('TryPrepare')
|
||||
Assert-True ($null -ne $tryPrepareMethod) 'Fixture paths must be checked through PathSmoothingPreprocessor.TryPrepare.'
|
||||
|
||||
$fixtures = $loadMethod.Invoke($null, @((Resolve-Path $FixturePath).Path))
|
||||
$fixtureDocument = Get-Content -Raw -Encoding UTF8 $FixturePath | ConvertFrom-Json
|
||||
$expected = @(
|
||||
'straight', 'single-turn', 's-bend', 'large-heading-change',
|
||||
'rectangle-detour', 'multi-obstacle-detour',
|
||||
'narrow-corridor', 'forward-reverse-switch')
|
||||
Assert-Equal $expected.Count $fixtures.Count 'Fixture loader must return exactly eight fast fixtures.'
|
||||
|
||||
$actualIds = @($fixtures | ForEach-Object { $_.Id })
|
||||
Assert-Equal ($expected -join ',') ($actualIds -join ',') 'Fixture IDs must be stable and in documented order.'
|
||||
Assert-Equal $actualIds.Count (@($actualIds | Select-Object -Unique).Count) 'Fixture IDs must be unique.'
|
||||
foreach ($fixture in $fixtures) {
|
||||
Assert-True ($fixture -is $fixtureType) 'Loader must return immutable smoothing fixture values.'
|
||||
Assert-True ($fixture.FixtureVersion -gt 0) "Fixture $($fixture.Id) must carry a positive version."
|
||||
Assert-True $fixture.IsConfigurationFingerprintCurrent "Fixture $($fixture.Id) must match its stored configuration fingerprint."
|
||||
Assert-True ($fixture.ConfigurationFingerprint -match '^sha256:[0-9a-f]{64}$') "Fixture $($fixture.Id) must expose a lowercase SHA-256 fingerprint."
|
||||
Assert-True ($fixture.Path.Count -gt 1) "Fixture $($fixture.Id) must include a coarse path."
|
||||
Assert-True ($fixture.Segments.Count -gt 0) "Fixture $($fixture.Id) must include direction segments."
|
||||
foreach ($segment in $fixture.Segments) {
|
||||
Assert-True ($segment.StartIndex -ge 0 -and $segment.EndIndex -lt $fixture.Path.Count -and $segment.EndIndex -ge $segment.StartIndex) "Fixture $($fixture.Id) must retain valid segment coverage."
|
||||
}
|
||||
}
|
||||
foreach ($record in $fixtureDocument.scenarios) {
|
||||
Assert-True ($null -ne $record.planningConfiguration) "Fixture $($record.id) must retain the planning configuration that produced its coarse path."
|
||||
}
|
||||
|
||||
$requests = $fixtureRequestsMethod.Invoke($null, @((Resolve-Path $FixturePath).Path))
|
||||
Assert-Equal 8 $requests.Count 'Fast fixtures must create exactly eight comparison requests without Hybrid A*.'
|
||||
foreach ($request in $requests) {
|
||||
Assert-True ($request -is $comparisonRequestType) 'Fast fixture factory must create comparison requests.'
|
||||
$prepareArguments = [object[]]@($request.SmoothingRequest, $null, $null)
|
||||
$prepared = $tryPrepareMethod.Invoke([Activator]::CreateInstance($preprocessorType), $prepareArguments)
|
||||
Assert-True $prepared "Fixture path must satisfy the PathSmoothingPreprocessor input contract. Reason=$($prepareArguments[2])"
|
||||
}
|
||||
|
||||
$loaderSource = Get-Content -Raw -Encoding UTF8 (Join-Path $PSScriptRoot '..\ParkrobTrajplanner\PathSmoothing\Test\SmoothingScenarioFixtureLoader.cs')
|
||||
Assert-True (-not $loaderSource.Contains('HybridAStarPlanner')) 'Fixture-only loading must not reference HybridAStarPlanner.'
|
||||
$generatorSource = Get-Content -Raw -Encoding UTF8 (Join-Path $PSScriptRoot '..\ParkrobTrajplanner\PathSmoothing\Test\SmoothingFixtureGenerator.cs')
|
||||
Assert-True $generatorSource.Contains('CoarsePathPlanningService') 'Fixture generation must snapshot actual successful coarse-path planning outputs.'
|
||||
Assert-True $generatorSource.Contains('CoarsePathScenarioFactory') 'Fixture generation must use the established coarse-path scenarios where available.'
|
||||
|
||||
function Write-CorruptedFixture([scriptblock]$Mutate) {
|
||||
$temporaryPath = [IO.Path]::GetTempFileName()
|
||||
$document = Get-Content -Raw -Encoding UTF8 $FixturePath | ConvertFrom-Json
|
||||
& $Mutate $document
|
||||
[IO.File]::WriteAllText($temporaryPath, ($document | ConvertTo-Json -Depth 16), [Text.UTF8Encoding]::new($false))
|
||||
return $temporaryPath
|
||||
}
|
||||
|
||||
$coverageFixture = Write-CorruptedFixture { param($document) $document.scenarios[0].segments[0].endIndex = 1 }
|
||||
$directionFixture = Write-CorruptedFixture { param($document) $document.scenarios[0].segments[0].direction = 1 }
|
||||
$switchFixture = Write-CorruptedFixture { param($document) $document.scenarios[0].segments[0].endsAtGearSwitch = $true }
|
||||
try {
|
||||
Assert-ThrowsMatching { $loadMethod.Invoke($null, @($coverageFixture)) } 'Fixture path contract' 'Loader must reject segment gaps before accepting the fingerprint.'
|
||||
Assert-ThrowsMatching { $loadMethod.Invoke($null, @($directionFixture)) } 'Fixture path contract' 'Loader must reject segment direction mismatches before accepting the fingerprint.'
|
||||
Assert-ThrowsMatching { $loadMethod.Invoke($null, @($switchFixture)) } 'Fixture path contract' 'Loader must reject illegal gear-switch topology before accepting the fingerprint.'
|
||||
}
|
||||
finally {
|
||||
foreach ($temporaryPath in @($coverageFixture, $directionFixture, $switchFixture)) {
|
||||
if ($temporaryPath -and [IO.File]::Exists($temporaryPath)) { [IO.File]::Delete($temporaryPath) }
|
||||
}
|
||||
}
|
||||
|
||||
$generationPath = [IO.Path]::GetTempFileName()
|
||||
try {
|
||||
Assert-ThrowsMatching { $generateMethod.Invoke($null, @($generationPath, $false)) } '.+' 'Fixture generation must refuse to overwrite an existing target.'
|
||||
$generateMethod.Invoke($null, @($generationPath, $true))
|
||||
$generatedFixtures = $loadMethod.Invoke($null, @($generationPath))
|
||||
Assert-Equal 8 $generatedFixtures.Count 'Generated fixture data must remain loadable and retain all scenarios.'
|
||||
}
|
||||
finally {
|
||||
if ([IO.File]::Exists($generationPath)) { [IO.File]::Delete($generationPath) }
|
||||
}
|
||||
|
||||
Write-Output 'Path smoothing fixture checks passed.'
|
||||
@@ -0,0 +1,140 @@
|
||||
param([string]$AssemblyPath = (Join-Path $PSScriptRoot '..\bin\Debug\netstandard2.0\ClumsyPilot.dll'))
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
$assembly = [Reflection.Assembly]::LoadFrom((Resolve-Path $AssemblyPath))
|
||||
|
||||
function Assert-True($Actual, [string]$Message) { if (-not $Actual) { throw $Message } }
|
||||
function Assert-Equal($Expected, $Actual, [string]$Message) {
|
||||
if ($Expected -ne $Actual) { throw "$Message Expected=$Expected Actual=$Actual" }
|
||||
}
|
||||
function Assert-Near([double]$Expected, [double]$Actual, [string]$Message) {
|
||||
if ([Math]::Abs($Expected - $Actual) -gt 0.000001) { throw "$Message Expected=$Expected Actual=$Actual" }
|
||||
}
|
||||
function Get-RequiredType([string]$Name) { return $assembly.GetType($Name, $true) }
|
||||
|
||||
function Assert-CoarsePathGeometry($ExpectedPath, $ActualPath, $Map, [string]$ScenarioName) {
|
||||
Assert-Equal $ExpectedPath.Count $ActualPath.Count "Raw comparison request $ScenarioName must preserve every coarse-path point."
|
||||
for ($index = 0; $index -lt $ExpectedPath.Count; $index++) {
|
||||
$expected = $ExpectedPath[$index]
|
||||
$actual = $ActualPath[$index]
|
||||
Assert-Near $expected.X $actual.X "Raw comparison request $ScenarioName point $index must preserve X."
|
||||
Assert-Near $expected.Y $actual.Y "Raw comparison request $ScenarioName point $index must preserve Y."
|
||||
Assert-Near $expected.Heading $actual.Heading "Raw comparison request $ScenarioName point $index must preserve heading."
|
||||
Assert-Near $expected.UnwrappedHeading $actual.UnwrappedHeading "Raw comparison request $ScenarioName point $index must preserve unwrapped heading."
|
||||
Assert-Near $expected.ArcLength $actual.ArcLength "Raw comparison request $ScenarioName point $index must preserve arc length."
|
||||
Assert-Equal $expected.Direction $actual.Direction "Raw comparison request $ScenarioName point $index must preserve travel direction."
|
||||
Assert-Near $expected.VehicleCurvature $actual.VehicleCurvature "Raw comparison request $ScenarioName point $index must preserve vehicle curvature."
|
||||
$expectedClearance = $expected.BodyClearance
|
||||
if ([double]::IsPositiveInfinity($expectedClearance)) {
|
||||
$widthMeters = ($Map.Bounds.XMax - $Map.Bounds.XMin) / 1000.0
|
||||
$heightMeters = ($Map.Bounds.YMax - $Map.Bounds.YMin) / 1000.0
|
||||
$expectedClearance = [Math]::Sqrt($widthMeters * $widthMeters + $heightMeters * $heightMeters)
|
||||
}
|
||||
Assert-Near $expectedClearance $actual.BodyClearance "Raw comparison request $ScenarioName point $index must preserve or normalize clearance for smoothing."
|
||||
Assert-Equal $expected.IsGearSwitchPoint $actual.IsGearSwitchPoint "Raw comparison request $ScenarioName point $index must preserve gear-switch flag."
|
||||
Assert-Equal $expected.Source $actual.Source "Raw comparison request $ScenarioName point $index must preserve point source."
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-SegmentTopology($ExpectedSegments, $ActualPath, $ActualSegments, [string]$Description) {
|
||||
Assert-Equal $ExpectedSegments.Count $ActualSegments.Count "$Description must preserve segment count."
|
||||
$expectedStartIndex = 0
|
||||
for ($index = 0; $index -lt $ActualSegments.Count; $index++) {
|
||||
$expected = $ExpectedSegments[$index]
|
||||
$actual = $ActualSegments[$index]
|
||||
Assert-Equal $index $actual.SegmentIndex "$Description segment $index must retain its stable index."
|
||||
Assert-Equal $expected.Direction $actual.Direction "$Description segment $index must preserve travel direction."
|
||||
Assert-Equal $expected.StartsAtGearSwitch $actual.StartsAtGearSwitch "$Description segment $index must preserve start gear-switch topology."
|
||||
Assert-Equal $expected.EndsAtGearSwitch $actual.EndsAtGearSwitch "$Description segment $index must preserve end gear-switch topology."
|
||||
Assert-Equal $expectedStartIndex $actual.StartIndex "$Description segment $index must start directly after the prior segment."
|
||||
Assert-True ($actual.EndIndex -ge $actual.StartIndex -and $actual.EndIndex -lt $ActualPath.Count) "$Description segment $index must cover valid path indices."
|
||||
Assert-Equal $actual.StartsAtGearSwitch $ActualPath[$actual.StartIndex].IsGearSwitchPoint "$Description segment $index start flag must match its path point."
|
||||
for ($pointIndex = $actual.StartIndex; $pointIndex -le $actual.EndIndex; $pointIndex++) {
|
||||
Assert-Equal $actual.Direction $ActualPath[$pointIndex].Direction "$Description segment $index may not contain mixed directions."
|
||||
}
|
||||
$hasNext = $index + 1 -lt $ActualSegments.Count
|
||||
$expectedEndSwitch = $hasNext -and $ActualPath[$actual.EndIndex + 1].IsGearSwitchPoint
|
||||
Assert-Equal $expectedEndSwitch $actual.EndsAtGearSwitch "$Description segment $index end flag must match the next gear switch."
|
||||
$expectedStartIndex = $actual.EndIndex + 1
|
||||
}
|
||||
Assert-Equal $ActualPath.Count $expectedStartIndex "$Description segments must cover every path point."
|
||||
}
|
||||
|
||||
function Assert-GearSwitchGeometry($ExpectedPath, $ActualPath, [string]$Description) {
|
||||
$expectedSwitches = @($ExpectedPath | Where-Object { $_.IsGearSwitchPoint })
|
||||
$actualSwitches = @($ActualPath | Where-Object { $_.IsGearSwitchPoint })
|
||||
Assert-Equal $expectedSwitches.Count $actualSwitches.Count "$Description must preserve gear-switch count."
|
||||
for ($index = 0; $index -lt $expectedSwitches.Count; $index++) {
|
||||
Assert-Near $expectedSwitches[$index].X $actualSwitches[$index].X "$Description gear switch $index must preserve X."
|
||||
Assert-Near $expectedSwitches[$index].Y $actualSwitches[$index].Y "$Description gear switch $index must preserve Y."
|
||||
Assert-Near $expectedSwitches[$index].Heading $actualSwitches[$index].Heading "$Description gear switch $index must preserve heading."
|
||||
Assert-Equal $expectedSwitches[$index].Direction $actualSwitches[$index].Direction "$Description gear switch $index must preserve direction."
|
||||
}
|
||||
}
|
||||
|
||||
function Assert-RawBaselinePath($ExpectedPath, $ActualPath, [string]$ScenarioName) {
|
||||
Assert-Equal $ExpectedPath.Count $ActualPath.Count "Raw baseline $ScenarioName must preserve every coarse-path point."
|
||||
for ($index = 0; $index -lt $ExpectedPath.Count; $index++) {
|
||||
$expected = $ExpectedPath[$index]
|
||||
$actual = $ActualPath[$index]
|
||||
Assert-Near $expected.X $actual.X "Raw baseline $ScenarioName point $index must preserve X."
|
||||
Assert-Near $expected.Y $actual.Y "Raw baseline $ScenarioName point $index must preserve Y."
|
||||
Assert-Near $expected.Heading $actual.Heading "Raw baseline $ScenarioName point $index must preserve heading."
|
||||
Assert-Near $expected.UnwrappedHeading $actual.UnwrappedHeading "Raw baseline $ScenarioName point $index must preserve unwrapped heading."
|
||||
Assert-Near $expected.ArcLength $actual.ArcLength "Raw baseline $ScenarioName point $index must preserve arc length."
|
||||
Assert-Equal $expected.Direction $actual.Direction "Raw baseline $ScenarioName point $index must preserve travel direction."
|
||||
Assert-Near $expected.VehicleCurvature $actual.VehicleCurvature "Raw baseline $ScenarioName point $index must preserve vehicle curvature."
|
||||
Assert-Equal $expected.IsGearSwitchPoint $actual.IsGearSwitchPoint "Raw baseline $ScenarioName point $index must preserve gear-switch topology."
|
||||
}
|
||||
}
|
||||
|
||||
$coarse = 'MultiWheelC.TrajectoryPlanning.CoarsePath.'
|
||||
$coarseFacade = $coarse + 'Facade.'
|
||||
$coarseTest = $coarse + 'Test.'
|
||||
$smoothingTest = 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Test.'
|
||||
$smoothingFacade = 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Facade.'
|
||||
$comparison = 'MultiWheelC.TrajectoryPlanning.PathSmoothing.Comparison.'
|
||||
|
||||
$coarseServiceType = Get-RequiredType ($coarseFacade + 'CoarsePathPlanningService')
|
||||
$coarseJobType = Get-RequiredType ($coarseFacade + 'CoarsePathPlanningJob')
|
||||
$coarseResultType = Get-RequiredType ($coarseFacade + 'CoarsePathPlanningJobResult')
|
||||
$scenarioType = Get-RequiredType ($coarseTest + 'CoarsePathTestScenario')
|
||||
$coarseFactoryType = Get-RequiredType ($coarseTest + 'CoarsePathScenarioFactory')
|
||||
$scenarioFactoryType = Get-RequiredType ($smoothingTest + 'SmoothingScenarioFactory')
|
||||
$comparisonServiceType = Get-RequiredType ($smoothingFacade + 'PathSmoothingComparisonService')
|
||||
$comparisonRequestType = Get-RequiredType ($comparison + 'PathSmoothingComparisonRequest')
|
||||
|
||||
$coarseCreate = $coarseFactoryType.GetMethod('Create', [Type[]]@($scenarioType))
|
||||
$coarsePlan = $coarseServiceType.GetMethod('Plan', [Type[]]@($coarseJobType, [Threading.CancellationToken]))
|
||||
$createComparisonRequest = $scenarioFactoryType.GetMethod('CreateEndToEndRequest', [Type[]]@($coarseJobType, $coarseResultType))
|
||||
$compare = $comparisonServiceType.GetMethod('Compare', [Type[]]@($comparisonRequestType, [Threading.CancellationToken]))
|
||||
Assert-True ($null -ne $createComparisonRequest) 'Smoothing scenario factory must convert a successful coarse planning job into a comparison request.'
|
||||
|
||||
$planner = [Activator]::CreateInstance($coarseServiceType)
|
||||
$comparisonService = [Activator]::CreateInstance($comparisonServiceType)
|
||||
foreach ($scenarioName in @('ExplicitEmpty', 'RectangleDetour', 'ManualAndTwoLeg', 'ReverseGearSwitch')) {
|
||||
$scenario = [Enum]::Parse($scenarioType, $scenarioName)
|
||||
$job = $coarseCreate.Invoke($null, @($scenario))
|
||||
$planningTimer = [Diagnostics.Stopwatch]::StartNew()
|
||||
$planned = $coarsePlan.Invoke($planner, @($job, [Threading.CancellationToken]::None))
|
||||
$planningTimer.Stop()
|
||||
Assert-Equal 'Success' $planned.PlanningResult.Status.ToString() "Coarse scenario $scenarioName must succeed before smoothing comparison."
|
||||
$request = $createComparisonRequest.Invoke($null, @($job, $planned))
|
||||
Assert-CoarsePathGeometry $planned.PlanningResult.Path $request.SmoothingRequest.CoarsePath $planned.MapResult.Map $scenarioName
|
||||
$comparisonTimer = [Diagnostics.Stopwatch]::StartNew()
|
||||
$comparisonResult = $compare.Invoke($comparisonService, @($request, [Threading.CancellationToken]::None))
|
||||
$comparisonTimer.Stop()
|
||||
Assert-True (-not $comparisonResult.IsCancelled) "Comparison $scenarioName must not be cancelled."
|
||||
Assert-Equal 'Success' $comparisonResult.RawPathBaseline.Status.ToString() "Raw baseline $scenarioName must remain a feasible, verified copy of the coarse path."
|
||||
Assert-RawBaselinePath $planned.PlanningResult.Path $comparisonResult.RawPathBaseline.Path $scenarioName
|
||||
Assert-SegmentTopology $planned.PlanningResult.Segments $comparisonResult.RawPathBaseline.Path $comparisonResult.RawPathBaseline.Segments "Raw baseline $scenarioName"
|
||||
Assert-GearSwitchGeometry $planned.PlanningResult.Path $comparisonResult.RawPathBaseline.Path "Raw baseline $scenarioName"
|
||||
foreach ($entry in $comparisonResult.Entries | Where-Object { $_.Status.ToString() -eq 'Success' }) {
|
||||
Assert-SegmentTopology $comparisonResult.RawPathBaseline.Segments $entry.Path $entry.Segments "Successful $($entry.Method) $scenarioName"
|
||||
Assert-GearSwitchGeometry $comparisonResult.RawPathBaseline.Path $entry.Path "Successful $($entry.Method) $scenarioName"
|
||||
}
|
||||
$successfulEntryCount = @($comparisonResult.Entries | Where-Object { $_.Status.ToString() -eq 'Success' }).Count
|
||||
Write-Output ("$scenarioName diagnostics: planning=$([Math]::Round($planningTimer.Elapsed.TotalSeconds, 3))s; comparison=$([Math]::Round($comparisonTimer.Elapsed.TotalSeconds, 3))s; successfulMethods=$successfulEntryCount")
|
||||
}
|
||||
|
||||
Write-Output 'Path smoothing end-to-end integration checks passed.'
|
||||
Reference in New Issue
Block a user