2026-08-03 22:14:37 +08:00
using System ;
2026-08-03 22:22:44 +08:00
using System.Collections.Generic ;
2026-08-03 22:14:37 +08:00
using MultiWheelC.TrajectoryPlanning.CoarsePath ;
2026-08-03 22:22:44 +08:00
using MultiWheelC.TrajectoryPlanning.Mapping ;
using MultiWheelC.TrajectoryPlanning.PathSmoothing ;
2026-08-03 22:14:37 +08:00
namespace MultiWheelC.TrajectoryPlanning.EMPlanner ;
internal static class FoundationChecks
{
public static void Run ()
2026-08-03 22:22:44 +08:00
{
VerifyContracts ();
VerifyConfigurationAndRequestValidation ();
2026-08-06 20:48:44 +08:00
VerifyFullDirectionScopeContractsConfigurationAndValidation ();
2026-08-03 22:22:44 +08:00
}
private static void VerifyContracts ()
2026-08-03 22:14:37 +08:00
{
var reverseState = new VehicleMotionState (
new Pose2D ( 1.5d , - 2d , 0.25d ),
- 0.15d ,
- 0.03d ,
new DateTimeOffset ( 2026 , 8 , 3 , 0 , 0 , 0 , TimeSpan . Zero ),
17L );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.15d , reverseState . SignedLongitudinalSpeedMetersPerSecond ,
"reverse signed speed" );
var point = new EmTrajectoryPoint (
1.25d ,
- 0.75d ,
0.5d ,
- 0.12d ,
0.4d ,
- 0.2d ,
3 ,
0.6d ,
0.8d ,
TravelDirection . Reverse ,
EmBoundaryType . GearSwitchApproach ,
- 0.04d ,
0.03d );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1.25d , point . X , "point x" );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.75d , point . Y , "point y" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.5d , point . Yaw , "point yaw" );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.12d , point . SignedLongitudinalVelocity , "point signed speed" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.4d , point . TimeFromStart , "point time" );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.2d , point . VehicleCurvature , "point curvature" );
EMPlannerVerificationHost . Verification . Equal ( 3 , point . SegmentIndex , "point segment index" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.6d , point . SegmentLocalS , "point segment local s" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.8d , point . PathS , "point path s" );
EMPlannerVerificationHost . Verification . Equal ( TravelDirection . Reverse , point . Direction , "point direction" );
EMPlannerVerificationHost . Verification . Equal ( EmBoundaryType . GearSwitchApproach , point . BoundaryType , "point boundary type" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.12d , point . Speed , "point derived speed" );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.12d * Math . Cos ( 0.5d ), point . VelocityX , "point derived velocity x" );
EMPlannerVerificationHost . Verification . NearlyEqual (- 0.12d * Math . Sin ( 0.5d ), point . VelocityY , "point derived velocity y" );
EMPlannerVerificationHost . Verification . NearlyEqual ((- 0.12d ) * (- 0.2d ), point . YawRate , "point derived yaw rate" );
}
2026-08-03 22:22:44 +08:00
private static void VerifyConfigurationAndRequestValidation ()
{
EmPlannerConfiguration configuration = EmPlannerConfiguration . CreateDefault ();
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Scheduling . ReplanPeriodSeconds , "replan period" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 6d , configuration . Scheduling . TimeHorizonSeconds , "time horizon" );
2026-08-06 20:48:44 +08:00
EMPlannerVerificationHost . Verification . True ( configuration . Scheduling . DistanceHorizonMeters > 0d ,
"distance horizon remains positive" );
2026-08-03 22:22:44 +08:00
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.05d , configuration . Scheduling . OutputTimeStepSeconds , "output time step" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.10d , configuration . Scheduling . SolverTimeoutSeconds , "solver timeout" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.30d , configuration . Scheduling . HandoffLookaheadSeconds , "handoff lookahead" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Scheduling . MaximumVehicleStateAgeSeconds , "vehicle state age" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.10d , configuration . Corridor . LongitudinalSampleSpacingMeters , "longitudinal sample spacing" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.025d , configuration . Corridor . LateralSampleSpacingMeters , "lateral sample spacing" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.30d , configuration . Corridor . MaximumLateralOffsetMeters , "maximum lateral offset" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.02d , configuration . Corridor . AdditionalClearanceReserveMeters , "clearance reserve" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.025d , configuration . Corridor . MaximumCollisionCheckStepMeters , "collision check step" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.50d , configuration . Frenet . MaximumProjectionDistanceMeters , "maximum projection distance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Frenet . MinimumFrenetDenominator , "minimum Frenet denominator" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1e-8d , configuration . Frenet . BoundaryAnchorToleranceMeters , "boundary anchor tolerance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.05d , configuration . Lateral . MaximumLateralStepPerIterationMeters , "lateral trust region" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.50d , configuration . Lateral . MaximumLateralSlope , "maximum lateral slope" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d , configuration . Lateral . MaximumLateralSecondDerivativePerMeter , "maximum lateral second derivative" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 2d , configuration . Lateral . MaximumLateralThirdDerivativePerSquareMeter , "maximum lateral third derivative" );
2026-08-06 20:48:44 +08:00
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d , configuration . Longitudinal . MaximumForwardSpeedMetersPerSecond , "maximum forward speed" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.5d , configuration . Longitudinal . MaximumReverseSpeedMetersPerSecond , "maximum reverse speed" );
2026-08-03 22:22:44 +08:00
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Longitudinal . MaximumAccelerationMetersPerSecondSquared , "maximum acceleration" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.30d , configuration . Longitudinal . MaximumDecelerationMetersPerSecondSquared , "maximum deceleration" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.50d , configuration . Longitudinal . MaximumJerkMetersPerSecondCubed , "maximum jerk" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Longitudinal . MaximumLateralAccelerationMetersPerSecondSquared , "maximum lateral acceleration" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.50d , configuration . Longitudinal . MaximumCurvatureRatePerMeterPerSecond , "maximum curvature rate" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.01d , configuration . Longitudinal . StopSpeedToleranceMetersPerSecond , "stop speed tolerance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d , configuration . Longitudinal . ZeroSpeedHoldSeconds , "zero speed hold" );
EMPlannerVerificationHost . Verification . Equal ( 5 , configuration . Solver . MaximumOuterIterations , "maximum outer iterations" );
EMPlannerVerificationHost . Verification . Equal ( 4000 , configuration . Solver . MaximumOsqpIterations , "maximum OSQP iterations" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1e-5d , configuration . Solver . AbsoluteTolerance , "absolute tolerance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1e-5d , configuration . Solver . RelativeTolerance , "relative tolerance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1e-5d , configuration . Solver . StrictResidualTolerance , "strict residual tolerance" );
EMPlannerVerificationHost . Verification . Equal ( true , configuration . Solver . WarmStart , "warm start" );
EMPlannerVerificationHost . Verification . Equal ( true , configuration . Solver . Polish , "polish" );
EMPlannerVerificationHost . Verification . Equal ( false , configuration . Solver . NativeVerbose , "native verbose" );
VerifyLateralWeights ( configuration . Lateral . Weights );
VerifyLongitudinalWeights ( configuration . Longitudinal . Weights );
2026-08-05 17:13:09 +08:00
EmPlannerConfiguration insufficientPreview = EmPlannerConfiguration . CreateDefault ();
insufficientPreview . Scheduling . DistanceHorizonMeters = 0.01d ;
EmPlanningRequestValidationResult insufficientPreviewValidation = EmPlanningRequestValidator . Validate (
CreateValidRequest ( insufficientPreview ));
AssertStatus ( EmPlanningStatus . InvalidInput , insufficientPreviewValidation , "insufficient stopping preview" );
EMPlannerVerificationHost . Verification . True (
insufficientPreviewValidation . FailureReason . Contains ( "DistanceHorizonMeters" ) &&
insufficientPreviewValidation . FailureReason . Contains ( "required" ) &&
insufficientPreviewValidation . FailureReason . Contains ( "configured" ),
"insufficient stopping preview describes configured and required distance" );
2026-08-03 22:22:44 +08:00
EmPlanningRequest valid = CreateValidRequest ( configuration );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( null !, valid . Map , valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "null reference path" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , null !, valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "null map" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , null !, 0 , EmMotionModel . NonholonomicForwardReverse )), "null configuration" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , CreateMap ( false ), valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "map not ready" );
AssertStatus ( EmPlanningStatus . InvalidReferencePath , EmPlanningRequestValidator . Validate (
CreateRequest ( CreateFailedReferencePath (), valid . Map , valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "smoothing failure" );
AssertStatus ( EmPlanningStatus . InvalidReferencePath , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , configuration , 1 , EmMotionModel . NonholonomicForwardReverse )), "segment index" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , CreateState ( double . NaN , 9L , valid . RequestedAtUtc ), configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "non-finite speed" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , CreateState ( 0d , - 1L , valid . RequestedAtUtc ), configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "negative sequence ID" );
AssertStatus ( EmPlanningStatus . StaleVehicleState , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , CreateState ( 0d , 9L , valid . RequestedAtUtc . AddSeconds (- 1d )), configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "stale state" );
AssertStatus ( EmPlanningStatus . InvalidInput , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , new VehicleParameters { LengthMeters = 1d , WidthMeters = 0.5d }, valid . VehicleState , configuration , 0 , EmMotionModel . NonholonomicForwardReverse )), "missing curvature limit" );
AssertStatus ( EmPlanningStatus . UnsupportedMotionMode , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . CrabTranslation )), "crab motion" );
AssertStatus ( EmPlanningStatus . UnsupportedMotionMode , EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , configuration , 0 , EmMotionModel . InPlaceRotation )), "in-place rotation" );
EmPlanningRequestValidationResult first = EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , configuration , 1 , EmMotionModel . NonholonomicForwardReverse ));
EmPlanningRequestValidationResult second = EmPlanningRequestValidator . Validate (
CreateRequest ( valid . ReferencePath , valid . Map , valid . Vehicle , valid . VehicleState , configuration , 1 , EmMotionModel . NonholonomicForwardReverse ));
EMPlannerVerificationHost . Verification . Equal ( first . FailureReason , second . FailureReason , "deterministic rejection message" );
}
2026-08-06 20:48:44 +08:00
private static void VerifyFullDirectionScopeContractsConfigurationAndValidation ()
{
EmPlannerConfiguration defaults = EmPlannerConfiguration . CreateDefault ();
EmPlanningRequest fullRequest = CreateValidRequest ( defaults , EmPlanningScope . FullDirectionSegment );
EMPlannerVerificationHost . Verification . Equal ( EmPlanningScope . FullDirectionSegment , fullRequest . PlanningScope ,
"full request freezes its scope" );
var fullMetadata = new EmTrajectoryMetadata ( "full-scope" , DateTimeOffset . UnixEpoch , DateTimeOffset . UnixEpoch ,
1L , "reference" , 1L , string . Empty , 0 , TravelDirection . Forward , EmTerminalType . Goal ,
EmLongitudinalMode . ExactStopAtBoundary , EmPlanningScope . FullDirectionSegment );
EMPlannerVerificationHost . Verification . Equal ( EmPlanningScope . FullDirectionSegment , fullMetadata . PlanningScope ,
"metadata freezes its scope" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d ,
defaults . Longitudinal . DesiredForwardSpeedMetersPerSecond , "forward desired speed" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.5d ,
defaults . Longitudinal . DesiredReverseSpeedMetersPerSecond , "reverse desired speed" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d ,
defaults . Longitudinal . MaximumForwardSpeedMetersPerSecond , "forward hard limit" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.5d ,
defaults . Longitudinal . MaximumReverseSpeedMetersPerSecond , "reverse hard limit" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.20d ,
defaults . Scheduling . MaximumOptimizationTimeStepSeconds , "adaptive maximum dt" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.10d ,
defaults . Scheduling . MaximumOptimizationSpatialStepMeters , "adaptive maximum ds" );
EMPlannerVerificationHost . Verification . Equal ( 401 , defaults . Scheduling . MaximumOptimizationKnotCount ,
"optimization knot cap" );
EMPlannerVerificationHost . Verification . Equal ( 5001 , defaults . Scheduling . MaximumPublishedSampleCount ,
"publication sample cap" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.03d ,
defaults . Validation . TerminalPositionToleranceMeters , "terminal position tolerance" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 5d * Math . PI / 180d ,
defaults . Validation . TerminalYawToleranceRadians , "terminal yaw tolerance" );
EMPlannerVerificationHost . Verification . Equal ( EmPlanningStatus . NoProgress , EmPlanningStatus . NoProgress ,
"no-progress status exists" );
EMPlannerVerificationHost . Verification . Equal ( EmPlanningStatus . TerminalPoseMismatch ,
EmPlanningStatus . TerminalPoseMismatch , "terminal-pose status exists" );
EMPlannerVerificationHost . Verification . Equal ( EmPlanningStatus . FullSegmentResourceLimitExceeded ,
EmPlanningStatus . FullSegmentResourceLimitExceeded , "resource-limit status exists" );
EmPlannerConfiguration copied = ( EmPlannerConfiguration ) typeof ( EmPlannerConfiguration )
. GetMethod ( "Copy" , System . Reflection . BindingFlags . Instance | System . Reflection . BindingFlags . NonPublic )!
. Invoke ( defaults , null )!;
defaults . Longitudinal . DesiredForwardSpeedMetersPerSecond = 0.25d ;
defaults . Scheduling . MaximumOptimizationKnotCount = 3 ;
defaults . Validation . TerminalPositionToleranceMeters = 0.01d ;
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d ,
copied . Longitudinal . DesiredForwardSpeedMetersPerSecond , "copy keeps desired forward speed" );
EMPlannerVerificationHost . Verification . Equal ( 401 , copied . Scheduling . MaximumOptimizationKnotCount ,
"copy keeps knot cap" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 0.03d ,
copied . Validation . TerminalPositionToleranceMeters , "copy keeps terminal tolerance" );
EmPlannerConfiguration invalidKnotCap = EmPlannerConfiguration . CreateDefault ();
invalidKnotCap . Scheduling . MaximumOptimizationKnotCount = 2 ;
AssertStatus ( EmPlanningStatus . InvalidInput ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( invalidKnotCap , EmPlanningScope . FullDirectionSegment )),
"invalid optimization knot cap" );
EmPlannerConfiguration invalidDesiredSpeed = EmPlannerConfiguration . CreateDefault ();
invalidDesiredSpeed . Longitudinal . DesiredForwardSpeedMetersPerSecond = 1.01d ;
AssertStatus ( EmPlanningStatus . InvalidInput ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( invalidDesiredSpeed , EmPlanningScope . FullDirectionSegment )),
"desired speed above hard limit" );
EmPlannerConfiguration invalidYawTolerance = EmPlannerConfiguration . CreateDefault ();
invalidYawTolerance . Validation . TerminalYawToleranceRadians = Math . PI + 0.01d ;
AssertStatus ( EmPlanningStatus . InvalidInput ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( invalidYawTolerance , EmPlanningScope . FullDirectionSegment )),
"terminal yaw tolerance above pi" );
EmPlannerConfiguration shortLegacyWindow = EmPlannerConfiguration . CreateDefault ();
shortLegacyWindow . Scheduling . DistanceHorizonMeters = 0.01d ;
AssertStatus ( EmPlanningStatus . Success ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( shortLegacyWindow , EmPlanningScope . FullDirectionSegment )),
"full scope ignores legacy stopping-preview truncation" );
AssertStatus ( EmPlanningStatus . InvalidInput ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( shortLegacyWindow , EmPlanningScope . RollingHorizon )),
"rolling scope retains legacy stopping-preview validation" );
AssertStatus ( EmPlanningStatus . InvalidInput ,
EmPlanningRequestValidator . Validate ( CreateValidRequest ( EmPlannerConfiguration . CreateDefault (),
( EmPlanningScope ) 99 )), "undefined planning scope" );
}
2026-08-03 22:22:44 +08:00
private static void VerifyLateralWeights ( LateralWeights weights )
{
EMPlannerVerificationHost . Verification . NearlyEqual ( 10d , weights . ReferenceOffset , "lateral reference weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d , weights . HeadingDeviation , "lateral heading weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 5d , weights . SecondDerivative , "lateral second derivative weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 10d , weights . ThirdDerivative , "lateral third derivative weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 5d , weights . Curvature , "lateral curvature weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 20d , weights . CurvatureVariation , "lateral curvature variation weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 5d , weights . PreviousTrajectory , "lateral previous weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 10d , weights . RollingTerminal , "lateral rolling terminal weight" );
}
private static void VerifyLongitudinalWeights ( LongitudinalWeights weights )
{
EMPlannerVerificationHost . Verification . NearlyEqual ( 10d , weights . ReferenceSpeed , "longitudinal speed weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d , weights . Acceleration , "longitudinal acceleration weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 10d , weights . Jerk , "longitudinal jerk weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 5d , weights . PreviousTrajectory , "longitudinal previous weight" );
EMPlannerVerificationHost . Verification . NearlyEqual ( 1d , weights . TerminalAcceleration , "longitudinal terminal acceleration weight" );
}
private static void AssertStatus ( EmPlanningStatus expected , EmPlanningRequestValidationResult actual , string name )
{
EMPlannerVerificationHost . Verification . Equal ( expected , actual . Status , name );
}
2026-08-06 20:48:44 +08:00
private static EmPlanningRequest CreateValidRequest ( EmPlannerConfiguration configuration ,
EmPlanningScope planningScope = EmPlanningScope . RollingHorizon )
2026-08-03 22:22:44 +08:00
{
DateTimeOffset requestedAtUtc = new DateTimeOffset ( 2026 , 8 , 3 , 1 , 0 , 0 , TimeSpan . Zero );
return CreateRequest (
CreateValidReferencePath (),
CreateMap ( true ),
new VehicleParameters { LengthMeters = 1d , WidthMeters = 0.5d , SafetyMarginMeters = 0.05d , MaximumCurvaturePerMeter = 0.5d },
CreateState ( 0d , 9L , requestedAtUtc ),
configuration ,
0 ,
2026-08-06 20:48:44 +08:00
EmMotionModel . NonholonomicForwardReverse ,
planningScope );
2026-08-03 22:22:44 +08:00
}
private static EmPlanningRequest CreateRequest (
PathSmoothingResult referencePath ,
PlanningGridMap map ,
VehicleParameters vehicle ,
VehicleMotionState vehicleState ,
EmPlannerConfiguration configuration ,
int segmentIndex ,
2026-08-06 20:48:44 +08:00
EmMotionModel motionModel ,
EmPlanningScope planningScope = EmPlanningScope . RollingHorizon )
2026-08-03 22:22:44 +08:00
{
DateTimeOffset requestedAtUtc = new DateTimeOffset ( 2026 , 8 , 3 , 1 , 0 , 0 , TimeSpan . Zero );
return new EmPlanningRequest (
referencePath ,
map ,
vehicle ,
vehicleState ,
configuration ,
segmentIndex ,
null !,
requestedAtUtc ,
requestedAtUtc . AddSeconds ( 0.1d ),
"trajectory-1" ,
"reference-1" ,
string . Empty ,
2026-08-06 20:48:44 +08:00
motionModel ,
planningScope );
2026-08-03 22:22:44 +08:00
}
private static VehicleMotionState CreateState ( double speed , long sequenceId , DateTimeOffset capturedAtUtc )
{
return new VehicleMotionState ( new Pose2D ( 0d , 0d , 0d ), speed , null , capturedAtUtc , sequenceId );
}
private static PlanningGridMap CreateMap ( bool planningReady )
{
var result = new PlanningMapFactory (). Create ( new PlanningMapRequest
{
Bounds = new MapBoundsMm (- 2000f , 2000f , - 2000f , 2000f ),
ResolutionMm = 100f ,
ObstacleSources = new List < IMapObstacleSource >(),
AllowExplicitEmptyMap = planningReady ,
});
if (! result . Succeeded || result . Map == null )
throw new InvalidOperationException ( "Unable to create test planning map." );
return result . Map ;
}
private static PathSmoothingResult CreateValidReferencePath ()
{
var points = new List < SmoothedPathPoint >
{
new SmoothedPathPoint ( 0d , 0d , 0d , 0d , 0d , TravelDirection . Forward , 0d , 0d , 1d , false , SmoothedPathPointSource . Anchor ),
new SmoothedPathPoint ( 1d , 0d , 0d , 0d , 1d , TravelDirection . Forward , 0d , 0d , 1d , false , SmoothedPathPointSource . Anchor ),
};
var segments = new List < SmoothedPathSegment >
{
new SmoothedPathSegment ( 0 , TravelDirection . Forward , 0 , 1 , false , false ),
};
var metrics = new PathQualityMetrics ( true , 1d , 0d , 0d , 0d , 0d , 1d , 0d , 0d , 0d , 0d , 0d );
return PathSmoothingResult . PublishLocalG2 ( PathSmoothingStatus . Complete , points , segments ,
new PathSmoothingDiagnostics ( metrics , TimeSpan . Zero ), new List < PathSmoothingRegionReport >());
}
private static PathSmoothingResult CreateFailedReferencePath ()
{
return PathSmoothingResult . Failure ( PathSmoothingStatus . Failed , new PathSmoothingDiagnostics ());
}
2026-08-03 22:14:37 +08:00
}