using System; using System.Collections.Generic; namespace MyParking.Shared { // 纯数学地把车队参考点速度分解成各成员车体系中的刚体速度。 public static class FleetKinematics { public static IReadOnlyList Decompose( FleetLayout layout, FleetMotionCommand command) { if (layout == null) { throw new ArgumentNullException(nameof(layout)); } EnsureCommandIsFinite(command); var commands = new FleetMemberCommand[layout.VehicleCount]; var referencePoint = command.ReferencePointInFleet; var referenceTwist = command.TwistAtReferencePoint; for (var index = 0; index < layout.VehicleCount; index++) { var vehicle = layout.Vehicles[index]; var offsetXMeters = vehicle.PoseInFleet.XMeters - referencePoint.XMeters; var offsetYMeters = vehicle.PoseInFleet.YMeters - referencePoint.YMeters; var twistAtVehicleInFleet = new Twist2D( referenceTwist.VxMetersPerSecond - referenceTwist.OmegaRadiansPerSecond * offsetYMeters, referenceTwist.VyMetersPerSecond + referenceTwist.OmegaRadiansPerSecond * offsetXMeters, referenceTwist.OmegaRadiansPerSecond); var fleetPoseInVehicle = FrameTransform2D.Inverse( vehicle.PoseInFleet); var twistInVehicleBody = FrameTransform2D.TransformTwistAtSamePoint( fleetPoseInVehicle, twistAtVehicleInFleet); commands[index] = new FleetMemberCommand( vehicle.VehicleId, twistInVehicleBody); } return Array.AsReadOnly(commands); } private static void EnsureCommandIsFinite( FleetMotionCommand command) { NumericGuard.EnsureFinite( command.ReferencePointInFleet.XMeters, nameof(command.ReferencePointInFleet)); NumericGuard.EnsureFinite( command.ReferencePointInFleet.YMeters, nameof(command.ReferencePointInFleet)); NumericGuard.EnsureFinite( command.TwistAtReferencePoint, nameof(command.TwistAtReferencePoint)); } } }