using System; using MultiWheelC.TrajectoryPlanning.CoarsePath; namespace MultiWheelC.TrajectoryPlanning.EMPlanner; /// /// 轨迹发布身份、来源版本、有效时间、方向段和终端边界的不可变元数据。 /// public sealed class EmTrajectoryMetadata { /// /// 创建轨迹的发布和来源元数据。验证标识、序列号、索引和枚举值; 可为 null 并会规范化为空字符串,两个 UTC 时刻的先后关系不在此处验证。 /// public EmTrajectoryMetadata( string trajectoryId, DateTimeOffset generatedAtUtc, DateTimeOffset effectiveAtUtc, long mapSnapshotId, string referencePathId, long vehicleStateSequenceId, string previousTrajectoryId, int segmentIndex, TravelDirection direction, EmTerminalType terminalType, EmLongitudinalMode longitudinalMode, EmPlanningScope planningScope) { if (string.IsNullOrWhiteSpace(trajectoryId)) throw new ArgumentException("A trajectory ID is required.", nameof(trajectoryId)); if (mapSnapshotId < 0) throw new ArgumentOutOfRangeException(nameof(mapSnapshotId)); if (string.IsNullOrWhiteSpace(referencePathId)) throw new ArgumentException("A reference path ID is required.", nameof(referencePathId)); if (vehicleStateSequenceId < 0) throw new ArgumentOutOfRangeException(nameof(vehicleStateSequenceId)); if (segmentIndex < 0) throw new ArgumentOutOfRangeException(nameof(segmentIndex)); if (!Enum.IsDefined(typeof(TravelDirection), direction)) throw new ArgumentOutOfRangeException(nameof(direction)); if (!Enum.IsDefined(typeof(EmTerminalType), terminalType)) throw new ArgumentOutOfRangeException(nameof(terminalType)); if (!Enum.IsDefined(typeof(EmLongitudinalMode), longitudinalMode)) throw new ArgumentOutOfRangeException(nameof(longitudinalMode)); if (!Enum.IsDefined(typeof(EmPlanningScope), planningScope)) throw new ArgumentOutOfRangeException(nameof(planningScope)); TrajectoryId = trajectoryId; GeneratedAtUtc = generatedAtUtc; EffectiveAtUtc = effectiveAtUtc; MapSnapshotId = mapSnapshotId; ReferencePathId = referencePathId; VehicleStateSequenceId = vehicleStateSequenceId; PreviousTrajectoryId = previousTrajectoryId ?? string.Empty; SegmentIndex = segmentIndex; Direction = direction; TerminalType = terminalType; LongitudinalMode = longitudinalMode; PlanningScope = planningScope; } /// /// 非空白的本次发布轨迹标识,由消费者用于去重、替换和追踪。 /// public string TrajectoryId { get; } /// /// 生成此元数据的 UTC 时刻;值原样保存,构造器不与生效时刻比较。 /// public DateTimeOffset GeneratedAtUtc { get; } /// /// 轨迹计划开始生效的 UTC 时刻;执行消费者负责按其调度策略解释。 /// public DateTimeOffset EffectiveAtUtc { get; } /// /// 地图快照的非负版本标识;用于确认轨迹依赖的环境版本。 /// public long MapSnapshotId { get; } /// /// 非空白的输入参考路径标识;用于关联轨迹的几何来源。 /// public string ReferencePathId { get; } /// /// 车辆状态的非负序列版本;用于判断轨迹是否基于当前状态快照。 /// public long VehicleStateSequenceId { get; } /// /// 前一轨迹的可选标识;null 输入已规范化为空字符串,空字符串表示没有可关联的前轨迹标识。 /// public string PreviousTrajectoryId { get; } /// /// 参考路径中此轨迹所属的非负方向段索引。 /// public int SegmentIndex { get; } /// /// 所属方向段的已验证行驶方向。 /// public TravelDirection Direction { get; } /// /// 轨迹最后一个终端的已验证业务类型。 /// public EmTerminalType TerminalType { get; } /// /// 生成轨迹时采用的已验证纵向终端速度语义。 /// public EmLongitudinalMode LongitudinalMode { get; } /// /// 生成轨迹时采用的已验证规划覆盖范围。 /// public EmPlanningScope PlanningScope { get; } }