fix: orient observation LS chart by path S

This commit is contained in:
梁薄云
2026-08-04 16:24:58 +08:00
parent 08f6603cad
commit fded5181db
2 changed files with 70 additions and 8 deletions
@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Drawing; using System.Drawing;
using System.Globalization; using System.Globalization;
using ClumsyCore; using ClumsyCore;
@@ -36,6 +37,46 @@ public static class TrajectoryObservationPresentationText
} }
} }
public sealed class TrajectoryObservationLsPresentationPoint
{
public TrajectoryObservationLsPresentationPoint(double horizontalPathS, double verticalLateralOffset)
{
HorizontalPathS = horizontalPathS;
VerticalLateralOffset = verticalLateralOffset;
}
public double HorizontalPathS { get; }
public double VerticalLateralOffset { get; }
}
public sealed class TrajectoryObservationLsPresentationModel
{
private TrajectoryObservationLsPresentationModel(IReadOnlyList<TrajectoryObservationLsPresentationPoint> samples)
{
Samples = new ReadOnlyCollection<TrajectoryObservationLsPresentationPoint>(
new List<TrajectoryObservationLsPresentationPoint>(samples));
}
public string HorizontalAxisLabel => "path-S (m)";
public string VerticalAxisLabel => "lateral offset (m)";
public IReadOnlyList<TrajectoryObservationLsPresentationPoint> Samples { get; }
public static TrajectoryObservationLsPresentationModel Create(TrajectoryObservationCharts charts)
{
if (charts == null) throw new ArgumentNullException(nameof(charts));
var samples = new List<TrajectoryObservationLsPresentationPoint>(charts.LsSamples.Count);
for (int index = 0; index < charts.LsSamples.Count; index++)
{
TrajectoryObservationLsSample sample = charts.LsSamples[index];
samples.Add(new TrajectoryObservationLsPresentationPoint(sample.PathS, sample.LateralOffset));
}
return new TrajectoryObservationLsPresentationModel(samples);
}
}
public sealed class TrajectoryObservationPresentation public sealed class TrajectoryObservationPresentation
{ {
private const float MillimetersPerMeter = 1000f; private const float MillimetersPerMeter = 1000f;
@@ -82,17 +123,21 @@ public sealed class TrajectoryObservationPresentation
return; return;
} }
TrajectoryObservationLsPresentationModel model = TrajectoryObservationLsPresentationModel.Create(charts);
float maxS = MaximumPathS(charts.LsSamples); float maxS = MaximumPathS(charts.LsSamples);
float maxL = MaximumLateralOffset(charts.LsSamples); float maxL = MaximumLateralOffset(charts.LsSamples);
lsPainter.DrawLine(Color.Gainsboro, -maxL, 0f, maxL, 0f, width: 2); lsPainter.DrawLine(Color.Gainsboro, 0f, 0f, maxS, 0f, width: 2);
lsPainter.DrawLine(Color.Gainsboro, 0f, 0f, 0f, maxS, width: 2); lsPainter.DrawLine(Color.Gainsboro, 0f, -maxL, 0f, maxL, width: 2);
lsPainter.DrawText(Color.White, "L-S (lateral offset / path-S)", -maxL, maxS + 150f); lsPainter.DrawText(Color.White, "S-L", maxS + 100f, maxL + 150f);
for (int index = 1; index < charts.LsSamples.Count; index++) lsPainter.DrawText(Color.White, model.HorizontalAxisLabel, maxS + 100f, -200f);
lsPainter.DrawText(Color.White, model.VerticalAxisLabel, 100f, maxL + 300f);
for (int index = 1; index < model.Samples.Count; index++)
{ {
TrajectoryObservationLsSample previous = charts.LsSamples[index - 1]; TrajectoryObservationLsPresentationPoint previous = model.Samples[index - 1];
TrajectoryObservationLsSample current = charts.LsSamples[index]; TrajectoryObservationLsPresentationPoint current = model.Samples[index];
lsPainter.DrawLine(Color.MediumPurple, ToMillimeters(previous.LateralOffset), ToMillimeters(previous.PathS), lsPainter.DrawLine(Color.MediumPurple, ToMillimeters(previous.HorizontalPathS),
ToMillimeters(current.LateralOffset), ToMillimeters(current.PathS), width: 3); ToMillimeters(previous.VerticalLateralOffset), ToMillimeters(current.HorizontalPathS),
ToMillimeters(current.VerticalLateralOffset), width: 3);
} }
} }
@@ -18,6 +18,7 @@ internal static class TrajectoryObservationChecks
RejectsObstacleOutsideConfiguredBounds(); RejectsObstacleOutsideConfiguredBounds();
VerifiesLsAndStUsePublishedTrajectoryData(); VerifiesLsAndStUsePublishedTrajectoryData();
VerifiesPresentationTextDescribesObservationWithoutSendingCommand(); VerifiesPresentationTextDescribesObservationWithoutSendingCommand();
VerifiesLsPresentationUsesPathSOnHorizontalAxis();
VerifiesRollingRequestUsesOnePublishedTrajectorySnapshot(); VerifiesRollingRequestUsesOnePublishedTrajectorySnapshot();
FreezesBootstrapVehicleForRollingRequests(); FreezesBootstrapVehicleForRollingRequests();
} }
@@ -155,6 +156,22 @@ internal static class TrajectoryObservationChecks
"observer presentation LS projection failures"); "observer presentation LS projection failures");
} }
private static void VerifiesLsPresentationUsesPathSOnHorizontalAxis()
{
TrajectoryObservationCharts charts = TrajectoryObservationCharts.Build(
CreatePublishedTrajectory(new DateTimeOffset(2026, 8, 4, 0, 0, 0, TimeSpan.Zero)),
CreateStraightSegment(), 0.5d);
TrajectoryObservationLsPresentationModel model = TrajectoryObservationLsPresentationModel.Create(charts);
Verification.Equal("path-S (m)", model.HorizontalAxisLabel, "observer LS horizontal axis label");
Verification.Equal("lateral offset (m)", model.VerticalAxisLabel, "observer LS vertical axis label");
Verification.NearlyEqual(10.25d, model.Samples[0].HorizontalPathS,
"observer LS path-S is horizontal");
Verification.NearlyEqual(0.10d, model.Samples[0].VerticalLateralOffset,
"observer LS lateral offset is vertical");
}
private static void FreezesBootstrapVehicleForRollingRequests() private static void FreezesBootstrapVehicleForRollingRequests()
{ {
DateTimeOffset effectiveAt = new DateTimeOffset(2026, 8, 4, 2, 0, 0, TimeSpan.Zero); DateTimeOffset effectiveAt = new DateTimeOffset(2026, 8, 4, 2, 0, 0, TimeSpan.Zero);