using MyParking.Shared; namespace MultiWheelC.StateEstimation { /// /// 保存一次经过校验的车辆位姿和速度估计快照,统一使用SI单位。 /// public readonly struct VehicleState { /// /// 创建车辆状态,并将世界坐标速度同步转换到车体坐标系。 /// public VehicleState( double sampleTimestampSeconds, Pose2D poseInWorld, Twist2D twistInWorld, bool hasValidVelocityEstimate) { NumericGuard.EnsureFiniteNonNegative( sampleTimestampSeconds, nameof(sampleTimestampSeconds)); NumericGuard.EnsureFinite( poseInWorld, nameof(poseInWorld)); NumericGuard.EnsureFinite( twistInWorld, nameof(twistInWorld)); SampleTimestampSeconds = sampleTimestampSeconds; PoseInWorld = new Pose2D( poseInWorld.XMeters, poseInWorld.YMeters, AngleMath.NormalizeRadians( poseInWorld.YawRadians)); HasValidVelocityEstimate = hasValidVelocityEstimate; // 第一帧或定位重置后的速度不可用于闭环控制, // 此时显式置零,避免调用方误用残留速度。 TwistInWorld = hasValidVelocityEstimate ? twistInWorld : Twist2D.Zero; var worldPoseInBody = FrameTransform2D.Inverse( PoseInWorld); TwistInBody = FrameTransform2D.TransformTwistAtSamePoint( worldPoseInBody, TwistInWorld); } /// /// 获取状态源单调时钟中的采样时刻,单位为s。 /// public double SampleTimestampSeconds { get; } /// /// 获取车体中心在Detour世界坐标系中的位姿,单位为m和rad。 /// public Pose2D PoseInWorld { get; } /// /// 获取在世界坐标系中表达的车辆速度,单位为m/s和rad/s。 /// public Twist2D TwistInWorld { get; } /// /// 获取在车体坐标系中表达的车辆速度,X向前、Y向左、逆时针为正。 /// public Twist2D TwistInBody { get; } /// /// 获取当前速度估计是否已经初始化并可用于闭环控制。 /// public bool HasValidVelocityEstimate { get; } } }