using System; using System.Collections.Generic; using System.Collections.ObjectModel; using MultiWheelC.TrajectoryPlanning.CoarsePath; using MultiWheelC.TrajectoryPlanning.EMPlanner; namespace TrajectoryOutputDemo; /// 供外部控制模块消费的单个只读轨迹点;全部字段直接来自已验证的 public sealed class ControlTrajectoryPoint { internal ControlTrajectoryPoint(EmTrajectoryPoint source) { TimeFromStartSeconds = source.TimeFromStart; XMeters = source.X; YMeters = source.Y; YawRadians = source.Yaw; SignedLongitudinalVelocityMetersPerSecond = source.SignedLongitudinalVelocity; YawRateRadiansPerSecond = source.YawRate; CurvaturePerMeter = source.VehicleCurvature; Direction = source.Direction; SegmentIndex = source.SegmentIndex; PathSMeters = source.PathS; BoundaryType = source.BoundaryType; } public double TimeFromStartSeconds { get; } public double XMeters { get; } public double YMeters { get; } public double YawRadians { get; } public double SignedLongitudinalVelocityMetersPerSecond { get; } public double YawRateRadiansPerSecond { get; } public double CurvaturePerMeter { get; } public TravelDirection Direction { get; } public int SegmentIndex { get; } public double PathSMeters { get; } public EmBoundaryType BoundaryType { get; } } /// 轨迹元数据与控制点序列的不可变组合;它不包含也不发送任何硬件命令。 public sealed class ControlTrajectorySequence { internal ControlTrajectorySequence(EmTrajectoryMetadata metadata, IReadOnlyList points) { Metadata = metadata ?? throw new ArgumentNullException(nameof(metadata)); Points = points ?? throw new ArgumentNullException(nameof(points)); } public EmTrajectoryMetadata Metadata { get; } public IReadOnlyList Points { get; } } /// 将不可变 EM 轨迹投影为控制模块可引用的只读序列,不进行采样、插值或底盘协议转换。 public sealed class ControlModuleTrajectoryAdapter { /// 逐点复制公开控制字段;调用方只能在完整非空轨迹上调用此方法。 public ControlTrajectorySequence Create(EmTrajectory trajectory) { if (trajectory == null || trajectory.Points == null || trajectory.Points.Count == 0) throw new ArgumentException("必须提供完整非空的 EM 轨迹。", nameof(trajectory)); var points = new List(trajectory.Points.Count); for (int index = 0; index < trajectory.Points.Count; index++) points.Add(new ControlTrajectoryPoint(trajectory.Points[index])); return new ControlTrajectorySequence(trajectory.Metadata, new ReadOnlyCollection(points)); } }